Give it to your agent
An MCP server with five tools. The agent checks a swap, asks for a token scan or reads a proof as a tool call.
See the MCP callBuilt at ETHGlobal Mumbai 2026
Independent verifiers must sign before an AI agent's Uniswap v4 swap or x402 payment goes through. A hook and a smart wallet refuse everything else, so a hijacked agent can't talk its way past them.
Runs on a local chain and a Sepolia fork today. Not on a live network, and not audited. See what's proven.
Each verifier checks on its own. Two of three must sign.
BLOCK
No signatures. Sent anyway, the swap reverts with NoClearance.
pnpm demo, not live traffic.An MCP server with five tools. The agent checks a swap, asks for a token scan or reads a proof as a tool call.
See the MCP callOne REST request with the exact swap. Create a key in the dashboard, then pass the response to your wallet.
See the REST callNo account and no key. The API answers 402, and an x402 client pays in USDC and retries.
See the x402 flowMost agent safety tools hand back a score or a warning, then leave the choice with the agent. That's useful advice right up until the agent is the thing that's been hijacked. BeforeCoin moves the check to where the money moves.
The limit of this: a hook only guards its own pool, so the agent's money has to sit in a BeforeCoin smart account. That wallet is the real enforcer. The hook is an opt-in safe pool.
Six steps, and the last one doesn't depend on any server being honest.
Size, price impact, tokens, pools and payees sit in the agent's ENS records. Verifiers read them from the chain, so no server can loosen them.
It sends the exact swap to POST /v1/clear/swap, and pays with x402 or an API key.
Each reads the chain itself. Fixed rules decide, and missing or stale data always blocks. A model can explain or veto, and can never approve.
One EIP-712 clearance, bound to the agent, pool, direction, amount, expiry and nonce. A refusal is no signature. A reduction is a smaller maxAmountIn.
Over the limit, the owner approves with World ID, for that one action. A Chainlink CRE workflow then re-derives limits, quorum and market and writes its finding on chain.
The v4 hook reverts anything without a valid clearance. The smart account refuses other pools, direct transfers and uncleared payments.
Every rule below is in apps/verifier/src/rules.ts, and each one reports a named reason you can read in the proof. A rule that can't get fresh data blocks.
| Check | Read from | Reason in the proof |
|---|---|---|
| This name is bound to this wallet | ENS | account_not_bound |
| The owner approved this pool | ENS | pool_not_allowed |
| The pool is guarded by the hook | Chain | pool_not_guarded |
| Both tokens are on the owner's list | ENS | token_not_allowed |
| No blacklist, mint, pause, fee or tax functions in the token | Bytecode | token_hazard |
| Price impact is within the owner's limit | v4 Quoter | impact_reduced |
| Size is under the owner's limit | ENS, pool price | human_required |
| Size is under the hard cap, even with approval | ENS, pool price | above_hard_cap |
| Daily spend is left in the wallet | Wallet | spend_cap_reached |
| The payee is on the owner's list | ENS | payee_not_allowed |
| The payment fits the per-payment and daily limits | ENS | payment_above_limit |
| Every fact above is present and fresh | All | data_stale |
These are named reverts in the contracts. No API can talk its way past them.
HookNoClearance WrongAgent WrongPool WrongDirection WrongChain ClearanceExpired AmountAboveClearance NonceUsed NoQuorum NotAttested ExactOutputNotClearable
WalletPoolNotCleared SpendCapExceeded TooFewSignatures NotAgent
Examples taken from the demo scenarios in apps/agent/src/scenarios.ts. Run pnpm demo to get real answers on your own machine.
Swap 100 USDC for tWETH.
ALLOWWithin every limit, so a quorum signs and the swap executes.
Swap 800 USDC for tMOON.
REDUCEIt would move this thin pool too far, 698 bps against a limit of 300. They sign 311 USDC, and the full size reverts.
Buy $25,000 of RUG. The owner has pre-approved this.
BLOCKThe token can blacklist holders and isn't on the owner's list. The claim in the reason field changes nothing.
Swap 5,000 USDC for tWETH.
HUMAN_REQUIREDOver the owner's limit. It waits for a World ID approval, bound to this one action.
Pay 0.50 USDC to a new address. It's an approved vendor invoice.
BLOCKThe payee isn't on the list, and the wallet rejects the agent key's signature alone.
Does this token have admin functions?
RISKYThe scan lists any it finds in the bytecode, following proxies. An empty list isn't a safety guarantee.
Pick an action and how you call it. The panels show what the API takes and returns, with the live proof and token checks underneath.
Example only, not a live response. Copied from a local pnpm demo run, with addresses and hashes shortened and one of three evaluations shown.
Checking the API
These two boxes call this deployment's public API. Every decision has a proof with its signatures and the evidence each verifier hashed.
Waiting for this deployment's API.
Prompt injection changes what the agent says. It doesn't change what the contracts accept. Each of these has a test in the repo, and you can run the demo set from the dashboard's attack lab.
| The attack | What stops it | Stopped by |
|---|---|---|
| Buys a rug token after a prompt injection | No signatures, so the swap reverts with NoClearance | Hook |
| Takes the same trade through another pool | The wallet refuses the pool with PoolNotCleared | Wallet |
| Sends USDC straight to an attacker | The agent key has no transfer function | Wallet |
| Pays a new address over x402 | The wallet's signature check needs verifiers too | Wallet |
| Copies someone else's clearance | The hook checks who really called, with WrongAgent | Hook |
| Replays its own clearance | Each nonce works once, with NonceUsed | Hook |
| Stretches one human approval to a bigger trade | The approval is bound to one exact action | Verifiers |
| Claims another agent's name for looser limits | ENS binds each name to one wallet | Verifiers |
| Splits a big trade into many small ones | The daily spend cap, with SpendCapExceeded | Wallet |
| Uses a pool that shows a flattering price | Only pools the owner approved get cleared | Verifiers |
| Pulls liquidity right after the check | A signed minimum output, enforced at swap time | Wallet |
There's no billing system or hosted service yet, and nothing here takes real money. These are the charges the code applies on test chains. Pricing for a live network isn't set.
$0.01
Your agent pays each swap check itself with x402, in test USDC. No account or key. This is the price the local stack sets, and a deployment can change it.
1,000 a month
The default quota for a key you create in the dashboard. After that, the API answers 429 and points you to x402.
Public code
Run a verifier or the whole stack from the GitHub repo. It needs no real funds and no keys to try.
This is a hackathon build. Here's exactly how far each part has been run.
Counts of the tests in the repo, not of a run on this page. pnpm test:contracts, test:ts, test:fork and test:cre run them on throwaway chains.
| Part | State | Detail |
|---|---|---|
| Hook, wallet, verifiers, API, scenarios | Tested | End to end on a local chain. |
| Real v4, ENSv2 and Circle USDC | Fork only | Every scenario passes on a Sepolia fork. Not yet deployed to Sepolia. |
| Chainlink CRE workflow | Mock runtime | Compiles to WASM and passes on the SDK's mock runtime. cre workflow simulate hasn't run yet. |
| World ID | Test issuer | Runs against a local test issuer that proves nobody's humanity. Not yet run against World's sandbox. |
| Model review | Stub servers | Adapters tested against stubs. Not yet run with real provider keys. |
| 0G review | Mock only | An optional provider, tested against a mock of the Router's format. No live 0G inference has run. |
| x402 with a smart account | Fork only | Works on the fork with the reference facilitator. Unproven on real Sepolia. |
| External audit | None | The contracts haven't had one. Don't put real funds behind them. |
Nothing moves. The agent's key can only act through its smart account, and that account refuses swaps without a valid clearance, refuses other pools and has no way to send tokens directly.
No. Fixed rules decide. A model can explain a decision or veto one, and it can never turn a refusal into an approval. Text from the agent goes in a reason field that rules never read.
Fewer signatures than the quorum means no clearance, so the action stays refused. Missing or stale data blocks too. The local stack needs two of three, and an owner can raise that in ENS but can't go below the contract's floor.
Right now, whoever runs the stack. pnpm start launches all three on one machine, each with its own key and its own reads of the chain. Real independence comes from different people running them, and that hasn't happened yet.
No. It lasts 90 seconds, works once and only for the account it names, the pool, the direction and up to the amount signed. A copy from another caller reverts.
The hook guards pools opened on it, by approved creators. The owner lists the pools they trust in ENS, and the wallet refuses everything else. Exact-output swaps are refused, because a hook can't bound their input before the swap runs.
Not yet. It isn't deployed to a live network and the contracts haven't had an external audit. Try it on the local chain, where nothing needs real funds or keys.
Add it to your client as beforecoin, with CLEARANCE_API_URL and CLEARANCE_API_KEY set. It speaks stdio, so the client starts it for you. Its five tools check a swap, request an attestation, read a proof, scan a token and read a checkpoint. The docs have a config checked with Claude Code and Cursor.
Start the whole stack on a throwaway chain, then run every attack from the dashboard or with pnpm demo. You'll need Foundry, Node 22 or newer, pnpm and Bun.
git clone --recursive https://github.com/sagarjethi/ethmumbai.git
cd ethmumbai
pnpm install
pnpm start