# 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

```typescript
// 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

```typescript
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

```typescript
// 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

```typescript
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

```typescript
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

```typescript
// 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

```typescript
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

1. **Default Settings**
   * 0.5% for normal conditions
   * 0.1% for stable pairs
   * 2-5% for volatile assets
2. **User Control**
   * Allow manual adjustment
   * Show impact clearly
   * Warn on high settings
3. **Auto-adjust**
   * Monitor recent volatility
   * Check liquidity depth
   * Consider trade size

### Related Topics

* [Calculate Swap Output](https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/calculate-swap-output) - Get expected amounts
* [Price Impact](https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/price-impact) - Understand trade effects
* [Execute Swap](https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/execute-swap) - Perform protected swaps
