Description
The token contract exposes a balance_at(owner, ledger) function intended to return a voter's token balance at a specific historical ledger (snapshot), which the governance contract uses to prevent vote manipulation via flash-loan or last-minute token acquisition.
The current implementation is a stub that ignores the ledger parameter and simply returns the current balance:
pub fn balance_at(env: Env, owner: Address, _ledger: u64) -> i128 {
// TODO: implement historical snapshot
GovernanceStorage::balance(&env, &owner) // returns CURRENT balance, not snapshot
}
The governance contract stores a snapshot_ledger on each proposal (set at proposal creation time) and passes it to balance_at when computing a voter's voting power. Since the snapshot is not honored, an attacker can:
- Acquire a large token position after a proposal is created
- Vote with that inflated balance
- Transfer tokens away after voting
This undermines the entire voting-power fairness model.
Acceptance Criteria
Security Impact
Without snapshot voting, the system is vulnerable to vote manipulation via token transfers between voters within the voting window. This is a security issue, not just a correctness issue.
Priority
Critical
Estimated Effort
Large — requires storage schema changes, migration strategy, and new tests.
Description
The token contract exposes a
balance_at(owner, ledger)function intended to return a voter's token balance at a specific historical ledger (snapshot), which the governance contract uses to prevent vote manipulation via flash-loan or last-minute token acquisition.The current implementation is a stub that ignores the
ledgerparameter and simply returns the current balance:The governance contract stores a
snapshot_ledgeron each proposal (set at proposal creation time) and passes it tobalance_atwhen computing a voter's voting power. Since the snapshot is not honored, an attacker can:This undermines the entire voting-power fairness model.
Acceptance Criteria
balance_atbinary-searches checkpointsbalance_at(owner, ledger)returns the balance the owner held atledger, not the current balancecast_votecorrectly usesproposal.snapshot_ledgerto query historical voting powerbalance_atis documented indocs/gas-budgeting.mddocs/storage.mdSecurity Impact
Without snapshot voting, the system is vulnerable to vote manipulation via token transfers between voters within the voting window. This is a security issue, not just a correctness issue.
Priority
Critical
Estimated Effort
Large — requires storage schema changes, migration strategy, and new tests.