All incidents

Unauthorized WETH drain via unprotected Uniswap V3 callback

Share
Jul 03, 2024 02:47 UTCAttackLoss: 27.35 WETHManually checked1 exploit txWindow: Atomic

Root Cause Analysis

Unauthorized WETH drain via unprotected Uniswap V3 callback

1. Incident Overview TL;DR

0x452e25 Uniswap-style callback contract (Ethereum mainnet)

An unprivileged attacker-controlled EOA 0xabee16e7... deployed helper contract 0x27b2784... and then, in a single transaction, used it to call contract 0x452e25...'s Uniswap V3-style callback function 0xfa461e33. That callback blindly executed WETH9.transfer(msg.sender, amount) based solely on calldata, causing 27.349 WETH to be transferred out of 0x452e25... to the attacker cluster. The attacker later unwrapped the WETH to ETH and forwarded 16.41 ETH to profit address 0xad425f..., confirming successful value extraction.

Contract 0x452e25...'s 0xfa461e33 uniswapV3SwapCallback implementation lacks any msg.sender or accounting checks and unconditionally calls IERC20(token).transfer(msg.sender, amount) using a token address decoded from attacker-controlled calldata, enabling arbitrary unprivileged callers to drain its WETH holdings via a single transaction.

2. Key Background

Uniswap V3-style swaps call back into user-supplied contracts via uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes path), and secure implementations must verify that msg.sender is the expected pool contract before transferring tokens. WETH9 (0xc02a...) is a standard wrapper for ETH; balance diffs and the WETH9.transfer call in the trace show that 27.349 WETH were moved from 0x452e25... to the attacker cluster in the seed tx. Contract 0x452e25... is an unverified, owner-configured contract whose other functions include explicit caller checks (e.g., FlashBorrower: Untrusted loan initiator) and owner-gated logic, but its 0xfa461e33 callback path does not use the stored owner or any whitelist.

3. Vulnerability Analysis & Root Cause Summary

4. Detailed Root Cause Analysis

5. Adversary Flow Analysis

6. Impact & Losses

  • 27.349 WETH

The immediate, on-chain impact is a 27.349 WETH reduction in contract 0x452e25...'s WETH9 balance, with the same amount credited to the attacker-controlled cluster. Subsequent unwrap and forwarding steps convert a substantial portion of this WETH into ETH and deliver at least 16.41 ETH to profit address 0xad425f..., demonstrating successful value extraction from the contract. No evidence from the collected artifacts indicates any counteracting inflows that would offset this loss.

7. References

[1] Seed tx metadata and balance diff for 0x1194e1d6... (artifacts/root_cause/seed/1/0x1194e1d6085885ce054a7ff8cd3cd0c3fa308ec87e4ccde8dd0549842fef4f1b) [2] Decompiled and disassembled code for contract 0x452e25... (artifacts/root_cause/data_collector/iter_2/contract/1/0x452e253eeb3bb16e40337d647c01b6c910aa84b3) [3] Storage slots for 0x452e25... and 0x27b2 at block 20223095 (artifacts/root_cause/data_collector/iter_3/contract/1) [4] Address txlists for 0xabee16e7..., 0x27b2, 0x452e25..., and 0x6074... (artifacts/root_cause/data_collector/iter_3/address/1)