Users will lose funds when calling unstake. The unstake function will wrongly clear the stake amount and users will never get funds back.
Proof of Concept
2022/1/1: Alice stakes 1000 to TWELVE_MONTHS
2023/2/3: Alice stakes 10,000 to SIX_MONTHS, now the state is:
0 NONE
0 THREE_MONTHS
10,000 SIX_MONTHS (still staking)
1000 TWELVE_MONTHS (which can be unstaked)
Now, when Alice try to call unstake(1000), it will calculate totalVested = 0 + 0 + 0 + 1000 >= amount so it's able to unstake, then it will call _updateUserStakedAmounts.
But in _updateUserStakedAmounts L306-L308, it will wrongly clear amount of SIX_MONTHS:
Lines of code
https://github.com/code-423n4/2022-06-infinity/blob/main/contracts/staking/InfinityStaker.sol#L290-L325
Vulnerability details
Impact
Users will lose funds when calling
unstake
. Theunstake
function will wrongly clear the stake amount and users will never get funds back.Proof of Concept
2022/1/1: Alice stakes
1000
toTWELVE_MONTHS
2023/2/3: Alice stakes10,000
toSIX_MONTHS
, now the state is:Now, when Alice try to call
unstake(1000)
, it will calculatetotalVested = 0 + 0 + 0 + 1000 >= amount
so it's able to unstake, then it will call_updateUserStakedAmounts
. But in_updateUserStakedAmounts
L306-L308, it will wrongly clear amount of SIX_MONTHS:Finally, the state will be:
Alice loses 10,000 tokens (in SIX_MONTHS amount) forever.
Tools Used
None
Recommended Mitigation Steps
It should check vested amount in every durations in
_updateUserStakedAmounts
: