In the BaseGauge contract, _updateReward updates the global lastUpdateTime before calculating a user's earned rewards, leading to incorrect reward calculations because earned() uses the already updated `lastUpdateTime.
In the _updateReward function:
When calculating earned rewards:
The issue is:
lastUpdateTime is updated to current time
Then earned() is called which uses getRewardPerToken()
getRewardPerToken() calculates using (lastTimeRewardApplicable() - lastUpdateTime)
This time difference will be 0 since lastUpdateTime was just updated
Results in users losing rewards for the period between their last update and current update
Users lose rewards for the period between updates
Manual review
Calculate earned rewards before updating the global state.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.