The governance contract fails to take snapshott total voting power when proposals are created. Attackers can artificially reduce the total voting power after proposal creation to lower the quorum requirement, enabling proposals to pass with fewer votes than originally needed.
The quorum() uses current total voting power:
The _veToken.getTotalVotingPower looks like this
The issue is the getTotalVotingPower can reduce or increase because there is no snapshot of it when proposal is being created and as such will affect the quorum when it changes.
Attack Scenario:
Setup
Total veTokens in system: 1,000,000
Quorum rule: 40% of total → 400,000 votes needed
Alice holds 500,000 veTokens
Step 1: Create Proposal
Alice starts a new proposal
System snapshots her voting power: 500,000 votes
Step 2: Withdraw Tokens
Alice immediately withdraws all 500,000 veTokens
New total voting power: 500,000 (1M - 500k)
New quorum: 40% of 500k = 200,000 votes needed
Step 3: Vote
Alice votes using her snapshotted 500,000 votes
Votes counted: 500,000 (from snapshot)
Current quorum: 200,000
Result
Proposal passes with 500k votes
Only needed 20% of original total voting power
Manual review
Consider snapshotting Total voting power when creating proposal
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.