Calculate Output Amounts
Preview exact token amounts you'll receive before removing liquidity. Essential for setting expectations and avoiding surprises from price movements.
Prerequisites
Position ID to analyze
Understanding of bin reserves and fees
Current pair state data
Basic Calculation
// Get amounts for all bins in position
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
// Calculate total returns
const totals = amounts.reduce((sum, bin) => ({
x: sum.x + bin.amountX,
y: sum.y + bin.amountY
}), { x: 0n, y: 0n });
console.log("Will receive:", {
tokenX: formatUnits(totals.x, 18),
tokenY: formatUnits(totals.y, 6)
});
Understanding the Calculation
For each bin, you receive:
Your Amount = (Your Liquidity / Total Supply) × (Reserves + Fees)
The SDK's getPositionBinsAmount
handles this automatically.
Preview Specific Bins
// Calculate for selected bins only
const binsToRemove = [8388606, 8388607, 8388608];
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
const selectedAmounts = amounts
.filter(bin => binsToRemove.includes(bin.id))
.reduce((sum, bin) => ({
x: sum.x + bin.amountX,
y: sum.y + bin.amountY
}), { x: 0n, y: 0n });
console.log("Selected bins will return:", selectedAmounts);
Manual Calculation Method
import { getAmountOutOfBin } from '@ferra-labs/dlmm';
// For precise control
async function calculateBinReturns(
pair: LBPair,
positionId: string,
binId: number
) {
// Get position's liquidity in bin
const positionBins = await sdk.Position.getPositionBins(pair, positionId);
const positionLiquidity = positionBins.find(b => b.id === binId)?.liquidity || 0n;
// Get bin reserves and total supply
const reserves = await sdk.Pair.getPairReserves(pair);
const binReserve = reserves.find(r => r.id === binId);
const totalSupply = await getTotalSupply(pair, binId);
// Calculate output
return getAmountOutOfBin(binReserve, positionLiquidity, totalSupply);
}
Compare to Initial Investment
// Track profit/loss
const currentAmounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
const currentValue = {
x: currentAmounts.reduce((sum, b) => sum + b.amountX, 0n),
y: currentAmounts.reduce((sum, b) => sum + b.amountY, 0n)
};
// Compare to initial (stored elsewhere)
const pnl = {
tokenX: currentValue.x - initialDeposit.x,
tokenY: currentValue.y - initialDeposit.y
};
console.log("P&L:", pnl);
Include Price Impact
// Consider current price vs entry
const currentPrice = getPriceFromBinId(
pair.parameters.active_id,
Number(pair.binStep)
);
// Value in quote token
const totalValueUSD =
Number(totals.x) * currentPrice +
Number(totals.y);
console.log("Total value:", totalValueUSD);
Preview with Slippage
// Add safety margin for price movements
const slippage = 0.01; // 1%
const minAmounts = {
x: totals.x * BigInt(Math.floor((1 - slippage) * 1000)) / 1000n,
y: totals.y * BigInt(Math.floor((1 - slippage) * 1000)) / 1000n
};
console.log("Minimum expected (1% slippage):", minAmounts);
Common Patterns
Full Position Preview
async function previewFullRemoval(pair: LBPair, positionId: string) {
const amounts = await sdk.Position.getPositionBinsAmount(pair, positionId);
return {
totalX: amounts.reduce((sum, b) => sum + b.amountX, 0n),
totalY: amounts.reduce((sum, b) => sum + b.amountY, 0n),
binCount: amounts.length,
bins: amounts.map(b => ({
id: b.id,
amountX: b.amountX,
amountY: b.amountY
}))
};
}
Important Notes
Amounts include accumulated fees
Price changes affect token ratios
Calculation assumes no other trades
Always use recent data
Related Topics
Remove from Specific Bins - Execute removal
Position Value - Current worth
Calculate Position Fees - Fee portion
Get Position Bins - Check liquidity
Last updated