# Unable to remove liquidity in Recovery Mode

UniswapHandler removes liquidity and sends tokens directly to msg.sender, triggering the recovery-mode transfer whitelist check and reverting, locking users out of withdrawals.

- Payout: Audit contest
- Severity: high
- Program: Malt Finance
- Found by: gzeon
- Disclosed: 2022-02-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-11-malt-findings/issues/323
- Library page: https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-02
- Tags: area:web3 domain:web3 impact:dos kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:dos

**Target:** UniswapHandler.sol / PoolTransferVerification.sol (Solidity contracts)
**Root cause:** UniswapHandler.removeLiquidity sends the removed tokens directly to msg.sender; UniswapV2Pair's safeTransfer invokes _beforeTokenTransfer -> verifyTransfer, which reverts for non-whitelisted addresses when price is below peg.
**Steps:**
1. Enter recovery mode (Malt TWAP >2% below peg) so verifyTransfer reverts non-whitelisted transfers.
2. Call UniswapHandler.removeLiquidity as a non-whitelisted user.
3. Handler burns LP and transfers underlying tokens to msg.sender.
4. UniswapV2Pair.safeTransfer triggers _beforeTokenTransfer -> verifyTransfer(msg.sender) which reverts.
5. Liquidity removal fails; funds stuck unless admin whitelists each user.
**How found:** Read the protocol's stated recovery-mode design (users withdraw via whitelisted UniswapHandler) and traced the handler's transfer recipient against the PoolTransferVerification whitelist check invoked by UniswapV2Pair transfers.
**Insight:** When a protocol whitelists a helper contract to bypass a guard, verify the helper's internal transfers don't route value back through the guarded path to a non-whitelisted msg.sender.
