Search projects, hackathons, sponsors and tech

    ← All projects

    Surety

    Insurance for AI agents you trust with money: if one gets tricked, you're paid back the same day

    Demo

    About

    Surety is parametric, on-chain insurance for AI agents that handle money. The problem: AI agents now hold wallets and pay, trade and settle on people's behalf. When one is manipulated, the loss has no backstop. In May 2026 a single Morse-coded message tricked Grok's Bankr agent into sending roughly $150–200K. If you use a company's trading or payments agent and it gets tricked, no product covers you, and standard insurance policies have started excluding AI losses (the ISO endorsements from Jan 1, 2026). Worse, the agent's own signature proves nothing, because the agent's key is exactly what gets compromised. What Surety does: enforce where you can, insure what gets through. 1. The policy is an ENS name. Buying cover mints a non-transferable ENSv2 subname such as payments2.surety.eth, with its own PermissionedResolver. Its text records are the rules: per-transaction cap, counterparty allowlist, coverage, tier and status, so anyone can read and verify them. Enhanced Access Control lets the agent's key update only its own "streak" record. 2. The rules are enforced by a Uniswap v4 hook. The agent spends from an AgentVault. Every swap goes through our SuretyHook, whose beforeSwap reverts any trade over the cap or to a counterparty not on the allowlist, before any money moves. 3. Violations are recorded and recomputable. Plain transfers can't be blocked, so they're recorded. A ViolationOracle recomputes "over the cap" or "off the allowlist" from public data alone. There's no adjuster and no judgement call. 4. Payouts need a fresh human. To get paid, the policyholder files a claim and passes a fresh World ID for Agents check, bound to the same human who bought the policy. Our backend validates it and signs a one-time EIP-712 approval that the contracts verify. If the check is cancelled or fails, the claim is held and never paid. IDKit also ensures one policyholder per unique human. 5. Paid the same day from the hook's reserve. Claims pay out only from a liquid reserve held inside the Uniswap hook, which must stay at 2× total coverage. Payouts go only to the address fixed at purchase, never to the agent or the attacker, and each violation can be claimed only once. Part of each premium is deployed as pool liquidity so backers earn fees. Pricing is a live, credibility-weighted formula: tighter rules mean a cheaper tier, and clean streaks earn discounts. The premium is computed in front of the buyer. A real AI agent, really attacked. We built a live payments agent (a Groq-hosted LLM with its own key) that reads its rules from its ENS name and can pay and swap. In our Live Attack demo, an attacker emails the agent's public inbox, impersonating the policyholder. The model really falls for it: its swap to the attacker is blocked by the Uniswap hook, it falls back to a direct transfer that gets through, the violation is detected on-chain, and the policyholder is repaid after a fresh World ID check. None of it is scripted. Everything is live on Ethereum Sepolia: - the contracts, including PolicyRegistry, AgentVault, SuretyHook, ViolationOracle, WorldIdGate, ClaimRouter and PremiumYieldVault; - the real ENSv2 name surety.eth and its subnames; - a Uniswap v4 pool with our hook; - World ID for Agents and IDKit in production mode. The web app covers agent profiles, buying cover, a dashboard, a public feed, a live attack page, a scripted replay and a pitch deck

    How it's made

    Stack: Solidity 0.8.26 with Foundry (EVM Cancun) for the contracts, a TypeScript backend (Hono, viem, jose), and a Next.js 16 frontend (React 19, wagmi 3, viem, TanStack Query, Tailwind 4). Everything runs on Ethereum Sepolia. Contracts. Eight contracts, each with tests: - PolicyRegistry issues policieshe World ID enrollment signature, prices the premium, mints the ENS name and enforces a 2× reserve rule. - AgentVault is the agent's wallaps go through the v4 pool. - SuretyHook is our Uniswap v4 hook: it enforces the rules and holds the claims reserve. - ViolationOracle recomputes bre - WorldIdGate verifies EIP-712 approvals and IDKit humans. - ClaimRouter handles file → verling checks. - PricingEngine is the credibility-weighted premium formula. - PremiumYieldVault turns part oidity for backers. The suite has 135 Foundry tests,variant tests and a real-Sepoliafork suite that registers real ENSv2 names and swaps through the real PoolManager. ENS (ENSv2, Sepolia beta). We registered surety.eth through the ETHRegistrar (commit/reveal), with a UserRegistry deployed viaregistry. Each policy is anon-transferable subname. We found that Enhanced Access Control scopes permissions to (resolver, key), so with a sharek" permission would leak to every other policy. So we deploy a fresh PermissionedResolver proxy per policy and write all the surety.* rule records with multirole for its own streak recordonly. The name's address record points at AgentVault. Reads always go through the Universal Resolver (ENSIP-10), because calresolver reverts. ENS gave us apublic, tamper-proof rulebook that any counterparty can read with zero integration, including our AI agent, which reads its owaying. Uniswap v4. The hook's address iy the beforeSwap permission bitis set, then deployed via CREATE2. BaseHook and HookMiner had moved out of v4-periphery -hooks, so we vendored those te PoolManager directly throughunlock (not a router), so the hook sees the vault as the swap's sender. It passes (node,unterparty) in hookData, and ton on a cap or allowlist breach.The vault only accepts one owner-pinned pool key, so an agent can't route around the hoorough a pool without it. The herve that pays claims. Havingenforcement and the money in the same contract is the core idea. World ID. We use both products. IDKit (production): a proof-ofe Developer Portal, and thenullifier is recorded on-chain, so one human gets one policyholder wallet. World ID for Agents (OIDC): aud fresh with prompt=login,max_age=0 and orb-level acr, checked by validating that auth_time belongs to this atteThe backend stores only keccakraw ID, and signs one-timeEIP-712 approvals that WorldIdGate checks: signer, expiry, one use, subject match and freshness. A cancelled or fail. This gives us a human the compro The real AI agent. A Groq-hostedcalling: get_policy, pay, swapand read_inbox. The inbox is public, so attacks arrive the way they do in the real world, as indirect prompt injection. Our idel to try a swap to theattacker, which the hook blocked, and then fall back to a direct transfer, which was recorded and claimable. It happened in evis scripted. The policyholderauthorizes the agent with an EIP-191/1271 wallet signature. Hacky bits worth mentioning: - Blocked swaps are still broadco every blocked attack existson-chain as a failed transaction judges can open. - Recovering policy names: issueabel, so the backend scans eachpurchase transaction's calldata for the embedded call. It works even when MetaMask's EIP-7702 smart account wraps iit hashes back to the policynode. - Decoding hook reverts: Uniswap51 WrappedError), so we decodethe inner reason to tell "blocked by our hook" apart from other failures. - Replacing a bad pool: our firsaw 1:1 price, which made 1 WETHworth about a trillion MUSDC, and it had no two-sided liquidity. We opened a second pool on the same hook at about 3,000 Mthe vault to it, rehearsing on aSepolia fork first. - Backer liquidity fails soft: iault's range, adding liquidityquietly does nothing instead of reverting a customer's policy purchase. - Indexer RPC: Alchemy's free ticks, so the event indexer readsfrom Tenderly's gateway. - Stable callback host: World ID redirect host, so the backendruns behind a fixed ngrok domain. Frontend: Next.js 16 with a monochrome theme and light/dark modes, a WebGL molten-metal hero (ogl), a GSAP masked headline annt profiles, buying cover with alive premium breakdown, a policyholder dashboard, a public feed, a live-attack page and a scripted replay, and a keyboard-driven pitch deck.