The Governance contract determines voting power at the time of voting rather than using a snapshot taken at proposal creation. This allows voters to temporarily increase their voting power to influence proposals, then if needed , reduce it afterward (through emergency withdrawal) , undermining the fairness and security of the governance process.
https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/governance/proposals/Governance.sol
The contract calls _veToken.getVotingPower(msg.sender) during voting, which returns the voter’s current voting power. There is no mechanism to snapshot voting power at the time of proposal creation or voting start.
Proposal #789 is created with a 7-day voting period.
Attacker deposits tokens to increase their voting power on Day 6.
Attacker votes with maximum power on the same Day 6.
Attacker uses the emergencyWithdraw() function in the veRAACToken contract to withdraws tokens after the 3 day emergency delay period , reducing their voting power.
Proposal outcome is influenced by the attacker’s temporary stake.
Governance Attacks: Malicious actors can sway critical decisions
manual review
Add Snapshot Timestamp to Proposal Data
Modify the ProposalCore struct to include a snapshot timestamp:
Set Snapshot on Proposal Creation
During proposal creation, store the snapshot timestamp;
Use Historical Voting Power in Votes
Update castVote() to use the snapshot timestamp:
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.