In the stake()
function of the Steaking
contract, the usersToStakes[_onBehalfOf]
value is overwritten each time a user stakes ETH, rather than incremented. Therefore, every new stake effectively resets the user’s total staked amount to the latest value, erasing any prior contributions.
When a user stakes ETH, the following line in the stake()
function overwrites the existing amount (which could be != 0) in the usersToStakes
mapping:
Instead of adding the new amount to the existing stake, this line replaces the previous amount entirely. Therefore, every new stake effectively resets the user’s total staked amount to the latest value, erasing any prior contributions.
Due to the overwriting of the staked amount in the usersToStakes
mapping, users who stake multiple times on behalf of the same address will only be able to unstake the most recent staked amount, not the total of all their stakes. This effectively locks up any prior contributions, preventing users from recovering the full amount of ETH they originally staked.
After the staking period ends, users are supposed to convert their staked ETH into WETH and deposit it into the vault. However, because only the most recent stake is recorded, users will not be able to deposit the actual total amount of ETH they staked. Instead, they will only be able to deposit the amount from their last transaction, resulting in a discrepancy between the actual ETH staked and the WETH deposited into the vault.
So the user's funds are lost and remain locked in the contract.
PoC:
Place the following test into steaking-contracts/test/Steaking.t.sol
;
Manual Review
Modify the logic in the stake()
function to accumulate the user's stake rather than overwriting it. Replace the line that overwrites the stake amount with the following:
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.