Skip to content
Mainnet Live. All executions, addresses and hashes are live.
WORMHOOK
conceptualv0.1 · skeleton docs

Adapters

The boundary between WORMHOOK and the logic it executes.

Why adapters

The gateway knows how to verify a call. It shouldn't know how to start an IMD job, burn into POOL4 or rebalance a vault. Adapters hold that knowledge, so:

  • hook logic can change without touching the gateway;
  • a broken or malicious hook is contained to its adapter's permissions;
  • every hook is invoked through one interface the gateway can wrap in try/catch, gas limits and spend accounting.

Interface

IWormHookAdapter.solconceptual
interface IWormHookAdapter {
    /// Called only by the WormHookGateway after verification.
    /// MUST revert on failure; the gateway converts reverts into failed receipts.
    /// Returned bytes are hashed into HookReceipt.outputHash.
    function execute(
        bytes32 callId,
        bytes calldata payload
    ) external returns (bytes memory output);
}

The final interface will likely add the action selector, the spend budget and a spent-amount return value. Those decisions are tracked in CORE_TECH_PLAN.md §Adapters.

Kinds

AdapterHooksNotes
IMD Adapterimd.research.v1, imd.build.v1, imd.swarm.v1Starts IMD work and returns job identifiers. Final action set depends on IMD's real job interfaces.
POOL4 Adapterimd.pool4.v1Contributions with CappedBurn semantics: burns min(amount, cap) and reports the actual amount.
Customanything elseYour contract, implementing the interface. Registered under your namespace.

Rules for adapter authors

  1. Only the gateway may call execute. Check msg.sender.
  2. Never trust the payload shape. Decode defensively; malformed input should revert, producing WH-402.
  3. Respect the budget. Never move more than the call's maxSpend. The gateway also enforces caps, and both layers check.
  4. Be idempotent per call ID if your hook has external side effects. The gateway prevents replays, but defence in depth is cheap.
  5. Return compact output. Only its hash goes on the return path; full output belongs in an event or in your own storage.
  6. No re-entrancy into the gateway.

Testing locally

The SDK's simulator lets you exercise how your hook's outcomes surface (success, partial, revert) before any contract exists:

const execution = await client.simulate(call, { scenario: "reverted" });
const receipt = await execution.waitForReceipt();   // status: "failed"