Skip to main content

AMM vs CPAMM on Solana — constant product vs CLMM, DLMM, PMM, and order books

· 15 min read
Vadim Nicolai
Senior Software Engineer at Vitrifi

Solana runtime constraints: accounts, locks, and contention

TL;DR

  • AMM is the category: any on-chain venue that computes prices algorithmically from state (reserves, parameters, or inventory).
  • CPAMM / CPMM is one specific AMM family: constant product with invariant x · y = k (Uniswap v2-style).
  • The useful comparison is CPAMM vs other liquidity designs:
    • StableSwap (stable/correlated assets),
    • CLMM (concentrated liquidity / ticks),
    • DLMM (bin-based liquidity + often dynamic fees),
    • PMM / oracle-anchored (proactive quoting around a “fair price”),
    • CLOB (order books),
    • TWAMM (time-sliced execution),
    • bonding-curve launch mechanisms (virtual reserves → migration).
  • On Solana, the tradeoffs are heavily shaped by:
    • account write locks / hot accounts (parallelism vs contention),
    • Token-2022 extensions (transfer fees/hooks can break naive “amount_in == amount_received” math),
    • router-first distribution (aggregator integration matters),
    • MEV & atomic execution tooling (bundles / private routes / quote freshness).

AMM vs CPAMM (and why the wording matters)

AMM (the umbrella)

An AMM is any on-chain market maker that:

  • holds on-chain state (reserves, inventory, parameters),
  • updates price algorithmically,
  • executes swaps against that state.

An on-chain order book can be fully on-chain too, but it’s not an AMM: it matches explicit bids/asks, not a curve/invariant rule.

CPAMM / CPMM (the subtype)

A CPAMM is a constant-function AMM where:

xy=kx \cdot y = k

x and y are pool reserves.

So:

  • all CPAMMs are AMMs
  • not all AMMs are CPAMMs

CPAMM mechanics in one screen (math + semantics)

Let reserves be (x, y) and you swap dx of X for Y.

Fee model (input fee)

If fee is f (e.g. 0.003 for 30 bps):

dx=dx(1f)dx' = dx \cdot (1 - f)

Output

dy=ydxx+dxdy = \frac{y \cdot dx'}{x + dx'}

Reserve update

  • x := x + dx
  • y := y - dy

Observed vault delta (Token-2022-safe input amount):

dxeff=vaultaftervaultbeforedx_{eff} = vault_{after} - vault_{before}

Price intuition (useful when comparing designs)

  • Spot price (ignoring fees): p ≈ y/x (direction depends on quote convention)
  • For small trades, slippage is roughly proportional to trade size / liquidity depth.
  • Fees retained in the pool tend to increase k over time (LPs get paid via reserve growth).

Comparison tables

Taxonomy and “what is being compared?”

Term / designCategory?Core ideaTypical on-chain stateWho provides liquidity?Quote source
AMMYesAlgorithmic pricing vs statevariesvariescurve/parameters/inventory
CFAMM (constant-function AMM)YesTrades move along an invariantreserves + paramsLPs or protocolinvariant
CPAMM / CPMMYesx*y=k2 vaults + pool state (+ LP mint)passive LPsreserves ratio
StableSwapYeshybrid curve (sum-like near peg)vaults + params (A, etc.)passive LPscurve + params
CLMMYesliquidity concentrated in ranges/ticksvaults + tick arrays + position accountsactive LPsticks + reserves
DLMM (bins)Yesdiscrete bins + liquidity distributionvaults + bin arrays + position stateactive/semi-active LPsbins + params
PMM / oracle-anchoredYesprice anchored to oracle fair valueinventory + params + oracle feedsmarket maker / protocoloracle + model
CLOB (order book)No (not AMM)match bids/asksmarket + order statemakerslimit orders
TWAMMNo (mechanism)execute large order over timelong-term order statetrader ordersschedule
Bonding curve launchYes (often)virtual reserves / issuance curvecurve params + reserveslaunch poolcurve

Trader view: execution quality & UX

DesignTypical spread / slippage (for same TVL)“Always liquid”?Best forPain points (trader)Router friendliness
CPAMMworst for tight marketsYeslong-tail discovery, simple swapshigh price impact without huge TVLhigh (simple routes)
StableSwapexcellent near pegYes (until extreme imbalance)stable/stable, correlated assetsparameter risk; off-peg behaviorhigh
CLMMbest near spotNo (can be out-of-range)majors, low slippagedepth depends on LP rangeshigh (but more accounts)
DLMMvery good when bins are well-setmostlystructured liquidity & dynamic feesbin distribution mattershigh (but more accounts)
PMMpotentially excellentdepends on MM inventorymajors & flow-driven quotingoracle/model risk; opaque behaviorhigh if integrated (RFQ-like)
CLOBbest when book is thickn/apro trading, limit ordersneeds makers & incentivesmedium/high (depends on infra)
TWAMMoptimized for large ordersn/asize executionnot instantrouted as a strategy leg
Bonding curvedeterministic but can be harshcurve-dependentlaunchescan be gamed / MEV-heavyusually “launch-only”

LP view: risk, complexity, and who wins when

DesignLP position typeCapital efficiencyIL profileOperational complexityWho tends to outperform?
CPAMMfungible LP tokenlowclassic IL (full range)lowpassive LPs in long-tail / high fees
StableSwapoften fungible LPhigh near pegsmaller IL near pegmediumLPs in correlated pairs
CLMMtokenized/NFT-like positionvery highcan be worse if misrangedhighsophisticated LPs / managed vaults
DLMMbin/strategy position statehigh (configurable)strategy-dependentmedium/highstrategy LPs; can be “MM-like”
PMMusually MM-managed inventoryhighmodel-controlledhighmarket makers (not passive LPs)
CLOBmaker ordersn/ainventory risk, not ILhighprofessional makers
Bonding curvenot traditional LPn/an/amediumlaunch designers + snipers (unless mitigated)

Solana runtime view: contention, accounts, compute

This is the table people skip, but it often determines what scales.

DesignWhat gets written per swap?Hot-account tendencyParallelism shapeTx/account footprintNotes
CPAMMsame pool state + both vaultshighmany swaps serialize on same poollow/mediumsimplest, but hotspot-prone
StableSwapsame as CP-ish + paramshighsimilar to CP contentionmediummore compute than CP
CLMMvaults + tick arrays + position-related statemediumcan shard via tick arrayshighermore accounts; better scaling shape
DLMMvaults + active bin(s) + paramsmediumcan shard by binshigherdepends on bin layout
PMMinventory + oracle state + paramslow/mediumdepends on designmediumquote updates may dominate
CLOBmarket state + order matching statevariesdepends on matching engine designhighcrankless helps UX
TWAMMlong-term order state + execution legsn/atime-slicedmedium/highoften pairs with CLOB/AMM legs

Parameter surface area (“knobs you must ship and maintain”)

DesignParameters you can’t ignoreTuning difficultyCommon footguns
CPAMMfee bps, min liquidity lock, rounding ruleslowoverflow in x*y, wrong deposit proportionality
StableSwapamplification A, fee(s), admin fees, rampingmedium/highbad A → fragility near peg/off-peg
CLMMtick spacing, fee tier(s), init price, range UXhightick array provisioning, out-of-range UX
DLMMbin step, dynamic fee curve, rebalancing rulesmedium/highbin skew → bad execution; edge-bin depletion
PMMoracle choice, spread model, inventory/risk limitsvery highstale oracle, model blowups, adversarial flow
CLOBtick size, lot size, maker/taker fees, risk limitshighdust orders, spam, maker incentives
Bonding curvevirtual reserves, slope, caps, migration ruleshighsniping, MEV extraction, mispriced curve

Token-2022 / “non-standard token semantics” compatibility

Token-2022 extensions change what “amount in” means.

Token featureWhat breaks in naive AMMsSafe patternDesigns most sensitive
Transfer feeamount_in ≠ vault deltacompute dx = vault_after - vault_beforeall curve AMMs
Transfer hookextra logic executed on transferstrict account lists; avoid re-entrancy assumptionsall; especially CPI-heavy
Confidential transfersyou can’t observe amounts easilyoften incompatible without special supportmost AMMs
Interest-bearingbalances drift over timeuse observed balances; avoid cached reservesall pool AMMs
Memo/metadata extusually fineno-opnone

Rule of thumb: if you don’t base math on observed vault deltas, you’re designing for 2019 SPL Token semantics.


MEV & adversarial flow profile

DesignSandwich susceptibility“Pick-off” riskMitigations that actually workNotes
CPAMMhighhighprivate routing, tighter fees, better routing, smaller hopspassive curve is easy to arb
StableSwapmediummediumsimilar; parameter robustnessoff-peg events get brutal
CLMMmediumhigh (LPs)managed LP vaults; dynamic feesLPs can get wrecked by volatility
DLMMmediummedium/highdynamic fees, bin strategydepends on fee model
PMMlow/mediummediumoracle + inventory + RFQ-style routing“MM-like” behavior
CLOBmediummediummaker protections, anti-spam, risk controlsdepends on market design
Bonding curvevery highvery highanti-bot design + fair launch mechanicslaunch is an MEV magnet

“Which one should I choose?” (builder POV)

If your goal is…PickBecauseBut be honest about…
ship fastest + minimal stateCPAMMsimplest accounts & mathcontention + worse execution unless TVL is high
best majors execution with public LPsCLMMcapital efficiency near spotposition UX + account explosion
stable pairs / correlated assetsStableSwaplow slippage near pegparameter tuning & off-peg behavior
strategy-friendly liquidityDLMMbins + dynamic fees can match volatilitybin UX + more moving parts
tight quotes controlled by MM logicPMMcan beat passive curvesoracle/model risk is the product
limit orders + pro featuresCLOBexplicit bids/asksmaker bootstrapping + ops complexity
reduce impact of whale flowTWAMM (+ a venue)time-slicingneeds execution infra
token launch discovery pathBonding curve → migratedeterministic launch → deep liquidity laterlaunch MEV + migration design

A “migration path” table (how protocols evolve in practice)

PhaseTypical mechanismWhy it fitsWhat you usually add next
launch / discoverybonding curve / small CP poolsimple, deterministicanti-bot + migration
early liquidityCPAMMeasy integrationsmultiple fee tiers / incentives
scaling majorsCLMM or DLMMbetter executionmanaged LP vaults
pro tradingCLOBlimit orderscross-margin/perps
flow optimizationPMM / RFQ-likebest execution for routed flowprivate routing + inventory mgmt
large order UXTWAMMreduces impactbundle/atomic strategies

Anchor CPAMM: the “don’t ship this” checklist (most common bugs)

1) Proportional deposits are ratios, not products

If you want users to deposit proportionally, you preserve:

  • amount_a / amount_b ≈ reserve_a / reserve_b

A clamp-style approach:

Δb=Δareservebreservea\Delta b = \Delta a \cdot \frac{reserve_b}{reserve_a}

and then you clamp the other side if user supplies less.

2) LP minting: sqrt(Δa·Δb) is bootstrap-only

For subsequent deposits, use proportional minting:

liquidity=min(Δasupplyreservea,Δbsupplyreserveb)liquidity = \min\left( \frac{\Delta a \cdot supply}{reserve_a}, \frac{\Delta b \cdot supply}{reserve_b} \right)

Otherwise LP shares drift and you can mint unfairly.

3) Invariant checks must be A·B and must use u128

If you verify k, do:

  • new_x * new_y >= old_k (often allowing rounding to favor LPs)
  • compute with u128 intermediates.

4) Token-2022: do not trust amount_in

For fee-on-transfer tokens:

  • the only safe dx is vault_after - vault_before.

Minimal “correct CPAMM math” snippet (overflow-safe, vault-delta friendly)

/// Compute CPAMM output (dy) from reserves (x, y) and effective input (dx_eff),
/// using u128 intermediates to avoid u64 overflow.
///
/// IMPORTANT (Token-2022):
/// - If the token can take a transfer fee, compute dx_eff from observed vault delta:
/// dx_eff = vault_x_after - vault_x_before
pub fn cpamm_out_amount(x: u64, y: u64, dx_eff: u64) -> u64 {
let x = x as u128;
let y = y as u128;
let dx = dx_eff as u128;

// dy = (y * dx) / (x + dx)
let den = x + dx;
if den == 0 {
return 0;
}

let dy = (y * dx) / den;
dy.min(u64::MAX as u128) as u64
}

Extra comparison tables (for the “systems” view)

Public API ergonomics: what you expose to integrators

Design“Simple swap” interfaceQuote interfaceCommon integration shapeGotcha
CPAMMswap(amount_in, min_out)deterministic from reservesdirect CPIneed observed deltas for Token-2022
CLMMsame, but more accountstick-dependentSDK computes accountsaccount list errors are common
DLMMsimilarbin-dependent + dynamic feeSDK requiredbin selection correctness matters
PMMoften RFQ-likeoracle + MM paramsrouter integration is key“quote freshness” is the product
CLOBorder placementbook dataoff-chain client + on-chain settlemaker ops are non-trivial

Testing strategy: what to property-test per design

DesignInvariants to testEdge casesSuggested approach
CPAMMk non-decrease (fee), no negative reservesrounding, overflow, zero-liquidityproperty tests with random swaps
StableSwapmonotonicity near peg, conservationextreme imbalance, A rampsfuzz + numerical bounds
CLMMtick crossing correctness, fee growthboundary ticks, out-of-rangedifferential tests vs reference
DLMMbin transitions, dynamic fee functionbin depletion, fee spikesfuzz + scenario sims
PMMoracle staleness handling, risk limitsoracle outages, adversarial flowsimulation + kill-switch tests
CLOBmatching engine correctnessself-trade, partial fillsdeterministic replay tests

References (URLs)