HyperFX ·Ethereum
CallDispatcher — unauthenticated dispatch() drains stranded tokens
Verified with working PoC
Contract: 0xE2C7e576E26E0bE7aC97c6fE925bcDAbD87c4bEd
Summary
An honest, fully valid IntentGatewayV2.placeOrder() order that unwraps a real LP position via predispatch strands the undeclared leg on CallDispatcher, which an unrelated third party can then drain via a direct, unauthenticated dispatch() call.
Root cause
placeOrder's sweep loop iterates order.inputs, not whatever the predispatch calldata actually produced, and dispatch() has no caller restriction at all.
Verification
Falsifies the invariant 'no undeclared ERC20 ever remains on CallDispatcher after a valid placeOrder() call' with a passing mainnet-fork Foundry test - real, currently-deployed CallDispatcher address confirmed by reading the actual on-chain storage, correcting an earlier address mismap from the minified frontend bundle mid-investigation.
Verified against real, live deployed contract state.
Receipt on GitHub