# TransitFinance: unvalidated pool in exactInputV3Swap drains router

TransitFinance router failed to validate the pool address in exactInputV3Swap, letting an attacker-supplied fake pool drain ~$110k of USD from the router.

- Payout: Real-world hack
- Severity: high
- Program: TransitFinance
- Analysis by: DeFiHackLabs
- Disclosed: 2023-12-20
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-12/TransitFinance_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20231220-transitfinance
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** TransitFinance swap router (exactInputV3Swap) on BSC
**Root cause:** The router trusted the caller-supplied `pools` array and invoked `swap` on an arbitrary contract without verifying it was a legitimate Uniswap V3 pool. The attacker's contract implemented the pool interface and returned fabricated amounts.
**Steps:**
1. Deploy attacker contract implementing `token0()`, `token1()`, `fee()`, and `swap()` to mimic a Uniswap V3 pool.
2. Build `ExactInputV3SwapParams` with `srcToken=bnb`, `dstToken=bnb`, `wrappedToken=wbnb`, `amount=1`, `pools[0]=attacker`, `pools[1]=<encoded pool id>`.
3. Call `ITransitRouter(0x00000047bB99ea4D791bb749D970DE71EE0b1A34).exactInputV3Swap{value:1}(params)`.
4. In the attacker's `swap()`, return `(-int256(IERC20(usd).balanceOf(router)), -int256(IERC20(usd).balanceOf(router)))` to signal a large output.
5. Router transfers its USD balance to the attacker as `dstReceiver`.
**How found:** Likely spotted that `exactInputV3Swap` accepts a user-controlled `pools` array and performs a low-level call to `swap` on each entry without checking it against a factory registry, enabling arbitrary contract invocation.
**Exploitation:** Attacker supplied a fake pool contract in the `pools` array. The router called `swap` on it, and the fake pool returned negative amounts equal to the router's entire USD balance, causing the router to pay out ~$110k in USD to the attacker for a 1 wei BNB input.
**Insight:** In DEX routers/aggregators, any user-supplied pool address passed to a low-level `swap` call must be validated against a trusted factory; otherwise an attacker can substitute a malicious contract that fabricates swap results.
