Summary
Rewards amount miscalculated in _calculateReward due to periodEmission's wrong application.
Vulnerability Details
The calculateReward calculates the reward of a gauge when called from the distributeRewards
function _calculateReward(address gauge) internal view returns (uint256) {
Gauge storage g = gauges[gauge];
uint256 totalWeight = getTotalWeight();
if (totalWeight == 0) return 0;
uint256 gaugeShare = (g.weight * WEIGHT_PRECISION) / totalWeight;
uint256 typeShare = (typeWeights[g.gaugeType] * WEIGHT_PRECISION) / MAX_TYPE_WEIGHT;
@> uint256 periodEmission = g.gaugeType == GaugeType.RWA ? _calculateRWAEmission() : _calculateRAACEmission();
return (periodEmission * gaugeShare * typeShare) / (WEIGHT_PRECISION * WEIGHT_PRECISION);
}
The problem here is that the function tries to scale the periodEmission , this however is wrong as the returned value has already been scaled based on the gaugeType
RWA
function _calculateRWAEmission() internal view returns (uint256) {
return 1000000 * 10**18;
}
RAAC
function _calculateRAACEmission() internal view returns (uint256) {
return 250000 * 10**18;
}
This means that the code will return wrong values to to the calculations.
Impact
Incorrect periodEmission leads to incorrect rewards distribution.
Tools Used
Manual review.
Recommendations
The issue can be mitigated like :
function _calculateReward(address gauge) internal view returns (uint256) {
Gauge storage g = gauges[gauge];
uint256 totalWeight = getTotalWeight();
if (totalWeight == 0) return 0;
uint256 gaugeShare = (g.weight * WEIGHT_PRECISION) / totalWeight;
uint256 periodEmission = g.gaugeType == GaugeType.RWA ? _calculateRWAEmission() : _calculateRAACEmission();
@> return (periodEmission * gaugeShare) / WEIGHT_PRECISION;
}