Core Contracts

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

Inconsistent Boost Calculation Due to Mismatched Token Balance Metrics

Summary

The contract calculates user boost inconsistently by using two different metrics to determine a user's veToken holdings. The internal function _calculateBoost uses balanceOf(user), which reflects the total locked veTokens, while the external function calculateBoost uses getVotingPower(user, block.timestamp), which represents effective voting power that decreases over time.

Vulnerability Details

The inconsistency arises because _calculateBoost and calculateBoost are designed to compute the same boost logic, but they use different methods to fetch user token information. The issue originates in these two parts of the contract:

_calculateBoost (Internal Function)

This function retrieves the user's veToken balance using IERC20(address(veToken)).balanceOf(user). This typically represents the total amount of veTokens the user holds without considering time decay.

uint256 userBalance = IERC20(address(veToken)).balanceOf(user);
uint256 totalSupply = IERC20(address(veToken)).totalSupply();

calculateBoost (External Function)

Unlike _calculateBoost, this function calls veToken.getVotingPower(user, block.timestamp), which accounts for token lock expiry and decreases over time.

uint256 userVotingPower = veToken.getVotingPower(user, block.timestamp);

Because the boost system relies on _calculateBoost to update the user's stored boost value but allows external queries through calculateBoost, users and contracts may see different boost values than what is actually applied.

A user’s boost might be calculated based on the full locked balance (even if some tokens are close to expiry), but when querying their boost, they see a lower number based on decayed voting power. This creates confusion and potential misallocation of rewards or voting weight.

Impact

  • Mismatched expectations between displayed and applied boost values.

  • Potential unfair reward distribution if calculations rely on inconsistent boost metrics.

  • Users making incorrect decisions based on misleading boost values.

Tools Used

  • Manual code review

Recommendations

To ensure consistency in boost calculations, the contract should use the same metric for both _calculateBoost and calculateBoost. The recommended solution is to standardize on getVotingPower(user, block.timestamp) in _calculateBoost, ensuring that boost calculations align with effective voting power.

Modify _calculateBoost as follows:

uint256 userBalance = veToken.getVotingPower(user, block.timestamp);
Updates

Lead Judging Commences

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