/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 (invertingfairRate 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 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.
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.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.
Signal 2 — Pool-vs-MM spread + MM win-rate (NON-CIRCULAR: YES, as a spread)
Signal 2 — Pool-vs-MM spread + MM win-rate (NON-CIRCULAR: YES, as a spread)
The pool quotes a mechanical load; an MM undercuts when it has an edge. The spread
— 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.Signal 3 — Convexity term structure (NON-CIRCULAR: PARTIAL)
Signal 3 — Convexity term structure (NON-CIRCULAR: PARTIAL)
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).Signal 4 — Demand skew by geometry (NON-CIRCULAR: PARTIAL)
Signal 4 — Demand skew by geometry (NON-CIRCULAR: PARTIAL)
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.Signal 5 — Net gamma / supply depth (NON-CIRCULAR: YES, as a quantity gauge)
Signal 5 — Net gamma / supply depth (NON-CIRCULAR: YES, as a quantity gauge)
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.
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
/datais served live from the subgraph through the hosted API. The subgraph (sluginflexion-arb-sepolia) is deployed and indexing on The Graph Studio, and the API + Path-B engine are hosted as one combined backend athttps://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-chainCvammPricing.loadComponentsbreakdown have been live on-chain since the 2026-06-05 redeploy (subgraphstartBlock274081134), which the subgraph has indexed from that block forward. - Conditional degradation, by design: if
SUBGRAPH_URLis unset, a history / aggregate surface degrades to a typedpendingbody 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
pendingstate — never an error.
What the footer says
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).
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.Related pages
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.