Core Contracts

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

Static Maximum Boost Limitation Due to Hardcoded Constant Usage

Summary

In BoostController contract where the maximum boost multiplier is improperly constrained by a hardcoded constant (MAX_BOOST = 25000) instead of utilizing the configurable boostState.maxBoost parameter. This flaw renders the protocol's boost adjustment mechanism ineffective, permanently capping user boosts at 2.5× even when administrators attempt to raise the limit via governance actions.

Vulnerability Details

The BoostController implements a Curve-style boost system where:

  • MAX_BOOST is defined as 25,000 basis points (2.5× multiplier)

  • Administrators can configure boost parameters via setBoostParameters()

  • Boost calculations occur in _calculateBoost() and getBoostMultiplier()

Root Cause

Two key functions incorrectly reference the constant MAX_BOOST rather than the dynamic boostState.maxBoost:

1. Boost Calculation Capping (_calculateBoost):

uint256 maxBoostAmount = amount * MAX_BOOST / 10000; // Hardcoded cap
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
  • The setBoostParameters() function updates boostState.maxBoost but these changes never propagate to critical calculations

  • Protocol remains bound to 25,000 basis points (2.5×) despite configuration changes

  • Creates inconsistency between configured parameters and actual system behavior

Impact

Users receive incorrect boost rewards relative to protocol configuration

Tools Used

Manual Code Review


Recommendations

Immediate Fixes

function _calculateBoost(
address user,
address pool,
uint256 amount
) internal view returns (uint256) {
if (amount == 0) revert InvalidBoostAmount();
if (!supportedPools[pool]) revert PoolNotSupported();
// Get current weights without modifying state
(uint256 totalWeight, uint256 totalVotingPower, uint256 votingPower) = updateTotalWeight();
uint256 userBalance = IERC20(address(veToken)).balanceOf(user);
uint256 totalSupply = IERC20(address(veToken)).totalSupply();
if (userBalance == 0 || totalSupply == 0) {
return amount;
}
// Create parameters struct for calculation
BoostCalculator.BoostParameters memory params = BoostCalculator.BoostParameters({
maxBoost: boostState.maxBoost,
minBoost: boostState.minBoost,
boostWindow: boostState.boostWindow,
totalWeight: totalWeight,
totalVotingPower: totalVotingPower,
votingPower: votingPower
});
(uint256 boostBasisPoints, uint256 boostedAmount) = BoostCalculator.calculateTimeWeightedBoost(
params,
userBalance,
totalSupply,
amount
);
if (boostedAmount < amount) {
return amount;
}
- uint256 maxBoostAmount = amount * MAX_BOOST / 10000;
+ uint256 maxBoostAmount = amount * boostState.maxBoost / 10000;
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
return boostedAmount;
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!