Pick your door
Protect an LP position
min(IL, MaxIL) at expiry from pre-locked collateral. LP / claim A.Earn in the cvAMM
ConvexityVault and earn the volatility-risk premium. Pick a tranche — senior (low-variance) or junior (first-loss, high APY). Depositor / claim B.Underwrite as a market maker
Before you start — prerequisites
These apply to every door that writes to the chain (Protect, Earn, Underwrite). Read-only doors — the markets browser and the data moat — need no wallet at all. Full detail lives on App prerequisites.Connect a wallet on Arbitrum Sepolia (chainId 421614)
ConnectGate — reads work immediately, writes need a connected wallet. The stack is RainbowKit + wagmi + viem.Get demo tokens — dUSDC and dWETH
dWETH < dUSDC so token1 = dUSDC is the numéraire — distinct from Circle’s testnet USDC/WETH. Addresses are in the deployments registry — never hardcode them.(To protect) hold an eligible, in-range v3 position
tokenId 3218) used for previews and the illustrative /underwrite pricing. Out-of-range positions are rejected at creation.@inflexion/sdk — the app never hardcodes them. See the address table for the full registry.Optional backends — degradation is honest if absent
Path B (the MM rail) and history surfaces lean on optional backends. If they’re not configured, the app does not crash — it falls back honestly to what RPC alone can serve.inflexion-arb-sepolia), indexing on-chain history from the redeploy block 274081134 — including the lifecycle swaps. Everything 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 REST API.Live over RPC: premium preview, payoff, buy/settle (Path A), vault deposit/withdraw, market pricing, the current clearing-load surface, σ_ref, the book, and coarse fills. Live over the API + subgraph: per-market history, NAV history, and the time-series data-moat signals. If a backing (subgraph URL, RPC, or telemetry) is unset, the corresponding surface degrades to a typed pending state that names the exact API route it will be served from — never a fake number, never a thrown error. See status & caveats for the full ledger.Door 1 — Protect an LP position
The shortest path from “I have an LP NFT” to “my in-range IL is hedged.” Full walkthrough: the Protect page guide.Pick the market and your position
lp.listEligiblePositions(owner, ...); each row shows its tokenId, an in-range badge, V0, MaxIL (the cap), and stored L.Preview the premium and read the payoff-with-cap chart
lp.previewPremium(tokenId, marketId) returns { maxIL, fairPremium, fairRateWad, sigmaRefWad, premiumA, premiumB?, best, path }. You see Path A · pool vs Path B · MM side by side, the on-chain Φ-sum fair premium as the floor, and σ_ref. The chart draws your payout min(IL, MaxIL) (teal) against true IL (dashed red), capped at the amber MaxIL line.Buy — one click, auto-approve, routed
lp.buyProtection({ tokenId, marketId, maxPremium, approve: true }) auto-approves the NFT to Core and dUSDC to InflexionCore, then sends createSwapRouted — which picks the cheaper of pool vs MM and never reverts on a bad MM quote (it falls back to the pool). A 1% slippage buffer caps the premium sent.Settle at expiry
lp.settle(swapId) walks the Chainlink feed for the bracketing round and pays your realized IL — capped at MaxIL — from the underwriter’s collateral, returning the NFT to you.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. This is the floor/ceiling routing, demonstrated.Door 2 — Earn in the cvAMM
Supply underwriting capital to the pooledConvexityVault and earn the volatility-risk premium. You choose your risk dose. Full walkthrough: the Earn page guide.
Read the disclosure — it's first, not a footnote
/earn is “Capital is NOT guaranteed.” You are underwriting in-range IL: junior is first-loss; senior is protected from underwriting loss only (via the junior-first waterfall totalLocked ≤ juniorAssets), not from the systemic tail.Pick a tranche
Deposit
depositor.deposit(tranche, raw, { autoApprove: true }) checks allowance, sends dUSDC approve(convexityVault, amount) — spender is the ConvexityVault, not Core (a common gotcha) — then deposit(tranche, amount).Withdraw — request, cooldown, withdraw
requestWithdrawal(tranche, shares), then after the cooldown withdraw(tranche). A junior withdraw can revert JuniorBelowLocked if it would breach senior protection while collateral is locked.Door 3 — Underwrite as a market maker
Compete with the pool by streaming firm signed quotes that win only by undercutting it. The MM rail is the ceiling of price; the pool is the floor of liquidity. Full walkthrough: the Underwrite page guide.Post collateral to the UnderwriterVault
approve(UnderwriterVault, amount) then UnderwriterVault.deposit(amount). Locked == Σ MaxIL of your active fills; invariant I5 holds locked ≤ deposited. Collateral must stay instantly liquid — never route it to utilization-gated venues.Build a PER-MARKET quote — there is no tokenId
MaxIL/V0 ∈ [min, max] bps, up to capacity. Because MaxIL is the unit of risk, positions are fungible — the SignedQuote carries no tokenId. Set your load (bps over FairPremium), a price band (Fork 2), capacity (maxNotionalV0), and a validity window.Stay under the pool and under the I10 cap
loadBps must be strictly below the live pool load AND ≤ maxLoadBps (invariant I10). A guard banner blocks signing otherwise; the page re-reads both fresh right before you sign.Sign (EIP-712) and publish
SignedQuote struct via walletClient.signTypedData (domain { 'Inflexion', '1', 421614, core.inflexionCore }) — the field order must match InflexionCore.SIGNED_QUOTE_TYPEHASH exactly. It’s POSTed to the engine; if the engine URL is unset, the page renders the exact wire envelope instead. See quote signing.createSwapRouted routes the LP to the cheaper rail and only the executed rail mutates nonce, capacity, and lock. An absent or stale MM quote silently routes to the pool.Door 4 — Integrate (SDK, API, subgraph)
Build LP, depositor, MM, or data surfaces on top of the protocol. Start at the SDK overview; for the data plane see the architecture.SDK — @inflexion/sdk
lp, depositor, mm, data, plus Greeks/hedge and the cvAMM TS port. Addresses and units in addresses & units.REST API
inflexion-backend.onrender.com. Endpoints serve per-market history, NAV, and the data-moat signals live from the subgraph.Subgraph
SwapPriced / QuoteFilled and the lifecycle events. See marketId parity so your off-chain ids match the chain exactly.Engine & recipes
{ available: false } / { priceable: false } envelope and renders an honest pending state — never an error. For the full behavior see SDK degradation and guardrails.- 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.