Core Contracts

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

Incorrect Initialization of boostState.minBoost in BaseGauge will cause functions in the contract to revert

Summary

The constructor initializes boostState.minBoost with a value of 1e18, but it should be set to **1000 or any other value in basis point **to be consistent with the expected precision used in the boost calculation logic. The calculateBoost function computes the boost range as:

uint256 boostRange = params.maxBoost - params.minBoost;

Since maxBoost is initialized as 2500 and minBoost is mistakenly set as 1e18, boostRange becomes negative (mathematically), but since uint256 cannot hold negative values, the subtraction will underflow and cause the function to revert.

Vulnerability Details

constructor(
address _rewardToken,
address _stakingToken,
address _controller,
uint256 _maxEmission,
uint256 _periodDuration
) {
rewardToken = IERC20(_rewardToken);
stakingToken = IERC20(_stakingToken);
controller = _controller;
// Initialize roles
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(CONTROLLER_ROLE, _controller);
// Initialize boost parameters
@> boostState.maxBoost = 25000; // 2.5x
@> boostState.minBoost = 1e18;
boostState.boostWindow = 7 days;
uint256 currentTime = block.timestamp;
uint256 nextPeriod = ((currentTime / _periodDuration) * _periodDuration) + _periodDuration;
// Initialize period state
periodState.periodStartTime = nextPeriod;
periodState.emission = _maxEmission;
TimeWeightedAverage.createPeriod(
periodState.votingPeriod,
nextPeriod,
_periodDuration,
0,
10000 // VOTE_PRECISION
);
}
function _applyBoost(address account, uint256 baseWeight) internal view virtual returns (uint256) {
if (baseWeight == 0) return 0;
IERC20 veToken = IERC20(IGaugeController(controller).veRAACToken());
uint256 veBalance = veToken.balanceOf(account);
uint256 totalVeSupply = veToken.totalSupply();
// Create BoostParameters struct from boostState
BoostCalculator.BoostParameters memory params = BoostCalculator.BoostParameters({
maxBoost: boostState.maxBoost,
minBoost: boostState.minBoost,
boostWindow: boostState.boostWindow,
totalWeight: boostState.totalWeight,
totalVotingPower: boostState.totalVotingPower,
votingPower: boostState.votingPower
});
@> uint256 boost = BoostCalculator.calculateBoost(
veBalance,
totalVeSupply,
params
);
return (baseWeight * boost) / 1e18;
}
// BoostCalculator
function calculateBoost(
uint256 veBalance,
uint256 totalVeSupply,
BoostParameters memory params
) internal pure returns (uint256) {
// Return base boost (1x = 10000 basis points) if no voting power
if (totalVeSupply == 0) {
return params.minBoost;
}
// Calculate voting power ratio with higher precision
uint256 votingPowerRatio = (veBalance * 1e18) / totalVeSupply;
// Calculate boost within min-max range
@> uint256 boostRange = params.maxBoost - params.minBoost;
uint256 boost = params.minBoost + ((votingPowerRatio * boostRange) / 1e18);
// Ensure boost is within bounds
if (boost < params.minBoost) {
return params.minBoost;
}
if (boost > params.maxBoost) {
return params.maxBoost;
}
return boost;
}

Wrong initialization of boostState.minBoostin the contructor, this will lead to an overflow when the applyBoost()calls the calculateBoost function.

This will affect any function that calls the _applyBoost, the updateReward is affected, and any function that uses the upatedReward modifier will revert when called.

Impact

Any function that calls _applyBoost() will revert due to an underflow error in calculateBoost().

Users will not receive correct boost calculations, affecting voting weight or rewards.

Tools Used

Manual Review

Recommendations

Modify the constructor to correctly initialize boostState.minBoost with the precision in basis point:

Updates

Lead Judging Commences

inallhonesty Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

boostState.minBoost is set to 1e18

Support

FAQs

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