# Transit Swap: owner validation flaw drains approved user funds

Transit Swap's claimTokens contract failed to validate the owner address, letting an attacker pass any approved victim as owner and transferFrom their BUSD, stealing over $21M.

- Payout: Real-world hack
- Severity: critical
- Program: Transit Swap
- Analysis by: DeFiHackLabs
- Disclosed: 2022-10-02
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2022-10/TransitSwap_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20221002-transitswap
- Tags: area:web3 domain:web3 impact:funds-loss impact:mass-exploit kind:incident platform:defihacklabs sev:critical tech:evm technique:source-review vuln:access-control vuln:business-logic

**Target:** BSC smart contract claimTokens/swap router (0x8785bb8d...)
**Root cause:** The claimTokens contract (0xed1afc8c...) accepted an arbitrary owner address without verifying the caller was authorized for that owner, then executed transferFrom() against that owner's prior token approvals.
**Steps:**
1. Identify a victim (e.g. 0x1aae0303f795b6fcb185ea9526aa0549963319fc) who previously granted token approval to 0xed1afc8c4604958c2f38a3408fa63b32e737c428.
2. Craft calldata for TransitSwap 0x8785bb8deAE13783b24D7aFE250d42eA7D7e9d72 embedding the victim address as owner and the attacker as recipient in the nested claimTokens call.
3. Call TransitSwap with the crafted `hex"006de4df..."` payload; the claimTokens contract runs `transferFrom(victim, attacker, amount)` on BUSD (0x55d39832...).
4. Receive the victim's BUSD in the attacker contract.
**How found:** Attacker studied past transactions to learn how to combine calldata so the claimTokens contract would treat an arbitrary approved user as the owner; the PoC notes you must study prior txs to assemble the call data.
**Exploitation:** Attacker submitted a single crafted transaction to the TransitSwap router that routed into the claimTokens contract, which performed transferFrom() pulling the victim's approved BUSD balance to the attacker; repeated across many approved users to net over $21M.
**Escalation:** Reused the same primitive against every user who had outstanding approvals to the claimTokens contract, scaling losses to $21M+.
**Insight:** When a router/claim contract takes an 'owner' or 'from' address as a parameter, check whether it verifies msg.sender against that address before calling transferFrom — any user with a lingering approval to the helper contract becomes drainable.

