Core Contracts

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

Users can artificially inflate gauge weights beyond their actual voting power causing unfair reward distribution

Summary

The code in the vote() function does not check if the user’s total votes exceed 100% across all gauges. This allows users to over-allocate their voting power, leading to incorrect gauge weights.

Vulnerability Details

The vote() function in GaugeController updates userGaugeVotes[msg.sender][gauge] directly without adjusting other gauges the user might have voted on. The _updateGaugeWeight() function then subtracts the old weight and adds the new one for that specific gauge. But there's no mechanism to track the sum of all the user's weights across all gauges.

While the function includes a check to ensure each individual vote weight doesn't exceed WEIGHT_PRECISION (10000, representing 100%), it lacks any mechanism to track or limit the sum of a user's votes across multiple gauges.

function vote(address gauge, uint256 weight) external override whenNotPaused {
if (!isGauge(gauge)) revert GaugeNotFound();
if (weight > WEIGHT_PRECISION) revert InvalidWeight();
uint256 votingPower = veRAACToken.balanceOf(msg.sender);
if (votingPower == 0) revert NoVotingPower();
uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
userGaugeVotes[msg.sender][gauge] = weight;
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
emit WeightUpdated(gauge, oldWeight, weight);
}

In a proper system, each vote should adjust the user's total allocated voting power. For example, when a user changes their vote from Gauge A to Gauge B, the system should subtract their old weight from A and add the new weight to B, ensuring the total doesn't exceed 100%. Without this check, users can allocate more than their available voting power, leading to incorrect gauge weights and manipulation of reward distributions.

Consider this attack scenario:

  1. A user holds 100 veTokens (representing 100% voting power)

  2. The user votes with weight 10000 (100%) for Gauge A
    This allocates 100 weight points (10000 * 100 / 10000) to Gauge A

  3. The same user then votes with weight 10000 (100%) for Gauge B

  4. This allocates another 100 weight points to Gauge B
    Result: The user has effectively allocated 200 weight points despite only having 100 veTokens worth of voting power

Impact

Over-voting distorts gauge weights, causing rewards to be distributed unfairly.

Tools Used

Manual Review

Recommendations

  1. Add a mapping to track total allocated votes per user:

  2. Modify the vote() function to enforce total vote limits:

Updates

Lead Judging Commences

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

GaugeController::vote lacks total weight tracking, allowing users to allocate 100% of voting power to multiple gauges simultaneously

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

GaugeController::vote lacks total weight tracking, allowing users to allocate 100% of voting power to multiple gauges simultaneously

Support

FAQs

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