Core Contracts

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

`_distributeToGauges` is not sending resources to underlying gauges

Summary

In the GaugeController, during reward distribution, the _distributeToGauges function does not successfully send tokens to the underlying gauges, preventing users from receiving rewards.

Relevant Code:

function _distributeToGauges(
GaugeType gaugeType,
uint256 amount
) internal {
uint256 totalTypeWeight = 0;
uint256[] memory gaugeWeights = new uint256[](_gaugeList.length);
uint256 activeGaugeCount = 0;
// First pass: calculate total weight and store gauge weights
for (uint256 i = 0; i < _gaugeList.length; i++) {
address gauge = _gaugeList[i];
if (gauges[gauge].isActive && gauges[gauge].gaugeType == gaugeType) {
gaugeWeights[i] = gauges[gauge].weight;
totalTypeWeight += gaugeWeights[i];
activeGaugeCount++;
}
}
if (totalTypeWeight == 0 || activeGaugeCount == 0) return;
// Second pass: distribute 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) {
IGauge(gauge).notifyRewardAmount(gaugeShare);
}
}
}
}

Vulnerability Details

  • The _distributeToGauges function attempts to distribute rewards by calling IGauge(gauge).notifyRewardAmount(gaugeShare).

  • However, there is no actual token transfer from GaugeController to the individual gauges.

  • The notifyRewardAmount function in the IGauge contract checks if amount > periodState.emission but does not receive the tokens, meaning the reward balance remains insufficient.

  • This results in InsufficientRewardBalance() being reverted, preventing users from claiming rewards.

Impact

  • No Funds in Gauges: The reward tokens are never moved to the gauges, meaning no rewards can be distributed.

  • Failed Reward Distribution: Users expecting staking rewards will receive nothing due to insufficient balances in the gauges.

  • Broken Incentive Mechanism: Without proper distribution, the incentive mechanism for staking and governance participation is disrupted.

Tools Used

Manual review

Recommendations

Ensure Token Transfers Before Notification
Before calling notifyRewardAmount, explicitly transfer the reward tokens to each gauge:

IERC20(rewardToken).transfer(gauge, gaugeShare);
IGauge(gauge).notifyRewardAmount(gaugeShare);

This ensures that when notifyRewardAmount is called, the gauge actually has the rewards.

Updates

Lead Judging Commences

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

GaugeController notifies gauges of rewards without transferring tokens in both distributeRewards and _distributeToGauges functions, breaking reward distribution

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

GaugeController notifies gauges of rewards without transferring tokens in both distributeRewards and _distributeToGauges functions, breaking reward distribution

Support

FAQs

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