Core Contracts

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

`getBoostMultiplier` always returns maximum boost for any non-zero value

Author Revealed upon completion

Summary

The getBoostMultiplier function in the BoostController contract contains a critical mathematical flaw that causes any non-zero boost amount to result in the maximum boost multiplier (2.5x or 25000 basis points).

Vulnerability Details

The issue is the following:

  1. The function attempts to calculate a boost multiplier using the ratio of userBoost.amount to a baseAmount

  2. baseAmount is calculated as userBoost.amount * 10000 / MAX_BOOST (where MAX_BOOST = 25000)

  3. The final calculation userBoost.amount * 10000 / baseAmount mathematically simplifies to MAX_BOOST

function getBoostMultiplier(
address user,
address pool
) external view override returns (uint256) {
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
if (userBoost.amount == 0) return MIN_BOOST;
// @audit-issue incorrect math, will be always 2500
uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
return userBoost.amount * 10000 / baseAmount;
}

For any non-zero userBoost.amount value (let's call it x):

  1. baseAmount = x * 10000 / 25000

  2. Final calculation = x * 10000 / (x * 10000 / 25000)

  3. Simplifying: x * 10000 * 25000 / (x * 10000) = 25000

This means regardless of the input amount, the function will always return MAX_BOOST (25000) for any non-zero boost.

Impact

  • Function returns the MAX_BOOST regardless of the user's boost amount for the pool.

  • This can lead to miscalculation of rewards.

Tools Used

Manual Review

Recommendations

Scale the value to get the boost in basis points just once:

function getBoostMultiplier(
address user,
address pool
) external view override returns (uint256) {
if (!supportedPools[pool]) revert PoolNotSupported();
UserBoost storage userBoost = userBoosts[user][pool];
if (userBoost.amount == 0) return MIN_BOOST;
// Single scaling calculation to get boost in basis points (10000 = 100%)
return userBoost.amount * 10000 / MAX_BOOST;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 8 days ago
Submission Judgement Published
Validated
Assigned finding tags:

BoostController::getBoostMultiplier always returns MAX_BOOST for any non-zero boost due to mathematical calculation error, defeating the incentive mechanism

Support

FAQs

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