Summary
The constructor initialization in BaseGuage.sol
is as follow -
constructor(
address _rewardToken,
address _stakingToken,
address _controller,
uint256 _maxEmission,
uint256 _periodDuration
) {
rewardToken = IERC20(_rewardToken);
stakingToken = IERC20(_stakingToken);
controller = _controller;
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(CONTROLLER_ROLE, _controller);
boostState.maxBoost = 25000;
@-> boostState.minBoost = 1e18;
boostState.boostWindow = 7 days;
uint256 currentTime = block.timestamp;
uint256 nextPeriod = ((currentTime / _periodDuration) * _periodDuration) + _periodDuration;
periodState.periodStartTime = nextPeriod;
periodState.emission = _maxEmission;
TimeWeightedAverage.createPeriod(
periodState.votingPeriod,
nextPeriod,
_periodDuration,
0,
10000
);
}
The maxBoost = 25000 and minBoost = 1e18, which is totally incorrect as minimum value is greater than maximum value.
Vulnerability Details
This incorrect initilization of min and max boost will lead to reverting of calculateBoost()
, because of line -
uint256 boostRange = params.maxBoost - params.minBoost;
As, (25000 - 1e18) will always revert.
Code snippet of calculateBoost()
function.
function calculateBoost(
uint256 veBalance,
uint256 totalVeSupply,
BoostParameters memory params
) internal pure returns (uint256) {
if (totalVeSupply == 0) {
return params.minBoost;
}
uint256 votingPowerRatio = (veBalance * 1e18) / totalVeSupply;
@ -> uint256 boostRange = params.maxBoost - params.minBoost;
uint256 boost = params.minBoost + ((votingPowerRatio * boostRange) / 1e18);
if (boost < params.minBoost) {
return params.minBoost;
}
if (boost > params.maxBoost) {
return params.maxBoost;
}
return boost;
}
Impact
calculateBoost()
function is necessary for determining reward for user. if this function will revert, it means user funds
stuck.
Also boost update function will not work, as it's also dependent on calculateBoost()
.
Tools Used
Manual
Recommendations
Change -
- boostState.maxBoost = 25000; // 2.5x
+ boostState.maxBoost = 25 * 1e17; // 2.5x