Summary
distributeRewards in GaugeController forgets to send any tokens.
Details
Whenever distributeRewards is invoked, it performs some sanity checks and a reward calculation before proceeding to notifyRewardAmount in the gauge.
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);
}
Let's observe notifyRewardAmount
function notifyRewardAmount(uint256 amount) external override onlyController updateReward(address(0)) {
if (amount > periodState.emission) revert RewardCapExceeded();
rewardRate = notifyReward(periodState, amount, periodState.emission, getPeriodDuration());
periodState.distributed += amount;
@> uint256 balance = rewardToken.balanceOf(address(this));
if (rewardRate * getPeriodDuration() > balance) {
revert InsufficientRewardBalance();
}
lastUpdateTime = block.timestamp;
emit RewardNotified(amount);
}
There is no line of code where the reward token is actually transferred to the gauge in question, meaning that the balance will always be 0 and the method witll always revert
Impact
Broken functionality, loss of rewards
Mitigation
Send the tokens