Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.meteora.ag/llms.txt

Use this file to discover all available pages before exploring further.

DAMM v2 is designed around constant-product liquidity. The formulas below explain the product math and the implementation details users most often need to reason about. On-chain values use integer math, so rounding matters.

Constant Product

The basic AMM idea is simple: x×y=kx \times y = k x is the token A reserve, y is the token B reserve, and k is the pool’s liquidity invariant. In compounding mode this is reserve-based. In concentrated mode, the same idea is bounded by the pool’s configured square-root price range.

Price and Square-Root Price

DAMM v2 stores price as a square-root price: P=token B amounttoken A amount\sqrt{P} = \sqrt{\frac{\text{token B amount}}{\text{token A amount}}} This format makes liquidity math more precise and efficient on-chain. Product users can still think of it as the pool price expressed in a form that is easier for the program to update during swaps and liquidity changes.

Concentrated Liquidity

In concentrated liquidity mode, a DAMM v2 pool has a fixed lower and upper square-root price: PminPPmax\sqrt{P_{\min}} \le \sqrt{P} \le \sqrt{P_{\max}} For a liquidity amount L, the token amounts are: ΔA=L×(1P1Pmax)\Delta A = L \times \left(\frac{1}{\sqrt{P}} - \frac{1}{\sqrt{P_{\max}}}\right) ΔB=L×(PPmin)\Delta B = L \times (\sqrt{P} - \sqrt{P_{\min}}) The program rounds required deposit amounts up and withdrawal or swap output amounts down. Token A calculations also guard against values larger than u64::MAX.

Compounding Liquidity

In compounding mode, DAMM v2 uses full-range constant-product liquidity and prices the pool from reserves: token A reserve×token B reserve=k\text{token A reserve} \times \text{token B reserve} = k P=token B reservetoken A reserveP = \frac{\text{token B reserve}}{\text{token A reserve}} At initialization, compounding mode derives reserves from liquidity and square-root price: A0=LPA_0 = \left\lceil \frac{L}{\sqrt{P}} \right\rceil B0=L×P2128B_0 = \left\lceil \frac{L \times \sqrt{P}}{2^{128}} \right\rceil The first position receives: Lposition=L(10064)L_{\text{position}} = L - (100 \ll 64) because 100 << 64 is kept as dead liquidity in the pool.

Trading Fees

DAMM v2 fee rates are stored as numerators over 1,000,000,000: Total Fee Numerator=min(Base Fee Numerator+Dynamic Fee Numerator,Pool Fee Cap)\text{Total Fee Numerator} = \min(\text{Base Fee Numerator} + \text{Dynamic Fee Numerator}, \text{Pool Fee Cap}) For fees taken from an amount that already includes the fee, the program rounds the fee up: Trading Fee=Included Amount×Fee Numerator1,000,000,000\text{Trading Fee} = \left\lceil \frac{\text{Included Amount} \times \text{Fee Numerator}}{1{,}000{,}000{,}000} \right\rceil For fees added to an amount that excludes the fee: Included Amount=Excluded Amount×1,000,000,0001,000,000,000Fee Numerator\text{Included Amount} = \left\lceil \frac{\text{Excluded Amount} \times 1{,}000{,}000{,}000}{1{,}000{,}000{,}000 - \text{Fee Numerator}} \right\rceil After the trading fee is calculated, DAMM v2 splits it: Protocol Fee=Trading Fee×Protocol Fee Percent100\text{Protocol Fee} = \left\lfloor \text{Trading Fee} \times \frac{\text{Protocol Fee Percent}}{100} \right\rfloor LP Fee Before Compounding=Trading FeeProtocol Fee\text{LP Fee Before Compounding} = \text{Trading Fee} - \text{Protocol Fee} If the pool uses compounding mode, the LP fee can be split again: Compounding Fee=LP Fee Before Compounding×Compounding Fee Bps10,000\text{Compounding Fee} = \left\lfloor \text{LP Fee Before Compounding} \times \frac{\text{Compounding Fee Bps}}{10{,}000} \right\rfloor Claimable Fee=LP Fee Before CompoundingCompounding Fee\text{Claimable Fee} = \text{LP Fee Before Compounding} - \text{Compounding Fee} If a referral is present, the referral fee is taken from the protocol fee: Referral Fee=Protocol Fee×Referral Fee Percent100\text{Referral Fee} = \left\lfloor \text{Protocol Fee} \times \frac{\text{Referral Fee Percent}}{100} \right\rfloor DAMM v2’s default protocol fee percent is 20, and the referral fee percent is 20 of the protocol fee when a referral account is used.

Dynamic Fee

Dynamic fees use a volatility accumulator. When price changes quickly, the accumulator rises. When the market calms down, it decays. Dynamic Fee Numerator=(Volatility Accumulator×Bin Step)2×Variable Fee Control100,000,000,000\text{Dynamic Fee Numerator} = \left\lceil \frac{(\text{Volatility Accumulator} \times \text{Bin Step})^2 \times \text{Variable Fee Control}}{100{,}000{,}000{,}000} \right\rceil In the current implementation, dynamic fee bin_step must be 1 bps and bin_step_u128 must match the default 1 bps fixed-point value. filter_period must be lower than decay_period, and both variable_fee_control and max_volatility_accumulator are capped at 0xffffff.

Liquidity Mining Rewards

DAMM v2 liquidity mining distributes reward tokens by position liquidity: Reward Per Liquidity=Elapsed Time×Reward RateTotal Pool Liquidity\text{Reward Per Liquidity} = \frac{\text{Elapsed Time} \times \text{Reward Rate}}{\text{Total Pool Liquidity}} Position Reward=Position Liquidity×Reward Per Liquidity Since Last Checkpoint\text{Position Reward} = \text{Position Liquidity} \times \text{Reward Per Liquidity Since Last Checkpoint} This means LPs earn rewards in proportion to their share of pool liquidity. Unlocked, vesting, and permanently locked liquidity can all count toward rewards because the position’s total liquidity is used for reward accounting. The reward rate is stored as a fixed-point value scaled by 2^64, while reward-per-liquidity accounting is accumulated with a 2^128 liquidity scale. Integer division truncates fractional rewards.