The starting point
A Flint vault accepts one asset on one network: USDC on Ethereum. Depositors rarely hold exactly that. Their capital sits in other tokens on other networks, from Sonic and Solana to Stellar and Sui. The goal was for every one of those holders to reach a vault position without first becoming an Ethereum USDC holder by hand.Why a plain swap was not enough
SODAX already moves value between networks with intents. A plain cross-network swap could take a depositor’s asset and land USDC in their Ethereum wallet. The depositor would then still need to:- Hold ETH for gas on Ethereum.
- Approve the vault to pull their USDC.
- Submit a deposit request to the vault themselves.
What SODAX built
The answer is a delivery hook: a small contract on Ethereum that receives the output of a SODAX intent and acts on it in the same delivery. SODAX is a hub-and-spoke system. Each supported network is a spoke, and the hub runs on Sonic. Here is the full path of a Flint deposit: Step by step:- Intent on the source network. The depositor signs one intent where their asset lives. The output is set to USDC on Ethereum, and the delivery target is the Flint hook rather than their own wallet.
- Execution on the Sonic hub. The intent is filled on the hub like any other SODAX swap.
- Delivery with data. The output is delivered on Ethereum together with a small payload that names the depositor. The Ethereum spoke contract transfers the USDC to the hook and calls its
hookfunction. - Deposit request. The hook calls the vault’s
requestDepositwith the depositor as the ERC-7540 controller. The request, and the shares it settles into, belong to the depositor. The hook holds nothing afterwards.
Using it from the SDK
The hook is registered in the public@sodax/sdk. Builders pick it by name and the SDK fills in the deployed hook address and encodes the payload, so the two can never drift apart.
A Flint deposit is an ordinary intent with one extra field:
hook set, dstAddress keeps its plain meaning: the person being credited. The SDK swaps the real delivery target for the hook’s address behind the scenes.
The repo includes a runnable version of this flow at
apps/node/src/flint-deposit.ts (pnpm flint-deposit). It defaults to a dry run that prints the quote and the built intent, and reads the hook’s live minimum deposit before submitting.What it means for depositors
- Any asset, any network. Funds can start on any of the 20+ networks SODAX supports, EVM and non-EVM.
- One signature. The depositor signs one intent, on the network where the asset already sits. No bridging step, no ETH for Ethereum gas, no separate vault transaction.
- The position is theirs. The vault request is recorded against the depositor’s own address from the start.
The lesson for builders
The Flint hook is a custom build, and it sits on a general mechanism. When SODAX delivers an intent’s output on a spoke network, the spoke can hand those tokens to a receiver contract and call itshook(token, amount, data) with a payload chosen at intent time. Any contract that implements that receiver interface can turn a delivery into an action.
Flint is not the only hook in the SDK registry. A second one, for Hyperliquid, deposits delivered USDC straight into a HyperCore trading account on HyperEVM. Both are selected the same way, with a HookKind, and the registry is designed to hold many hooks per network. For receivers not yet in the registry, intents also accept raw deliveryData aimed at a custom receiver address.
So the pattern is open: if your product needs value from many networks to arrive as a position, a deposit or an account credit rather than a wallet balance, a delivery hook is the place to put that logic. Each hook is a focused contract shaped around one partner’s flow, exactly as the Flint hook was shaped around an ERC-7540 vault.