Core Contracts

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

Manipulate rewards distributions to a gauges by voting manipulations

Summary

Attacker can down votes all gauges weights to 0 and prevents rewards distributions, i.e. breaks GaugeController functionality

Vulnerability Details

When user votes it's votingPower equals to the balance of the veRAACToken that can be freely transfered. Attacker can create multiple users, vote and transfer tokens to the next user and so on. As a result of such voting manipulation attacker can prevent rewards distribution using the following attack path:

  1. vote with small amount of veRAACToken and big weight.

  2. increase balance of veRAACToken and vote with 0 weight

  3. gauge weight will be decreased (link): uint256 newGaugeWeight = oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) + (newWeight * votingPower / WEIGHT_PRECISION)

  4. transfer veRAACToken to next user and repeat gauge downvoting until it's weight will be decreased to 0

  5. gauge with 0 weight is excluded from rewards distribution (link)

Example:

  • some gauge has weight 1

  • first vote: attacker votes with veRAACToken balance 1 and weight 10000, _updateGaugeWeight (link) will be called with oldWeight = 0, newWeight = 10000, votingPower = 1, new gauge weight will be

newGaugeWeight = oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) + (newWeight * votingPower / WEIGHT_PRECISION) = 1 - (0 * 1 / 10000) + (10000 * 1 / 10000) = 2
  • second vote: attacker increases it's veRAACToken balance to 20000 and votes with weight 0, _updateGaugeWeight will be called with oldWeight = 1, newWeight = 0, votingPower = 20000, calculate new gauge weight

newGaugeWeight = oldGaugeWeight - (oldWeight * votingPower / WEIGHT_PRECISION) + (newWeight * votingPower / WEIGHT_PRECISION) = 2 - (1 * 20000 / 10000) + (0 * 20000 / 10000) = 0

Impact

Attacker can manipulate rewards distributions to a gauges

Tools Used

Manual code review

Recommendations

Use veRAACToken::getVotingPower (link) as votingPower instead of user's veRAACToken balance.

Updates

Lead Judging Commences

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

BaseGauge::_applyBoost, GaugeController::vote, BoostController::calculateBoost use balanceOf() instead of getVotingPower() for vote-escrow tokens, negating time-decay mechanism

Support

FAQs

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