Slippage Protection
Set minimum output amounts to protect swaps from price movements between quote and execution. Essential for safe trading in volatile markets.
What is Slippage?
Slippage occurs when:
Price moves between quote and execution
Other trades consume liquidity
Network delays cause stale quotes
Protection ensures you receive at least a minimum amount.
Basic Implementation
// Calculate minimum output with slippage tolerance
function calculateMinimumOutput(
expectedOutput: bigint,
slippagePercent: number = 0.5 // 0.5% default
): bigint {
const slippageFactor = 10000 - Math.floor(slippagePercent * 100);
return (expectedOutput * BigInt(slippageFactor)) / 10000n;
}
// Usage
const expectedOut = await calculateSwapOutput(pair, amountIn, xtoy);
const minimumOut = calculateMinimumOutput(expectedOut, 1.0); // 1% slippage
Protected Swap Pattern
async function swapWithProtection(
pair: LBPair,
amountIn: bigint,
xtoy: boolean,
slippagePercent: number = 0.5
) {
// 1. Calculate expected output
const expectedOutput = await calculateSwapOutput(pair, amountIn, xtoy);
// 2. Set minimum acceptable
const minOutput = calculateMinimumOutput(expectedOutput, slippagePercent);
// 3. Build transaction with protection
const tx = new Transaction();
// Add swap
const [_, coinXOut, coinYOut] = await sdk.Pair.prepareSwap(
pair,
{ amount: amountIn, xtoy },
tx
);
// Add minimum check (pseudo-code - actual implementation varies)
const outputCoin = xtoy ? coinYOut : coinXOut;
tx.moveCall({
target: "0x2::coin::value",
arguments: [outputCoin],
// Assert minimum amount
});
return tx;
}
Dynamic Slippage
// Adjust slippage based on conditions
function getDynamicSlippage(
pair: LBPair,
tradeSize: bigint,
volatility: number
): number {
// Base slippage
let slippage = 0.3;
// Increase for large trades
const avgTradeSize = getAverageTradeSize(pair);
if (tradeSize > avgTradeSize * 10n) {
slippage += 0.5;
}
// Increase for volatile pairs
if (volatility > 0.05) { // 5% daily volatility
slippage += 0.5;
}
// Cap at reasonable maximum
return Math.min(slippage, 3.0);
}
Slippage by Asset Type
const SLIPPAGE_PRESETS = {
stable: 0.1, // USDC/USDT: 0.1%
bluechip: 0.5, // ETH/USDC: 0.5%
volatile: 2.0, // MEME/USDC: 2%
illiquid: 5.0 // Low liquidity: 5%
};
function getRecommendedSlippage(
tokenX: string,
tokenY: string
): number {
if (isStablePair(tokenX, tokenY)) return SLIPPAGE_PRESETS.stable;
if (isBluechipPair(tokenX, tokenY)) return SLIPPAGE_PRESETS.bluechip;
if (hasLowLiquidity(tokenX, tokenY)) return SLIPPAGE_PRESETS.illiquid;
return SLIPPAGE_PRESETS.volatile;
}
User-Friendly Display
interface SlippageSettings {
percent: number;
minOutput: bigint;
maxSlippage: bigint;
}
function calculateSlippageInfo(
expectedOutput: bigint,
slippagePercent: number
): SlippageSettings {
const minOutput = calculateMinimumOutput(expectedOutput, slippagePercent);
const maxSlippage = expectedOutput - minOutput;
return {
percent: slippagePercent,
minOutput,
maxSlippage
};
}
// Display to user
const info = calculateSlippageInfo(expectedOut, 1.0);
console.log(`Minimum received: ${formatUnits(info.minOutput, decimals)}`);
console.log(`Max slippage: ${formatUnits(info.maxSlippage, decimals)}`);
MEV Protection
// Tight slippage for MEV protection
function getMEVProtectedSlippage(
normalSlippage: number,
isMEVProne: boolean
): number {
if (isMEVProne) {
// Tighter tolerance for sandwich protection
return Math.min(normalSlippage * 0.5, 0.3);
}
return normalSlippage;
}
// High-value trades need extra protection
const needsMEVProtection = tradeValueUSD > 10000;
const slippage = getMEVProtectedSlippage(1.0, needsMEVProtection);
Handling Failures
async function swapWithRetry(
pair: LBPair,
amountIn: bigint,
xtoy: boolean,
maxRetries: number = 3
) {
let slippage = 0.5;
for (let i = 0; i < maxRetries; i++) {
try {
return await swapWithProtection(pair, amountIn, xtoy, slippage);
} catch (error) {
if (error.message.includes("Slippage exceeded")) {
// Increase tolerance and retry
slippage = Math.min(slippage * 1.5, 5.0);
console.log(`Retry with ${slippage}% slippage`);
} else {
throw error;
}
}
}
throw new Error("Max retries exceeded");
}
Best Practices
Default Settings
0.5% for normal conditions
0.1% for stable pairs
2-5% for volatile assets
User Control
Allow manual adjustment
Show impact clearly
Warn on high settings
Auto-adjust
Monitor recent volatility
Check liquidity depth
Consider trade size
Related Topics
Calculate Swap Output - Get expected amounts
Price Impact - Understand trade effects
Execute Swap - Perform protected swaps
Last updated