ChainScore Labs
All Guides

Common Slippage and MEV-Related Vulnerabilities

LABS

Common Slippage and MEV-Related Vulnerabilities

Chainscore © 2025

Core Concepts and Attack Vectors

Foundational knowledge of the mechanisms and adversarial strategies that lead to value extraction in decentralized trading.

Slippage Tolerance

Slippage tolerance is the maximum acceptable price deviation a user sets for a trade. It is a critical parameter in AMMs.

  • Protects against front-running by setting a cap on price impact.
  • If exceeded due to a large pending trade, the transaction reverts.
  • A high tolerance increases vulnerability to sandwich attacks, while a low one causes frequent failures.

Sandwich Attack

A sandwich attack is a form of MEV where an attacker exploits a visible pending transaction.

  • The attacker front-runs the victim's buy order, then back-runs it with a sell.
  • Profits from the artificial price movement created.
  • Requires low-latency bots and is most effective on high-slippage trades in liquid pools.

Front-Running

Front-running is the act of placing a transaction ahead of a known future transaction to profit from its execution.

  • Can be generalized (any profitable opportunity) or targeted (specific user trades).
  • Executed by bots monitoring the public mempool.
  • Increases gas costs for users and distorts fair price discovery on-chain.

Mempool

The mempool is a node's holding area for broadcasted, unconfirmed transactions. It is the primary data source for MEV.

  • Transactions are visible to searchers and bots before block inclusion.
  • Its public nature is the root cause of many MEV vulnerabilities.
  • Private transaction relays (e.g., Flashbots) aim to mitigate this exposure.

Price Impact

Price impact is the change in an asset's price caused by executing a trade against an AMM's liquidity pool.

  • Directly proportional to trade size relative to pool depth.
  • High price impact leads to significant slippage and worse execution.
  • Attackers exploit predictable high-impact trades to execute profitable MEV strategies.

Back-Running

Back-running involves placing a transaction immediately after a target transaction to capitalize on its state changes.

  • Common in arbitrage, where a bot profits from price discrepancies after a large trade.
  • Also used in liquidation bots that trigger after a loan becomes undercollateralized.
  • Less harmful than front-running but still extracts value from user actions.

Vulnerability Categories and Examples

Understanding Slippage Risks

Slippage is the difference between the expected price of a trade and the executed price. In volatile markets or with large orders, this can lead to significant losses. The primary risk is front-running, where bots exploit public mempools to execute trades ahead of yours, worsening your price.

Key Attack Vectors

  • Sandwich Attacks: A bot sees your pending swap on a DEX like Uniswap, places a buy order before it to inflate the price, then sells after your trade executes, profiting from the artificial price movement at your expense.
  • Liquidity Manipulation: In pools with low liquidity, a large trade can drastically move the price. Attackers can drain liquidity just before your transaction or exploit the price impact for arbitrage.
  • Oracle Price Discrepancies: When a protocol uses a lagging price oracle, an attacker can execute a trade on a faster DEX, causing the oracle to update to a worse price for subsequent protocol users.

Example Scenario

When swapping 100 ETH for USDC on a low-liquidity pool, you might expect a price of $3,000 per ETH. A bot detects your transaction, buys ETH first, causing your swap to execute at $2,950, and then sells the ETH it bought, netting a profit from your slippage.

Anatomy of a Sandwich Attack

Process overview

1

Identify a Pending Victim Transaction

The attacker monitors the mempool for a profitable target.

Detailed Instructions

Attackers use mempool surveillance tools like Flashbots' mev-inspect or private RPC endpoints to scan for pending transactions. The primary target is a large DEX swap order (e.g., a 100 ETH for USDC swap on Uniswap V3) that will significantly move the market price due to its size relative to pool liquidity. The attacker analyzes the transaction's slippage tolerance parameter; a high tolerance (e.g., 5%) indicates the user is willing to accept a worse price, creating a larger profit window. The goal is to find a transaction where the expected price impact exceeds the victim's slippage, ensuring the sandwiched transaction will still be valid.

  • Sub-step 1: Filter the mempool for swapExactTokensForTokens or similar function calls on major DEX routers.
  • Sub-step 2: Simulate the transaction locally to calculate its expected price impact on the target pool.
  • Sub-step 3: Confirm the victim's transaction has a high gas price, indicating it is likely to be included in the next block.
javascript
// Example pseudo-logic for identifying a target const targetTx = mempool.find(tx => tx.to === UNISWAP_V3_ROUTER && tx.functionName === 'exactInputSingle' && calculatePriceImpact(tx) > 2.0 // Impact greater than 2% );

Tip: Attackers often target new token launches or low-liquidity pools where large swaps have a more pronounced effect.

2

Front-Run with a Buy Order

The attacker executes a transaction to buy the asset before the victim.

Detailed Instructions

Using a high-priority gas auction, the attacker submits their own swap transaction with a higher gas price than the victim's to ensure it is mined first. This transaction buys the same asset the victim is buying (e.g., USDC), driving up its price in the target liquidity pool. The attacker's capital must be sufficient to meaningfully shift the reserves ratio. For instance, if the victim is swapping 100 ETH for USDC in a 10,000 ETH / 30M USDC pool, the attacker might front-run with a 50 ETH buy order. This increases the price of ETH in the pool from 3000 USDC to, for example, 3025 USDC, based on the constant product formula x * y = k.

  • Sub-step 1: Construct a swap transaction on the same DEX pair as the victim.
  • Sub-step 2: Set the transaction's maxPriorityFeePerGas and maxFeePerGas to outbid the victim's transaction.
  • Sub-step 3: Submit the transaction via a private relay or a builder to avoid being front-run themselves.
solidity
// Simplified interface for a swap call interface IUniswapV3Router { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; // Slippage control uint160 sqrtPriceLimitX96; } function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); }

Tip: The amountOutMinimum in the attacker's front-run is typically set to 0, as their goal is execution, not price protection.

3

Allow Victim Transaction to Execute

The victim's swap occurs at the now-inflated price.

Detailed Instructions

The victim's transaction, which was originally pending, is now mined immediately after the attacker's front-run. Due to the altered pool state, the victim receives significantly less output than expected. If the victim's swap had a 5% slippage tolerance, their transaction will still succeed as long as the price they receive is within that bound. Continuing the example, the victim intended to swap 100 ETH at ~3000 USDC each for 300,000 USDC. After the front-run, the price is ~3025 USDC. Their 100 ETH now yields approximately 297,500 USDC, a loss of 2,500 USDC (or ~0.83%) compared to the original expectation, which is captured as profit for the attacker in the next step. This step requires precise timing; the attacker's and victim's transactions must be in consecutive positions within the same block.

  • Sub-step 1: The block builder includes both the attacker's front-run and the victim's transaction in the prescribed order.
  • Sub-step 2: The victim's contract call executes, interacting with the manipulated pool reserves.
  • Sub-step 3: The DEX's AMM formula calculates the victim's output amount based on the new, worse exchange rate.
solidity
// The victim's transaction executes the same function, but with worse pricing // Pool state post-front-run: more ETH, less USDC. // Constant product k is now higher, meaning less USDC per ETH. uint256 amountOut = getAmountOut(victimAmountIn, reserveIn, reserveOut); // amountOut is lower than in the original simulated state.

Tip: The victim's effective slippage is the difference between the expected price and the execution price, which must be less than their amountOutMinimum parameter for the tx to succeed.

4

Back-Run with a Sell Order

The attacker sells the asset back to profit from the price reversion.

Detailed Instructions

Immediately after the victim's swap, the attacker executes the final back-run transaction. They sell the asset they purchased in step 2 (e.g., USDC) back into the base asset (e.g., ETH). The victim's large purchase has further increased the price of the bought asset, so when the attacker sells, they receive more of the base asset than they started with. The profit is the difference between the initial and final ETH balance, minus gas costs. In our example, the attacker bought USDC with 50 ETH, the victim bought more USDC, and then the attacker sells their USDC back for perhaps 50.5 ETH—a net gain of 0.5 ETH. This step relies on the victim's trade pushing the price in a predictable direction to facilitate a profitable reversion.

  • Sub-step 1: Construct the reverse swap transaction, selling the acquired output token back to the input token.
  • Sub-step 2: Ensure the back-run transaction is positioned directly after the victim's in the block sequence.
  • Sub-step 3: Submit the transaction bundle (front-run, victim, back-run) to a block builder via a private channel like Flashbots Protect.
javascript
// Calculating approximate profit for the attacker const initialAttackerETH = 50; const attackerUSCObtained = swap(initialAttackerETH, 'ETH', 'USDC'); // Front-run // Victim swap executes here... const finalAttackerETH = swap(attackerUSCObtained, 'USDC', 'ETH'); // Back-run const profit = finalAttackerETH - initialAttackerETH - totalGasCost; console.log(`Sandwich profit: ${profit} ETH`);

Tip: The entire attack bundle must be atomic; if any part fails, the attacker risks significant losses, so simulations are run beforehand.

5

Analyze the Economic Outcome

Calculate the attacker's profit and the victim's loss.

Detailed Instructions

The success of the sandwich attack is measured by the net profit for the attacker, which is directly extracted from the victim's swap. The profit is calculated as: (Final Asset Balance - Initial Asset Balance) - Total Gas Costs. The victim's loss is the negative slippage they experienced, quantified as (Expected Output - Actual Output). In sophisticated attacks, bots perform real-time profitability simulations before submitting the bundle, ensuring the expected profit exceeds a threshold (e.g., >0.1 ETH) and covers potential gas wars with other searchers. Tools like EigenPhi or Etherscan can be used post-hoc to analyze such attacks by looking for three tightly sequenced transactions in a block that trade the same pair, with the middle transaction belonging to a different address.

  • Sub-step 1: Sum the gas used by the front-run and back-run transactions, multiplied by the effective gas price paid.
  • Sub-step 2: Subtract the total gas cost from the gross profit in the asset's base terms (e.g., ETH).
  • Sub-step 3: Compare the victim's transaction receipt amountOut to a simulated amountOut based on the block state prior to the attack.
solidity
// Post-attack analysis snippet concept uint256 victimExpectedOutput = simulateSwap(victimTx, blockNumber - 1); uint256 victimActualOutput = getTxReceipt(victimTx).logs[0].data; // Actual output from event uint256 victimLoss = victimExpectedOutput - victimActualOutput; // This loss approximates the attacker's gross profit before fees.

Tip: Not all victim loss translates to attacker profit; some value is lost to liquidity provider fees and permanent price impact.

Defensive Strategy Comparison

Comparison of common user strategies to mitigate slippage and MEV risks.

Defensive FeaturePrivate RPCsSlippage ToleranceMEV-Protected RPCs

Primary Protection

Transaction privacy

Price impact cap

Full transaction bundle privacy

Typical Latency

100-200ms

N/A (wallet setting)

300-500ms

Cost Premium

0.001-0.01 ETH

0

0.005-0.05 ETH

Frontrunning Resistance

High

None

Very High (via encryption)

Sandwich Attack Resistance

Moderate

Partial (via limit)

High

Implementation Complexity

Medium (RPC endpoint swap)

Low (UI slider)

Medium (RPC endpoint swap)

Failure Mode

RPC downtime

Failed tx if limit exceeded

Bundle simulation failure

Protocol-Level Mitigations

Technical strategies implemented at the smart contract or consensus layer to reduce exposure to slippage and MEV.

Time-Weighted Average Price (TWAP) Oracles

TWAP oracles calculate asset prices based on a historical average over a set period, dampening the impact of short-term price manipulation.

  • Uses cumulative price data from an AMM like Uniswap V2.
  • Requires a minimum observation window (e.g., 30 minutes).
  • This matters because it provides a manipulation-resistant price feed for lending protocols and derivatives, preventing instantaneous oracle attacks that cause liquidations.

Batch Auctions

Batch auctions aggregate orders and clear them at a single, uniform clearing price discovered after the batch closes.

  • Orders are submitted off-chain and settled on-chain in discrete intervals.
  • Eliminates intra-block ordering advantages for searchers.
  • This matters for fair price discovery in DEXs like CowSwap, preventing front-running and sandwich attacks by making transaction order within a batch irrelevant.

Commit-Reveal Schemes

Commit-reveal schemes separate the submission of a transaction's intent from its execution across two separate phases.

  • Users first commit a hash of their trade details with a deposit.
  • In a later block, they reveal the actual transaction data.
  • This matters by hiding strategic information from block builders until it's too late to front-run, protecting limit orders and governance votes from MEV extraction.

Private Transaction Pools

Private transaction pools (e.g., Flashbots Protect, Taichi Network) allow users to submit transactions directly to builders without exposing them to the public mempool.

  • Transactions bypass the open, competitive mempool.
  • Builders include them in blocks without revealing details to general searchers.
  • This matters for reducing the surface for sandwich attacks and failed arbitrage, providing predictable execution for large trades and contract deployments.

MEV-Aware AMM Design

MEV-aware AMM design incorporates mechanisms like just-in-time liquidity and LP fee adjustments to internalize or redistribute MEV.

  • Uniswap V4 hooks can allow LPs to react to arb opportunities.
  • Dynamic fees can increase during volatile periods to compensate LPs for adverse selection.
  • This matters because it realigns incentives, turning extractable MEV into protocol revenue or LP yield, mitigating the 'loss-versus-rebalancing' problem.

Proposer-Builder Separation (PBS)

Proposer-Builder Separation is a consensus-layer architecture where block proposal and construction are performed by separate entities.

  • Builders compete to create the most profitable block bundle.
  • Proposers (validators) simply choose the highest-paying header.
  • This matters for Ethereum's roadmap as it democratizes MEV revenue, reduces validator centralization risks, and allows for more sophisticated censorship resistance techniques like inclusion lists.

Practical Guidance for Users and Developers

Process overview

1

Analyze and Simulate Transactions Before Signing

Use tools to preview transaction outcomes and identify potential MEV extraction.

Detailed Instructions

Before signing any transaction, especially swaps or liquidity provisions, use a transaction simulator to preview the exact outcome. This reveals the final token amounts you will receive, including any slippage or unexpected fees. For developers, integrate simulation into your dApp's frontend using services like Tenderly or OpenZeppelin Defender.

  • Sub-step 1: For users, paste your pending transaction hash into a block explorer like Etherscan's "State Override" feature or a dedicated MEV dashboard like EigenPhi.
  • Sub-step 2: Check the simulated effective gas price and the final token delta; compare it to the quoted price from your wallet.
  • Sub-step 3: Verify if any unexpected internal transfers or contract calls appear, which could indicate a sandwich attack or a drainer contract.
javascript
// Example using ethers.js to simulate a swap via Tenderly const simulation = await tenderly.simulateTransaction({ from: userAddress, to: routerAddress, data: swapCalldata, value: ethers.utils.parseEther('1.0') }); console.log('Simulated output amount:', simulation.transaction.status);

Tip: Always simulate with a slight block delay to account for frontrunning; bots often act in the same block your transaction is pending.

2

Implement Slippage Tolerance and Deadline Controls

Configure robust parameters to protect against price movement and stale transactions.

Detailed Instructions

Set a strict, absolute slippage tolerance (e.g., 0.5%) rather than using a default like 1-3%. For developers, enforce maximum limits in your smart contract interfaces. Always pair this with a short transaction deadline (e.g., 20 minutes) to prevent miners from holding and executing your transaction at a worse future price.

  • Sub-step 1: In your wallet (e.g., MetaMask), manually set the slippage percentage on the swap confirmation screen; avoid using "auto" settings.
  • Sub-step 2: For contract interactions, encode the deadline parameter as a UNIX timestamp block.timestamp + 1200 in your transaction calldata.
  • Sub-step 3: Monitor the mempool for identical trades with higher gas fees that could be frontrunning you; consider canceling and resubmitting.
solidity
// Example slippage and deadline check in a Solidity router function function swapExactTokensForTokens( uint amountIn, uint amountOutMin, // Enforce slippage tolerance here address[] calldata path, address to, uint deadline // Enforce transaction deadline here ) external { require(block.timestamp <= deadline, 'EXPIRED'); // ... swap logic ... require(amounts[amounts.length - 1] >= amountOutMin, 'INSUFFICIENT_OUTPUT_AMOUNT'); }

Tip: For large trades, calculate slippage based on pool depth using the constant product formula x * y = k to estimate price impact before setting tolerance.

3

Utilize MEV-Protection Tools and RPC Endpoints

Route transactions through services that offer frontrunning protection and private mempools.

Detailed Instructions

Mitigate sandwich attacks by submitting transactions through MEV-protected RPC endpoints like Flashbots Protect, Eden Network, or the native eth_sendPrivateTransaction RPC call. These services bypass the public mempool, reducing visibility to searcher bots. For developers, integrate these endpoints as a fallback in your wallet connection library.

  • Sub-step 1: Configure your wallet (e.g., MetaMask) to use a custom RPC URL from Flashbots Protect (https://rpc.flashbots.net) for sensitive transactions.
  • Sub-step 2: When building a dApp, use a library like web3.py or ethers.js to send a private transaction bundle directly to a builder.
  • Sub-step 3: Verify the transaction was included in a block by checking for the absence of preceding/following arbitrage transactions in the same block.
python
# Example using web3.py to send a private transaction via Flashbots from flashbots import flashbot from eth_account import Account w3 = Web3(Web3.HTTPProvider('https://mainnet.infura.io/v3/YOUR_KEY')) flashbots = flashbot(w3, Account.from_key('searcher_key')) signed_tx = w3.eth.account.sign_transaction(transaction_dict, private_key) bundle = [{'signed_transaction': signed_tx.rawTransaction}] flashbots.send_bundle(bundle, target_block_number)

Tip: Private transactions may have higher inclusion latency. Always set a reasonable gas premium (e.g., 2-3 Gwei) even when using private channels to ensure miner incentive.

4

Audit and Harden Smart Contract Logic

Eliminate on-chain patterns that expose users to predictable and exploitable transaction ordering.

Detailed Instructions

Review contract functions for MEV leakage where outcome predictability allows extraction. Common vulnerabilities include price oracle updates that are view functions, unbounded loops over user arrays, and state changes based on predictable block variables like block.timestamp or blockhash. Implement commit-reveal schemes or threshold checks.

  • Sub-step 1: Use static analysis tools like Slither or Mythril to detect patterns such as tx.origin usage or expensive operations in loops that could be manipulated.
  • Sub-step 2: For AMMs or lending protocols, ensure critical price updates (e.g., TWAP oracle updates) require a minimum time delta or are permissioned.
  • Sub-step 3: Add a frontrunning resistance modifier that checks block.coinbase or includes a random seed from a trusted oracle to add uncertainty.
solidity
// Example modifier adding a commit-reveal scheme for sensitive actions modifier frontrunResisted(bytes32 _commitment) { require(commitments[msg.sender] == _commitment, "Commitment mismatch"); require(block.timestamp >= revealTime[msg.sender], "Reveal time not reached"); // Clear commitment after use delete commitments[msg.sender]; _; } // Users first submit a hash of their action + a secret, then reveal later.

Tip: For governance or voting contracts, consider using vote escrow models or batch processing to aggregate actions into a single block, reducing granular MEV opportunities.

5

Monitor and Respond to Live Network Conditions

Actively track mempool activity and gas markets to time transactions optimally.

Detailed Instructions

Network congestion and gas price volatility are primary enablers of MEV. Use real-time dashboards to monitor base fee trends and pending transaction volumes. Schedule high-value transactions during periods of low activity, typically weekend nights UTC, to reduce competition with bots.

  • Sub-step 1: Use a gas tracker like Etherscan's Gas Tracker, GasNow, or the eth_gasPrice RPC call to get current base fee and priority fee estimates.
  • Sub-step 2: Monitor the mempool for large pending swaps or liquidations that could indicate imminent volatility; tools like Mempool.space provide visualizations.
  • Sub-step 3: Set up alerts for sudden base fee spikes (e.g., >100 Gwei) using a service like Telegram bot from Blocknative or EigenPhi to pause automated systems.
bash
# Example using curl to fetch current gas estimates from Etherscan API curl "https://api.etherscan.io/api?module=gastracker&action=gasoracle&apikey=YOUR_KEY" # Response includes SafeGasPrice, ProposeGasPrice, FastGasPrice for different inclusion times.

Tip: For developers running keepers or bots, implement a dynamic gas pricing strategy that uses an EIP-1559 fee model, adjusting maxFeePerGas and maxPriorityFeePerGas based on a percentile of recent blocks.

SECTION-FAQ

Frequently Asked Questions

Ready to Start Building?

Let's bring your Web3 vision to life.

From concept to deployment, ChainScore helps you architect, build, and scale secure blockchain solutions.