# 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](/integration/dlmm/typescript-sdk/swap-operations/calculate-swap-output.md) - Get expected amounts
* [Price Impact](/integration/dlmm/typescript-sdk/swap-operations/price-impact.md) - Understand trade effects
* [Execute Swap](/integration/dlmm/typescript-sdk/swap-operations/execute-swap.md) - Perform protected swaps


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ferra.ag/integration/dlmm/typescript-sdk/swap-operations/slippage-protection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
