# Members lose SPARTA tokens in removeLiquiditySingle()

removeLiquiditySingle() with toBASE=true leaves the member's withdrawn SPARTA stranded in the Router instead of returning it, so LPs lose their SPARTA share.

- Payout: Audit contest
- Severity: high
- Program: Spartan Protocol
- Found by: 0xRajeev
- Disclosed: 2021-09-16
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-07-spartan-findings/issues/133
- Library page: https://bugbountylibrary.com/r/c4%3A2021-07-spartan%3AH-04
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Router.sol removeLiquiditySingle() liquidity withdrawal path
**Root cause:** When toBASE=true, LP tokens are sent to the Pool and both SPARTA and TOKENs are withdrawn to the Router, but only the TOKENs are forwarded to the Pool for conversion; the SPARTA sitting in the Router is never transferred to the member.
**Steps:**
1. Member calls `removeLiquiditySingle()` with `toBASE = true` requesting only SPARTA.
2. Router sends LP tokens to Pool (Router.sol#L121).
3. Pool withdraws constituent SPARTA and TOKENs back to Router (L122).
4. Router sends only the TOKENs to the Pool (L126).
5. Pool converts TOKENs to SPARTA and sends that SPARTA directly to member via `swapTo()` (L127).
6. The member's withdrawn SPARTA remains stranded in the Router, claimable by later transactions.
**How found:** Code review of the Router's removeLiquiditySingle flow, tracing token movements line by line and noticing the withdrawn BASE SPARTA was never forwarded to the member.
**Exploitation:** Any LP calling removeLiquiditySingle with toBASE=true loses the SPARTA component of their LP; the stranded SPARTA in the Router is absorbed by subsequent transactions that pull SPARTA from the Router.
**Insight:** In multi-contract swap/withdraw flows, trace every token's custody path line by line; a token withdrawn to an intermediate contract but never forwarded is a classic stranded-funds bug, and the fix is to route it through the same swapTo/swap path as the other leg.

