Description
In BaseGauge.sol we see that distributionCap limit is configured:
File: contracts/core/governance/gauges/BaseGauge.sol
313:
314:@---> * @notice Sets cap on reward distribution
315: * @param newCap New distribution cap value
316: */
317: function setDistributionCap(uint256 newCap) external {
318: if (!hasRole(FEE_ADMIN, msg.sender)) revert UnauthorizedCaller();
319: distributionCap = newCap;
320: emit DistributionCapUpdated(newCap);
321: }
This is never checked inside notifyRewardAmount() implementation:
File: contracts/core/governance/gauges/BaseGauge.sol
349:
350: * @notice Notifies contract of reward amount
351: * @dev Updates reward rate based on new amount
352: * @param amount Amount of rewards to distribute
353: */
354: function notifyRewardAmount(uint256 amount) external override onlyController updateReward(address(0)) {
355:@---> if (amount > periodState.emission) revert RewardCapExceeded();
356:
357:@---> rewardRate = notifyReward(periodState, amount, periodState.emission, getPeriodDuration());
358: periodState.distributed += amount;
359:
360: uint256 balance = rewardToken.balanceOf(address(this));
361: if (rewardRate * getPeriodDuration() > balance) {
362: revert InsufficientRewardBalance();
363: }
364:
365: lastUpdateTime = block.timestamp;
366: emit RewardNotified(amount);
367: }
Note that while the check: amount > periodState.emission is required too, it is already checked inside notifyReward() which is called above on L357. Hence L355 should conduct the check against distributionCap.
Impact
Reward distribution may exceed the configured distributionCap.
Mitigation
File: contracts/core/governance/gauges/BaseGauge.sol
349: /**
350: * @notice Notifies contract of reward amount
351: * @dev Updates reward rate based on new amount
352: * @param amount Amount of rewards to distribute
353: */
354: function notifyRewardAmount(uint256 amount) external override onlyController updateReward(address(0)) {
- 355: if (amount > periodState.emission) revert RewardCapExceeded();
+ 355: if (periodState.distributed + amount > distributionCap) revert RewardCapExceeded();
356:
357: rewardRate = notifyReward(periodState, amount, periodState.emission, getPeriodDuration());
358: periodState.distributed += amount;
359:
360: uint256 balance = rewardToken.balanceOf(address(this));
361: if (rewardRate * getPeriodDuration() > balance) {
362: revert InsufficientRewardBalance();
363: }
364:
365: lastUpdateTime = block.timestamp;
366: emit RewardNotified(amount);
367: }