Core Contracts

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

Declared `VOTE_DELAY` (10 days) and `lastVoteTime` Are Ignored

GaugeController.sol

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/GaugeController.sol#L200-L202

Overview

Inside GaugeController, we see:

mapping(address => uint256) public lastVoteTime;
uint256 public constant VOTE_DELAY = 10 days;

But in the vote(...) function:

function vote(address gauge, uint256 weight) external override whenNotPaused {
// ...
// No check: block.timestamp >= lastVoteTime[msg.sender] + VOTE_DELAY
// ...
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
emit WeightUpdated(gauge, oldWeight, weight);
}

Nowhere does the contract reference lastVoteTime[msg.sender] or set lastVoteTime[msg.sender] = block.timestamp; after voting. This means:

  1. The user’s last vote time is never stored or updated.

  2. The VOTE_DELAY = 10 days requirement is never enforced—no revert occurs if the user tries to vote again immediately.

Attack / Proof of Concept

  1. User Votes:
    The user calls vote(gauge, 5000) at T0. The function never sets lastVoteTime[user] = block.timestamp, nor checks the previous timestamp.

  2. User Votes Again Immediately:
    The user calls vote(gauge, 6000) at T0+10 seconds. The code never references VOTE_DELAY or lastVoteTime, so it succeeds.

Effect: The user can spam the vote function, repeatedly adjusting gauge weights with no forced delay.

Impact

  • Documented Feature Not Enforced
    The code and doc mention a 10-day minimum interval between user votes (VOTE_DELAY), but the system actually allows unlimited immediate re-voting.

  • Gaming or Rapid Shifts
    Users can quickly re-vote to manipulate gauge weights back and forth, potentially causing instability or making it harder for other participants to see a stable allocation before distribution.

Recommendation

  1. Enforce Voting Delay
    In vote(...), do something like:

    uint256 last = lastVoteTime[msg.sender];
    if (block.timestamp < last + VOTE_DELAY) {
    revert VoteCooldownNotReached();
    }
    lastVoteTime[msg.sender] = block.timestamp;
    //This ensures a 10-day wait after each vote.
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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 7 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.

Give us feedback!