The Governance contract's dynamic quorum calculation can prevent the execution of proposals that previously passed voting and are queued for execution.
The execute function is called twice - once to queue a proposal in TimelockController and once to execute the queued proposal. Before each operation in execute, the state of the proposal is checked.
The issue arises from recalculating quorum every time state is called:
A proposal that already passed and is in the queued state (quorum met once and ready for execution), cannot be executed due to checking the state (recalculating quorum) again in execute before executing:
The quorum function always returns 4% of the current total supply of veRAAC:
Example scenario:
Total voting power = 1,000
Quorum = 40 (4%)
Proposal receives 50 votes (passes quorum) and is queued for execution
Total voting power increases to 2,000
New quorum = 80
Before _executeProposal in execute is called, state sees 50 < 80
Proposal becomes unexecutable despite previously passing
After voting ends, currentQuorum cannot change, but requiredQuorum is dynamic. Large locks in veRAACToken can significantly inflate requiredQuorum.
High: Proposals that successfully passed voting can become unexecutable due to changes in total voting power. This prevents critical governance actions, potentially leaving the protocol in a stuck state.
Consider calculating and storing the quorum for a proposal only when creating the proposal or when queuing it.
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.