The governance system allows proposals to transition to a successful state without properly validating quorum requirements. This creates a vulnerability where minority voters can push through proposals against the protocol's intended democratic process.
In Governance.sol
, the _isProposalSuccessful() function performs an incomplete validation:
The vulnerability manifests when:
Total votes fall below required quorum (4% of total voting power)
A proposal receives majority support from this insufficient voter base
The system transitions the proposal to "Succeeded" state
The validation gap in execute()
Imagine a town hall meeting where decisions require 40% attendance to be valid. Now picture someone holding a meeting at 3 AM with just 5% of residents, yet their decisions become binding. This is exactly what's happening in RAAC's governance system.
The governance contract's _isProposalSuccessful()
function acts as the meeting moderator, but it's not properly checking attendance. When checking if a proposal passes, it looks at whether more people voted "yes" than "no", but fails to enforce the critical 4% quorum requirement (defined in quorumNumerator
).
A malicious actor could execute protocol-changing proposals with as little as 0.1% of total voting power. For perspective, in a protocol with 1 million veRAAC tokens, decisions affecting everyone could be made with just 1,000 tokens.
The Attack Flow
An attacker waits for a period of low voter engagement, perhaps during a holiday or market downturn. They create a proposal to, for example, redirect protocol fees to their wallet. With just a small fraction of votes, they can transition the proposal to Succeeded
state and execute it through the timelock.
This proposal would pass despite having only 0.15% participation, far below the intended 4% threshold.
This proposal would pass despite having only 0.15% participation, far below the intended 4% threshold.
maintain the protocol's democratic requirements by enforcing both participation thresholds and majority consensus before allowing proposals to advance.
Explicit quorum check before any success determination
Proper order of validation (quorum first, then majority)
Early return pattern prevents proposals from succeeding without sufficient participation
Integration with existing state transition checks in execute() function
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.