Hook Executor
The HookExecutor
is a helper contract deployed by Escrow
to execute a sequence of on-chain hooks (typically DEX swaps) before locking funds for bridging. This lets the user convert their ERC20 tokens into a stable asset upfront so the Market Maker (MM) who fronts liquidity on the destination chain is not exposed to volatility risk.
Hooks are precomputed off-chain by calling the Most public API and are passed into Escrow.swapAndCreateOrder
, which deploys a fresh HookExecutor
via CREATE2, funds it, and triggers execution. When the swap completes, the executor returns the swapped tokens to Escrow
, which then creates the order using the swapped token and amount.
Key Interfaces
Struct
Hook
:target
: address to callcallData
: ABI-encoded calldata for the target
Execution Lifecycle
Escrow.swapAndCreateOrder(...)
deploysHookExecutor
with CREATE2 (usinghookExecutorSalt
), and transfers the user’s_srcAmount
of_srcToken
to the executor.Escrow
callsHookExecutor.execute(swapId, hooks, _srcToken, _expectedOutToken, address(this))
.The executor:
Reads its
tokenIn
balance and approves eachhooks[i].target
to spend that balance.Iterates through
hooks
and performstarget.call(callData)
in order.Checks the resulting
tokenOut
balance; reverts if zeroTransfers all
tokenOut
toescrow
and invokesonPreBridgeSwapReturn(swapId, tokenOut, amountOut)
onEscrow
Verifies no residual
tokenIn
ortokenOut
remain; reverts if any are leftSelf-destructs to
escrow
(safe under EIP-6780 since creation and destruction occur in the same transaction)
If any hook call fails, the executor reverts the entire transaction (HookFailed
). If tokenOut
balance is zero at the end, it reverts (ZeroOutputTokens
).
How Escrow Uses the Result
In
swapAndCreateOrder
, afterexecute
returns,Escrow
expects the executor to have calledonPreBridgeSwapReturn
Escrow
validates that the executor returned and provided a non-zerotokenOut
address. It then sets the order’s source token/amount to the returned values and proceeds to create the order as usualEscrow
emitsSwapCompleted
with the swap details
Parameters and Constraints
hooks
: Ordered list of calls to perform the swap route. Provided by the Most public API and passed through by the client.tokenIn
: ERC20 to be swapped. Swaps require ERC20; native ETH is not supported in the hook flow.tokenOut
: The expected output token address used by the executor to determine the balance to forward back toEscrow
.swapId
: Unique identifier binding the executor run to a specificswapAndCreateOrder
call.
Security and Safety Considerations
The executor only holds funds explicitly sent for this swap and destroys itself at the end; it reverts if any tokens remain unreturned, limiting any potential attack vectors.
Approvals are set per-hook target for the current executor
tokenIn
balance only.Hooks are external calls and may be unsafe if crafted maliciously, however the risk is minimized with the creation and destruction of the HookExecutor with each call. In practice, they are generated by the Most public API; clients should validate slippage and route off-chain. In the near future the hooks passed will be computed and checked on the client side to prevent the need for any trust.
The flow is atomic: a failure in any hook or post-conditions reverts the entire
swapAndCreateOrder
call.
Minimal Flow
User calls
swapAndCreateOrder
with_srcToken
,_srcAmount
,hooks
,_expectedOutToken
, andhookExecutorSalt
.Escrow
deploysHookExecutor
, sends it_srcAmount
, and callsexecute
.HookExecutor
performs the swap route, sendstokenOut
back, callsonPreBridgeSwapReturn
, and self-destructs.Escrow
records the swapped token/amount and creates the order.
Last updated