In Staking.sol, there is no lock or delay in withdrawing the TKN token out after having received the shares in WETH. This can be manipulated to receive the shares many times by withdrawing the TKN token and deposit again with a new different address.
See line 86: https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol#L86
_delta is calculated by index - _supplyIndex
, index is updated and fixed after there is an increased amount of WETH in the contract, while _supplyIndex
is the mapping of user's address. By withdrawing from the old address and depositing with a new different address which hasn't been used in this Staking contract, user can claim the reward many times as _supplyIndex
is always 0 which make the _delta > 0
every time.
https://github.com/Cyfrin/2023-07-beedle/blob/main/src/Staking.sol#L46. As you can see, withdraw doesn't have any lock or delay declaration to stop the user from withdrawing too soon. This breaks the purpose of staking, since deposit itself is enough for reward.
A user deposits 1000 TKN.
Deposit function calls to updateFor()
and update the shares amount can be claimed by the user.
The user calls claim()
to receive the WETH and calls withdraw()
.
Repeat from step 1 until there is none of WETH left in the contract.
There won't be enough WETH for those who are late to claim the reward, they will have to wait until the contract is fulfilled with WETH again. And user can claim the reward many times without having to lock the token.
Manual
Implement a delay for withdraw, like 3-7 days. This can be done by declaring a startTime
when user deposits, and when withdrawing we can check if block.timestamp - startTime > 3-7 days
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.