Summary
contracts/governance-dao/src/lib.rs stores total_supply inside DaoConfig in instance storage. Admin can call update_config() at any time, including during an active vote. finalize() reads config.total_supply at finalization time to compute quorum, not the supply at proposal creation.
Code
finalize (line 229–232):
let config: DaoConfig = env.storage().instance().get(&StorageKey::Config).unwrap();
let total_supply = config.total_supply; // ← reads CURRENT supply
let quorum_needed = total_supply * config.quorum_bps as i128 / 10_000;
Attack Scenarios
Reducing quorum to force a pass:
- Proposal is active; votes_for = 500, total_supply = 10,000 (quorum = 1,000 → proposal fails)
- Admin calls
update_config setting total_supply = 5,000
- quorum_needed = 5,000 × 10% = 500 → proposal now passes with only 500 votes
Increasing quorum to force a fail:
- Proposal is 90% approved with high participation
- Admin inflates total_supply to make the quorum unreachable, causing the proposal to fail
Impact
- Governance integrity is undermined — admin can unilaterally decide the outcome of any proposal by adjusting
total_supply
total_supply is particularly sensitive because it cannot be verified on-chain against the actual token's total supply (no oracle)
Fix
Snapshot total_supply at proposal creation and store it on the Proposal struct:
// In Proposal struct
pub total_supply_at_creation: i128,
// In finalize
let quorum_needed = proposal.total_supply_at_creation * config.quorum_bps as i128 / 10_000;
Severity: High
Summary
contracts/governance-dao/src/lib.rsstorestotal_supplyinsideDaoConfigin instance storage. Admin can callupdate_config()at any time, including during an active vote.finalize()readsconfig.total_supplyat finalization time to compute quorum, not the supply at proposal creation.Code
finalize(line 229–232):Attack Scenarios
Reducing quorum to force a pass:
update_configsetting total_supply = 5,000Increasing quorum to force a fail:
Impact
total_supplytotal_supplyis particularly sensitive because it cannot be verified on-chain against the actual token's total supply (no oracle)Fix
Snapshot
total_supplyat proposal creation and store it on theProposalstruct:Severity: High