Skip to content

[governance-dao] finalize() refunds config.proposal_threshold from live config not the amount locked at creation — admin can steal proposer deposit by changing config #137

Description

@nonsobethel0-dev

Summary

In contracts/governance-dao/src/lib.rs, create_proposal() locks config.proposal_threshold tokens from the proposer. finalize() refunds config.proposal_threshold by reading the live config at finalization time — not the amount that was originally deposited.

Code

create_proposal (line 129): deposits current threshold

gov_token.transfer(&proposer, &env.current_contract_address(), &config.proposal_threshold);

finalize (line 251): refunds current threshold

let config: DaoConfig = env.storage().instance().get(&StorageKey::Config).unwrap();
gov_token.transfer(&env.current_contract_address(), &proposal.proposer, &config.proposal_threshold);
// ↑ uses live config.proposal_threshold, not what was deposited

Attack Scenarios

Scenario A — Admin steals proposer tokens:

  1. Proposer locks 1,000 SHIELD at creation (threshold = 1,000)
  2. Admin calls update_config setting threshold = 1 (before voting ends)
  3. finalize refunds only 1 SHIELD — proposer loses 999 SHIELD

Scenario B — Proposer extracts excess tokens:

  1. Proposer locks 100 SHIELD (threshold = 100)
  2. Admin raises threshold to 10,000 before finalize
  3. finalize attempts to transfer 10,000 SHIELD — will panic if contract has < 10,000

Fix

Store the deposited amount on the Proposal struct at creation and refund that exact amount:

// In Proposal struct
pub deposit: i128,

// In create_proposal
let deposit = config.proposal_threshold;
gov_token.transfer(&proposer, &env.current_contract_address(), &deposit);
let proposal = Proposal { ..., deposit, ... };

// In finalize
gov_token.transfer(&env.current_contract_address(), &proposal.proposer, &proposal.deposit);

Severity: High

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programbugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions