Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Valid

Incorrect calculation of rewards in the _calculateReward function in the GuageController.sol

Summary

The _calculateReward function calculates the rewards for a guage based on the weight ratio of that particular guage.
Basically reward is proportional to guage.weight/total weight of all guages. But this differs from the reward calculation made by the _distributeToGauges fuction. In this admin function the denominator is taken from only the same types of guages. either RWA or RAAC , not all the guages.

Vulnerability Details

The calculateRewar function calls the getTotalWeight function which calculates the total weight of all the guages. Not just of the total weight of that particular guage type. But when the admin calls the distributeRevenue function, it calculates the weight of only that type of guage. Further in the calculateReward function, the fraction is multiplied by the calculateRWAEmission or the _calculateRAACEmission, both of which are different and are for the different type of guages. This discrepancy causes incorrect rewards to be transferred.

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;
// Calculate period emissions based on gauge type
uint256 periodEmission = g.gaugeType == GaugeType.RWA ? _calculateRWAEmission() : _calculateRAACEmission();
return (periodEmission * gaugeShare * typeShare) / (WEIGHT_PRECISION * WEIGHT_PRECISION);
}
function getTotalWeight() public view override returns (uint256) {
uint256 total = 0;
// This could be optimized by maintaining a running total
for (uint256 i = 0; i < _gaugeList.length; i++) {
if (gauges[_gaugeList[i]].isActive) {
total += gauges[_gaugeList[i]].weight;
}
}
return total;
}

Impact

Lower than expected rewards will be transferred to the guages.

Tools Used

manual review

Recommendations

calcualte only the weights of that paritcular guage type in the getTotalWeight() function

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

GaugeController::_calculateReward uses combined weight of all gauge types instead of type-specific weights, causing incorrect reward distribution between RWA and RAAC gauges

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

GaugeController::_calculateReward uses combined weight of all gauge types instead of type-specific weights, causing incorrect reward distribution between RWA and RAAC gauges

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!