Skip to content

[governance-dao] update_config can change total_supply mid-vote — quorum calculation in finalize() uses new supply, invalidating ongoing proposals #138

Description

@nonsobethel0-dev

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:

  1. Proposal is active; votes_for = 500, total_supply = 10,000 (quorum = 1,000 → proposal fails)
  2. Admin calls update_config setting total_supply = 5,000
  3. quorum_needed = 5,000 × 10% = 500 → proposal now passes with only 500 votes

Increasing quorum to force a fail:

  1. Proposal is 90% approved with high participation
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions