# Liquidations miss delegate call to swapper

LiquidationRow calls asyncSwapper.swap via normal call instead of delegatecall, so swapper lacks tokens and liquidation always reverts, trapping claimed rewards.

- Payout: Contest reward
- Severity: high
- Program: Tokemak
- Credited: 0x007
- Disclosed: 2023-06-30
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-tokemak-judging/issues/205
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-tokemak%3AH-3
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** LiquidationRow / BaseAsyncSwapper swap flow
**Root cause:** LiquidationRow invokes IAsyncSwapper(asyncSwapper).swap(params) with a normal external call, but neither LiquidationRow transfers tokens to the swapper nor does the swapper pull them; the swapper is designed to operate on caller's tokens via delegatecall as done in LMPVaultRouter.
**Steps:**
1. Call `LiquidationRow.liquidateVaultsForToken(fromToken, asyncSwapper, vaultsToLiquidate, params)` as LIQUIDATOR_ROLE.
2. `_prepareForLiquidation` computes balances but does not transfer tokens to asyncSwapper.
3. `_performLiquidation` executes `IAsyncSwapper(asyncSwapper).swap(params)` as a normal call.
4. BaseAsyncSwapper.swap attempts to swap tokens it does not hold, reverting the whole liquidation.
5. Compare with `LMPVaultRouter.swapAndDepositToVault` which uses delegatecall so the swapper operates on caller's balance.
**How found:** Reviewer traced the liquidation flow, noticed no token transfer into or out of the swapper, then searched the codebase and found the swapper is invoked via delegatecall in LMPVaultRouter, revealing the call-type mismatch; also noted the test mock mints tokens so tests never caught it.
**Insight:** When a helper contract is designed to act on caller-held balances, check every call site for delegatecall vs normal call; a mock that mints tokens instead of requiring pre-funded balances masks this class of bug.
