Core Contracts

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

`GaugeController::vote`: Users voting power is not decreased after voting for a gauge

Summary

Users voting power is not decreased after voting for a gauge, allowing users to simply use all their voting power for as many gauge as they want at the same time.

Vulnerability Details

As we can see in the public and unrestricted vote() function, while users votes are registered for a specific gauge L197, users voting power is not decreased.
This means users can vote for another gauge, and at the end distribute more votes than they own.

File: contracts/core/governance/gauges/GaugeController.sol
190: function vote(address gauge, uint256 weight) external override whenNotPaused {
191: if (!isGauge(gauge)) revert GaugeNotFound();
192: if (weight > WEIGHT_PRECISION) revert InvalidWeight();
193:
194: uint256 votingPower = veRAACToken.balanceOf(msg.sender);
195: if (votingPower == 0) revert NoVotingPower();
196:
197: uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
198: userGaugeVotes[msg.sender][gauge] = weight;
199:
200: _updateGaugeWeight(gauge, oldWeight, weight, votingPower);
201:
202: emit WeightUpdated(gauge, oldWeight, weight);
203: }

Impact

Duplication of voting power.

Recommendations

Add a mapping to register how many votes have been distributed by each user, and ensure its never above their vote balance:

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();
+ if(userAllocatedVotes[msg.sender] > votingPower) revert NoVotingPower();
uint256 oldWeight = userGaugeVotes[msg.sender][gauge];
+ if(weight == oldWeight) revert VotesHasNotChanged() ;
userGaugeVotes[msg.sender][gauge] = weight;
+ uint256 delta;
+ if(weight > oldWeight)
+ delta = weight - oldWeight;
+ userAllocatedVotes[msg.sender] += delta;
+ else
+ delta = oldWeight - weight;
+ userAllocatedVotes[msg.sender] -= delta;
_updateGaugeWeight(gauge, oldWeight, weight, votingPower);
emit WeightUpdated(gauge, oldWeight, weight);
}
Updates

Lead Judging Commences

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