Summary
The boost calculation is depend on the total supply of the veRAAC token which means early User can get more boost leads to higher boost for the ealry User and then as more user grows and total supply the boosted amount will be lower compare to early one.
Vulnerability Details
The function GaugeController::calculateBoost() calls -> BoostCalculator::calculateTimeWeightedBoost()
-> Internal CalculateBoost() fucntion to calculate the boostBasis point on the basis of votingPowerRatio and this will be calcuated to on basis of totalVeSupply of veRAAC Token it means if the totalVeSupply is lower at early stage then the user get more boostedBasisPoint than later stage in that totalSupply will be increased.
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
Early user get more boost than later users
Tools Used
HardHat , Manual View
Recommendations
Implement the gradual decay over time than instant boost and cap initial boost for low supply periods.
function calculateBoost(
uint256 veBalance,
uint256 totalVeSupply,
BoostParameters memory params,
uint256 InitialTimestamp,
uint256 currentTimestamp
) internal pure returns (uint256) {
if (totalVeSupply == 0) {
return params.minBoost;
}
uint256 votingPowerRatio = (veBalance * 1e18) / totalVeSupply;
uint256 boostRange = params.maxBoost - params.minBoost;
uint256 rawBoost = params.minBoost + ((votingPowerRatio * boostRange) / 1e18);
uint256 DeltaTimestamp = currentTimestamp - InitialTimestamp;
uint256 decayFactor = DeltaTimestamp > params.boostWindow
? 1e18
: (DeltaTimestamp * 1e18) / params.boostWindow;
uint256 adjustedBoost = params.minBoost + ((rawBoost - params.minBoost) * decayFactor) / 1e18;
if (adjustedBoost > params.maxUserBoost) {
return params.maxUserBoost;
}
return adjustedBoost;
}