/protect is the LP’s door. You hold a Uniswap v3 LP NFT; you want to hedge its in-range impermanent-loss risk for a fixed upfront premium. This page walks the whole flow end to end — from picking a market to settling at expiry — against the live deployment on Arbitrum Sepolia (chainId 421614).
The page is driven by the SDK’s LpClient (lp.*). Its header copy restates the entire product in two sentences, including the qualified no-bad-debt clause. This is claim A: the LP is always paid in FULL mode — qualified.
Three facts the UI repeats on every risk surface, because they are load-bearing.
- This is an in-range convexity hedge, not “IL insurance.” Entry requires — out-of-range positions are rejected at creation.
- Payout . The cap is load-bearing for the no-bad-debt guarantee.
- “No bad debt” is only true with its full qualifying clause — never stated unqualified.
The page at a glance
The layout is two columns plus a full-width footer:- Left — the market picker and your eligible v3 positions.
- Right — the premium preview (Path A vs Path B), the payoff-with-cap chart, and the Buy panel.
- Below, full width — Your active protections, with per-swap Settle buttons.
ConnectGate — reads work immediately, writes need a connected wallet. The empty connect state reads: “Connect a wallet on Arbitrum Sepolia to view your positions and buy protection.”
The seven steps
1
Connect a wallet on Arbitrum Sepolia
Reads are graceful and resolve without a wallet, but buying and settling require a connected signer. The stack is RainbowKit + wagmi + viem. See App prerequisites for tokens and network setup, and addresses & units for the numéraire decimals.
2
Pick the market — fee tier × duration
Two button rows derived from the canonical
MARKETS list: fee tiers 0.05% / 0.30% / 1.00% and durations 7d / 30d / 90d — 9 markets in all. The default is the fee-500 / 7d market. The selected marketId is shown truncated under the picker.The marketId is deterministic geometry, not an off-chain registry key:The same derivation runs on-chain, so your off-chain id matches the chain exactly.3
Pick a position — read the in-range badge
The left list calls
lp.listEligiblePositions(owner, { durations: [selectedDuration] }). It enumerates your NPM positions and computes geometry and MaxIL per position. Each PositionRow shows:- the tokenId (e.g.
#3218); - an in-range badge — teal “in range”, amber “out of range”, or “oracle degraded” when
inRangeisundefined; - V0 (notional), MaxIL (the cap, in amber), and L (the stored liquidity) when priceable; otherwise a degraded reason.
inRange = sqrtP0 >= sqrtPa && sqrtP0 <= sqrtPb — the same gate createSwap enforces on-chain. If there are no eligible positions, the empty-state explains the gate: “Out-of-range positions are not protectable — entry requires ”.4
Preview the premium — Path A vs Path B, cheaper highlighted
PreviewAndBuy calls lp.previewPremium(tokenId, marketId) and refetches every 30s. The PreviewResult carries { maxIL, fairPremium, fairRateWad, sigmaRefWad, premiumA, premiumB?, best, path }. The panel shows:- Premium (best) — what you pay once, with a Path A/B badge in the panel header;
- MaxIL (cap) in amber;
- side-by-side Path A · pool vs Path B · MM — the MM cell shows ”—” / “no live MM quote” when
premiumBis undefined because the engine isn’t running; - Fair premium (the on-chain Φ-sum floor) and σ_ref (annualised vol).
5
Read the payoff-with-cap chart
Rendered from the selected position’s geometry , the chart draws the whole product in one picture:
The caption is the protocol’s safety argument in one sentence: “You are paid your realized IL up to MaxIL (teal) while the price is in range. Beyond the range the true IL (dashed red) keeps growing but your payout is capped at the amber line — the cap that makes the no-bad-debt guarantee hold”.The curve math is deterministic v3 geometry:all normalized to a percentage of V0. If geometry is unavailable, the chart shows a degraded note instead of failing. See the IL formula and the MaxIL derivation for the full math.
6
Buy — approve (three spenders) + createSwapRouted
The Buy panel states the deal in plain language — “Pay $X now to cover this position’s in-range IL up to $MaxIL for ” — and shows the max premium sent with a 1% slippage buffer (
SLIPPAGE_BPS = 100).On click, onBuy calls lp.buyProtection({ tokenId, marketId, maxPremium, approve: true }). The SDK auto-approves two things, then sends one create call:- NPM
approve(core.inflexionCore, tokenId)— the position NFT, to InflexionCore. - dUSDC
approve(core.inflexionCore, maxPremium)— the premium, spender is InflexionCore. createSwapRouted(default) — picks the cheaper of pool vs MM, and never reverts on a bad MM quote (a missing quote uses theEMPTY_QUOTEsentinel so the router falls back to the pool).
useTx to drive through signing → pending → success, waits for the receipt, and trims viem’s verbose revert dumps to the first line. On success, the eligible-positions, owner-swaps, and preview queries invalidate so the new protection appears immediately.Escape hatches exist, but the default UI always routes.
escapeHatch:'A' forces createSwapPathA (the always-on pool); escapeHatch:'B' forces createSwap against a specific signed quote. The default — createSwapRouted — is the right choice for almost everyone: it gives you the cheaper rail with no signature risk. See routing.After the buy — manage active protections and settle
ActiveProtections (full-width, below the columns) discovers your swaps by an on-chain scan — no subgraph required. It reads nextSwapId, walks up to 200 swap ids, and keeps the ones where the protection’s lp matches the connected owner. Each renders an ActiveProtection card:
- a header with
swap #id, an Active / Settled badge, and a Path A · pool vs Path B · MM badge (isPathA = mm == convexityVault); - stats: Premium paid, MaxIL cap (amber), V0, and IL to date with the live
payoutand a ”· capped” flag when the cap is hit. IL-to-date is itself aPriceable— a degraded oracle renders a pending note, not an error: “The protection is intact — payout is still computed at settlement from the price-at-expiry”.
Settle at expiry
The Settle button appears only once the swap is expired (secondsToExpiry === 0n) and still active. Clicking calls lp.settle(swapId), which:
- reads
Core.swaps(swapId)to recover expiry; - walks the Chainlink feed backwards to find the bracketing round if no hint is supplied;
- calls
settle(swapId, hintRoundId).
L stored at creation, never re-read from the NFT — invariant I6. That is why an external increaseLiquidity cannot inflate your payout, and why the payout is min(IL, MaxIL) computed against frozen geometry. The settlement core is identical regardless of which rail opened the swap.
Protect: preview → buy → settle
The in-range / cap framing — why it is the whole product
Everything on/protect reinforces two geometric facts:
In-range entry
Entry requires . The in-range badge, the eligible-positions filter, and the on-chain
createSwap gate all enforce it. Out-of-range is rejected at creation.The MaxIL cap
Payout . The amber line on the chart is the cap; it is also the unit of risk that makes positions fungible to an underwriter — which is why an MM quote is per-market, not per-NFT.
Live on-chain lifecycle (2026-06-05).
- Path A swap #1 — V0 $270,531, MaxIL $1,669.24, premium $9.70 (0.58% of MaxIL), realized IL $148.64 paid in full from the
ConvexityVault. - Path B swap #2 — the MM beat the pool ($8.93 vs $13.80), locked $3,215.65 of its own collateral, and settled $245.66 from the
UnderwriterVault.
What is live, and what degrades to pending
The subgraph is deployed and indexing — history and aggregate surfaces are live.Anything historical or aggregate (per-market volume, NAV history, the time-series data-moat signals, precise MM fill attribution) is served live from the subgraph via the hosted API. The rich on-chain events (
SwapPriced, QuoteFilled) have been indexed since deploy block 274081134, including the lifecycle swaps.On /protect specifically, everything in the buy-and-settle flow is live over RPC: premium preview, the payoff chart, eligible-position discovery, buy (Path A), and settle. Path B previews need the engine running (NEXT_PUBLIC_ENGINE_URL, hosted at https://inflexion-backend.onrender.com/engine); without it the preview shows Path A only and premiumB is undefined. Graceful degradation is a design property: if a backing route is unset, the surface returns a typed pending body that names the route it will be served from — never a fake number, never a thrown error. See status & caveats./protect reads degrade honestly even when the chain is healthy:
- If the live oracle reverts (stale feed / sequencer down), the preview panel renders a
PendingNote— not priceable now, the position still exists, becomes quotable when the oracle recovers — and Buy is disabled. See oracles. - IL-to-date on an active card is a
Priceable; a degraded oracle shows a pending note, since the actual payout is computed at settlement from the price-at-expiry, not from the live price.
Live deployment addresses
Network: Arbitrum Sepolia · chainId421614 · deploy block 274081134 (subgraph startBlock) · deployed 2026-06-05
Core protocol
Stylus & libraries
Oracles
Uniswap
Chainlink feeds
Demo tokens / pool / LP
Lifecycle swaps
Live create→settle lifecycle (2026-06-05, short 300s fee-500 market
0xb8bbd684f213d5833886ade7b531a6949d85522249881a2b5d46a5cc76e439c2):
- Path A (cvAMM convexity) — swapId 1, LP tokenId 3220 · V0 $270,531.28 · MaxIL $1,669.24 · premium $9.70 (0.58% of MaxIL) · settled payout $148.64 from ConvexityVault.
- Path B (MM routing) — swapId 2, LP tokenId 3221 · MM beat cvAMM ($8.93 vs $13.80) · MaxIL $3,215.65 · MM collateral locked $3,215.65 · settled payout $245.66 from MM collateral.
The claim, stated correctly
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.
Where to go next
Earn in the cvAMM
The other side: deposit dUSDC and underwrite the in-range IL you just hedged. Claim B — capital is not guaranteed.
Underwrite as an MM
Stream firm per-market signed quotes that win flow only by undercutting the pool.
The LP SDK client
previewPremium, buyProtection, settle, and listEligiblePositions in full.Routing
How
createSwapRouted picks the cheaper rail and falls back to the pool.The payoff & cap
MaxIL as both the cap and the unit of risk.
The full lifecycle
The swap’s journey from create through ACTIVE custody to the settlement core.