Charter is a set of Soroban smart contracts for on-chain treasury management. An organization deploys a treasury with a set of approvers and an approval threshold, organizes its funds into budget categories with lifetime spending caps, and releases funds only when enough approvers sign off. A factory contract deploys and tracks these treasuries so many organizations can run independent treasuries from a single, verifiable deployment. Every balance, category, request, and approval is stored on-chain and publicly readable.
| Name | Role | GitHub |
|---|---|---|
| Fuhad | Lead maintainer | @fadesany |
Charter splits treasury management across two contracts:
- A treasury holds a single token for one organization. Funds are grouped into budget categories, each with a lifetime cap. Spending happens through a request-and-approval flow: a member submits a request against a category, approvers sign it, and once the approval threshold is met the payout executes automatically.
- A factory deploys and registers treasuries. Each treasury is deployed from a single verified wasm hash with a deterministic address, so every organization runs the same reviewed code.
This design suits DAOs, grant programs, and any group that needs multi-party control over shared funds with an auditable, on-chain record.
Network: Testnet (Test SDF Network ; September 2015)
| Contract | Address | Wasm hash |
|---|---|---|
| Factory | CCUQBFFRGR4RUWHKLWSRWKBL3WORHNTHFLTKMHTNUZL4T5733ODN5WD4 |
e6ee93a93dd18927abab8dc1c4f95ec820da020310b2b2a45a0588b91581df8a |
| Treasury (reference deployment) | CAH4PUADD2X3K52TKETWTIL4GHPZT55LWUEVVOSH6B3D3KA2ZH7HQGTT |
b72f664802f395192375b4fca2e0930cff6f994a8053ca568d4f96eb0032ba6c |
Treasuries are normally created through the factory's deploy_treasury. The treasury above is one reference deployment kept for verification; both wasm hashes are reproducible from stellar contract fetch.
- Rust
1.92.0(pinned inrust-toolchain.toml, which also adds thewasm32v1-nonetarget) - Stellar CLI
26.x(stellar 26.1.0is the tested version)
CI builds and tests on Linux, and the contracts are platform-independent Soroban wasm.
.cargo/config.tomlcarries a Windows (windows-gnu) linker override for contributors who build natively on Windows; it is inert on other hosts.
# Compile the contracts to wasm
stellar contract build
# Run the test suite (47 treasury + 11 factory = 58 tests)
cargo testThe scripts under scripts/ deploy and exercise the contracts end to end. Run them in order:
# 1. Create and fund testnet identities (deployer, admin, approvers, requester)
./scripts/setup-testnet.sh
# 2. Build, upload the treasury wasm, deploy the factory, and initialize it.
# Writes the resulting factory address + treasury wasm hash to scripts/.env
./scripts/deploy.sh
# 3. Verify the deployment by exercising the factory's read paths.
# Pass `deploy-treasury` to also deploy a treasury through the factory.
./scripts/verify.sh
./scripts/verify.sh deploy-treasuryThe factory must be initialized with the treasury's wasm hash before it can deploy treasuries — deploy.sh handles this ordering (upload treasury wasm → deploy factory → initialize).
contracts/
├── treasury/ # Per-organization treasury: categories, caps, approval flow
├── factory/ # Deploys and registers treasuries from the treasury wasm hash
└── test-token/ # Minimal mintable token used only in tests and verification
scripts/
├── setup-testnet.sh # Create + fund testnet identities
├── deploy.sh # Build, upload, deploy, initialize
└── verify.sh # Exercise factory read/deploy paths on-chain
A treasury holds one token for one organization and is controlled by a set of approvers with an approval threshold. Its lifecycle:
- Initialize with an admin, approvers, threshold, and token.
- Create categories, each with a lifetime spending cap.
- Deposit the token into the treasury.
- Submit a request to spend from a category.
- Approve — when approvals reach the threshold, the payout executes automatically and the category's spent total increases. Requests can also be rejected or cancelled.
Caps are lifetime totals: a category tracks cumulative spent against its cap and never resets.
The factory is initialized once with the treasury wasm hash. Each deploy_treasury call deploys a treasury at a deterministic address (salted by a sequential org id), initializes it, and records an on-chain org registry entry. Reads are available through get_org, get_org_count, and the paginated get_orgs.
Contributions are welcome. To get started:
- Browse the open issues — issues labelled
good first issueare a good entry point. - Fork the repo and create a branch (
feat/…,fix/…, ordocs/…). - Make your change and ensure
cargo testpasses andstellar contract buildsucceeds. - Open a pull request against
mainwith a clear description. Commits follow Conventional Commits (feat(scope):,fix(scope):,docs(scope):).
See SECURITY.md for how to report vulnerabilities.
Licensed under the MIT License.