Core Contracts

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

Revenue distribution to gauges faces DoS once one gauge reaches its max emission

Summary

The reward distribution mechanism in the distributeRevenue() function DoS condition. This occurs when one gauge reaches its emission limit, causing the entire distribution process to fail and preventing other eligible gauges from receiving their rewards.

Vulnerability Details

The notifyRewardAmount() function in the BaseGauge contract includes a check that reverts the transaction if the total amount of rewards being distributed exceeds the gauge's emission limit:

if (amount + state.distributed > state.emission) revert RewardCapExceeded();

On the other hand, the _distributeRevenue() function loops through all gauges of the specified type and calls notifyRewardAmount() for each gauge with its calculated share of the total rewards.

for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
uint256 gaugeShare = (amount * gaugeWeights[i]) / totalTypeWeight;
if (gaugeShare > 0) {
// @audit-issue Potential DoS here
>> IGauge(gauge).notifyRewardAmount(gaugeShare);
}
}
}

However, this method does not check for the gauge's limit before notifying contract of reward amount.

Impact

If any gauge has already reached its emission limit, the call to notifyRewardAmount() will revert, causing the entire transaction to fail. This means that even if other gauges are eligible to receive rewards, they will not get them due to the failure of the transaction.

Tools Used

Manual Review

Recommendations

Modify the _distributeToGauges() function to include a check before calling notifyRewardAmount(). Specifically, verify whether the gauge can accept the additional rewards without exceeding its emission limit:

for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
uint256 gaugeShare = (amount * gaugeWeights[i]) / totalTypeWeight;
if (gaugeShare > 0) {
- IGauge(gauge).notifyRewardAmount(gaugeShare);
+ if (gaugeShare + IGauge(gauge).periodState.distributed <= IGauge(gauge).periodState.emission) {
+ IGauge(gauge).notifyRewardAmount(gaugeShare);
+ }
}
}
}
Updates

Lead Judging Commences

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

GaugeController._distributeToGauges iterates twice over unbounded gauges list without error handling, causing DoS risk from out-of-gas or single gauge revert

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

GaugeController._distributeToGauges iterates twice over unbounded gauges list without error handling, causing DoS risk from out-of-gas or single gauge revert

Support

FAQs

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

Give us feedback!