When claiming rewards from StakeV2, vault tokens are zapped out via the zapper contract. However, if a user specifies a smaller inputAmount for the token swap, any excess tokens are erroneously sent to StakeV2 and become permanently locked.
Vulnerability Details
Users claim their rewards using the following functions:
claimRewardsInNative
claimRewardsInToken0
claimRewardsInToken1
claimRewardsInToken
The vulnerability applies to all of them, but we will focus on claimRewardsInToken1:
The function validates the withdrawal amount and delegates to the zapper via zapOutToToken1:
Here, _yeetOut returns amounts in token0Debt and token1Debt. The user provides a swap amount (swapData.inputAmount) for converting token0 to token1. Any leftover token0Debt (i.e., token0Debt - inputAmount) is sent to _msgSender(), which is the StakeV2 contract.
This leads to a scenario where if a user intends to convert only part of their token0Debt (e.g., 50%), the remaining 50% is sent to StakeV2 and becomes inaccessible to the user. This results in a permanent partial loss.
Impact Details
Permanent, irrecoverable loss of user funds occurs when the user specifies a swapData.inputAmount smaller than the full token0Debt. The excess token0 is sent to StakeV2 and becomes trapped.