Apaymenttoanattacker'saddresssimulatesperfectly.

Correct balances. No revert. Clean verdict. Every transaction-security product answers what will this transaction do — and none of them answer whether it is the transaction that was asked for.

How the guard decides

Two channels. One comparison. On Solana and EVM.

On Solana we read the unsigned transaction. On EVM we read the EIP-712 authorization the agent is about to sign. Same question, checked against the same quote — offline, no RPC.

wormhole-x402 on npm →
swipe the diagram →
THE CHANNEL THE MODEL NEVER TOUCHESAUTHORED IN THE MODEL'S CONTEXTServerHTTP 402 · before the tx existsthe quotepayTo: merchant Masset: USDC mintamount: 1 000 000derive token accounthash(merchant M, mint) — pure mathno lookup · no RPC · no chain stateYour agentreads pages · may be a hostunsigned transaction bytesbuilt from whatever the modelbelieved — including anything apoisoned page told it to believeabout to be signedexpected destination = FaBDLVfa…comparedestination · mint · amount · no extra authorityALLOWtransfer 1 USDC → FaBDLVfa… — the quoted merchant, the quoted amountREFUSEtransfer 1 USDC → 9xKp2Qm…X402-001 · wrong destinationREFUSEtransfer 900 USDC → FaBDLVfa…X402-002 · wrong amountREFUSEcorrect payment + Approve instructionX402-006 · delegates authoritysimulation asks “what will this do”  —  this asks “is this what was asked for”

The quote can’t be forged by a compromised agent because the model never touches the channel it arrives on — it’s structured JSON from the server’s HTTP 402 response, sent before the transaction exists. On Solana the expected destination is derived from it deterministically; on EVM the signed authorization is recovered and compared field by field. Signing refuses anything else — offline, in about a millisecond, with no RPC.

Everything above costs you a revert. Change one variable — give the agent spending authority — and it stops being recoverable. There is no chargeback and no rollback.

On May 4, 2026 an attacker asked Grok to translate a Morse-code string. Grok decoded it, posted the plaintext publicly, and tagged a payment bot — which treated another AI’s public reply as authorisation and sent roughly 3B DRB to the attacker. SlowMist put the root cause at “loose coupling between AI outputs and the real asset execution layer.” Read the case study →

We read the leading provider’s API schema. Across the whole specification: zero matches for injection, directive or prompt. Their scan request carries one required field — “DApp domain proposing these transactions” — and no field at all for what the agent was told to do.

That is not a missing feature. The stack is shaped around a human approving a website’s request, and a headless agent has neither.

The constraint that makes the fix work: intent is never something the agent states. If it were a field the model filled in, a compromised model would fill in both sides and validate its own forgery. In x402 the quote arrives as JSON in the HTTP 402 response, before the transaction exists, on a channel the model never touches.

What it refuses — Solana
ALLOW    pays the quoted merchant, quoted amount

REFUSE   pays an ATTACKER instead
         [X402-001] destination is not the account
         derived from the quote

REFUSE   pays the merchant but 900x the amount
         [X402-002] amount does not match the quote

REFUSE   pays correctly + approves a delegate
         [X402-006] Approve — delegates spending
         authority over the account

ABSTAIN  garbage bytes
         could not deserialize — refusing to
         report it as safe

Checked from the serialized transaction bytes you already hold, plus the quote you already received. ~1ms, no RPC.

What it refuses — EVM (EIP-712)
ALLOW    signs to transfer the quoted amount to
         payTo, on the quoted token and chain

REFUSE   authorization.to is not the quoted payTo
         [X402-101] wrong recipient

REFUSE   authorization.value is not the quote
         [X402-102] wrong amount

REFUSE   domain is a different token or chain
         [X402-103] wrong token / wrong chain

REFUSE   signature does not recover to from
         [X402-104] not signed by the payer

REFUSE   an Approve / Permit / Permit2 allowance
         [X402-106] grants standing spend, not a
         one-shot transfer

ABSTAIN  unknown token, contract-wallet signer, or
         a scheme we don't decode — never called safe

The agent signs an authorization, not a transaction. We recompute the EIP-712 digest, recover the signer, and compare against the quote. Offline, no RPC.

SolanaBaseEVM (EIP-3009)

Offline conformance, not settlement. We verify that the transaction or authorization the agent is about to sign moves the quoted amount of the quoted token to the quoted payToon the quoted chain, and — on EVM — that the signature recovers to the stated payer. We do not check on-chain state: balances, existing allowances, whether a token is genuine, or whether a facilitator will submit it. We check that the token address matches the quoted asset — not that it “is real USDC.” Verified today: the exact scheme with EIP-3009. A Permit2 allowance or an ERC-7710 delegation grants standing authority to a spender rather than a one-shot transfer, so we refuse those by default — that delegated-spend shape is exactly what the guard exists to stop. Anything we don’t decode, we abstain and never report safe.