Skip to main content
The cvAMM (Path A) is more than an always-on underwriter — it is a depositor product. When you deposit USDC into the ConvexityVault you become the counterparty to LPs hedging their impermanent loss: you sell convexity and earn the volatility-risk premium for taking the in-range IL risk LPs want to shed. But selling volatility is not a savings account. A volatility seller earns a steady premium in calm markets and pays out in crashes. So a single undifferentiated pool forces every depositor onto the same risk/return point — and that point is too risky for a conservative depositor and too tame for a vol specialist. Inflexion’s answer is a dual-tranche vault from launch: one pool, two claims on it.

Junior — the first-loss vol tranche

Absorbs underwriting losses first, buffers senior, and earns the larger share of premium. High-APY, high-variance. The “vol-seller” tranche.

Senior — the convexity savings account

Structurally protected from underwriting loss while the junior buffer holds. Earns a smaller, smoother premium share. Exposed only to the systemic tail.
Depositor capital is NOT guaranteed: the junior tranche is first-loss; the senior tranche is structurally protected from underwriting loss only, not systemic tail.Underwriting capital — whether supplied to the pooled cvAMM vault (Path A) or posted directly by a market maker (Path B) — is at risk:
  • Junior tranche — first-loss. Junior depositors absorb underwriting losses first and buffer the senior tranche.
  • Senior tranche — protected from underwriting loss, exposed to the systemic tail. The senior tranche is structurally shielded from ordinary underwriting loss while junior capital buffers, but it still takes the systemic tail once the junior buffer is exhausted.
No-bad-debt is a guarantee to the LP being paid (see the FULL-mode payout clause), not a guarantee that depositor or MM capital is preserved.

One vault, two tranches

There is one ConvexityVault per pair, with fungible USDC backing all nine marketIds for that pair (3 fee tiers × 3 durations). It is dual-tranche SENIOR / JUNIOR from launch — not a roadmap upgrade, live at the deployed address. The vault keeps the two tranches accounted separately end to end: Two derived quantities drive everything downstream: totalAssets=seniorAssets+juniorAssets,freeAssets=totalAssets−totalLocked\text{totalAssets} = \text{seniorAssets} + \text{juniorAssets}, \qquad \text{freeAssets} = \text{totalAssets} - \text{totalLocked} freeAssets is what is available to underwrite the next swap; totalLocked is the sum of collateral (each equal to a swap’s MaxIL) locked against open positions.

The premium waterfall — money in

Every premium paid on Path A is split before it ever touches a depositor. First the protocol takes its cut, then the remainder is divided across the two tranches.
1

99% to the pool, 1% to the treasury

On _executePathA the premium is split 99% accrued into the vault (accruePremium) and 1% to the treasury. There is no per-tranche split at this layer — that happens inside the vault.
2

The senior/junior split (accruePremium)

Inside accruePremium the pool’s share is divided by a single immutable parameter, seniorPremiumShareBps:toSenior=amount⋅seniorPremiumShareBps104,toJunior=amount−toSenior\text{toSenior} = \text{amount}\cdot\frac{\text{seniorPremiumShareBps}}{10^4}, \qquad \text{toJunior} = \text{amount} - \text{toSenior}seniorPremiumShareBps is immutable and read from the calibrated risk-parameter set, never hardcoded.
Because senior is protected from underwriting loss (next section), it accepts a smaller slice of premium — that is the price of safety. Junior takes the larger slice as compensation for standing in front of every loss. This is the structural reason the two tranches have genuinely different risk/return, not a cosmetic label: senior is a low-yield “convexity savings account,” junior is the high-APY vol-seller.
The premium split is purely a distribution of income. It does not touch the no-bad-debt math, the I10 price cap, or settle semantics — those are orthogonal. The tranche structure changes who earns and who loses inside the pool; it never changes what the LP is paid.

The loss waterfall — money out

When a swap settles with a positive payout, the LP is paid from locked collateral and the loss is applied to depositors junior-first. The waterfall lives in releaseAndDistribute: juniorLoss=min⁡(payout, juniorAssets),seniorLoss=payout−juniorLoss\text{juniorLoss} = \min(\text{payout},\ \text{juniorAssets}), \qquad \text{seniorLoss} = \text{payout} - \text{juniorLoss} Junior assets absorb the loss up to their full balance; only what spills over — if anything — reaches senior. The waterfall first requires payout ≤ lockedAmount (PayoutExceedsCollateral) and lockedAmount ≤ lockedByMarket[marketId], then unlocks the collateral, applies the junior-first split, transfers payout to the LP, and emits JuniorLoss.
The seniorLoss arm is defense-in-depth. By the senior-protection invariant below, seniorLoss is provably always 0 — the min can never bind against senior. The arm exists so that even a future change that weakened the invariant would still fail closed (junior-first) rather than silently socializing losses onto senior.

The senior-protection invariant — why senior is structurally shielded

The reason seniorLoss is always 0 is a single structural invariant, enforced at every lockCollateral via the SeniorProtectionBreached revert:  totalLocked≤juniorAssets \boxed{\ \text{totalLocked} \le \text{juniorAssets}\ } The proof that this protects senior is two lines. Every payout is capped at its swap’s MaxIL, and that swap’s MaxIL is exactly the collateral locked for it. So: ∑payouts ≤ totalLocked ≤ juniorAssets⟹payout≤locked≤junior\sum \text{payouts} \ \le\ \text{totalLocked} \ \le\ \text{juniorAssets} \quad\Longrightarrow\quad \text{payout} \le \text{locked} \le \text{junior} Total underwriting loss can never exceed total locked collateral, and total locked collateral can never exceed the junior buffer — so junior absorbs all underwriting loss before senior is ever touched (see the no-bad-debt math). This is the adaptive code form of the roadmap’s u ≤ 1−sf rule, keyed to the actual junior buffer rather than a fixed ratio — which is strictly safer, because the guard tracks reality (if junior shrinks, lock capacity shrinks with it). With the calibrated target ratio sf = 0.60, the junior fraction is 1 − sf = 0.40, so totalLocked ≤ juniorAssets is exactly the utilization bound u ≤ 0.40 = 1 − sf under which the depositor calibration holds.
Senior protection is calibrated, not unconditional — and never covers the systemic tail.
  • Limit: “senior P(loss) = 0” is a calibration result, not a structural guarantee. It holds only while utilization stays u ≤ 1 − sf (the regime the invariant enforces) and only against underwriting loss. It does not shield senior from systemic failure — a USDC depeg, an oracle/settlement fault, or a contract bug.
  • Why: sf = 0.60 is a target tranche ratio for UX and incentives, not the hard cap. The hard cap is the adaptive totalLocked ≤ juniorAssets invariant. Senior protection from underwriting loss follows from that invariant; tail risk from a broken assumption (peg, oracle, code) is outside any in-protocol waterfall.
  • Mitigation: the invariant is checked on every lock and is the same accounting that powers the run defense and prices the utilization skew up before over-commitment. Capital-not-guaranteed remains the umbrella for both tranches — see ClaimB above and the risk disclosure.

The run defense

Both tranches share a deposit/withdraw model designed so the pool cannot be run even though depositor capital is at risk:
  • Deposits are instant. Capital can always join.
  • Withdrawals are cooldown-gated. requestWithdrawal → withdraw only after withdrawalCooldown elapses.
  • Junior cannot be drawn below totalLocked. The JuniorBelowLocked revert forbids withdrawing junior capital that is currently buffering live coverage.
The same locked/free accounting that prevents a run also prices the util_skew up as the pool nears full commitment — so marginal coverage gets more expensive before the pool over-commits, and the buffer that protects senior is never quietly withdrawn out from under open swaps.

The quant result — what each tranche actually earns and risks

The headline output of the quant is the depositor risk/return profile. The figures below come from the P1.13 heavy run — a deliberately adversarial model that is stronger than GBM: Student-t fat tails (t_df = 4), a 3-state Markov vol regime (calm 0.45 / normal 0.75 / stressed 1.30), tail-dependent crash correlation → 1 (a single-pair book settles against the same move), Poisson deep-crash months (~0.8/yr, mean −45%), and a lagging σ_ref so coverage written at a stress onset is underpriced exactly as it would be on-chain. The monthly P&L identity makes the volatility-seller nature explicit: monthly_return=utilization⋅∑i(premiumi−payouti)∑iMaxILi\text{monthly\_return} = \text{utilization}\cdot\frac{\sum_i\bigl(\text{premium}_i - \text{payout}_i\bigr)}{\sum_i \text{MaxIL}_i} premiumi=fairRate(σref)⋅(1+baseLoad)⋅MaxILi(income, risk-neutral at σref)\text{premium}_i = \text{fairRate}(\sigma_{\text{ref}})\cdot(1+\text{baseLoad})\cdot\text{MaxIL}_i \quad\text{(income, risk-neutral at }\sigma_{\text{ref}}\text{)} payouti=min⁡(ILi, MaxILi)(claim, real measure)\text{payout}_i = \min(\text{IL}_i,\ \text{MaxIL}_i) \quad\text{(claim, real measure)} Premium is collected under the risk-neutral measure at the conservative σ_ref; payout is paid under the real measure. The edge is the gap between them — the volatility risk premium — earned in calm months and given back in crashes.

Bare-pool figures (unhedged, untranched)

These are the single-asset bare pool numbers — before tranching, before the optional roadmap hedge — at base loads (calm/normal/stressed = 20/30/50%), gross of demand/competition/fees. Lead with the geometric 3y CAGR, never the arithmetic mean. How to read these:
  • 3y CAGR — the volatility risk premium compounds strongly in the median, with a wide distribution. The p10 column (50% at u = 0.40) is the honest downside of the median run, not the worst case.
  • P(losing month) ≈ 26.5% — roughly one month in four is red. This is intrinsic to volatility selling (you lose whenever realized vol exceeds the implied vol you priced at), not a flaw to be tuned away.
  • 1-in-100 month / worst month — the tail of a single bad month. At u = 0.40 a 1-in-100 month is −20.1% and the worst observed is −26.8%; both worsen materially at u = 0.60.
  • P(3y DD > 50%) — the probability of a peak-to-trough drawdown over 50% across three years. Utilization is the dominant drawdown lever: u = 0.40 → 2.7% vs u = 0.60 → 18.0%.
  • no bad debt ✓ — across every simulated path, min(IL, MaxIL)/MaxIL ≤ 1.0 (max_payout_frac = 1.000000). The LP guarantee holds structurally and oracle-independently even while the depositor P&L swings.
The honest headline: an unhedged, untranched single-pair ETH pool CANNOT meet the spec safety targets at any marketable load.
  • Limit: the binding targets — 1-in-100 monthly loss ≤ 10% and P(losing month) ≤ 15% — are unreachable for a bare single-asset pool at any load with premium ≤ MaxIL.
  • Why: these are intrinsic to single-asset volatility selling — you lose whenever realized > implied, and a synchronized crash pays the whole correlated book at once. No load setting changes that; raising load past premium ≤ MaxIL would mean charging more than the maximum possible payout, which the I10 cap forbids.
  • Mitigation: the targets were not loosened. The structural levers are the honest answer — and tranching is the launch one (next section). The targets were met by changing the structure, not the bar.

What tranching does to the picture

The dual-tranche structure is the launch lever that turns the bare-pool profile into two genuinely different products: The senior tranche converts the bare pool’s −26.8% worst month and 26.5% loss-month rate into a smooth, protected return while the junior buffer holds and utilization stays disciplined. The junior tranche concentrates the bare pool’s downside (worst −67%) in exchange for the larger premium slice. Neither is risk-free — junior can lose most of its principal in a crash, and senior takes the systemic tail once the junior buffer is exhausted or an assumption (peg / oracle / code) breaks.
There is a third, roadmap lever — a pool-side options hedge (h ≈ 0.60) that tightens the tail (1-in-100 → ~−9.6%, P(DD>50%) → ~0%) without much CAGR change. It is tail-tightening, not solvency (it carries basis risk from approximating a fixed v3 position with a perpetual options hedge), and it is not required for the no-bad-debt guarantee. Tranching is the launch structure; the hedge is a future enhancement.

The mandatory disclosure tone

The quant fixes the exact language depositor surfaces must use:
“You earn the volatility risk premium in calm markets and absorb losses in crashes. In FULL the pool cannot become insolvent and cannot be run, but YOUR CAPITAL IS NOT GUARANTEED.”
Never call it “stable” or “modest APY.” APY figures are gross of demand, competition, and fees and are model-illustrative — present the risk panel as the robust part and lead with the geometric 3y CAGR, never the arithmetic mean. The model is in fact net-conservative to depositors: the σ_ref floor of 0.50 sits above calm ETH vol (~0.45), so the pool overcharges the ~27% of months that are calm, and the heavy run’s all-months realized payout/premium came in at 0.654.
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 pending state — never an error.

Two claims, never merged

The tranche structure is where the two load-bearing disclosures sit side by side. They are separate claims and must never be combined. The LP-facing guarantee is structural and oracle-independent — it holds regardless of how the depositor P&L moves:
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.
The depositor-facing reality is the opposite: capital is at risk for both tranches, junior first.
Depositor capital is NOT guaranteed: the junior tranche is first-loss; the senior tranche is structurally protected from underwriting loss only, not systemic tail.Underwriting capital — whether supplied to the pooled cvAMM vault (Path A) or posted directly by a market maker (Path B) — is at risk:
  • Junior tranche — first-loss. Junior depositors absorb underwriting losses first and buffer the senior tranche.
  • Senior tranche — protected from underwriting loss, exposed to the systemic tail. The senior tranche is structurally shielded from ordinary underwriting loss while junior capital buffers, but it still takes the systemic tail once the junior buffer is exhausted.
No-bad-debt is a guarantee to the LP being paid (see the FULL-mode payout clause), not a guarantee that depositor or MM capital is preserved.
The crucial split: the LP’s no-bad-debt guarantee (Claim A) is structural — collateral = MaxIL ≥ payout by construction — and is orthogonal to every pricing oracle and to the tranche split. The depositor’s capital-at-risk (Claim B) is the economic substance of being a volatility seller. Senior protection sits inside Claim B (it reduces, but does not eliminate, junior-then- systemic risk); it is not a separate guarantee and never reaches across to the LP side. 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.

Where to go next

Earn — the depositor app

Deposit into senior or junior, see the live risk panel, and request a withdrawal.

Risk disclosure

The full statement of what each tranche risks and earns.

The cvAMM in depth

Path A end to end: pricing, locking, accrual, and the waterfall.

No-bad-debt math

Why the LP guarantee is structural and orthogonal to the tranche split.