Skip to content

Virtual reserves and graduation

Follow a token from finite curve inventory to a full-range CLMM without changing its pool or hook.

A grapl bonding curve is a pool mode with configurable virtual reserves and real token inventory. The virtual reserves define the price path. Real balances determine what can actually be paid out. Once the configured net quote target is reached, a separate atomic instruction turns the same pool into a CLMM.

flowchart LR
Mint[Create or bring a token] --> Curve[Fund curve inventory]
Curve --> Trading[Buy and sell against virtual reserves]
Trading --> Target[Reach net quote target]
Target --> Graduate[Atomic graduation]
Graduate --> CLMM[Same pool and hook / full-range CLMM]

Configure price, inventory, and the target separately

FieldMeaning
virtual_a, virtual_bPositive virtual reserves used to calculate output and marginal price
base_is_aIdentifies which ordered pool mint is the launched base token
inventoryActual base atoms the creator deposits
bootstrap_baseMinimum real base retained for graduation
target_quoteRequired real quote principal, excluding fees
position_idIdentifier assigned to the creator's graduation position

inventory must exceed the positive bootstrap floor. Virtual base must cover the initial inventory, and validation checks that the target can be reached without selling the reserved bootstrap base. It also checks that the resulting price can support the configured full-range position.

The quote can be WSOL, USDC, or another supported classic SPL token. A target_quote denominated in WSOL is a SOL amount, not a fixed USD valuation. No oracle conversion is implicit.

Price each trade

For virtual input reserve v_in, virtual output reserve v_out, and input after fees n:

output = floor(v_out × n / (v_in + n))

ExactOut reverses the equation, rounding the required net input upward. Input fees, output fees, inventory floors, real quote backing, price limits, and user limits remain separate checks. See AMM mathematics.

At any point, sqrt_price_x64 reflects the ratio of the current virtual reserves. It is not computed from the whole physical vault balance.

Real reserves keep the curve solvent

Track these buckets independently for each asset:

vault balance ≥ real curve principal
              + retained LP-share fees
              + protocol fee liabilities
              + beneficiary fee liabilities

Virtual quote is not collateral. Selling base into the curve can only withdraw real quote available after liabilities. Buying base cannot consume the reserved bootstrap inventory.

User LP deposits are disabled during curve mode. The configured LP fee share accumulates for the future bootstrap rather than being attributed to nonexistent public LP positions. Protocol and beneficiary debts remain claimable liabilities and are excluded from graduation funding.

Virtual reservesDefine price and output calculation
Pricing state
Cannot pay a withdrawal
Real vault balancesBack settlement and liabilities
Curve principal
LP fees + protocol and beneficiary debt
Only available principal can be spent
Virtual liquidity changes the price path. Solvency depends on real assets after reserving liabilities and bootstrap inventory.
One reservoir opens into structured liquidity channels on a shared base.
Conceptual transition from curve inventory to CLMM liquidity. The same pool, vaults, and hook remain bound through graduation.

Graduate without replacing the market

graduate_curve checks that the target is reached and creates a creator-owned full-range position. A caller may fund the instruction permissionlessly, but that does not give the caller ownership of the position.

The operation preserves:

  • the pool address and token vaults;
  • both mint identities and the existing hook binding;
  • the current Q64.64 marginal price;
  • already accrued protocol and beneficiary liabilities.

It uses real reserves plus retained LP-share fees to calculate affordable full-range liquidity. Rounding or token-ratio differences can leave a remainder; collect_curve_remainder allows the creator to withdraw only that recorded remainder after graduation.

Graduation is a separate atomic instruction, not a swap that crosses two engines. A trade does not automatically continue into CLMM mode. Repeated graduation must reject. A failing hook or settlement check rolls back the operation.

Policy continuity

Curve swaps use BeforeSwap and AfterSwap. Graduation uses the add-liquidity callbacks and updates pool_mode from curve to CLMM. There is no dedicated BeforeGraduate or AfterGraduate callback in ABI 4.

Keeping a hook attached preserves the policy program and configuration binding. A developer can still write a mode-dependent policy, so applications must inspect what that hook actually authorizes. See lifecycle hooks.

Source: instructions/curve/, state/curve.rs, and math/curve.rs under programs/grapl-amm/src/.