Trading Terminals can easily integrate with Meteora DAMM v2 by following this guide that explains in detail how to get the necessary data from indexing the DAMM v2 program.
Total Fees
totalFees = baseFees + dynamicFees
Base Fees
Base Fees includes either a Flat Fee, Fee Scheduler, Rate Limiter, or Fee Market Cap Scheduler.
BaseFeeMode can be enums 0, 1, 2, 3, or 4.
- 0 = Linear Fee Time Scheduler
- 1 = Exponential Fee Time Scheduler
- 2 = Rate Limiter
- 3 = Linear Fee Market Cap Scheduler
- 4 = Exponential Fee Market Cap Scheduler
Pool Version Note: Pool Version V1 supports up to 99% max fee (increased from V0’s 50% max fee).
Decoding BaseFee
The baseFee.data field is a number[] (byte array) that requires decoding when indexed. The decoder type depends on the data source and baseFeeMode.
From EvtInitializePool event (Borsh serialization, 30 bytes):
baseFeeMode 0-1: Use BorshFeeTimeScheduler
baseFeeMode 2: Use BorshFeeRateLimiter
baseFeeMode 3-4: Use BorshFeeMarketCapScheduler
From poolState account (Pod-aligned serialization, 32 bytes):
baseFeeMode 0-1: Use PodAlignedFeeTimeScheduler
baseFeeMode 2: Use PodAlignedFeeRateLimiter
baseFeeMode 3-4: Use PodAlignedFeeMarketCapScheduler
Flat Fee
You can fetch the flat fee directly from the cliffFeeNumerator in the baseFee object if all other parameters are 0.
// Example - Flat fee
baseFee: {
cliffFeeNumerator: 10000000, // 1% flat fee
baseFeeMode: 0,
numberOfPeriod: 0,
periodFrequency: 0,
reductionFactor: 0
}
The Fee Scheduler depends on the poolState.activationType.
- If the
poolState.activationType == 0, then numberOfPeriod and periodFrequency is calculated in SLOT == 400ms
- If the
poolState.activationType == 1, then numberOfPeriod and periodFrequency is calculated in SECONDS == 1000ms
Fee Time Scheduler
-
For Fee Time Scheduler, the fee reduces over time based on the scheduler configuration.
-
baseFeeMode can be 0 (Linear) or 1 (Exponential).
interface FeeTimeScheduler {
cliffFeeNumerator: BN; // Starting fee numerator (e.g., 500000000 = 50%)
baseFeeMode: number; // 0 = Linear, 1 = Exponential
numberOfPeriod: number; // Number of fee reduction periods
periodFrequency: BN; // Time between periods (slots or seconds based on activationType)
reductionFactor: BN; // Fee reduction per period
}
You can refer to the math formula for the Fee Time Scheduler
here
Here are some examples of how the Fee Time Scheduler works:
// Fee Time Scheduler: 50% reduce to 1% in 10 minutes linearly
{
cliffFeeNumerator: new BN(500000000), // 50% starting fee
baseFeeMode: 0, // Linear mode
numberOfPeriod: 100, // 100 periods
periodFrequency: new BN(1), // Time between periods
reductionFactor: new BN(4900000), // Reduction factor per period
}
// Fee Time Scheduler: 50% reduce to 1% in 10 minutes exponentially
{
cliffFeeNumerator: new BN(500000000), // 50% starting fee
baseFeeMode: 1, // Exponential mode
numberOfPeriod: 100, // 60 periods
periodFrequency: new BN(1), // Time between periods
reductionFactor: new BN(383), // Reduction factor per period
}
Rate Limiter
-
For Rate Limiter, the fee increases exponentially based on trade size to prevent large trades from manipulating the market.
-
baseFeeMode can only be 2.
When integrating swaps with Rate Limiter pools (baseFeeMode == 2), you must include SYSVAR_INSTRUCTIONS_PUBKEY in the remaining accounts of the swap instruction.
interface FeeRateLimiter {
cliffFeeNumerator: BN; // Base fee numerator (e.g., 10000000 = 1%)
baseFeeMode: number; // 2 = Rate Limiter
feeIncrementBps: number; // Fee increment in basis points per reference amount
maxLimiterDuration: number; // Maximum duration for rate limiter (slots or seconds)
maxFeeBps: number; // Maximum fee cap in basis points
referenceAmount: BN; // Reference amount for fee calculation
}
You can refer to the math formula for the Rate Limiter
here
Here are some examples of how the Rate Limiter works:
// Rate Limiter: Starts at 1% fee -> Exponential increase in fee for 10 slots based on trade size
// 0.5 SOL trade
// fee = 0.5 SOL * 0.1% = 0.0005 SOL
// 1.5 SOL trade
// fee = 1 SOL * 0.1% + 0.5 SOL * 0.2% = 0.002 SOL
// 3 SOL trade
// fee = 1 SOL * 0.1% + 1 SOL * 0.2% + 1 SOL * 0.3% = 0.006 SOL
{
cliffFeeNumerator: new BN(10000000), // Base fee numerator (1%)
baseFeeMode: 2, // Rate limiter mode
feeIncrementBps: 10, // Fee increment per reference amount in basis points
maxFeeBps: 5000, // Max fee cap in basis points (50%)
referenceAmount: new BN(1000000000), // Reference amount in lamports (1 SOL)
maxLimiterDuration: 10, // Duration in slots/seconds
}
Fee Market Cap Scheduler
-
Fee Market Cap Scheduler reduces fees based on price movement (market cap growth) rather than time. This is different from Fee Time Scheduler which reduces fees over time regardless of price action.
-
baseFeeMode can be 3 (Linear) or 4 (Exponential).
interface FeeMarketCapScheduler {
cliffFeeNumerator: BN; // Starting fee numerator (e.g., 500000000 = 50%)
baseFeeMode: number; // 3 = Linear, 4 = Exponential
numberOfPeriod: number; // Number of fee reduction periods
sqrtPriceStepBps: number; // Sqrt price step in bps to advance one period
schedulerExpirationDuration: number; // Duration after which scheduler expires (slots or seconds)
reductionFactor: BN; // Fee reduction per period
}
You can refer to the detailed math formula for the Fee Market Cap Scheduler
here
Here are some examples of how the Fee Market Cap Scheduler works:
// Fee Market Cap Scheduler: 50% starting fee, reduces linearly based on price growth
{
cliffFeeNumerator: new BN(500000000), // 50% starting fee
baseFeeMode: 3, // Linear mode
numberOfPeriod: 100, // 100 periods
sqrtPriceStepBps: 100, // 1% sqrt price step per period
schedulerExpirationDuration: 86400, // 24 hours expiration
reductionFactor: new BN(4950000), // Linear reduction factor
}
// Fee Market Cap Scheduler: 50% starting fee, reduces exponentially based on price growth
{
cliffFeeNumerator: new BN(500000000), // 50% starting fee
baseFeeMode: 4, // Exponential mode
numberOfPeriod: 100, // 100 periods
sqrtPriceStepBps: 100, // 1% sqrt price step per period
schedulerExpirationDuration: 86400, // 24 hours expiration
reductionFactor: new BN(390), // Exponential reduction factor (bps)
}
Dynamic Fees (Variable Fee)
You can refer to the Dynamic Fee calculation here
Plotting Charts
Using Transfer logs from Swap transactions is not the correct way of getting the token price as we have Anti-Sniper Suite features that can cause huge fee deductions from TokenAmountIn OR TokenAmountOut. Plotting the token chart price from these will lead to a very ugly chart.
The correct way is to fetch the EvtSwap2 CPI logs from the Swap transaction.
EvtSwap is an older version of the swap CPI logs and might be deprecated in the future. Use EvtSwap2 instead.
Because of the Anti-Sniper Suite features, you will have to apply the following checks to get the correct token price either before/after the fee deduction.
[1.1] Firstly, you will need to identify where the fees are coming from (either from input or output):
feeOnInput: (collectFeeMode == 1 && tradeDirection == 1)? true: false
[1.2] Next, calculate the amount and plot price depending on where the fees are coming from (either from input or output):
if (feeOnInput): price = excludedFeeInputAmount / outputAmount
if (!feeOnInput): price = excludedFeeInputAmount / outputAmount + tradingFee + protocolFee + referralFee + partnerFee
Trading Volume
Track from Swap CPI logs:
// Depending on Trade Direction:
trading_volume += actualAmountIn * token_price
Liquidity
In the DAMM v2 pool, the liquidity is fetched from the tokenAVault and tokenBVault of the DAMM v2 pool.
liquidity = tokenAVault * tokenAPrice + tokenBVault * tokenBPrice
Locked or Vested Liquidity
In DAMM v2, there are 3 different modes for liquidity:
lockedLiquidity - which means that the liquidity is permanently locked
vestedLiquidity - which means that the liquidity is vestedLiquidity
unlockedLiquidity - which means that the liquidity is unlocked and claimable
You can use our DAMM v2 API endpoint that tracks pool positions and show accurately whether the liquidity is locked or not on your trading terminal.
How to Identify Launchpads Using DAMM v2
You can ping us on Discord to get a list of all launchpads configuration who are launching on DAMM v2 directly so that you can index them on your trading terminal.
Open a ticket on
discord to get access to the list.
Referral Account
- For trading terminals, we have a feature that enables trading terminals to earn referral fees from all swaps that happens on our Meteora DBC program as long as they were swapped through your trading terminal.
- For referral fees, simply add your referral token account within the swap instruction & you will receive 20% of the protocol fees for all swaps.