Closed code423n4 closed 2 years ago
Withdrawal will reduce the userstakedAmounts[user][Duration.XX].amount so getUserStaekPower will not be 2
@nneverlander to clarify: this issue is precisely on the case where tokens are unlocked but the user does not unstake
This seems like a design choice. The power could be intentionally be weighted this way because although the tokens could be withdrawn, the user did choose to lock them up for that period of time.
I closed a very similar report as invalid, however the wrapper is an interesting consideration. Lowering risk and merging with the warden's QA report #294
Lines of code
https://github.com/code-423n4/2022-06-infinity/blob/765376fa238bbccd8b1e2e12897c91098c7e5ac6/contracts/staking/InfinityStaker.sol#L232
Vulnerability details
Impact
After a user's lock is expired, he can withdraw but his tokens still count in in
StakePower
Proof of Concept
getUserStakePower
usesuserstakedAmounts[user][Duration.XX].amount
, and does not check if the tokens are vested or not.So for example, if Alice stakes 1 token for 3 months, after 3 months she has 1 token she can instantly withdraw but
getUserStakePower
still returns 2.First I am not sure this is intended, and is not in the interest of the protocol as you'd like users to increase their commitment and their lock duration.
Then, in an extreme case, this could lead to a wrapper contract where users would stake through the contract, and then sell the property of this contract instead of withdrawing. Like Alice would sell her unlocked 3 months vested token for a premium instead of withdrawing.
Recommended Mitigation Steps
Correct
getUserStakePower
to count expired staked amounts as unlocked ones.