FairValueOracle evaluates live per quote. By the end you will be able to reconstruct FairPremium term by term, and you will know exactly how well the on-chain integer math agrees with a 50-digit reference.
The thesis of the page in one sentence: FairPremium = E_Q[min(IL, MaxIL)] is a finite Φ-sum of about 6–10 terms (Black–Scholes class) — no Monte Carlo, no lookup table, no fitted coefficients — because the capped v3 payoff is piecewise-polynomial in the terminal price, and every polynomial piece integrated against the lognormal density is a standard interval moment in the normal CDF Φ.
P = price of token0 in token1 (e.g. ETH in USDC; token1 is the numéraire). A position has liquidity L over [Pa, Pb], opened/snapshotted at P0 with Pa ≤ P0 ≤ Pb enforced at creation. The terminal (settlement) price is P_T. Φ is the standard normal CDF; σ is the per-annum volatility (σ_ref on-chain); T is the duration in years. Everything below runs in normalized units P0 = 1, L = 1 unless stated otherwise — that is exactly how the on-chain entry point computes it.1. The two-layer factorization
The entire pricing reduces to one multiplication, and the two factors do completely separate jobs: The point of the factorization is a clean separation of variables:MaxIL — pure geometry
max(IL(Pa), IL(Pb)). Frozen at creation, identical across all three durations, computed from (Pa, Pb, L, P0) only. Carries none of the vol/time dependence. Derived in the MaxIL derivation.fairRate — pure stochastics
σ²·T. Carries all of the vol/time dependence; geometry enters only through the normalized edges a = Pa/P0, b = Pb/P0. This page derives it.fairRate carries all the time dependence and MaxIL carries none, one position prices to three different FairPremium values (7 / 30 / 90 days), all backed by the same MaxIL — only fairRate moves. The S-curve runs between two asymptotes: fairRate → 0 as σ²·T → 0 (price barely moves, the cap is irrelevant, the claim is near-worthless) and fairRate → 1 as σ²·T → ∞ (price almost surely exits the range and almost surely pays the full MaxIL — you are pre-paying a near-certain loss).
2. The piecewise payoff — the object we integrate
The integrand is the capped IL as a function of the terminal price. Recall the IL function (full setup in the IL formula): withV_hold affine in P_T and V_lp piecewise across the range edges. Substituting the three regimes of V_lp makes IL(P_T) piecewise-polynomial in P_T: it is linear outside the range and a √P-bearing convex arm inside it. The capped payoff min(IL, MaxIL) then splits the price axis into three arms, separated by the range edges Pa, Pb and the two cap-crossing prices PcapL, PcapR:
- Below Pa (rotated into token0)
- Inside [Pa, Pb] (the convex arm)
- Above Pb (rotated into token1)
P_T:It is capped flat at MaxIL for P_T < PcapL (if the lower cap binds). The superscript b denotes the below-range arm.2.1 The cap-crossing prices
The cap binds where a linear arm reachesMaxIL. Setting each linear arm equal to MaxIL and solving gives the two crossing prices:
Whether a cap binds depends on geometry. When it does not bind, its interval simply collapses to zero width — which is precisely how the vectorized engine folds the branches away. The full set of integration limits is therefore the finite ordered set:
3. The lognormal interval-moment building block
Now the key move. Under risk-neutral GBM (next section),P_T is lognormal. Every arm above is a polynomial in P_T with terms of the form P_T^p for p ∈ {0, ½, 1} (a constant, the √P term, and the linear term). So each arm’s contribution to E_Q[min(IL, MaxIL)] is a sum of truncated lognormal moments — the expectation of a power of P_T restricted to a price interval. There is exactly one closed expression for that, and it is the entire engine of the page:
The sentinels handle the open ends of the price axis exactly:
So a lower bound of 0 and an upper bound of +∞ plug in cleanly with no special-casing.
Why this expression is exactly the truncated lognormal moment (the half-page derivation)
Why this expression is exactly the truncated lognormal moment (the half-page derivation)
P_T = P_0\,e^{X} where, under risk-neutral GBM with μ = 0 (next section), X \sim \mathcal{N}\!\left(-\tfrac12\sigma^2 T,\; \sigma^2 T\right). Then P_T^{\,p} = P_0^{\,p} e^{pX}. The unconstrained moment is the standard lognormal/MGF result:which is exactly the prefactor above. (Note p = 1 \Rightarrow prefactor = 1, i.e. E[P_T] = P_0 — the forward, consistent with r = 0.) The truncation \{K_1 < P_T < K_2\} is \{\ln(K_1/P_0) < X < \ln(K_2/P_0)\}. Performing the Gaussian integral of e^{pX} over that band and completing the square shifts the mean by p\sigma^2 T, which lands the integration limits at precisely d(K_1) and d(K_2) as written. The difference of two Φ values is the probability mass of the shifted Gaussian inside the band. ∎This is identical in form to the building blocks of the Black–Scholes formula — which is why the result is “Black–Scholes class.” p = 0 gives the digital (probability) piece; p = 1 gives the asset-or-nothing piece; p = ½ is the √P piece unique to the v3 in-range arm.3.1 The three moments the arms actually use
Each arm needs only the three momentsM0, Mh, M1 (for p = 0, ½, 1) over its own interval. Their prefactors are worth tabulating because two of them are trivial and one is not:
p = 0 and p = 1) are why the linear arms are pure Φ-differences; the single exp(−⅛σ²T) factor on Mh is the only place the √P regime injects extra variance dependence.
3.2 Assembling FairPremium as a finite Φ-sum
E_Q[min(IL, MaxIL)] is now the sum over the (up to five) sub-intervals carved by {0, Pa, Pb, PcapL, PcapR, +∞}, each contributing either a flat-MaxIL piece (a single M0-weighted probability mass, where the cap binds) or a polynomial-arm piece (a linear combination of M0, Mh, M1 over that interval). Summing them:
Each M is itself a difference of two Φ’s, so the whole expression is a finite linear combination of normal-CDF evaluations — Black–Scholes class, no Monte Carlo, no lookup table, no fitted coefficients, evaluated live per quote.
3.3 The vectorized engine and branch-free caps
The scalar form branches on whether each cap binds. The production-adjacent vectorized formfair_rate_vec removes the branches by clipping the split points:
When a cap does not bind, its interval collapses to zero width and contributes nothing — so the same straight-line formula is correct whether or not a cap binds. This is ~1000× faster than the scalar loop and is verified ≡ the scalar form in the test suite.
4. The one modeling assumption: GBM with μ = 0, r = 0
The Φ-sum is exact given the model. There is exactly one modeling assumption, and stating it plainly is mandatory: It is worth being precise about scope: a wrong or too-lowσ_ref makes the pool under-charge load, so premium income stops covering payouts and NAV compresses — junior absorbs it first, senior in the tail. It is not load-bearing for the FULL no-bad-debt invariant: in FULL, collateral = MaxIL ≥ payout regardless of what σ was. A vol-oracle fault can cost depositors money but can never create LP bad debt in FULL. Two separate guarantees, never merged.
5. L-independence — why positions are fungible
A structural property falls straight out of the normalization. The Φ-sum runs in unitsP0 = 1, L = 1, so it depends only on the normalized edges and the stochastic parameters:
— not on L. The on-chain entry point fair_rate_wad takes exactly (a, b, durationSeconds) normalized to P0 = 1, L = 1. MaxIL is the only place L (and the price scale) re-enters, linearly, when forming FairPremium = fairRate · MaxIL.
L-independence in the fair-rate sense is what makes positions fungible to an underwriter within a market. Two positions with the same geometry ratios (a, b) and duration price to the same fairRate no matter how large each is — only MaxIL scales them. That is the mechanical reason an MM quote is per-market, never per-NFT (the SignedQuote carries no tokenId): the MM quotes one (load, MaxIL-ratio band, capacity) for an entire marketId, and any in-band position fills against it. See two rails and quote signing.6. Verification — the closed form equals the settle-path math
A closed-form pricer is only safe if it cannot drift from the math that settles the claim. Inflexion verifies this with a chain of equalities, each one independently checkable, so the on-chain pricer is provably tied to the reference IL implementation, which is provably tied to brute-force integration and Monte Carlo:Closed form ≡ reference IL quadrature ≡ Monte Carlo
cvamm.verify_closed_form compares the Φ-sum against the reference IL implementation evaluated by dense quadrature and by Monte Carlo. Result: max_abs_err ≈ 5.1×10⁻¹¹ (verdict “CONFIRMED (machine precision)” when < 1e-5). The heavy calibration run restates it as ≡ the reference IL to 3.3×10⁻⁹. Both are far inside any tolerance.Vectorized engine ≡ scalar engine
fair_rate_vec — the branch-free clipped-split-point form — is verified equal to the scalar fair_rate across the test suite, ~1000× faster. The clipping is not an approximation: a non-binding cap collapses its interval to zero width, so the formula is identically correct.Stylus Φ-sum ≡ a 50-digit mpmath reference
mpmath fixtures (dps = 50) to ≤ 1×10⁻¹² on fairRate — equivalently ≤ 1e6 wei at the 1e18 scale, in practice a few wei. The Stylus integer fixed-point erf is “machine-precise” precisely because Stylus bans WASM floating point at activation, so there is no nondeterministic float to drift.Φ is only ~1.5×10⁻⁷ (÷MaxIL-amplified to ~1e-3 at the tight tier), which is exactly why the Solidity FairValueOracle is a revm-testable CI cross-check, not a second production oracle, and the Stylus oracle is production.
7. Reference points and a worked premium
The S-curve, made concrete. Atσ = 60%, risk-neutral, geometric half-widths — reference IL ground truth reproduced by cvamm.fair_rate:
σ²·T: a wide/short position (±20% / 7d) is worth only 18% of MaxIL — the cheapest fraction, the most convexity value for the LP; a tight/long position (±5% / 90d) is worth 91% — effectively pre-paying a near-certain loss.
Multiplying through by MaxIL gives the published premium. A 50,000 USDC position, ±10% geometric range, σ_ref = 60%, baseLoad = +15%, skews = 0. MaxIL = 1,280 USDC (2.56% of V0) — identical for all three durations; only the Φ-sum moves:
Live on-chain
This priced live swaps on the Arbitrum Sepolia stack (2026-06-05). Both rails priced off the same publishedFairPremium:
8. FAQ
Why is the inside-range arm never capped?
Why is the inside-range arm never capped?
IL(Pa) and IL(Pb). A convex function on [Pa, Pb] lies below the chord joining its endpoint values, and MaxIL = max(IL(Pa), IL(Pb)) is at least as large as either endpoint. So inside the range IL ≤ MaxIL everywhere — the cap can only bind on the linear tails outside the range. The cap-crossing prices PcapL, PcapR therefore always fall outside [Pa, Pb] when they bind at all. (See the MaxIL derivation.)Why only the moments p ∈ {0, ½, 1}?
Why only the moments p ∈ {0, ½, 1}?
P_T whose only powers are a constant (p = 0), a √P term (p = ½, from the in-range −2L√P), and a linear term (p = 1). There is no higher power anywhere in the v3 IL formula, so three truncated lognormal moments suffice for the whole Φ-sum. The p = ½ moment is the one genuinely characteristic of a v3 in-range position.What happens to the integral at the open ends of the price axis?
What happens to the integral at the open ends of the price axis?
K = 0 and the upper bound K = +∞ are handled by the sentinel rule K ≤ 0 ⇒ d = +∞ ⇒ Φ = 1 and K = +∞ ⇒ d = −∞ ⇒ Φ = 0. So the below-Pa arm integrates cleanly from 0 and the above-Pb arm integrates cleanly to +∞ with no special-casing in the code.Is the off-chain SDK allowed to recompute the Φ-sum?
Is the off-chain SDK allowed to recompute the Φ-sum?
FairPremium (from the Stylus oracle) and never approximates it — that is what guarantees the price the LP sees is the price that settles. See the SDK FairValue surface and the pricing stack.Where this sits
On-chain fair value (concept)
MaxIL — the cap and the unit
FairPremium.σ_ref — the volatility oracle
max(σ_short, σ_long, floor): the only stochastic input to the Φ-sum.The load stack
The IL formula
V_hold vs V_lp — the integrand this page integrates.