Skip to main content
MaxIL is the single most important number in Inflexion. It is the maximum in-range impermanent loss of a specific Uniswap v3 position — pure geometry, computable at creation, frozen for the life of the swap, and identical across all three durations. Everything the protocol does — collateralizing the trade, pricing it, and making positions interchangeable to an underwriter — is built on top of it. MaxIL is three things at once:

(a) The load-bearing cap

Payout is min(realized_IL, MaxIL). Locking collateral = MaxIL makes payout ≤ collateral true by construction — the structural core of no-bad-debt.

(b) The unit of risk

MaxIL is L-independent (in the fair-rate sense) and frozen at creation, so positions become fungible to an underwriter — which is why MM quotes are per-market, never per-NFT.

(c) The pricing denominator

The premium is quoted as a percentage of MaxIL, not of position value. This is what makes the underwriter indifferent to range width and gives the market full depth.
The one-line mental model from the math: MaxIL is pure geometry (the how much capital); fairRate is pure stochastics (the how risky); the load stack is pure inventory state (the how scarce). They multiply:premium=fairRate⋅MaxIL⋅(1+load)\text{premium} = \text{fairRate} \cdot \text{MaxIL} \cdot (1 + \text{load})MaxIL carries none of the vol/time dependence — that all lives in fairRate.

What MaxIL is

Let price PP be the price of token0 in token1 (e.g. ETH measured in USDC). A position is liquidity LL over a tick range [Pa,Pb][P_a, P_b], opened at P0P_0 with the in-range requirement Pa≤P0≤PbP_a \le P_0 \le P_b enforced at creation (out-of-range entries revert PositionOutOfRange). In-range impermanent loss is the gap between just holding the entry basket and what the LP position is actually worth: IL(P)=Vhold(P)−Vlp(P)\mathrm{IL}(P) = V_{\text{hold}}(P) - V_{\text{lp}}(P) MaxIL is the maximum value that gap takes while price stays in range:   MaxIL=max⁡(IL(Pa),  IL(Pb))  \boxed{\;\text{MaxIL} = \max\big(\mathrm{IL}(P_a),\; \mathrm{IL}(P_b)\big)\;} ILMath.computeMaxIL computes it on-chain. It is pure geometry — a function of (Pa,Pb,L,P0)(P_a, P_b, L, P_0) only, with no vol and no time. See the full IL setup in the IL formula and the boundary proof in the MaxIL derivation.

Why the maximum is at a boundary

IL(P)\mathrm{IL}(P) is convex on [Pa,Pb][P_a, P_b], so it attains its maximum at an endpoint:
  • Vhold(P)=amount0_entry⋅P+amount1_entryV_{\text{hold}}(P) = \texttt{amount0\_entry}\cdot P + \texttt{amount1\_entry} is affine in PP.
  • In range, Vlp(P)=L(2P−Pa−P/Pb)V_{\text{lp}}(P) = L\big(2\sqrt{P} - \sqrt{P_a} - P/\sqrt{P_b}\big), so d2VlpdP2=−14L P−3/2<0\dfrac{d^2 V_{\text{lp}}}{dP^2} = -\tfrac14 L\, P^{-3/2} < 0 ⇒ VlpV_{\text{lp}} is strictly concave.
  • IL=affine−concave=convex\mathrm{IL} = \text{affine} - \text{concave} = \text{convex}, and max⁡(0,IL)\max(0, \mathrm{IL}) (a pointwise max of convex functions) is convex too.
  • A convex function on a compact interval attains its max at an endpoint. ∎
This holds for any entry P0P_0 — centered or not. The asymmetry is real and predictable: even for a ratio-symmetric range, the convex curve is larger toward the upper boundary, so typically MaxIL=IL(Pb)\text{MaxIL} = \mathrm{IL}(P_b). In the canonical fixture [80,100,125][80, 100, 125], MaxIL=IL(Pb=125)>IL(Pa=80)\text{MaxIL} = \mathrm{IL}(P_b{=}125) > \mathrm{IL}(P_a{=}80).

(a) MaxIL as the load-bearing cap

The protocol does not cover unbounded IL. Above PbP_b the LP has fully rotated into token1, so VlpV_{\text{lp}} is constant while VholdV_{\text{hold}} keeps growing linearly with price — absolute IL is unbounded beyond the range. Anything promising to cover that could not be fully collateralized, so it could not be trustless. The protocol therefore covers the capped payoff: covered_payoff=min⁡(realized_IL,  MaxIL)\text{covered\_payoff} = \min(\text{realized\_IL},\; \text{MaxIL}) Lock exactly MaxIL of collateral at creation, and the no-bad-debt argument becomes a three-line construction:
This is orthogonal to the premium and oracle-independent: it holds for any price path and any (even wrong) σ\sigma. The relevant settle-path invariants are I1 (payout ≤ collateral == MaxIL), I2 (payout == min(realized_IL, MaxIL)), and I3 (the guarded, never-underflowing subtraction). See the invariants and the no-bad-debt math.
The cap is the product, not a defect. At the range boundary the LP has fully rotated into one asset; IL beyond that point is directional loss (foregone spot upside), not the impermanent loss the LP set out to hedge. Capping at MaxIL keeps the product fully collateralized and trustless. This is exactly why Inflexion is an in-range convexity hedge, NOT “IL insurance.”
The cap is also verified empirically. The heavy calibration run measured the payout fraction min(IL,MaxIL)/MaxIL over a ±99% (and widened −6…+6 log-move) grid on every simulated path: max_payout_frac = 1.000000, zero exceptions — structurally, independent of any oracle.
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.

(b) MaxIL as the unit of risk → positions are fungible

MaxIL is frozen at creation, identical across the three durations (7/30/90d) for a given position, and L-independent in the fair-rate sense — fairRate depends only on a=Pa/P0a = P_a/P_0, b=Pb/P0b = P_b/P_0, σ\sigma, TT, not on LL. Those properties together are what make positions fungible to an underwriter within a market. Because every position in a market reduces, for pricing purposes, to a normalized geometry plus a MaxIL, an underwriter does not need to quote each NFT individually. They express a single view over the whole market — and any position that fits fills against it.
MaxIL is a collateral / normalization unit, NOT a risk metric.Two positions with identical MaxIL can carry very different risk — different distance-to-edge, different delta profile, different probability of touching the cap. Both the pool and MMs price EQ[min⁡(IL,MaxIL)]/MaxILE_Q[\min(\mathrm{IL}, \text{MaxIL})]/\text{MaxIL} for the specific geometry, not for MaxIL alone. MaxIL/V0 is a useful monotone proxy for width when displaying or filtering positions, but it is never the pricing input — the pricing input is the full on-chain geometry, which is public via positions(tokenId). That public geometry dissolves the old adverse-selection story entirely.

Why this means MM quotes are per-market, never per-NFT

This is the direct mechanical consequence of fungibility. The SignedQuote struct carries a marketId — keccak256(token0, token1, fee, durationSeconds) — and has no tokenId field at all:
An MM streams a single quote — (load, MaxIL-ratio band, capacity) — for an entire marketId, and any LP position in that market fills against it. At fill, the contract computes the LP’s own ratio ratioBps=MaxIL⋅104/V0\texttt{ratioBps} = \text{MaxIL}\cdot 10^4 / V_0 and requires it lie in [minMaxILRatioBps, maxMaxILRatioBps], else reverts RatioOutOfBand. So an MM expresses “I write positions whose MaxIL is 2%–7% of V0” once, and the contract enforces it per-fill — positions within the band are interchangeable.
Post-pivot, the MaxIL-ratio band is a convenience filter, not an asymmetry fix. The old “the LP knows the range and the MM does not, so the MM quotes a band to avoid adverse selection” framing is void and deleted — v3 position parameters are public on-chain, so both rails read the exact geometry. See two rails.

(c) Why the premium is quoted as a percentage of MaxIL

This is the key pricing innovation, and it follows directly from MaxIL being the unit of risk. The premium is denominated as X%X\% of MaxIL — equivalently, of the underwriter’s posted collateral — never as a percentage of position value V0V_0. Consider the counterfactual. If premium were X%X\% of V0V_0:
Collateral posted is MaxIL, but income is tied to V0.
  • A narrow range has a tiny MaxIL relative to V0 → the underwriter posts little collateral but earns a fat fee → enormous return on collateral (ROC).
  • A wide range has a large MaxIL relative to V0 → the underwriter posts a lot of collateral for the same fee → insufficient ROC.
Result: underwriters adversely select against wide ranges. Wide-range LPs cannot find a counterparty at a fair price. Liquidity fragments.
Denominating in MaxIL also makes the two factors of price cleanly separable: fairRate=EQ[min⁡(IL,MaxIL)]/MaxIL\text{fairRate} = E_Q[\min(\mathrm{IL}, \text{MaxIL})]/\text{MaxIL} is a dimensionless fraction of MaxIL — an S-curve in σ2T\sigma^2 T bounded in [0,1][0, 1] — and FairPremium=fairRate⋅MaxIL\text{FairPremium} = \text{fairRate} \cdot \text{MaxIL}. Read more on the pricing stack and the load stack.

Reference magnitudes — MaxIL as a fraction of V0 by width

These are pure geometry (no vol, no time), for a geometric-symmetric range [ P0/(1+w),  P0⋅(1+w) ][\,P_0/(1+w),\; P_0\cdot(1+w)\,]. They are the verified outputs of compute_max_il, and ILMath computes them correctly on-chain:
Use the table above — older docs carry a stale, ~4.2× too-low set.
  • Limit: older centered-range ballparks list ±5% → 0.3%, ±10% → 1.2%, ±20% → 4.8%, ±50% → 25%.
  • Why: that was a documentation transcription bug — the ILMath contract always computed the correct (higher) values; no code ever shipped the low numbers.
  • Mitigation: the table above is the corrected set straight from compute_max_il. (The fixture table for [80,100,125] — MaxIL = 0.13932023, ≈6.6% of V0 — is correct and verified.)

Worked fixture [80, 100, 125], L = 1e18 (verified to the wei)

Asserted by the amounts_fixture_matches_python / maxil_fixture_matches_python tests and mirrored in the Solidity test suite: MaxIL=IL(Pb)>IL(Pa)\text{MaxIL} = \mathrm{IL}(P_b) > \mathrm{IL}(P_a) confirms the upper-boundary asymmetry, and MaxIL/Vhold(P0)≈6.6%\text{MaxIL}/V_{\text{hold}}(P_0) \approx 6.6\%. The on-node integer-floor MaxIL sits 1,691 wei from the Python float anchor — inside the 10,000-wei float-vs-integer tolerance; Stylus ≡ Solidity is exact to the wei.

One position, three prices — same MaxIL

This is the property that proves MaxIL carries none of the vol/time dependence. Take a 50,000 USDC position, ±10% geometric range, σref=60%\sigma_{\text{ref}} = 60\%, baseLoad = +15%, skews = 0. MaxIL is identical for all three durations; only fairRate moves: Collateral (MaxIL) is constant at 1,280 USDC for all three; the S-curve does all the work. Over 90d the ±10% band is touched ~75% of the time vs ~24% over 7d — so the product carries the most convexity value for wide/short positions (cheapest fraction of MaxIL) and the least for tight/long (e.g. ±5%/90d: fairRate ≈ 91%, effectively pre-paying a near-certain loss). See fairRate and the S-curve and the full worked example.

Live on-chain confirmation

The 2026-06-05 create→settle lifecycle on the Arbitrum Sepolia stack used a real MaxIL on both rails:
  • Path A (cvAMM): V0 = $270,531.28, MaxIL = $1,669.24, premium = $9.70 (0.58% of MaxIL — a wide/short position, low fairRate), realized IL at settle = $148.64, payout = $148.64 ≤ MaxIL, paid from the ConvexityVault.
  • Path B (MM won the route): MaxIL = $3,215.65, the MM’s own collateral locked = MaxIL, realized IL = $245.66, payout = $245.66 ≤ MaxIL, paid from UnderwriterVault.
On both rails payout ≤ MaxIL = collateral held end to end — I1 and I2 in production. See live addresses on the deployments page. Network: Arbitrum Sepolia · chainId 421614 · deploy block 274081134 (subgraph startBlock) · deployed 2026-06-05

Core protocol

Stylus & libraries

Oracles

Uniswap

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.

FAQ

No. MaxIL is computed from the liquidity L stored at creation in the SwapRecord, and settlement re-reads that stored L, never the live NFT (invariant I6). Anyone can increaseLiquidity on a custodied v3 NFT, but the extra liquidity is simply returned with the NFT at settlement and cannot inflate payout above MaxIL. See the invariants.
No — it is the worst case while price stays in range. Beyond the range the LP’s absolute IL is unbounded (fully rotated into one asset while a hold position keeps tracking price). That uncovered region is directional loss, not impermanent loss, and is deliberately out of scope — covering it would break full collateralization. LPs who want beyond-range protection re-cover after re-ranging.
No. MaxIL is a collateral / normalization unit, not a risk metric. Two positions with identical MaxIL can sit at very different distances from the current price and carry very different probabilities of touching the cap. Both the pool and MMs price the specific on-chain geometry — E_Q[min(IL,MaxIL)]/MaxIL — not MaxIL in isolation.
Because fairRate is an S-curve in σ2T\sigma^2 T and the three durations (7/30/90d) sit at different points on it, while MaxIL — pure geometry — is frozen and identical across all three. Longer duration ⇒ higher probability the band is touched ⇒ higher fairRate ⇒ higher premium, all backed by the same collateral. See fair value.
Quoting X% of MaxIL makes the underwriter’s return-on-collateral independent of range width, so they are indifferent to writing narrow vs wide positions — no adverse selection, full depth. Quoting % of V0 would hand narrow ranges an enormous ROC and starve wide ranges, fragmenting liquidity.

Where to go next

The MaxIL derivation

The full boundary proof, the asymmetric-entry case, and the verified fixtures.

The IL formula

V_hold vs V_lp, the three regimes, and the guarded realized-IL subtraction.

Fair value & fairRate

The exact closed-form Φ-sum that turns geometry + σ + T into a price.

No-bad-debt

How payout ≤ collateral = MaxIL becomes a construction, qualified correctly.