# GPU token self-transfer bug mints balance, drained via flash loan

GPU token's transfer logic doubles the sender's balance on self-transfers, letting an attacker flash-loan BUSD, loop 87 self-transfers, and dump tokens for ~$32K.

- Payout: Real-world hack
- Severity: high
- Program: GPU
- Analysis by: DeFiHackLabs
- Disclosed: 2024-05-08
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2024-05/GPU_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20240508-gpu
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity technique:chained vuln:accounting-error vuln:business-logic vuln:flash-loan

**Target:** BEP-20 token contract on BSC (GPU) and PancakeSwap BUSD/WBNB pair
**Root cause:** The token's transfer accounting credits the recipient with the transferred amount without correctly debiting the sender when sender == recipient, so a self-transfer increases the caller's balance.
**Steps:**
1. Flash-swap 22,600 BUSD from the BUSD/WBNB PancakeSwap pair via `swap(22_600 ether, 0, address(this), "0x42")`
2. In `pancakeCall`, swap borrowed BUSD to GPU tokens via router `swapExactTokensForTokensSupportingFeeOnTransferTokens`
3. Loop 87 times: `gpuToken.transfer(address(this), getBalance(gpuToken))` to double balance each iteration
4. Swap all GPU back to BUSD via router
5. Repay flash loan: `amount0 + (amount0*3/1000 + 1)` to the pair
**How found:** Attacker likely noticed the token's transfer function mishandled the sender==recipient case, allowing balance inflation, then wrapped it in a flash-loan cycle to extract value without upfront capital.
**Exploitation:** Attacker flash-borrows 22,600 BUSD from the PancakeSwap BUSD/WBNB pair, buys GPU tokens, repeatedly self-transfers to inflate GPU balance, sells inflated GPU for BUSD, repays the flash loan plus 0.3% fee, keeping ~$32K profit.
**Insight:** For fee-on-transfer or custom-accounting tokens, test self-transfers (from == to) and zero-value transfers: naive `balanceOf[from] -= amt; balanceOf[to] += amt` with from==to can inflate balances, and flash loans make even small inflation profitable.
