# ATM Token: hidden transferFrom auto-swap drains PancakeSwap pair

ATM token's _transfer auto-sold 20% of its own reserves on every sell; attacker spread holdings across 30 fresh clones to bypass anti-whale guards and drained ~$243k USDT from the PancakeSwap pair.

- Payout: Real-world hack
- Severity: high
- Program: ATM Token
- Credited: DeFiHackLabs
- Disclosed: 2026-06-04
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-06/ATM_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260604-atm
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic

**Target:** BEP-20 token custom _transfer / PancakeSwap ATM-USDT pair
**Root cause:** ATMToken._transfer sell branch calls _swapTokenForFund() dumping 20% of the contract's own ATM balance into the pair with amountOutMin=0 whenever balance exceeds swapAtAmount (200e18). Anti-whale guards (MAX_HOLDER, coldTime lastBuyTime, tOwnedU cost basis) are keyed only to sender/recipient fresh state, so fresh addresses bypass them.
**Steps:**
1. Fork BSC at block 102072357-1; confirm pair reserves, ATM self-balance > swapAtAmount, and 30 farmer clones each holding ~94,999 ATM with approvals to helper.
2. Setup leg (tx 0x3738..69b): helper buys ~2.85M ATM for ~154,319 USDT and distributes ~94,999 ATM to each of 30 CREATE2 clones (< MAX_HOLDER 100k), each pre-approving helper.
3. Pump leg (132 txs, nonce 2308-2440): burn-on-buy ratchet removes ~45.7M ATM from pair (92.0M -> 45.7M), doubling price to ~0.108 USDT/ATM.
4. Drain leg (tx 0x37b9..d86): helper calls each clone to sell its ATM into pumped pair; each sell triggers _swapTokenForFund auto-dump of 20% of sell size at amountOutMin=0.
5. Collect 243,543 USDT to helper; net profit ~89,224 USDT after setup cost.
**How found:** Source review of Sourcify-verified ATMToken revealed _transfer's sell branch auto-swapping contract-held tokens with amountOutMin=0, and that all anti-whale checks key off sender/recipient fresh state rather than global supply, enabling address-splitting.
**Exploitation:** Attacker pre-funded 30 fresh addresses each below MAX_HOLDER with ATM bought cheaply, pumped the pair via burn-on-buy, then sold from all clones in one tx. Fresh addresses had lastBuyTime=0 and tOwnedU=0, so sell lock and 25% profit fee never applied; each sell additionally forced the token contract to dump its own reserves into the pair at amountOutMin=0, worsening price for LPs and extracting USDT.
**Escalation:** Split position across 30 CREATE2 clones to stay under MAX_HOLDER and reset per-address anti-bot state; multi-tx pump campaign to double price before the drain.
**Insight:** When auditing token _transfer hooks, check whether anti-whale/anti-bot guards (max-holder, cooldown, cost-basis fee) are per-address only; if so, fresh-address splitting neutralizes them. Also flag any contract-held-balance auto-swap with amountOutMin=0 as a guaranteed LP leak on every sell.
