Summary
The function resetVestingPlans() is called by an administrator account and resets vesting plans for a list of users, with the corresponding amount provided as input. The function calls _resetVestingPlans(), where it checks whether the given amount is greater than or equal to the claimed amount for the user. After that, it calls resetAmount() from LibVestingPlan. In this function, the state is updated, the new amount is recorded, and claimedAmount is set to 0.
Root Cause
The issue here is that this can lead to double spending. Even though the user executing the request is trusted, they cannot know whether another transaction has been executed before theirs, in which the user whose vesting plan is being reset has withdrawn their locked amount by paying a penalty fee. If this happens, the user will be able to claim the same amount again after the reset, which would harm other users who might not be able to claim their rewards.
Internal Pre-conditions
None
External Pre-conditions
None
Attack Path
- Trusted user sends a transaction for executes resetVestingPlans()
- Regular user subject of this reset sends a transaction that is executed before the first one and claim their locked tokens as they pay a penalty
- After the reset the user is able to claim the tokens up to amount again
Impact
Loss of funds for the protocol and for the users