Summary
flawed range used in boost calculations will cause incorrect output
Vulnerability Details
uint256 public constant MAX_BOOST = 25000;
uint256 public constant MIN_BOOST = 10000;
MAX_BOOST and MIN_BOOST are the default value for boostState.maxBoost and boostState.minBoost, set when deployed the contract. Then MANAGER_ROLE could change those values with function setBoostParameters(), the max value of boostState.maxBoost could be 50000.
However, in some calculations, MAX_BOOST is used directly instead of boostState.maxBoost.
function _calculateBoost(
address user,
address pool,
uint256 amount
) internal view returns (uint256) {
if (amount == 0) revert InvalidBoostAmount();
if (!supportedPools[pool]) revert PoolNotSupported();
(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;
}
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;
if (boostedAmount > maxBoostAmount) {
return maxBoostAmount;
}
return boostedAmount;
}
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;
}
Impact
output of _calculateBoost() and getBoostMultiplier() could be incorrect
Tools Used
manually reviewed
Recommendations
for Line126 and Line291, use boostState.maxBoost instead of MAX_BOOST.