Summary
notifyRewardAmount is as follow -
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();
}
@ -1 > lastUpdateTime = block.timestamp;
emit RewardNotified(amount);
}
firstly it will call modifier updateReward() ->
modifier updateReward(address account) {
_updateReward(account);
_;
}
function _updateReward(address account) internal {
rewardPerTokenStored = getRewardPerToken();
@ -> lastUpdateTime = lastTimeRewardApplicable();
if (account != address(0)) {
UserState storage state = userStates[account];
state.rewards = earned(account);
state.rewardPerTokenPaid = rewardPerTokenStored;
state.lastUpdateTime = block.timestamp;
emit RewardUpdated(account, state.rewards);
}
}
lastTimeRewardApplicable() ->
function lastTimeRewardApplicable() public view returns (uint256) {
return block.timestamp < periodFinish() ? block.timestamp : periodFinish();
}
periodFinish() ->
function periodFinish() public view returns (uint256) {
return lastUpdateTime + getPeriodDuration();
}
getPeriodDuration() ->
function getPeriodDuration() public view virtual returns (uint256) {
return 7 days;
}
So, if block.timestamp is greater than periodFinish(), then lastUpdateTime = periodFinish().
But code line marked as @ -1 > is reupdating lastUpdateTime to block.timestamp.
lastUpdateTime = block.timestamp;
Which is incorrect, it should only be value that's being updated in modifier.
Vulnerability Details
Same as above.
Impact
lastUpdateTime is associated with reward claim on gauge contracts, it's incorrect value could either lead to delay of reward or early reward claim, not good for user and protcol repectively.
Tools Used
Manual
Recommendations
remove lastUpdateTime = block.timestamp; from notifyRewardAmount() functions.