# msg.value is Sent Multipletimes When Performing a Swap

LibSwap.swap forwards msg.value on every iteration of the swap loop, letting an attacker drain the contract's latent native token balance via repeated native-asset swaps.

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

**Target:** Solidity swap facet (Swapper/LibSwap)
**Root cause:** LibSwap.swap() uses `call{value: msg.value}` inside a loop over _swapData, so the original msg.value is forwarded once per swap instead of once per transaction.
**Steps:**
1. Call Swapper._executeSwaps with _swapData array where multiple entries have fromAssetId = native token
2. Send msg.value > 0 with the transaction
3. Each loop iteration executes `_swapData.callTo.call{value: msg.value}(_swapData.callData)`, forwarding msg.value again
4. Contract pays out _swapData.length * msg.value of native token, more than received
**How found:** Code reading of the swap loop in Swapper._executeSwaps and the `value: msg.value` external call in LibSwap.swap; noticed msg.value is transaction-scoped but used inside a per-swap loop.
**Exploitation:** Attacker submits a swap with several native-token swap entries; each iteration forwards the same msg.value out of the contract, converting the contract's latent native balance into ERC20 tokens sent to the attacker.
**Insight:** When auditing multicall/loop-based swap or batch routers, check whether transaction-scoped values like msg.value are forwarded inside per-item loops; latent contract balances make this exploitable even if the protocol claims no funds are held.
