Calculate Token Amounts
Calculate the exact token amounts required for each bin based on your liquidity distribution. Essential for preparing transactions and avoiding slippage.
Token Requirements by Bin
DLMM requires different token ratios based on bin position:
Below active bin: 100% token Y (quote token)
At active bin: Both tokens (ratio depends on position in bin)
Above active bin: 100% token X (base token)
Basic Calculation
import { getAmountXFromLiquidity, getAmountYFromLiquidity } from '@ferra-labs/dlmm';
// For a specific bin
const binId = 8388610;
const liquidity = 1000000n;
const binPrice = getPriceFromBinId(binId, binStep);
// Calculate required amounts
const amountX = getAmountXFromLiquidity(liquidity, 0n, binPrice);
const amountY = getAmountYFromLiquidity(liquidity, amountX, binPrice);
console.log(`Bin ${binId} needs:`, {
tokenX: amountX,
tokenY: amountY
});
Multi-Bin Calculation
// Calculate for distribution across bins
function calculateTokensForDistribution(
pair: LBPair,
deltaIds: number[],
distribution: number[],
totalLiquidity: bigint
) {
let totalX = 0n;
let totalY = 0n;
deltaIds.forEach((delta, i) => {
const binId = pair.parameters.active_id + delta;
const binLiquidity = (totalLiquidity * BigInt(distribution[i])) / 100n;
if (delta < 0) {
// Below active - only Y needed
totalY += binLiquidity;
} else if (delta > 0) {
// Above active - only X needed
totalX += binLiquidity;
} else {
// Active bin - both needed (simplified 50/50)
totalX += binLiquidity / 2n;
totalY += binLiquidity / 2n;
}
});
return { totalX, totalY };
}
Using SDK Helpers
// Preview before adding liquidity
const pair = await sdk.Pair.getPair(pairAddress);
const bins = await sdk.Pair.getPairBins(pair, [activeId - 5, activeId + 5]);
// Check current reserves
bins.forEach((bin, index) => {
const binId = activeId - 5 + index;
console.log(`Bin ${binId}:`, {
currentX: bin.reserve_x,
currentY: bin.reserve_y
});
});
Active Bin Calculation
For the active bin, token ratio depends on position within the bin:
// Simplified active bin calculation
function getActiveBinAmounts(
totalLiquidity: bigint,
currentPrice: number
) {
// Price determines ratio (simplified)
// Real calculation uses bin position
const ratio = currentPrice / (1 + currentPrice);
const amountX = (totalLiquidity * BigInt(Math.floor(ratio * 1000))) / 1000n;
const amountY = totalLiquidity - amountX;
return { amountX, amountY };
}
Practical Example
// Planning liquidity for ETH/USDC
const activeId = pair.parameters.active_id;
const distribution = {
deltaIds: [-2, -1, 0, 1, 2],
weights: [20, 20, 20, 20, 20] // Even distribution
};
// Calculate requirements
const required = calculateTokensForDistribution(
pair,
distribution.deltaIds,
distribution.weights,
parseEther("1") // 1 ETH worth of liquidity
);
console.log("Need to prepare:", {
ETH: formatEther(required.totalX),
USDC: formatUnits(required.totalY, 6)
});
Important Notes
Always add buffer for slippage (1-2%)
Active bin requirements change with price
Use current bin reserves for accurate calculation
Consider gas costs for many bins
Common Patterns
// Add 5% buffer for safety
const buffer = 1.05;
const safeAmountX = totalX * BigInt(Math.ceil(buffer * 100)) / 100n;
const safeAmountY = totalY * BigInt(Math.ceil(buffer * 100)) / 100n;
Related Topics
Add Liquidity Overview - Understanding requirements
SPOT Distribution - Simple calculations
Slippage Protection - Handle price changes
Last updated