# Failed transfer with low level call won't revert

Low-level call in LibSwap.swap returns success when target has no code, so failed swaps don't revert and user funds sent to Swapper are lost.

- Payout: Audit contest
- Severity: medium
- Program: LI.FI
- Found by: GeekyLumberjack
- Disclosed: 2022-05-05
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-03-lifinance-findings/issues/101
- Library page: https://bugbountylibrary.com/r/c4%3A2022-03-lifinance%3AM-11
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic

**Target:** LibSwap.swap / Swapper.sol swap execution
**Root cause:** Low-level `.call` to a non-existent contract returns success=true, and swap does not verify contract existence or return data, so a failed swap proceeds without reverting.
**Steps:**
1. Alice calls GenericSwapFacet with 100 DAI
2. DAI is transferred into Swapper.sol in preparation for swap
3. `_swapData.callTo.call{value: msg.value}(_swapData.callData)` targets a non-existent contract, returns success
4. postSwapBalance computed as 0, no revert
5. Alice receives nothing; funds remain lost
**How found:** Code review of LibSwap.swap against Solidity docs noting low-level call returns true on failure; cross-referenced missing require in GenericSwapFacet versus other facets.
**Exploitation:** Attacker or user supplies swapData whose callTo has no deployed code; the low-level call succeeds vacuously, funds already moved to Swapper are not returned and no revert occurs.
**Insight:** When auditing swap/aggregator libraries, check every low-level `.call` for contract-existence and return-data validation; a missing require in one facet (GenericSwapFacet) can expose a latent library flaw present everywhere.
