Core Contracts

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

Distributing gauge rewards is permissionless and can be abused to send rewards constantly

Summary

distributeRewards has no access control and can be called by anyone

Details

distributeRewards is used to calculate and send emissions to a specific gauge

/**
* @notice Distributes rewards to a gauge
* @dev Calculates and transfers rewards based on gauge weight
* @param gauge Address of gauge to distribute rewards to
*/
function distributeRewards(
address gauge
) external override nonReentrant whenNotPaused {
if (!isGauge(gauge)) revert GaugeNotFound();
if (!gauges[gauge].isActive) revert GaugeNotActive();
uint256 reward = _calculateReward(gauge);
if (reward == 0) return;
IGauge(gauge).notifyRewardAmount(reward);
emit RewardDistributed(gauge, msg.sender, reward);
}

Reward emissions are fixed per week/month and each gauge receives emissions based on its' weight.

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);
}

The output of _calculateReward is then passed to gauge.notifyRewardAmount which is responsible for transferring the rewards to the gauge.
Anyone can call distributeRewards until it fills up the periodState.emission variable and hit the reward cap instantly.

!NB Current implementation of notifyRewardAmount does not transfer any funds which is a subject of another submission and is a valid vulnerability itself. This submission relies on the assumption that everything else in the protocol works correctly and this is the only bug.

Impact

Unfair reward distribution

Mitigation

Impose access control on distributeRewards

Updates

Lead Judging Commences

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

GaugeController's distributeRewards lacks time-tracking, allowing attackers to repeatedly distribute full period rewards until hitting emission caps

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

GaugeController's distributeRewards lacks time-tracking, allowing attackers to repeatedly distribute full period rewards until hitting emission caps

Support

FAQs

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

Give us feedback!