Core Contracts

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

Incorrect calculation in getBoostMultiplier function

Summary

The vulnerability arises from an incorrect calculation of the boost multiplier—resulting in rewards that do not fairly reflect the user's intended boost.

Vulnerability Details

Below is an example that walks through the calculation performed by the getBoostMultiplier function

Assumptions and Constants

  • MIN_BOOST: 10,000 (representing a 1× multiplier)

  • MAX_BOOST: 25,000 (representing a 2.5× multiplier)

  • supportedPools[pool]: true (the pool is supported)

  • Suppose the user’s boost record for this pool is stored in the UserBoost struct and:

  • userBoost.amount: 15,000

Calculating the Baseline (baseAmount):
The code then calculates a “baseAmount”:

uint256 baseAmount = userBoost.amount * 10000 / MAX_BOOST;

Substituting the values:

  • baseAmount = (15,000×10,000) / 25,000

  • baseAmount=6,000

  • Calculating the Boost Multiplier:
    Finally, the boost multiplier is calculated as:

    return userBoost.amount * 10000 / baseAmount;

    Substituting our numbers:

    • return value = (15,000×10,000) / 6,000

    • return value=25,000

    This result means the boost multiplier is 25,000 basis points (or 2.5×)

In this calculation, any nonzero userBoost.amountwill always cancel out when applying the formula.

Therefore, as long as userBoost.amountis nonzero, the calculation always returns MAX_BOOST.

Impact

The formula, as written, effectively returns the maximum boost multiplier for any nonzero userBoost.amount.

Tools Used

Manual Review

Recommendations

We introduce a normalization constant (here called MAX_USER_BOOST) that represents the maximum boost amount a user can have. The new formula is:

boostMultiplier= MIN_BOOST+(((MAX_BOOST−MIN_BOOST)×userBoost.amount)) / MAX_USER_BOOST)

This means that when a user’s recorded boost amount is 0, the multiplier is exactly MIN_BOOST (i.e. 1x), and when the user’s boost amount reaches MAX_USER_BOOST, the multiplier becomes MAX_BOOST (e.g. 2.5x). Values in between are linearly interpolated.

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!