#41647 [SC-High] Unused tokens after zapping can be stuck and not entitled to users

Submitted on Mar 17th 2025 at 08:38:58 UTC by @trtrth for Audit Comp | Yeet

  • Report ID: #41647

  • Report Type: Smart Contract

  • Report severity: High

  • Target: https://github.com/immunefi-team/audit-comp-yeet/blob/main/src/StakeV2.sol

  • Impacts:

    • Theft of unclaimed yield

Description

Brief/Intro

The leftover tokens after a zapping action is sent from Zapper to the contract StakeV2. These tokens are unhandled by StakeV2, causing the tokens to be permanently stuck in the contract

Vulnerability Details

Users can claim staking rewards in either token0, token1, native token or whitelisted token through functions StakeV2#claimRewardsInNative(), StakeV2#claimRewardsInToken0(), StakeV2#claimRewardsInToken1(), StakeV2#claimRewardsInToken()

In the above functions, the user will spend vault shares and call Zapper contract to handle zap out the position to the wanted token.

For example with the function StakeV2#claimRewardsInToken1(), the contract StakeV2 calls Zapper#zapOutToToken1() to redeem from Vault to receive islandTokens which is then used to remove liquidity from KodiakVault to finally receive pool's token0 and token1. After received token0 and token1, the Zapper contract calls OB SwapRouter to swap token0 --> token1 (here user claims rewards in token1). After swap, all unused token0 are sent back to StakeV2 contract, and all token1 are sent to the user. Here, the function StakeV2#claimRewardsInToken1() does not handle the unused/leftover token0 sent from Zapper contract, which can cause the tokens to stuck in the contract

Indeed, if the liquidity pair is BERA-YEET, then the tokens can be used for the next reward distributions. However, these tokens should be entitled to the user, not for the reward distributions because it is redeemed from user shares amount

Impact Details

  • Users can not get the tokens that should be entitled to receive and the tokens are distributed among other stakers

References

https://github.com/immunefi-team/audit-comp-yeet/blob/da15231cdefd8f385fcdb85c27258b5f0d0cc270/src/StakeV2.sol#L361-L375 https://github.com/immunefi-team/audit-comp-yeet/blob/da15231cdefd8f385fcdb85c27258b5f0d0cc270/src/contracts/Zapper.sol#L272-L287

Proof of Concept

Proof of Concept

1.Update the test test_successful_zap_out_yeet at file test/zapper/ZapOut.t.sol

  1. Run the test and console shows

The result shows that YEET is sent to Alice successfully, but WBERA is not

Was this helpful?