Summary
The final boost calculation in BaseGauge::_applyBoost
return statement incorrectly divides by 1e18 when working with BPS values, effectively zeroing out any boost applied to users' weights.
Vulnerability Details
[](https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/governance/gauges/BaseGauge.sol#L252)
In BaseGauge._applyBoost
, the final calculation in the return statement divides by 1e18 when both input values are in BPS format (10_000 = 100%):
function _applyBoost(address account, uint256 baseWeight) internal view virtual returns (uint256) {
uint256 boost = BoostCalculator.calculateBoost(
veBalance,
totalVeSupply,
params
);
@> return (baseWeight * boost) / 1e18;
}
BoostCalculator::calculateBoost
ecompares boost
against minBoost
and maxBoost
which are BPS
[](https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/libraries/governance/BoostCalculator.sol#L92-L98)
function calculateBoost(
uint256 veBalance,
uint256 totalVeSupply,
BoostParameters memory params
) internal pure returns (uint256) {
....
if (boost < params.minBoost) {
return params.minBoost;
}
if (boost > params.maxBoost) {
return params.maxBoost;
}
return boost;
}
Example:
Example with real values:
minBoost = 10000 (1x in BPS)
maxBoost = 25000 (2.5x in BPS)
baseWeight = 5000 (0.5 in BPS)
veBalance = 500e18
totalVeSupply = 1000e18
boost = 17500
finalWeight = (baseWeight * boost) / 1e18
= (5000 * 17500) / 1e18
= 87500000 / 1000000000000000000
= 0
Result: Users get 0 weight instead of 8750 (proper boosted weight)
Impact
All user boost calculations effectively return 0 or a tiny fraction of what they should be
Users receive significantly reduced rewards compared to what they should get based on their veToken balance
The entire boost mechanism, which is core to the gauge system's incentive structure, is rendered ineffective
Tools Used
Foundry
Recommendations
Replace the 1e18 division in the return statement with BPS division:
function _applyBoost(address account, uint256 baseWeight) internal view virtual returns (uint256) {
- return (baseWeight * boost) / 1e18;
+ return (baseWeight * boost) / 10_000;
}