On-chain governance for DAOs on Solana. The program combines NFT-weighted governance voting with an optional council co-approval layer.
Program ID: Cz7vK7QDJ8MYVUsgYxvEudXEZbAFqGYfzPuhUS5RWKjm
Governance power is derived from NFT holdings in a configured collection. Tier boundaries and weights are configurable during initialization.
Default tier example:
| NFTs held | Governance Power |
|---|---|
| 0 | 0 |
| 1–2 | 1 |
| 3–5 | 2 |
| 6+ | 5 |
A proposal passes when both conditions are met:
- Total governance power across YES + NO votes reaches
min_quorum_gp - YES votes are at least
pass_threshold% of total governance power
Council voting acts as a co-requirement:
- If any council votes exist, council YES must be strictly greater than council NO
- If no council votes are cast, governance power voting alone decides the outcome
Each wallet receives one council vote per calendar month. The configured council wallets and admin can vote without this monthly limit.
| Instruction | Who can call | What it does |
|---|---|---|
initialize_dao |
Admin (once) | Initializes DAO config, vote tiers, council settings, and NFT collection |
create_proposal |
Anyone | Creates a proposal with voting window and pass threshold |
cast_vote |
Any voter | Casts governance or council vote; snapshots NFT count at vote time |
finalize_proposal |
Anyone | Finalizes after ends_at and records Passed/Rejected |
cancel_proposal |
Proposer or admin | Cancels an Active/Draft proposal before it ends |
update_config |
Admin | Updates tiers, council quota, or admin key |
transfer_admin |
Admin | Starts two-step admin transfer |
accept_admin |
Pending admin | Completes admin transfer |
close_vote |
Voter | Reclaims rent from vote account after finalization |
close_council_credits |
Wallet owner | Reclaims rent from monthly council credit tracker |
Prerequisites: Rust stable, Solana CLI 2.1.0, Anchor CLI 0.31.1, Node.js 20+
git clone <repo-url>
cd dao-voting-program
anchor build
anchor testDocker workflow:
docker compose run --rm build
docker compose up localnet # starts solana-test-validator
docker compose run --rm test # runs tests against itCommon make shortcuts:
make build # anchor build
make test # anchor test
make fmt # cargo fmt --all
make lint # cargo clippy --all-targets -- -D warnings
make clean # cargo clean (workspace + kani)
make deploy-devnet
make deploy-mainnetprograms/<dao_voting_program>/src/
├── lib.rs
├── error.rs
├── events.rs
├── seeds.rs
├── state/
│ ├── dao_config.rs # DaoConfig account, calculate_gp(), tier validation
│ ├── proposal.rs # Proposal account, should_pass()
│ ├── vote.rs # Vote record (immutable after creation)
│ └── council_credits.rs # Per-wallet monthly credit tracker
└── instructions/
├── initialize_dao.rs
├── create_proposal.rs
├── cast_vote.rs
├── finalize_proposal.rs
├── cancel_proposal.rs
├── update_config.rs
├── transfer_admin.rs
├── accept_admin.rs
├── close_vote.rs
└── close_council_credits.rs
kani_verification/ # Formal verification (standalone crate)
├── src/dao_proofs.rs # Kani harnesses across governance domains
└── verify.sh # Runner script
The kani_verification/ crate includes Kani harnesses for arithmetic safety, tier logic, voting-window constraints, authority guards, and council co-approval behavior.
make verify # full proof run
make verify-quick # bounded run with --default-unwind 4
make verify-one HARNESS=prove_council_veto_blocks_passing_gpProof outputs are stored in kani_verification/proofs/.
Security-sensitive checks include:
- Threshold and quorum validation
- Admin authority guards on configuration updates
- Council co-approval enforcement during proposal finalization
- Vote account immutability after creation
For vulnerability reports, contact the repository maintainers through your standard private disclosure channel.
# Devnet
solana config set --url devnet
anchor deploy --provider.cluster devnet
# Mainnet
./scripts/deploy-mainnet.shMIT.