Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: medium
Valid

Quorum update can cause past defeated proposals to pass.

Summary

Past defeated proposals can be later executed if there is a decrease in the quorum. This issue was found in Openzeppelin and is also applicable here.

Vulnerability Details

When the voting period is over and there are more yes votes than no votes, but the quorum requirement is not reached, meaning not many people voted, then in the execute function inside the state, we check for this scenario and mark the proposal as defeated.

function state(
uint256 proposalId
) public view override returns (ProposalState) {
ProposalCore storage proposal = _proposals[proposalId];
if (proposal.startTime == 0) revert ProposalDoesNotExist(proposalId);
if (proposal.canceled) return ProposalState.Canceled;
if (proposal.executed) return ProposalState.Executed;
if (block.timestamp < proposal.startTime) return ProposalState.Pending;
if (block.timestamp < proposal.endTime) return ProposalState.Active;
// After voting period ends, check quorum and votes
ProposalVote storage proposalVote = _proposalVotes[proposalId];
uint256 currentQuorum = proposalVote.forVotes +
proposalVote.againstVotes;
uint256 requiredQuorum = quorum();
// Check if quorum is met and votes are in favor
//@audit-issue past proposal can get executed if the quorom requirements changes.
if (
currentQuorum < requiredQuorum ||
proposalVote.forVotes <= proposalVote.againstVotes
) {
return ProposalState.Defeated;
}
bytes32 id = _timelock.hashOperationBatch(
proposal.targets,
proposal.values,
proposal.calldatas,
bytes32(0),
proposal.descriptionHash
);
// If operation is pending in timelock, it's Queued
if (_timelock.isOperationPending(id)) {
return ProposalState.Queued;
}
// If not pending and voting passed, it's Succeeded
return ProposalState.Succeeded;
}

Now later if the governance decide to lower the quorum using setParameter function then it is possible that this transaction will get executed when no one is expecting.

POC

  1. totalSupply of veRAAC is 1 million, current quorum requirement is 25% which is 250k.

  2. someone send a proposal to donate 1 million from the protocol treasury to some charity.

  3. 100k veRAAC is votes for yes and 50k is votes for no

  4. The execute function will mark proposal as defeated because of the quorum requirement, we only have a 15% quorum but we require 25%.

  5. Governance decide to lower the quorum requirement by 15% after 6 months of this proposal.

  6. now after 6 months if someone executes this proposal with that proposal ID then this will pass. At this time protocol might not be that healthy just to give away million $ to charity.

impact

This is a high-impact bug because governance is a huge part of the system and it can’t afford to execute something unknowingly.

Recommendations

Avoid lowering quorum requirements if a past proposal was defeated for lack of quorum.

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance allows execution of previously-defeated proposals if quorum requirements are later lowered, enabling unexpected resurrection of old proposals

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Governance allows execution of previously-defeated proposals if quorum requirements are later lowered, enabling unexpected resurrection of old proposals

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!