_applyStake
doesn't sync userRewardPerTokenPaid
with _rewardPerToken
, allowing any staker to claim the full _rewardPerToken
amount for their balance.
When staking with stakeFor
, users are assigned to their old, but empty index (no stakes on this index).
https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L265
After that, _applyStake
is called to update the _stakeInfos
map. Notice how the updateReward
modifier is called on _applyStake
, but because it's a modifier, it's called before we update the _stakeInfos
map.
https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L495
Since it's called before _stakeInfos
is initialized, it will calculate claimableRewards
and userRewardPerTokenPaid
as 0.
https://github.com/Cyfrin/2024-07-templegold/blob/main/protocol/contracts/templegold/TempleGoldStaking.sol#L594
However, after the _applyStake
call, our user has _stakeInfos
map with their balances, but userRewardPerTokenPaid
is 0. Now they would be able to call getReward
and claim the full _rewardPerToken
, even though they just staked.
Loss of funds. Users game the system.
Manual review
Inside _applyStake
, manually sync userRewardPerTokenPaid
to _rewardPerToken
. This may require more code, as we also need to account for vesting.
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.