Core Contracts

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

Dynamic Quorum Calculation Caused by `veToken.getTotalVotingPower()`

Overview

In many governance systems, quorum is fixed at proposal creation or at the start of voting. That way, the threshold is stable throughout the voting period. Here, the contract simply references the live result of:

_veToken.getTotalVotingPower()

which can change in real‑time as new locks or increases happen in the veRAACToken contract. This leads to:

  1. Increasing Quorum Mid‑Vote: If additional RAAC gets locked during the voting period, getTotalVotingPower() goes up, so the quorum requirement (quorumNumerator% of total power) also increases. Votes that would have met quorum earlier might fail to do so if the total supply soared near the end of voting.

  2. Unpredictable Governance: Voters cannot reliably predict the number of “for” votes needed because the denominator is in flux. This can hamper or favor short‑term manipulations (like whales locking tokens if they want to raise quorum so a proposal fails or possibly reduce quorum if tokens are withdrawn, though it’s less likely in this design).

Attack/Exploit Example

  1. Proposal is Created: At block T0, total veRAAC supply is 50 million. Quorum is 2 million (4% of 50M).

  2. Mid-Vote: Another user (or group) locks 30 million more RAAC. The total supply becomes 80 million. Quorum rises to 3.2 million (4% of 80M).

  3. Proposal Fails: The “for” side had 3 million votes, which would have met the old 2M requirement, but now fails since the required threshold is 3.2M. The entire dynamic changed after the proposal was posted and most participants had already voted.

Effect: The evolving total supply means the threshold can jump or drop within the same voting window. This is usually contrary to standard governance practice, which aims for stable thresholds across a single proposal's life.

Consequences

  • Instability and Gaming: Whale addresses can decide to lock or unlock significant amounts to manipulate the quorum threshold while voting is still open.

  • Confusion for Voters: Voters cannot know in advance how many “for” votes are needed at the end of the voting period because total supply can change at any time.

Recommendation

  • Snapshot Quorum at Proposal Creation
    Store the total voting power (or total supply of veToken) in the proposal struct at creation. For example:

    proposal.quorumAtCreation = (_veToken.getTotalVotingPower() * quorumNumerator) / QUORUM_DENOMINATOR;

    Then, in state(...), do:

    uint256 requiredQuorum = proposal.quorumAtCreation;

    instead of referencing the live getTotalVotingPower().

  • Use the same block snapshot as voting power
    If implementing a standard “snapshot at creation” approach for both voting power and total supply, you’d typically call veToken.getPastVotes(...) or store veToken.totalSupplyAtBlock(...)—ensuring a stable reference for the entire voting period.

Updates

Lead Judging Commences

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

Governance::quorum uses current total voting power instead of proposal creation snapshot, allowing manipulation of threshold requirements to force proposals to pass or fail

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

Governance::quorum uses current total voting power instead of proposal creation snapshot, allowing manipulation of threshold requirements to force proposals to pass or fail

Support

FAQs

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

Give us feedback!