A Zap cannot do anything it was not signed to do.
A Zap is a contract that holds funds and executes one policy its owner signed. This page documents the policy fields, current release state, the simulation API, and the execution lifecycle. Onchain actions are irreversible, so deposit only what you can afford to lose.
Execution riskOnchain actions are irreversible.The contracts are live on Robinhood Chain and carry bounded swaps through pinned aeWETH ↔ 0xZAPS and aeWETH ↔ USDG pools, a stitched USDG → 0xZAPS route, aeWETH/USDG liquidity, and the live v3/v3.1 recurring and price-triggered execution types — with the recipient forced to the owner and the relayer fee cap set to zero. Recovery is lineage-specific: owners can invalidate unused signed authority and recover tracked assets where the deployed lineage supports it. No control can undo a confirmed execution. Deposited funds are at risk.
Current release map
Status belongs to a contract lineage or product path, not to the repository as a whole. Live, deployed candidate, and source-ready are separate states.
v1.1 / v3 / v3.1
The current one-shot, recurring, and price-triggered lineages are live on Robinhood Chain. v3.1 derives a recurring run floor from an allowlisted spot source at execution.
Livev3.2 recurring stack
The isolated stack contracts are live on Robinhood Chain: creation, execution, and permanent-halt canaries passed with onchain receipts, and the app, relay, and executor lanes are open. The contracts remain unaudited.
Livev1.2 exact owner pull
The reviewed source path adds exact Permit2 owner pull and an irreversible policy halt. Governance deployment and independent post-deployment canaries have not happened.
Source-ready · not deployedPractice, request, or connect
Virtual Trading is browser-local and wallet-free. Request a Zap starts a human authority review. Connect pins one executor only inside terms the owner later signs.
Public product pathsThree authorities, kept apart
Stays with your wallet or Safe. Only you bring a Zap into existence.
Lives inside the immutable policy, or an EIP-712 typed intent. Not in an app, not in a key.
A courier. It picks the moment and nothing else.
Quickstart
The product lives at /zap in five surfaces: Start chooses an outcome, Compose builds the route and policy, Zap now creates and executes live v1.1 Zaps, Automate creates live v3/v3.1 recurring or price-triggered Zaps, and Connect prepares an executor address for terms the owner later signs. The builder compiles a design and names every guard the selected contract does not bind. A deployed route carries its amount, slippage, execution gas, and gas-price cap into Zap now. Automatable designs also carry cadence, Zap count, trigger terms, and executor access into Automate. The v3.2 stacking path remains a deployed candidate; anything else saves as a design and cannot deploy today. Simulation never broadcasts a transaction or asks for wallet authority.
A copied ?d= share link carries only the designed chain into Compose. The builder treats that payload as untrusted: it bounds its size and node count, keeps only recognized blocks and valid parameter values, then recompiles what survives against the current catalog. The link grants no wallet authority. Design mode never prompts for wallet access, approval, funding, a signature, or a transaction. A supported live route still requires the receiver to review the selected lineage's enforced bounds and confirm the required wallet signature or transaction; anything outside the supported routes remains a design-only blueprint.
curl -X POST https://www.0xzaps.com/api/policies/simulate \
-H "content-type: application/json" \
-d '{
"routeId": "robinhood-v4-weth-zaps",
"owner": "0x0000000000000000000000000000000000000001",
"amount": "0.01",
"slippageBps": 150
}'Execution policy composer
The block catalog now has three live execution-policy controls. The builder can insert every missing control as one stack, in one history checkpoint. One Undo restores the chain that existed before the stack was added. Each card stays independently editable after insertion.
maxGas · Zap now + Automate. Caps gas available to a Zap. If a design contains more than one gas-limit block, the lowest valid cap wins.
maxFeePerGas · Zap now + Automate. Rejects a Zap above the signed fee-per-gas ceiling. Multiple blocks resolve to the lowest valid price.
executor · Automate (v3/v3.1 live). Keeps execution open to anyone or restricts it to the owner. Owner only is the tighter result when blocks are combined.
Wallet balance → Execution gas limit 3,000,000 gas → Gas price cap 10 gwei → Executor access Anyone | Owner only → Swap → Send Zap now handoff: maxGas=3000000&maxFeeGwei=10 Automate handoff: maxGas=3000000&maxFeeGwei=10&executor=owner
Gas limit and gas price cap are signed in v1.1 one-shot intents and standing intents. Owner-only executor access is live in v3/v3.1; v3.2 uses the same field but remains a deployed candidate. The v1.1 one-shot Zap has no submitter restriction, so the builder leaves that field out of its Zap now handoff and shows the limitation before the user proceeds. Invalid or out-of-range handoff values fail closed instead of falling back silently.
Trade it. Use the app. Inspect the first fixed fee campaign.
OpenZaps can buy 0xZAPS through its pinned aeWETH → 0xZAPS route. Every Zap contract created by the current app converts its visible 0.00001 ETH creation fee into 0xZAPS atomically. A connected wallet holding 100,000+ 0xZAPS also gets auto-refreshing quotes, more saved Zaps and receipts, and receipt JSON export. The first 0xZAPS fee rewards campaign is fixed to a seven-day Aug 3–10, 2026 staking window. It was funded at launch with 50 of 100 tokenized Clanker fee shares and is configured to use time-weighted stake to allocate campaign-accounted WETH to eligible deposits during that window. Its harvest path was configured for Clanker fees, while direct WETH transfers can also be synchronized. Check /rewards for the current phase and later claim deadline. Every core workflow stays open without holding or staking the token.
Pinned Uniswap v4 pool, one bounded policy execution.
0.00001 ETH, converted atomically with a reviewed floor or the whole creation reverts.
Auto-refresh quotes, 50 saved Zaps, 100 receipts, JSON export.
Raises the app's saved-zap limit to 100.
Seven-day Aug 3–10, 2026 staking window; /rewards shows the current phase and later claim deadline.
Ownership alone grants no governance, automatic staking benefit, fee right, revenue claim, yield, equity, or return. The first campaign was limited to eligible deposits made during its fixed Aug 3–10, 2026 staking window; /rewards shows the current phase and later claim deadline.
Policy schema
The signed object is small on purpose. Any field that could widen what an execution may do is in the policy the owner reads before signing. A field that is not in the policy is not enforced by the contract.
deposit, intent, or Safe/ERC-1271. Session keys are not enabled; the simulator blocks them.
The only address allowed to receive tracked output assets. On the live route it is forced to the owner.
Draft spend and cadence fields. The v1.1 Zap binds the single step amount and tracks no cumulative budget or schedule.
An allowlisted adapter. There is no field for an arbitrary target plus calldata, so there is nothing to point at one.
A draft field. The v1.1 policy cannot bind a submitter, so whoever executes the Zap chooses the path.
Signed execution ceilings carried from the composer into one-shot and standing intents. A run outside either cap reverts.
A standing-intent field: live in v3/v3.1 and present in the v3.2 deployed candidate. Zero address leaves submission open; a nonzero address pins one eligible submitter. v1.1 does not bind a submitter.
Balance-delta, allowance-reset, recipient, and tracked-asset assertions, checked after the adapter returns. A failed assertion reverts the execution.
Simulation API
The chain-exact endpoint pins every required read and route quote to one canonical Robinhood Chain block. It returns the block identity, live adapter and token allowlists, runtime code hashes, a seeded-vault proof when the route requires one, the block-pinned quote and minimum output, the Solidity-exact policy hash, an unsigned EIP-712 draft, and an ephemeral factory eth_call. Stress-quote failures stay explicit and produce a warning instead of synthetic output. The endpoint never signs or broadcasts. In production it fails closed unless both the exact-policy API and durable-quota gates are active; an unavailable response is not a simulated pass.
type ExactPolicyArtifact = {
status: "pass" | "warn"
mode: "chain-exact"
chain: {
chainId: 4663
blockNumber: string
blockHash: `0x${string}`
rpcStatus: "verified"
}
allowlists: { adapterAllowed: true; tokens: Array<{ allowed: true }> }
runtimeCode: { factory: object; implementation: object; adapters: object[] }
quote: { amountIn: string; amountOut: string; minOut: string; blockNumber: string }
compiled: {
policyHash: `0x${string}`
predictedZap: `0x${string}`
unsignedEip712: object
}
ethCall: { method: "eth_call"; broadcast: false }
stressCases: Array<{ status: "quoted" | "rpc-failure" }>
authority: { signed: false; broadcast: false }
}Hookr pools: buy, zap in, zap out, migrate
Every token Hookr graduates trades in a hooked, dynamic-fee Uniswap v4 pool: the V5 launchpad’s HOOKR-quoted pools share one hook, Modular V2’s ETH-quoted markets share one kernel, and Modular V3 gives every market its own hook instance recorded by Hookr’s coordinator. OpenZaps reaches all of them through one HookedRangeVault per pool (a full-range position wrapped as an ERC-20 share, deployed permissionlessly by HookedRangeVaultFactory, which admits a V3 instance from the coordinator’s own live record), two universal LP adapters that take the vault or the settlement asset as factory-verified step data, and one market swap adapter that buys or sells any coordinator-recorded market by pool id. ETH-quoted markets are presented to the capsule with aeWETH as the quote. A third-party UI needs no contract integration: it links into the signer with a route id and an amount, the signer resolves every address from its own manifest, and the user signs one policy.
GET /api/hookr/routes // every pool, its route ids, and ready-made links // Buy a V3 market's token with aeWETH (one step; pool id is the route's bound) /zap?view=sign&src=build&route=hookr-market-buy-<pool>&amount=0.01&bps=150 // Zap in from HOOKR (one step) /zap?view=sign&src=build&route=hookr-lp-deposit-krn&amount=10000&bps=150 // Zap out to HOOKR (one step; amount = vault shares) /zap?view=sign&src=build&route=hookr-lp-withdraw-krn&amount=1&bps=150 // aeWETH -> HOOKR -> pool, or pool A -> HOOKR -> pool B (two steps, one signature): // the API's "policy" token pins the ordered steps; step 2's amount is frozen at // signing and becomes step 1's minimum output. /zap?view=sign&src=build&route=hookr-lp-withdraw-krn&amount=1&policy=<token>
Honest limits: a deposit swaps exactly half the input inside the pool (paying the hook’s dynamic fee), refunds whatever the ratio cannot absorb to the capsule, and reverts while a pool’s anti-snipe guard is still active. Redemption can never be blocked: the vault refuses hooks with removal permissions at construction. The vault and adapters custody real funds and are unaudited; a new launch becomes reachable after one permissionless createVault and one governance allowlisting of its share token.
Policy templates
The cards below are built-in draft starters. The public registry is readable only when configured; wallet-attributed publication and exact-version subscriptions are separate production-gated writes. A subscription is convenience metadata, not execution authority, reputation, or permission to follow an unreviewed latest version.
Recurring Zap in
Recurring ERC-20 Zaps, with spend, cadence, recipient, slippage, and relayer fee cap stated before signing. The v1.1 capsule holds one signed step; the v3 capsule in Automate binds cadence and total Zap count onchain under one signature.
ready previewZap in to a launch pool
A deposit into one named launch pool, with the recipient vault fixed and no arbitrary calldata. The live contracts currently deploy only bounded single-step swaps, so this template simulates and does not deploy.
requires reviewClaim and compound
Claims a reward and routes it into an approved asset, with exact approvals and balance-delta postconditions. A claim is two steps, and the live capsule executes one, so this is a draft shape rather than a route.
requires reviewGuarded Zap out
An exit triggered by a liquidity or oracle condition. Price-conditioned OPTIMIZATION zaps are live via the v3 trigger capsule (Automate tab); protective, liquidation-sensitive exits stay deferred until the protective-zap review completes — a missed protective trigger costs principal, and that class needs its own ADR.
deferredAutomation & the executor economy (v3 / v3.1)
The v3 Zap adds two standing execution types to the one-shot policy. Both are owner-signed once and condition-gated by the contract, so an eligible executor can submit a run the Zap owes, and the chain rejects every run it does not.
v3.2 adds an owner-signed post-fee output slice that stacks 0xZAPS, two spot-derived floors, and a one-way permanent policy halt. Its contracts are deployed, and the lineage remains a candidate until its production creation, execution, halt, and evidence canaries pass.
Recurring
One EIP-712 signature authorizes up to maxRuns Zaps over the frozen route, at least interval seconds apart, inside a signed window. Submitting early reverts (IntervalNotElapsed); exhaustion consumes the series; invalidateNonce cancels it at any time.
A series signs no absolute floor. Under v3.1 the owner signs an allowlisted price source and a slippage band, and the Zap derives each run's minimum output from that source's spot at execution — so a floor agreed weeks ago still protects the run happening now, and a series does not carry a stale floor into its next run.
Price trigger
One signature arms one execution against an allowlisted onchain price source. Until the market moves past the signed threshold the Zap reverts (TriggerNotMet); the submitter cannot supply a price. The spot threshold is an arming condition, not a fair-value oracle — the signed net-output floor still bounds every run.
Fees. Each automated Zap pays 1% of its measured output at settlement: 80% to the executor that submitted it, 20% to the protocol lottery pot, converted to 0xZAPS through the pinned bounded adapter by a later, permissionless keeper call. Floors are enforced netof the fee — both the absolute minimum-out a price trigger signs and the per-run floor a recurring Zap derives from spot. Every fee contribution credits lottery tickets to the Zap's owner; the pot pays prizes only in 0xZAPS and only to ticket holders — there is no owner drain. Winner selection is a deferred, governance-gated decision until a randomness ADR lands.
Creation fee. Every Zap created by the current app — one-shot, recurring, or triggered — separately pays exactly 0.00001 ETH. The fee gateway calls the existing lineage factory, wraps the fee to aeWETH, and converts it through the pinned aeWETH → 0xZAPS adapter in the same transaction. The wallet reviews both the fixed fee and a fresh minimum 0xZAPS output before signing; if factory creation or conversion misses that floor, the whole transaction reverts. The old immutable factories remain callable directly, so this is an app-enforced creation path rather than a retroactive change to already-deployed factory bytecode.
Build one in Compose, then review it in Automate. The signed intent exports as a JSON file an eligible executor can serve; the reference executor daemon lives in executor/ in the repository. The v3 and v3.1 contracts are live on Robinhood Chain.
Connecting an agent
An agent is connected to a Zap when you sign a standing intent naming that agent’s address in the intent’s executor field. The capsule reverts ExecutorMismatchfor anyone else. There is no credential to issue, store, or steal — the connection is one field of your own signature, and nothing off-chain is trusted to enforce it.
That bounds the blast radius exactly. A fully compromised agent can submit a run the capsule already owes, or refuse to submit one. It cannot change the recipient, amount, cadence, or output floor; cannot run early, twice, or past the end; and cannot create, fund, or drain a capsule. Leaving the executor unset (0x0) keeps the authorization open to any submitter, which maximises liveness; pinning one address trades that for exclusivity, and a pinned agent going offline stalls the series until you submit it yourself or sign new terms.
The read-only Agent Kit can discover capsules and request exact policy simulations. It holds no key and reads public chain data; it has no credential that could be mistaken for execution authority. Its scoped npm release is live; point your client at it, ask the agent for its public address, then pin that address in Connect.
{
"mcpServers": {
"openzaps": {
"command": "npx",
"args": [
"-y",
"@openzaps/mcp@0.1.0"
]
}
}
}Pinning is public: the executor address is inside the signed intent and in the chain’s logs, so anyone can see which agent runs your Zap. To revoke, stop the agent (the series stalls, costing no transaction), invalidate the authorization id onchain, or sign fresh terms under a new series id.
Execution lifecycle
Draft policy
Pick a template and fill the draft fields: authority model, spend ceiling, cadence, adapter, recipient, submitter, and postconditions.
Simulate
Deterministic checks run before any wallet prompt. A blocked policy does not proceed. A warned policy proceeds only after review.
Review signature
The typed intent binds chain, owner, recipient, nonce, deadline, policy hash, min-out, execution gas, gas-price ceiling, and executor access where the contract supports it. None can change after signing.
Submit
The owner submits from their own wallet. The v1.1 policy cannot bind a submitter, so whoever executes chooses the mempool path.
Monitor and recover
Receipts, allowance checks, balance deltas, nonce invalidation, and the owner's emergency-exit path stay attached to the Zap. Nothing watches it for you and no alert is delivered. Its page at /explore/<address> reports what the contract stores and what its own logs say, and nothing else.
SDK surface
The published @openzaps/sdk@0.1.0 source lives in packages/sdk. It compiles the Solidity policy tuple and prepares unsigned EIP-712 data; its client exposes the exact simulation endpoint and has no signing or broadcast method.
import { OpenZapsClient } from "@openzaps/sdk"
const openzaps = new OpenZapsClient()
const artifact = await openzaps.simulatePolicy({
routeId: "robinhood-v4-weth-zaps",
owner: "0xYourAddress",
amount: "0.01",
slippageBps: 150,
})
// Live allowlists + code hashes + quote + policy hash,
// unsigned EIP-712 draft + eth_call. Never a transaction.
if (artifact.status === "warn") reviewStressCases(artifact)Every chain-dependent field is pinned to one block. An RPC failure stays labelled unavailable; the client never substitutes a fixed token price. What actually executes is the deployed contract, not this surface. Read the verified source before signing anything. 0xZAPS is not required to simulate or inspect a policy.
Security model
A Zap — the immutable policy capsule the factory deploys — holds funds and accepts owner-signed intents that rehash to the policy frozen at creation. The adapter, the spender, the recipient, the input token, and the exact amount are fixed at that moment. An executor picks the moment and nothing else.
Bounded aeWETH ↔ 0xZAPS creation is open on Robinhood Chain, and the funds a Zap holds are real. Production use still needs formal verification, adapter governance, and a monitored launch path. Onchain actions are irreversible: once an execution lands, nothing here can undo it. Owners retain lineage-specific nonce or series invalidation and tracked-asset recovery controls; the v3.2 candidate also exposes a one-way permanent policy halt. Deposit only what you can afford to lose.
User / Safe -> OpenZapFactory -> OpenZap clone with frozen policy -> allowlisted adapter -> recipient-bound postcondition Agent / executor: discover -> simulate -> eligible submission -> public evidence no wallet key or signing authority no arbitrary calldata or automatic revoke right
Controls
The Zap calls an allowlisted adapter with the selector the policy names. There is no field for an arbitrary target plus calldata, so there is nothing to point at one.
The authorization is consumed before any external call. A reentrant call back into the Zap finds the nonce already spent.
The approval is the exact step amount, and it is reset to zero on the success path and the revert path. No standing allowance is left for anyone to draw on later.
After the adapter returns, the Zap asserts the tracked output asset, the recipient, the minimum output, and that no allowance remains. A failed assertion reverts the whole execution.
The v1.1 policy has no submitter field, so whoever executes the Zap chooses the mempool path. The live bounded route is submitted from the owner's own wallet.
The owner can invalidate unused intent nonces or emergency-exit tracked assets without an agent. The live v1.1 Zap has no generic pause function; its deployed policy remains immutable.
Threat model
A searcher who sees the pending execution can move the pool price against it. The signed minimum output and the ten-minute intent deadline bound what that is worth; the Zap cannot hide the transaction, because the policy cannot bind a submitter.
An adapter that kept an allowance could spend from the Zap again later. The approval is the exact step amount and is reset to zero on both paths, and a residual allowance fails the postcondition.
A submitter who edits a policy field before broadcasting produces a different policy hash, and the Zap rejects the intent. A chain-aware nonce and the typed-data domain make an intent signed elsewhere useless here.
A relayer can delay, censor, or pick a bad moment inside the signed limits. Every deployed policy commits a relayer fee cap of zero, so no submitter can bill the Zap through the policy; a v3/v3.1 automated run instead pays a fixed 1% of its measured output, 80% of it to the executor that submitted it. The owner can always submit the transaction themselves.
The v1.1 policy has no oracle precondition, so a design that depends on a price band is not enforced by it. Protective exits stay blocked in v1 for that reason.
Production gates
None of the following has completed. Each one is a precondition for calling the contracts production-cleared. Until they have, the only thing standing behind a failure in the contract, the interface, the relayer path, or the adapter registry is the owner's exit.
External audit
Independent review of factory, clone init, EIP-712/1271 verification, approval reset, and adapter boundaries.
Formal checks
A prover run over the authorization, approval-reset, call-surface, recipient, isolation, and token-allowlist invariants.
Adapter governance
Safe plus timelock ownership, adapter bytecode manifests, and a rollback process.
Testnet soak
Public testnet with real wallet review, alerts, receipts, and recovery drills.
Incident runbook
Emergency-control review, disclosure process, chain-monitor alerts, and postmortem template.