Core Contracts

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

Missing Vote Delay Check in `GaugeController.vote` Function Leads to Potential Voting Exploits

Summary:

The vote function in the GaugeController contract does not properly enforce the VOTE_DELAY. The function is not using the lastVotTime with repective to current timestamp to enfore the VOTE_DELAY and prevent users from voting repeatedly within the delay period. This omission allows users to vote without respecting the intended delay, potentially enabling voting exploits and undermining the governance mechanism.

Vulnerability Details:

The vote function is intended to allow veRAACToken holders to vote for gauges, with a VOTE_DELAY to prevent rapid vote changes. While the contract includes VOTE_DELAY constant, the vote function does not use this to enforce the delay, thus the flawed logic does not effectively prevent rapid voting. The absence of a proper vote delay check allows users to repeatedly vote for different gauges or change their vote weights without respecting the intended VOTE_DELAY. This can be used to manipulate gauge weights and unfairly influence reward distribution.

function vote(address gauge, uint256 weight) external override whenNotPaused {
// ... other checks ...
// Example of what is MISSING:
// if (block.timestamp - lastVoteTime[msg.sender] < VOTE_DELAY) {
// revert VoteDelayNotElapsed();
// }
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
// ... other code ...
}

Impact:

The failure to enforce the VOTE_DELAY has the following negative consequences:

  • Vote Manipulation: Users can repeatedly vote for different gauges or change their vote weights without respecting the VOTE_DELAY. This can be used to manipulate gauge weights and unfairly influence reward distribution.

  • Protocol Instability: The lack of enforced vote delay can lead to unpredictable and volatile gauge weight fluctuations, making it difficult for the protocol to function as intended.

Proof of Concept:

  1. Alice has veRAACTokens and wants to vote for a gauge.

  2. Alice calls vote(gaugeAddress, weight1). The vote is successful.

  3. Alice immediately calls vote(gaugeAddress, weight2).

  4. The VOTE_DELAY check is missing. It does not prevent the vote from proceeding.

  5. The vote is successful again, even though the VOTE_DELAY has not elapsed.

  6. Alice can repeat steps 3-5 indefinitely, effectively bypassing the VOTE_DELAY and potentially manipulating gauge weights.

Tools Used:

  • Manual code review

Recommended Mitigation:

The vote function should be modified to include a proper check for the VOTE_DELAY. The following should be added to the vote function:

function vote(address gauge, uint256 weight) external override whenNotPaused {
// ... other checks ...
+ if (block.timestamp - lastVoteTime[msg.sender] < VOTE_DELAY) {
+ revert VoteDelayNotElapsed();
+ }
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
// ... other code ...
}
Updates

Lead Judging Commences

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

GaugeController::vote never enforces VOTE_DELAY or updates lastVoteTime, allowing users to spam votes and manipulate gauge weights without waiting

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

GaugeController::vote never enforces VOTE_DELAY or updates lastVoteTime, allowing users to spam votes and manipulate gauge weights without waiting

Support

FAQs

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