Core Contracts

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

Incorrect voting power calculation in gauge controller leads to inflated gauge weights

Relevant Context

The veRAACToken contract implements a vote-escrowed token system where voting power decays linearly over time. The GaugeController contract allows users to vote on gauge weights using their voting power from veRAACToken.

Finding Description

The GaugeController#vote function incorrectly uses veRAACToken.balanceOf() to determine a user's voting power instead of veRAACToken.getVotingPower(). The balanceOf function returns the initial voting power when tokens were locked, while getVotingPower returns the actual current voting power that accounts for linear decay over time.

This means the gauge weights are being calculated using outdated, non-decayed voting power values, which inflates the actual influence users have over gauge weights compared to their true current voting power.

Impact Explanation

High. This vulnerability allows users to maintain their original voting weight even after their actual voting power has decayed, directly impacting the gauge weight distribution and consequently the reward allocation across the protocol. This undermines a core mechanism of the vote-escrowed token system.

Likelihood Explanation

High. This issue affects every vote cast through the GaugeController and will occur whenever a user votes after their voting power has started to decay, which is a common scenario in vote-escrowed token systems.

Proof of Concept

  1. Alice locks 1000 RAAC tokens for 4 years, receiving 1000 veRAAC tokens

  2. After 2 years, Alice's actual voting power has decayed to 500 (50% of original)

  3. Alice votes on a gauge with weight 10000 (100%)

  4. GaugeController#vote uses balanceOf() which returns 1000

  5. The gauge weight is calculated using 1000 voting power instead of the correct 500

  6. The gauge receives twice the intended weight influence from Alice's vote

Recommendation

Replace the voting power calculation in GaugeController#vote with the correct function call:

- uint256 votingPower = veRAACToken.balanceOf(msg.sender);
+ uint256 votingPower = veRAACToken.getVotingPower(msg.sender);
Updates

Lead Judging Commences

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

Give us feedback!