After the intended periodFinish
, the rewardPerTokenStored
must not be updated. But, in this case, periodFinish
keeps getting pushed. So, the rewardPerTokenStored
is incremented even after the intended periodFinish
. This would inflate the earned
value of the user.
lastTimeRewardApplicable
is defined as follows:
This implies that if block.timestamp
> periodFinish
, we should always return periodFinish
from lastTimeRewardApplicable
function.
So, in this calculation in getRewardPerToken
:
If lastUpdateTime
was updated to be equal to periodFinish
previously, lastTimeRewardApplicable
should ideally return periodFinish
, and the subtraction (lastTimeRewardApplicable() - lastUpdateTime)
must be 0.
So, rewardPerTokenStored
should not be updated, when the periodFinish
is reached and lastUpdateTime
was set equal to periodFinish
previously.
But in this case, when a periodFinish
is fixed, lastTimeRewardApplicable
will actually return a value greater than the intended period finish. This is because whenever stake
, withdraw
or getReward
is called lastUpdateTime
is set to block.timestamp
, which increases the periodFinish
value.
_updateReward
is called whenever stake
, withdraw
or getReward
is called:
And periodFinish
is defined like this:
As lastUpdateTime
is incremented with every stake
, withdraw
or getReward
call, periodFinish
keeps getting extended. So, if the intended period finish was 7 days, the periodFinish
will become more than 7 days, if users call stake
function.
So, lastTimeRewardApplicable
can return a value greater than the intended periodFinish
. This implies that rewardPerTokenStored
will get incremented even after the intended period finishes, when it should not be incremented:
If rewardPerTokenStored
is incremented, it will result in an inflated value of earned
for the user, allowing users to claim more than intended as earned
is directly dependent on rewardPerTokenStored
or getRewardPerToken
:
Manual review
periodFinish
should not be incremented every time lastUpdateTime
is set. This would indefinitely increase the periodFinish
. periodFinish
should only be set when notifyRewards
is called.
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.