free

Any outcome you're exposed to but can't control is a hedge you haven't placed yet.

free

Created At

ETHGlobal Lisbon 2026

Project Description

If your money, revenue, or plans depend on how some real-world outcome goes, you're carrying that risk unhedged whether you notice it or not. Parasol turns it into a position: tell the agent what outcome you're exposed to, and it prices and assembles a hedge from live prediction-market odds on exactly that outcome. If things go the wrong way, the position pays out and offsets the loss. This creates a market-priced hedge for any exposure a public source can settle far beyond your typical bespoke insurance product for one narrow case. You sign every transaction yourself; the agent only ever attests to what happened, it never touches your money.

How it's Made

Agent Risk elicitation runs as a conversational front-end to 0G Compute's Router, the vanilla OpenAI SDK repointed at the Router's baseURL, so the integration surface is trivially small and swappable. The Router mediates access to whichever underlying model is configured, settling inference cost on-chain per call; those settlement debits against the Router's payment contract are themselves the primary proof of inference, supplemented by raw request/response logs and, where the Router exposes one, a TEE attestation binding a specific model execution to a specific output. That attestation matters more than it might first appear: it's what lets a "private, verifiable inference" claim survive scrutiny instead of remaining a marketing assertion.

Architecturally, the model is confined to a single, narrow responsibility: producing a schema-constrained risk profile (event, threshold, target payout, a confidence scalar), and nothing downstream trusts it beyond that boundary. Output is validated against a strict JSON schema server-side; a malformed or underspecified response triggers a re-prompt rather than silent coercion. Everything with numerical consequence (pricing, position sizing, order construction, slippage bounds) lives in deterministic, unit-testable code that consumes the model's output as an opaque input, never as an instruction to execute. This is a deliberate separation of concerns: the stochastic component is quarantined to intent-capture, and the entire financial state machine downstream is reproducible and auditable independent of what the model said. A secondary inference provider sits behind an identical inference(messages) → json interface, so failing over is a one-line baseURL swap rather than an architectural rewrite, demonstrated live, as evidence the abstraction isn't cosmetic.

Execution The custody boundary is absolute: the backend never holds, generates, or has access to a Polygon private key at any point in the flow. It operates purely as a read/construct/relay service: reading public market state from Gamma and the CLOB order book, constructing unsigned limit orders pinned to the best ask with bounded slippage, and relaying already-signed payloads onward. Every state transition that touches value. the initial USDC.e approval, the collateral wrap into tradable position tokens, CLOB L1 authentication (an off-chain EIP-712 signature that derives API credentials without costing gas), individual order signatures, and eventual redemption is signed client-side by the user's own EOA. signatureType 0 is used throughout with funder set to the signer itself, so there is no delegated-execution path, no meta-transaction relayer with spending authority, nothing standing between the user's key and the outcome.

Threshold and weather markets settle through a structurally different exchange contract than plain binary markets, the NegRisk exchange, purpose-built for the bundled, mutually-exclusive-outcome markets these products are, which means the negRisk flag has to propagate correctly into the EIP-712 domain the client is asked to sign, or the venue rejects the signature outright. Rather than risk that flag being forgotten at some future call-site, order construction is centralized into a single module that every code path funnels through, with a small integration test firing one minimal real order against it before it's ever trusted at demo scale. Fill timeouts (roughly ten seconds without a match) trigger an automatic cancel-and-requote against the refreshed best ask rather than leaving a stale order hanging, the system re-derives its own price rather than assuming the world held still.

Indexing (The Graph) This was built and adversarially verified against live chain state rather than assembled from documentation. Two independently deployed subgraphs: one for Polymarket, one for Azuro, are mapped into a single canonical schema: Market, Outcome, Resolution, and an append-only PricePoint ledger that turns "current price" into an actual time series rather than a single mutable scalar that overwrites its own history.

Polymarket alone decomposes into two structurally distinct on-chain sub-systems, and treating them as one would have been the easiest possible silent mistake. Plain binary markets settle through one exchange contract with OrderFilled events keyed by a token ID derived straight from the Conditional Tokens Framework's getPositionId. Threshold/NegRisk markets, the daily weather buckets this product actually prices, settle through an entirely separate exchange contract and, critically, mint their tradable outcome tokens through a different derivation path, NegRiskAdapter.getPositionId(questionId, outcome), that has no relationship to the plain CTF formula. This was not discovered by reading an interface but by computing the plain-CTF derivation for a real, currently-trading weather market and getting a numeric mismatch against the token IDs Polymarket's own API actually reports for it, which is the only reliable way to know a derivation is wrong before it silently mispricess every weather market in production. The correct call was then located in the NegRisk adapter's interface and substituted in.

Modern Conditional Tokens compounds this further: collection-ID derivation isn't a simple keccak chain anymore but encoded as a point on an elliptic curve (an ecAdd precompile call plus a modular square root over a ~254-bit prime), which means reimplementing the math independently would have been a meaningful cryptographic undertaking with real odds of a subtle, undetectable error. The mapping instead calls the deployed contract's own view function for this derivation at index time: delegating the one piece of logic that's genuinely hard to get right to the only party guaranteed to have it right.

Azuro required a different kind of forensic work. The contract address published in Azuro's own developer documentation, when interrogated with real event logs pulled directly from the chain and matched against every ABI in their public config repository by topic-hash rather than by name, turned out to belong to their live, in-play betting product rather than the pre-match product the documentation implied, two structurally different contracts sharing a naming convention that suggested otherwise. Once corrected, Azuro's actual pricing signal is decimal odds carrying a bookmaker's margin, not a raw probability, so implied probability is derived via multiplicative de-vigging, inverting each outcome's odds and renormalizing across the full outcome set so the vig cancels out and the resulting number sits on the same 0-to-1 probability scale as Polymarket's direct trade price, rather than a systematically inflated one. Volume and trade-count aggregates accumulate per outcome from the same fill/bet events that drive price, at no additional indexing cost.

The net effect: a pricing engine or a resolution-watcher issues one query shape — implied probability, resolution status, winning outcome — against either venue, and is structurally incapable of knowing or caring which of three incompatible on-chain resolution mechanisms actually answered it. That query happens live against the deployed subgraphs at request time, which is what makes the integration load-bearing rather than a cached decoration sitting beside the real system.

Registry (0G) A minimal, purpose-built state machine — Issued → ResolvedYes | ResolvedNo → Paid deployed on 0G's Galileo testnet with a monotonic status-transition guard and custom errors rather than string reverts — it's already live, already attesting a real first policy on-chain. Inference runs through two tiers on 0G Compute: an OpenAI-compatible Router for drop-in model access, and — for the parts of the flow that need to be provably real — a direct compute-broker integration built on 0G's compute SDK, where each inference request is wallet-signed and settled against an on-chain ledger. The provider doesn't just trust a header claiming the call came from us; it verifies our account against the chain itself before serving the request. That's the actual proof of inference: not a log line we could have written ourselves, but a cryptographic handshake the provider independently checks on-chain.

ENS

On issuance, Parasol mints a real subdomain under parasol.eth and writes the policy's payout, premium, status, on-chain attestation hash, and 0G storage pointer directly into that name's text records, giving every position a human-readable, independently resolvable identity rather than a hex string only a database can explain. Resolution runs both directions: a buyer can hand the interface either a raw address or a .eth name and watch it resolve the other way live against mainnet, and the broker itself carries its own identity, resolved off parasol.eth through ENS's UniversalResolver. Naming and identity resolution deliberately live on different networks, the subdomain is written on Sepolia, where we actually own and can fund the parent name, while personal identity resolution reads mainnet, where the names people actually recognize live.

background image mobile

Join the mailing list

Get the latest news and updates