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: }