The quorum()
function uses the current total voting power (_veToken.getTotalVotingPower()
) instead of taking a snapshot at proposal creation time. This allows malicious actors to manipulate proposal execution by minting or burning veRAAC tokens after voting ends.
The quorum()
function calculates the required quorum based on the current total voting power:
This creates two critical issues:
A proposal that reached quorum during voting period may become unexecutable if veRAAC tokens are minted after voting ends, increasing the required quorum
A proposal that didn't reach quorum during voting can become executable later if veRAAC tokens are burned, decreasing the required quorum
High severity as this allows direct manipulation of governance proposal execution:
Malicious actors can prevent execution of passed proposals by minting veRAAC tokens
Failed proposals can be made executable by burning veRAAC tokens
Core protocol governance functionality can be subverted
Breaks key invariant that proposal outcome should be determined only by votes during voting period
Manual review
Add the following test case to the test/unit/core/governance/proposals/Governance.test.js
file:
Store the total voting power at proposal creation time and use it for quorum calculations:
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.