If staking amount becomes 0 in the staking period, some reward tokens will be left in the staking contract. Although some left reward tokes can be shifted to next reward period, there still is some left reward tokens. These tokens will be locked in this contract forever, because there is no recover method for reward token.
Staking contract should make sure that there is some staking supply before we start one new round distribution via distributeRewards(). However, stakers can withdraw in the distribution period, this may cause the staking supply decreased to 0. When we try to withdraw all staking supply before the end of this distribution period, the left supply will be 0. And the earning rewards will be calculated via vestingRate
. This means the earned reward is not calculated by one liner way. This mechanism aims to encourage users stake long time.
The vulnerability is that the left reward tokens can not be completed shifted to next distribution period. This will cause some tokens stuck in the contract.
For example:
wait for 4 weeks to get some reward tokens for staking contract. Assume the rewards are 100 TempleGold.
assume vesting period and reward duration are 4 weeks.
Alice stakes 100 Temple. And start distribute via distributeRewards()
Alice withdraw all stakes in 2 weeks. Earned rewards will be 100/2/2 = 25 TempleGold.
Other 75 TempleGold will be left in contract in this distribution period.
Add this test case into TempleGoldStaking.t.sol.
The test case's output is
From the output, the staker's whole earned rewards in this distribution period are less than the amount of reward distribution.
Manual
Considering to add these left reward tokens into the next distribution period.
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.