# InternetToken: fake V3 pool mints INT via unguarded callback

Permissionless swapV3 accepted an attacker-deployed fake Uniswap V3 pool, whose callback minted 925M INT; a Convertor burn/re-mint round-trip defeated the supply guard.

- Payout: Real-world hack
- Severity: critical
- Program: InternetToken
- Disclosed: 2026-09-21
- Write-up quality: 9/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2026-09/InternetToken_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20260921-internettoken
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:critical tech:evm tech:solidity technique:chained technique:source-review vuln:access-control vuln:business-logic

**Target:** LiquidityUnifier.swapV3 / uniswapV3SwapCallback on Base
**Root cause:** swapV3 validates the pool only by code existence, exclusion list, and token0()/token1(), with no factory/registry check; the callback trusts msg.sender == currentPoolV3, which the attacker sets to their fake pool, enabling arbitrary mint. The validateSupply modifier is bypassed by burning the minted INT through Convertor mid-call and re-minting after.
**Steps:**
1. Deploy FakePool returning token0()=INT, token1()=OTHER to pass _validatePoolV3Tokens
2. Call `LiquidityUnifier.swapV3(OTHER, fakePool)`
3. FakePool.swap() re-enters `UNIFIER.uniswapV3SwapCallback(mintAmount, mintAmount, "")`; guard msg.sender==currentPoolV3 passes, minting INT to fake pool
4. Inside same call, `CONVERTOR.convert(INT, mintAmount)` burns INT to restore totalSupply before validateSupply post-check
5. After swapV3 returns, `CONVERTOR.convert(OTHER, mintAmount)` re-mints INT to attacker
6. Swap 161.27M INT into real INT/WETH V3 pool for 5.847 WETH; keep 764.15M INT
**How found:** Code review of verified LiquidityUnifier source: noticed swapV3 pool validation lacked a factory/registry check and the callback guard relied solely on attacker-settable currentPoolV3; then identified validateSupply could be defeated by the Convertor burn/re-mint round-trip.
**Exploitation:** Attacker contract deployed in a contract-creation tx; fake pool drives arbitrary INT mint, Convertor round-trip neutralizes supply guard, then dumps a portion into the real INT/WETH pool for WETH and retains the rest.
**Insight:** When a contract validates a caller-supplied pool by only checking token0()/token1() and code existence, deploy a minimal fake pool that satisfies those getters and re-enters the protocol's own callback; also check whether supply/balance post-checks can be neutralized by routing minted tokens through a burn/mint converter mid-call.
