Core Contracts

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

getBoostMultiplier in BoostController only returns either MIN_BOOST or MAX_BOOST, no dynamic value in between

Description

Presumably a mistake within BoostController::getBoostMultiplier causes the function to either return MIN_BOOST for userBoost.amount == 0 and MAX_BOOST for any other amount of userBoost.amount != 0.

Vulnerability Details

BoostController::getBoostMultiplier

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;
@> uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;
@> return userBoost.amount * 10000 / baseAmount;
}

Looking at the highlighted lines within getBoostMultiplier we can see see on the first mark that the function returns MIN_BOOST for userBoost.amount == 0 as intended, the issue however arises in the 2nd and 3rd marker:

baseAmount = (userBoost.amount * 10000) / MAX_BOOST (1)
return value = (userBoost.amount * 10000) / baseAmount (2)
// Inserting the baseAmount equation into the return value:
return value = (userBoost.amount * 10000) / ((userBoost.amount * 10000) / MAX_BOOST)
// Simplifying the expression:
return value = (userBoost.amount * 10000) * (MAX_BOOST / (userBoost.amount * 10000))
// Canceling out terms:
return value = MAX_BOOST

And as we can see here, any other path besides userBoost.amount == 0 will result in MAX_BOOST returned here.

Impact

The intended behavior seems to be a linear progression between MIN_BOOST and MAX_BOOST proportional to the users amount staked to reward users contributing a higher stake with a higher boost, the implementation however does not return values of a linear progression.

The likelihood is evidently high, the impact though only a medium since we are only talking about rewards, and users would at least still get them, even though more than intended by the protocol.

This leaves the conclusion to rate the total severity as a Medium.

Tools Used

Manual Review

Recommendation

Implement a linear boost calculation, following the formulas used in other places within the contract.

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!