intent.escrow

Gasless escrow releases, verified on-chain.

A minimal intent-based escrow. Lock ETH or any ERC-20 for a counterparty; they authorise releases by signing an EIP-712 SettleIntent off-chain. Anyone can submit the signature to release funds, so the signer pays no gas.

Escrows created
ETH currently locked
Protocol fee
Network
Sepolia

The flow

1 · Deposit
Depositor locks ETH or an ERC-20 for a beneficiary with an expiry. Funds sit in the contract, not in either party's wallet.
2 · Sign
Beneficiary signs an EIP-712 intent off-chain authorising a partial or full release. No gas, no transaction.
3 · Settle
Anyone submits the signature on-chain; funds move and the nonce bumps to prevent replay. Signer pays nothing.

The intent

This is the exact EIP-712 typed struct the beneficiary signs. Wallets render it as a readable prompt instead of an opaque hex blob, and the per-escrow nonce plus deadline make every signature single-use.

struct SettleIntent {
    uint256 escrowId;   // which escrow this release applies to
    uint256 amount;     // how much to release (partial ok)
    uint256 deadline;   // UNIX seconds — signature auto-expires
    uint256 nonce;      // per-escrow; bumps on every settlement
}

Safety, at a glance

Replay-safe signatures
EIP-712 domain + per-escrow nonce + deadline. A signed intent can't be reused across chains, contracts, escrows, or after its deadline.
Smart-wallet compatible
Signatures verified via ERC-1271, so the beneficiary can be a Safe, an ERC-4337 account, or any contract wallet — not just an EOA.
Reentrancy-hardened
Every fund-moving function is nonReentrant and follows Checks-Effects-Interactions. Mock-attack test included in the suite.
Fee-on-transfer aware
createEscrow records the actual ERC-20 amount received, not the caller-supplied amount, so deflationary tokens can't desync accounting.
Deployed on Sepolia
IntentEscrow (verified)
0x3763507a41ff8B27C31c9F5b65BF902a945D6f34