AgentCap

← Blog

EIP-3009 nonces, replay, and how agent spend gets deduplicated

GetAgentCap team · published 10/1/2026

x402 payments on Base mostly settle through USDC's transferWithAuthorization. Its nonce model is not the account nonce you know, and that changes how you should count spend.

What transferWithAuthorization does

EIP-3009 lets a token holder sign an off-chain authorization that anyone can submit on-chain. The signed message covers from, to, value, validAfter, validBefore and a nonce. A facilitator or the resource server submits it and pays the gas.

USDC implements this function. That is why an agent can pay over x402 without holding ETH for gas: the agent signs, and someone else broadcasts.

The nonce is random, not sequential

EIP-3009 nonces are 32-byte values chosen by the signer, usually at random. They are not an incrementing counter like an account's transaction nonce, so there is no ordering between authorizations.

The contract records each (authorizer, nonce) pair once it is used. You can query that with authorizationState. A second submission with the same pair reverts.

What replay protection does and does not cover

Replay protection stops one signed authorization from settling twice. It does not stop an agent from signing two different authorizations for the same purchase. Each new nonce is a valid, separate payment.

So a retry loop that re-signs after a timeout produces two real transfers. The chain sees two legitimate payments, not a replay.

Signed but never submitted

An authorization can also expire unused once validBefore passes. Nothing happens on-chain, so no money moves.

This is why we count only settled transfers. A signature in your agent's logs is intent, not spend.

How GetAgentCap deduplicates

We key each payment by transaction hash plus log index of the USDC Transfer event. That key is unique on-chain, so re-ingesting the same block range cannot double-count it.

When a transfer came through EIP-3009, the contract also emits an AuthorizationUsed event carrying the authorizer and nonce. That lets you tie a settled payment back to the signature your agent produced.

What to check in your own agent

Make retries reuse the original authorization rather than signing a fresh one. Before re-signing, check authorizationState for the old nonce.

If you see two transfers to the same payee for the same amount seconds apart with different nonces, it was most likely a retry, not a replay. Fix it in the client.