The lastTimeRewardApplicable() function in BaseGauge.sol should return the latest applicable reward time but always returns periodFinish() with an incorrect value for the first 3,000 calls.
The lastTimeRewardApplicable() function is used to calculate how many reward tokens a user should receive
Now lets look closer in the lastTimeRewardApplicable() ->
it uses the PeriodFinish function with lastUpdateTime, the lastUpdateTime is only updated when a user use stake, withdraw or getReward, but it is not updated correctly
This is the path how it is updated ->
let's say the the block.timestamp = 1700000000
getPeriodDuration = 7 days
A user stake and it uses LastTimeRewardApplicable() it will check if the block.timestamp < PeriodFinish(), this will return false,
because PeriodFinish = lastUpdateTime + getPeriodDuration()
= 0 (because this is the first time called) + 7 days
= 7 days
and the lastTimeRewardApplicable will return the periodFinish() = 7 days
Now, the lastUpdateTime has to be updated in the _updateReward()
But Because the lastTimeRewardApplicable returned 7 days, lastUpdateTime will be equal to 7 days, not to block.timestamp
Now another user wants to stake tokens, to whole proccess is repeated again
Check if the block.timestamp < periodFinish() ? block.timestamp : periodFinish();
but now the PeriodFinish will equal to
= 7 days (lastUpdateTime) + 7 days (getPeriodDuration) = 14 days
which will again be false, and the return the PeriodFinish()
LastUpdateTime = 14 days
This whole process has to be repeated 3000 times untill the periodFinish be greater than the block.timestamp
Miss behaviour of the function, it will return a wrong value for the first 3000 calls
if it is the first time that is called _updateReward
Set the lastUpdateTime = block.timestamp
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.