Calculated from recorded token losses using historical USD prices at the incident time.
0xfe34c4beee447de536bbd3d613aa0e3aa7eeb63832e9453e4ef3999924ab466a0x65a8f07bd9a8598e1b5b6c0a88f4779dbc077675Ethereum0x00000000000044a361ae3cac094c9d1b14eece97Ethereumswap(bytes,uint256) Calldata-Offset Auth BypassAt Ethereum block 24575085, transaction 0xfe34c4beee447de536bbd3d613aa0e3aa7eeb63832e9453e4ef3999924ab466a exploited Uniswap v4 Router04 (0x00000000000044a361ae3cac094c9d1b14eece97) through malformed calldata passed to swap(bytes,uint256).
The adversary EOA 0xd6b7e831d64e573278f091aa7e68fbf2a8fa9916 called helper contract 0xded262d0a933b7bb4ed8c4b6cb2dce5b157b74a0, which issued a crafted router call that bypassed payer authentication and caused unauthorized spending from victim 0x65a8f07bd9a8598e1b5b6c0a88f4779dbc077675.
Incident outcome:
42,606.959179 USDC (42606959179 raw units, 6 decimals).21197984596759249607 wei.9331433496067 wei (210467 * 44336801).+21197975265325753540 wei (+21.197975265325753540 ETH).Pre-state (sigma_B) required for exploit realization:
The ACT sequence is a single adversary-crafted transaction and is inclusion-feasible without privileged access.
UniswapV4Router04 supports a dynamic-argument entrypoint:
function swap(bytes calldata data, uint256 deadline) external payable returns (BalanceDelta);
data is expected to contain ABI-encoded BaseData plus swap path parameters. In callback handling, the decoded BaseData determines who is charged and who receives proceeds:
struct BaseData {
uint256 amount;
uint256 amountLimit;
address payer;
address receiver;
uint8 flags;
}
Relevant settlement behavior (Router callback path):
BaseData memory data = abi.decode(callbackData, (BaseData));
inputCurrency.settle(poolManager, data.payer, inputAmount, input6909);
outputCurrency.take(poolManager, data.receiver, outputAmount, output6909);
For ERC20 input (USDC here), settle(...) resolves to a transferFrom(payer, PoolManager, amount) flow, so correctness of data.payer authentication is safety-critical.
Root-cause category: ATTACK.
The vulnerable check in UniswapV4Router04.swap(bytes,uint256) authenticates caller identity using a fixed calldata position (calldataload(164)) instead of decoding BaseData.payer from the actual dynamic bytes location. ABI dynamic offsets are attacker-controlled; therefore a non-canonical but valid encoding can place attacker-controlled bytes at the fixed check location while keeping the decoded payer field set to a victim address.
In this incident, the attacker set the dynamic bytes offset to 0xc0, spoofed the fixed auth slot to the helper caller address, and retained victim as decoded payer in the payload. The auth check passed, then _unlockAndDecode consumed the decoded payload and charged the victim through token transfer settlement.
This violates the invariant that the authenticated payer used for settlement must equal the transaction caller for all accepted encodings. The concrete breakpoint is the assembly check:
assembly ("memory-safe") {
if iszero(eq(calldataload(164), caller())) {
mstore(0x00, 0x82b42900) // Unauthorized()
revert(0x1c, 0x04)
}
}
Security principles violated:
Exploit mechanism (deterministic sequence):
0xd6b7e831d64e573278f091aa7e68fbf2a8fa9916.0xded262d0a933b7bb4ed8c4b6cb2dce5b157b74a0.swap(bytes,uint256) (selector 0xaf2b4aba).word[0]) was 0xc0 (non-canonical for a two-arg call).word[5], absolute args byte offset 160) was set to helper caller address 0xded262....BaseData.payer (word[9]): 0x65a8f07bd9a8598e1b5b6c0a88f4779dbc077675 (victim).BaseData.receiver (word[10]): 0xd6b7e831d64e573278f091aa7e68fbf2a8fa9916 (adversary EOA).Representative decoded words (from the router-call calldata inspection):
selector=af2b4aba
word[0] = ...000000c0
word[5] = ...ded262d0a933b7bb4ed8c4b6cb2dce5b157b74a0
word[9] = ...65a8f07bd9a8598e1b5b6c0a88f4779dbc077675
word[10] = ...d6b7e831d64e573278f091aa7e68fbf2a8fa9916
calldataload(164) and compared it to caller(), which passed because the attacker controlled that absolute slot._unlockAndDecode(data), where data resolved from offset 0xc0, not from fixed slot assumptions.data.payer (victim) and data.receiver (attacker EOA).FiatTokenV2_2::transferFrom(
0x65A8F07Bd9A8598E1b5B6C0a88F4779DBC077675,
PoolManager: 0x000000000004444c5dc75cB358380D2e3dE08A90,
42606959179
)
PoolManager::take(
ETH,
0xd6B7e831D64e573278f091AA7E68Fbf2A8FA9916,
21197984596759249607
)
Gas used: 210467
42606959179 -> 0 (delta -42606959179).+42606959179.+21197975265325753540 wei (net after gas).Exploit conditions (all satisfied in this incident):
Adversary strategy summary: one permissionless transaction using helper-crafted calldata to convert victim-approved USDC into attacker-received ETH.
Adversary-related accounts:
0xd6b7e831d64e573278f091aa7e68fbf2a8fa9916 (EOA): tx sender and ETH profit recipient.0xded262d0a933b7bb4ed8c4b6cb2dce5b157b74a0 (contract): direct Router caller and fixed-slot spoof value.Victim candidates identified in analysis:
0x65a8f07bd9a8598e1b5b6c0a88f4779dbc077675 (is_verified: unknown).0x00000000000044a361ae3cac094c9d1b14eece97 (is_verified: true).Lifecycle stages:
0xfe34...466a in block 24575085: attacker EOA calls helper with victim/token targets.swap(bytes,uint256) with offset/payload mismatch; fixed-slot auth passes while decoded payer is victim.This is ACT because execution required only public state, public interfaces, and standard transaction submission.
Measured losses and gains:
42,606.959179 USDC.+21.197975265325753540 ETH after gas.Scope:
0x65a8f07bd9a8598e1b5b6c0a88f4779dbc077675.Success predicate used for ACT validation:
value_after - value_before - gas > 0) is satisfied with observed net delta.Primary evidence:
0xfe34c4beee447de536bbd3d613aa0e3aa7eeb63832e9453e4ef3999924ab466a (Ethereum mainnet, block 24575085).transferFrom, PoolManager::take, gas used).UniswapV4Router04::swap(bytes,uint256) fixed-offset auth check).BaseSwapRouter::_unlockCallback settlement and payout semantics).selector, dynamic offset, payer/receiver positions).Referenced contract/function identifiers:
0x00000000000044a361ae3cac094c9d1b14eece97, swap(bytes,uint256).0x000000000004444c5dc75cb358380d2e3de08a90, take(...).0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48, transferFrom(...).