Core Contracts

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

Mathematical Error in `BoostController::getBoostMultiplier` Calculation Leading to Incorrect User Rewards

Summary

In the BoostController::getBoostMultiplier function that results in all non-zero user boosts returning a fixed maximum multiplier (2.5×) regardless of actual configuration or user conditions. This flaw stems from an incorrect mathematical formula and the hardcoding of the MAX_BOOST constant, rendering dynamic boost adjustments ineffective and compromising core protocol mechanics.

Vulnerability Details

BoostController.solgetBoostMultiplier(address user, address pool) function.

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;
// Calculate actual boost multiplier in basis points
uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
return userBoost.amount * 10000 / baseAmount;
}

The implemented formula erroneously computes the multiplier as:

uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
return userBoost.amount * 10000 / baseAmount;

Simplification Proof:
For any non-zero userBoost.amount:

Let a = userBoost.amount
baseAmount = (a * 10000) / 25000
Result = (a * 10000) / baseAmount
= (a * 10000) / [(a * 10000) / 25000]
= 25000 (constant)

This reduces the multiplier to always return 25000 basis points (2.5×) when userBoost.amount > 0, irrespective of the actual boost parameters or user-specific conditions.

Impact

getBoostMultiplier return incorrect boost multiplier

Tools Used

Manual Review

Recommendations

Compute the multiplier as a direct ratio of the boosted amount to the base amount:

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;
// Calculate actual boost multiplier in basis points
- uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
- return userBoost.amount * 10000 / baseAmount;
+ uint256 baseAmount = 10000; // 1x = 10000 basis points
+ return (userBoost.amount * 10000) / baseAmount;
}
Updates

Lead Judging Commences

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

Give us feedback!