Core Contracts

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

Issues in voting in `GaugeController`contract

Vulnerability Details

In GaugeControllercontract, function vote()is used for user to vote for gauge:

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);
}
/**
* @notice Updates a gauge's weight based on vote changes
* @dev Recalculates gauge weight using voting power
* @param gauge Address of the gauge
* @param oldWeight Previous vote weight
* @param newWeight New vote weight
* @param votingPower Voter's voting power
*/
function _updateGaugeWeight(
address gauge,
uint256 oldWeight,
uint256 newWeight,
uint256 votingPower
) internal {
Gauge storage g = gauges[gauge];
uint256 oldGaugeWeight = g.weight;
uint256 newGaugeWeight = oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) // <--
+ (newWeight * votingPower / WEIGHT_PRECISION);
g.weight = newGaugeWeight;
g.lastUpdateTime = block.timestamp;
}

Lets look at formula to calculate new weight:

oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) + (newWeight * votingPower / WEIGHT_PRECISION);

There are multiple issues in this formula, and this voting mechanism:

  • Voting might be reverted due to underflow: If only one user voting for that gauge, and their voting power is increase, they can not voting after voting for first time because oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) will revert due to underflow. Or another cases that can lead to unintentionally underflow is someone what to break gauge weight by doing these actions:

    1. Vote with dust amount with maximum weight (for example: 10000)

    2. Increase voting power by getting more veraac token, then voting for that gauge with smaller weight (for example: 100), that lead to weight smaller that before voting.

  • Wrong votingPower is used in formula to calculate newGaugeWeight: it can be seen that this formula will not change if user increase their voting power and keep the same old weight and new weight. Minus value should be rely on old voting power, not same as new voting power that used in the new one

Impact

Wrong formula to calculate new weight, and voting can be reverted in some cases

Recommendations

Update voting mechanism.

Updates

Lead Judging Commences

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

GaugeController::_updateGaugeWeight uses current voting power for both old and new vote calculations, causing underflows when voting power increases and incorrect gauge weights

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

GaugeController::_updateGaugeWeight uses current voting power for both old and new vote calculations, causing underflows when voting power increases and incorrect gauge weights

Support

FAQs

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

Give us feedback!