Description
The _extruction instruction allows an order's program to delegate execution to an arbitrary external contract. This external contract can differentiate between being called in a static context (from the quote() function) and a non-static context (from the swap() function). A malicious Maker can create an order that uses _extruction to call a contract they control. This contract can be programmed to return favorable swap terms (e.g., a high amountOut ) during a static quote() call, tricking the Taker into executing the swap. However, during the actual swap() execution, the same contract can alter the swap registers to malicious values (e.g., setting amountOut to zero), causing the Taker to lose their input tokens for nothing in return. This breaks the fundamental 'Quote/Swap Consistency' invariant of the protocol
function _extruction(Context memory ctx, bytes calldata args) internal {
address target = address(bytes20(args.slice(0, 20, ExtructionMissingTargetArg.selector)));
uint256 choppedLength;
if (ctx.vm.isStaticContext) {
// Attacker's contract returns a favorable result here
(ctx.vm.nextPC, choppedLength, ctx.swap) = IStaticExtruction(target).extruction(...);
} else {
// Attacker's contract returns a malicious result here (e.g., amountOut = 0)
(ctx.vm.nextPC, choppedLength, ctx.swap) = IExtruction(target).extruction(...);
}
// ...
}
Severity
- The settlement pipeline enforces a taker-specified minimum output (minOut) or equivalent invariant that reverts when execution produces worse results than quoted.
- Takers or integrator UIs set reasonable
minOut values rather than zero.
Description
The
_extructioninstruction allows an order's program to delegate execution to an arbitrary external contract. This external contract can differentiate between being called in a static context (from thequote()function) and a non-static context (from theswap()function). A malicious Maker can create an order that uses_extructionto call a contract they control. This contract can be programmed to return favorable swap terms (e.g., a highamountOut) during a staticquote()call, tricking the Taker into executing the swap. However, during the actualswap()execution, the same contract can alter the swap registers to malicious values (e.g., settingamountOutto zero), causing the Taker to lose their input tokens for nothing in return. This breaks the fundamental 'Quote/Swap Consistency' invariant of the protocolSeverity
minOutvalues rather than zero.