Skip to main content
The /data page is the public-alpha surface of the protocol — “the first public view into the microstructure of the DeFi LP volatility-risk premium”. It is read-only and wallet-free: no ConnectGate, no writes. Anyone can open it and inspect the same convexity risk premium an MM has to price against, with no RPC key and no signature. This is the in-app rendering of the data moat. For the conceptual treatment of why the flow is a defensible dataset, read the data moat; for the rigorous, citation-by-citation signal definitions, read the five signals.
Data is the moat, not a paywall. The surface is built passively from day one and exposed as free public APIs (The Graph subgraph + REST). Revenue is protocol fees; the data is the competitive moat. /data is the human-readable window onto the same dataset the DataClient and public API serve.

Lead with the five signals

Every page that touches the moat leads with the five non-circular behavioral signals and each signal’s explicit non-circularity verdict — never with the circular idea (inverting fairRate to read implied vol) that was deliberately dropped. The /data page is organized around exactly these five, in order. A signal is non-circular iff its informative degrees of freedom come from an MM’s freely-chosen loadBps or an LP’s geometry/duration choice — measured against the transparent mechanical baseline, never derived from it. Four of the five separate a behavioral leg (an actor’s free choice) from a mechanical baseline (the protocol’s price-to-beat); the subtraction is what isolates the actor’s view:
The circular idea — “invert fairRate to read an implied-vol surface” — is dropped, and /data never shows it.
  • Limit: every premium is, by construction, charged/MaxIL=fairRate(σref)⋅(1+load)\text{charged}/\text{MaxIL} = \text{fairRate}(\sigma_{\text{ref}}) \cdot (1 + \text{load}). Inverting fairRate from the charged premium recovers nothing but the protocol’s own published σref\sigma_{\text{ref}} plus its own dealer load stack.
  • Why: both inputs are protocol-computed, not external. Inverting a function with the function’s own published inputs cannot yield independent information — it is a tautology, not a market-implied vol.
  • Mitigation: the entire moat is reframed around actor behavior — the free choices the protocol does not compute, measured against the mechanical baseline. The full proof lives on circular vs behavioral.

The honest split: 1 live, 4 structural-now / dynamic-with-volume

The /data page is explicit about which signal is live today and which mature with volume. Signal 1’s current load surface is served live via RPC; Signals 2-5’s history / aggregate surfaces are served live from the subgraph via the API, with their dynamic / latent telemetry halves capturing now.

Signal 1 — Clearing-load surface (LIVE)

The hero of the page. A fee × duration heat-matrix of the pool clearing load — bps over fair value — computed over a transparent σ_ref and read live via RPC: getCurrentLoadSurface + getSurfaceSigmaRef, on a 30s refetch, rendered with the live block number of the multicall. This is the load every Path-B market maker must undercut to win the fill. It is the mechanical price-to-beat, surfaced so the public can see the floor an MM competes against. The grid draws the 3×3 with heat colouring scaled to the hottest priceable cell; each cell shows:
  • +N bps — the clamped pool load stack over fair value;
  • pool premium — the dollar premium at that load;
  • regime — calm / normal / stressed, from the σ_ref band;
  • the fair rate — the on-chain Φ-sum baseline the load multiplies.
The clamped load shown in each cell is, exactly as deployed: totalLoad  =  min⁡ ⁣( baseLoad(σref)+utilSkew(u)+dispSkew(h),  maxLoad )\text{totalLoad} \;=\; \min\!\Big(\, \text{baseLoad}(\sigma_{\text{ref}}) + \text{utilSkew}(u) + \text{dispSkew}(h),\; \text{maxLoad} \,\Big) and the pool premium is poolPremium=⌈fairPremium⋅(1+totalLoad)⌉\text{poolPremium} = \lceil \text{fairPremium} \cdot (1 + \text{totalLoad}) \rceil, hard-capped at MaxIL — invariant I10 by construction.
Why Signal 1’s current surface is the one live SDK exception. Almost every other moat surface is history/aggregate and routes through the API → subgraph. The current load surface is the only DataClient method that hits live RPC instead: per market, one multicall over public getters (InflexionCore.markets, FairValueOracle.fairPremium, ConvexityVault.inventory, InflexionCore.loadParams), then the two skews are finished client-side with the parity-locked CvammPricing TS port — never by eth_call-ing the delegatecall-only library.

Per-cell degradation is honest, never dropped

A market that is unregistered, or whose oracle is reverting (stale feed / sequencer down), does not vanish from the grid and does not throw. It renders inline as a muted cell with an honest reason — “not registered” or “oracle degraded” — while every priceable cell around it stays live. This is the same pending-not-error discipline that governs Signals 2-5; here it operates per cell rather than per signal.
Read the load level in context — it is contaminated; trade the spread, not the level.
  • Limit: the clearing load mixes the convexity premium with liquidity, smart-contract-risk, capital-lock, and inventory-skew premia.
  • Why: a single observed load is a sum of several premia, not a clean vol-risk number.
  • Mitigation: compare the spread (MM − pool, vs implied/forward vol), which is exactly Signal 2 — the subtraction cancels the shared contamination. And exclude cap-bound fills (SwapPriced.cappedAtMaxIL == true), which carry zero load information.

Signals 2-5 — structural-now, dynamic-with-volume

The remaining four signals render on /data from live data today: the on-chain structures exist from launch, and the history / aggregate / dynamic layers are served live from the subgraph via the API. The dynamics still mature with multiple competing MMs and accumulating flow. Each carries its explicit non-circularity verdict.
The pool quotes a mechanical load; an MM undercuts when it has an edge. The spread spread=poolLoad−mmLoad\text{spread} = \text{poolLoad} - \text{mmLoad} — plus how often and how deeply MMs beat the pool — is forward-vol expectation extracted from MM behavior, a VIX-like signal for LP markets. The subtraction (behavioral MM load − mechanical pool load) is exactly what removes the circular component. On /data: getQuoteCompetition (subgraph Swap.spreadWad + MarketMaker win counts, plus the off-chain COMPETITION_LOG dynamic half). Maturity: structural at launch; the competitive distribution matures only with ≥3 MMs.
The same range is protectable at 7/30/90d; the slope of the MM’s loadBps across those three duration markets is the LP-convexity-premium term structure — the slope is the signal. Watch the subtlety: the Path-A load stack is duration-independent by construction — none of baseLoadWad, utilSkewWad, dispSkewWad takes durationSeconds, so a Path-A “term structure of load” is a flat line (all maturity dependence lives in fairRate(...,T)). Only the Path-B slope is a behavioral signal; the Path-A curve is the published fairRate term structure, not a behavioral one. On /data: getLoadSurfaceHistory (subgraph).
Which positions LPs seek to protect (tight vs wide; centered vs near-edge) — an LP-sentiment / leading-stress indicator. Realized demand (which tokenId/duration an LP brings) is an LP choice → non-circular for the fills we see. But the latent half — geometries priced/queried but not bought — never touches the chain by design: invariant I7 guarantees an unchosen quote touches no nonce and no capacity, so it leaves no on-chain trace. That latent demand is captured off-chain in engine telemetry (DEMAND_LOG), from the first interaction — it is unreconstructable retroactively. On /data: getDemandRequests.
The total convexity the protocol is short (pool + every MM) and at what aggregate load, plus Σfree / Σlocked across the open swap set — a real-time gauge of DeFi appetite to sell vol, tradeable vs Deribit. It is a sum over actor positions (a real-world quantity), not a price computation, so it needs no de-circularization. The per-swap Greeks are finite-differenced off the deployed ILMath.computeIL / FairValueOracle.fairRate — anchored to protocol math, no parallel model. On /data: getNetGamma, computed off-chain over the open swap set. Maturity: meaningful from a handful of swaps — the most launch-robust of the five.

Pool NAV history — the depositor-risk surface

Below the five signals, /data also renders Pool NAV history, the depositor-risk surface. It is subgraph/API-backed → served live via the API. Because it is a depositor-facing surface, it carries the capital-NOT-guaranteed claim.
Depositor capital is NOT guaranteed: the junior tranche is first-loss; the senior tranche is structurally protected from underwriting loss only, not systemic tail.Underwriting capital — whether supplied to the pooled cvAMM vault (Path A) or posted directly by a market maker (Path B) — is at risk:
  • Junior tranche — first-loss. Junior depositors absorb underwriting losses first and buffer the senior tranche.
  • Senior tranche — protected from underwriting loss, exposed to the systemic tail. The senior tranche is structurally shielded from ordinary underwriting loss while junior capital buffers, but it still takes the systemic tail once the junior buffer is exhausted.
No-bad-debt is a guarantee to the LP being paid (see the FULL-mode payout clause), not a guarantee that depositor or MM capital is preserved.

The pending-not-error pattern, framed

This is the single most important UX property of /data: “pending” is never “error,” and it is never a fabricated number. It is a design property: if a backing (subgraph URL / RPC / telemetry) is absent, a signal degrades to a typed pending state rather than throwing. In that case it renders via a PendingHistory → PendingNote that prints env.detail and the exact API route + query it is served from, read straight off the typed ApiPending envelope. The envelope embeds the GraphQL/REST query verbatim, so a degraded surface recovers with a one-line body swap the moment its backing returns.
The subgraph is deployed and indexing — Signals 2-5’s history/aggregate layers are served live from it via the API.
  • Live now: every history / aggregate moat surface on /data is served live from the subgraph through the hosted API. The subgraph (slug inflexion-arb-sepolia) is deployed and indexing on The Graph Studio, and the API + Path-B engine are hosted as one combined backend at https://inflexion-backend.onrender.com (REST API at /, engine at /engine).
  • Why it works: the contracts emit every event the moat needs — SwapPriced, QuoteFilled, and the on-chain CvammPricing.loadComponents breakdown have been live on-chain since the 2026-06-05 redeploy (subgraph startBlock 274081134), which the subgraph has indexed from that block forward.
  • Conditional degradation, by design: if SUBGRAPH_URL is unset, a history / aggregate surface degrades to a typed pending body naming its route — never an error, never a faked value. Signal 1’s current surface is served live via the SDK multicall, and the off-chain telemetry halves (DEMAND_LOG, COMPETITION_LOG) are capturing now from the first interaction (see SDK degradation, the status caveats).
  • Note: on the free hosting tier the backend sleeps after ~15 min idle, so the first request after a quiet period may incur a brief cold start.
Structures ship from day one; the full DYNAMICS (pool-vs-MM spread as a forward-vol signal) mature with multiple competing MMs and volume. The dataset begins at the single redeploy; the off-chain telemetry halves begin at the first interaction logged.What Inflexion offers today is the architecture and the first public view into the microstructure of the DeFi LP volatility-risk premium — not yet a mature dataset:
  • Structures are present day-one. All five non-circular behavioral signals are defined and queryable from launch.
  • Dynamics mature with volume. The richer signal — the pool-vs-MM spread read as a forward-vol indicator — only sharpens once multiple market makers compete and real flow accumulates.
  • The dataset begins at the single redeploy, and the off-chain telemetry halves begin at the first interaction logged. History is served live from the subgraph via the API; if a backing (subgraph URL / RPC / telemetry) is absent, surfaces degrade to a typed pending state — never an error.
The /data footer states the thesis verbatim — “Structures from day one, dynamics mature with volume” — names the rich on-chain events already emitted since the deploy (SwapPriced, QuoteFilled), and repeats both load-bearing disclosures. They are kept as separate claims and never merged:
  • The LP no-bad-debt claim (Claim A) — qualified, capped, FULL-mode.
  • The depositor / MM capital-not-guaranteed claim (Claim B).
LPs are always paid with no bad debt in FULL mode — qualified: capped payoff + solvent USDC + oracle/settlement liveness.The no-bad-debt guarantee is exact only under the full clause:
  • FULL collateralization — the underwriter has posted exactly MaxIL per swap, locked for the life of the position.
  • Capped payoff — the payout is min(realized_IL, MaxIL). The cap is load-bearing: it is what makes payout ≤ collateral hold by construction.
  • Solvent USDC — the collateral numeraire (dUSDC) holds its peg and remains redeemable.
  • Oracle / settlement liveness — the price oracle stays live and settle() runs within the protocol’s settlement window.
  • No rehypothecation breach — locked collateral stays instantly liquid; it is never routed to utilization-gated venues.
Stated without these qualifiers, the guarantee is not correct.
Depositor capital is NOT guaranteed: the junior tranche is first-loss; the senior tranche is structurally protected from underwriting loss only, not systemic tail.Underwriting capital — whether supplied to the pooled cvAMM vault (Path A) or posted directly by a market maker (Path B) — is at risk:
  • Junior tranche — first-loss. Junior depositors absorb underwriting losses first and buffer the senior tranche.
  • Senior tranche — protected from underwriting loss, exposed to the systemic tail. The senior tranche is structurally shielded from ordinary underwriting loss while junior capital buffers, but it still takes the systemic tail once the junior buffer is exhausted.
No-bad-debt is a guarantee to the LP being paid (see the FULL-mode payout clause), not a guarantee that depositor or MM capital is preserved.

How to consume the same data programmatically

/data is the human window; the same surfaces are available without the browser.

DataClient (SDK)

getCurrentLoadSurface (live RPC, Signal 1), getQuoteCompetition, getLoadSurfaceHistory, getDemandRequests, getNetGamma.

Public REST API

The cached, wallet-free facade — GET /pool/load-surface (live), GET /data/* (history, served live from the subgraph).

The subgraph

The internal indexer the API reads — BucketAggregate, GeometryDemandBucket, NetGammaSnapshot, and the rest.

The data moat (concept)

Why the flow is a defensible dataset, and who consumes it.

The five signals (deep)

Exhaustive per-signal definitions, sourcing, verdicts, and maturity.

Circular vs behavioral

The non-circularity table and the proof of why inverting fairRate is circular.

On-chain primitives

SwapPriced, QuoteFilled, and the load-breakdown library.

Markets browser (in-app)

The action-oriented market grid — Signal 1’s load surface as live action links.

State and limits

The exact state of the dataset and the full set of honest limits.