Skip to main content

front-running-patterns

Front-running and MEV protection patterns for Solidity protocols. Use when designing swaps, auctions, NFT mints, or any transaction-ordering-dependent logic. Covers sandwich attacks, commit-reveal, Flashbots, slippage protection, and deadline parameters.

Ir a la instalación

Datos de origen

Repositorio
ccashwell/evm-cortex
Última actividad en el origen
10 de abril de 2026 a las 16:31
Idioma detectado de SKILL.md
inglés
Estrellas
131
Forks
18

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
front-running-patterns
description
Front-running and MEV protection patterns for Solidity protocols. Use when designing swaps, auctions, NFT mints, or any transaction-ordering-dependent logic. Covers sandwich attacks, commit-reveal, Flashbots, slippage protection, and deadline parameters.
# Front-Running & MEV Patterns ## What Is MEV? Maximal Extractable Value (MEV) is the profit extractable by reordering, inserting, or censoring transactions within a block. Validators and searchers extract MEV through: - **Sandwich attacks**: front-run + back-run a victim's swap - **Front-running**: copy a profitable transaction and get it mined first - **Back-running**: execute immediately after a target transaction - **Liquidation racing**: compete to liquidate undercollateralized positions - **Just-in-Time (JIT) liquidity**: add/remove concentrated liquidity around a trade ## Sandwich Attacks on Swaps ``` 1. Victim submits swap: buy 100 ETH of TOKEN 2. Attacker front-runs: buys TOKEN, pushing price up 3. Victim's swap executes at worse price 4. Attacker back-runs: sells TOKEN at inflated price ``` ### Defense: Slippage Protection ```solidity error SlippageExceeded(uint256 amountOut, uint256 minAmountOut); function swap( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, // user sets minimum acceptable output uint256 deadline ) external returns (uint256 amountOut) { if (block.timestamp > deadline) revert Expired(); amountOut = _executeSwap(tokenIn, tokenOut, amountIn); if (amountOut < minAmountOut) { revert SlippageExceeded(amountOut, minAmountOut); } emit Swapped(msg.sender, tokenIn, tokenOut, amountIn, amountOut); } ``` ### Defense: Deadline Parameters Without deadlines, pending transactions can be held in the mempool and executed later at unfavorable prices. ```solidity modifier beforeDeadline(uint256 deadline) { if (block.timestamp > deadline) revert TransactionExpired(deadline, block.timestamp); _; } function addLiquidity( uint256 amount0, uint256 amount1, uint256 minLiquidity, uint256 deadline ) external beforeDeadline(deadline) returns (uint256 liquidity) { // ... } ``` ## Commit-Reveal Scheme For auctions, NFT mints, or any scenario where knowing the action gives an advantage. ```solidity uint256 public constant COMMIT_PERIOD = 1 hours; uint256 public constant REVEAL_PERIOD = 30 minutes; uint256 public constant MIN_COMMIT_AGE = 2 minutes; // at least 1 block gap mapping(address => bytes32) public commitments; mapping(address => uint256) public commitTimestamps; function commit(bytes32 hash) external { commitments[msg.sender] = hash; commitTimestamps[msg.sender] = block.timestamp; emit Committed(msg.sender); } function reveal(uint256 bid, bytes32 salt) external { uint256 commitTime = commitTimestamps[msg.sender]; if (commitTime == 0) revert NoCommitment(); if (block.timestamp < commitTime + MIN_COMMIT_AGE) revert RevealTooEarly(); if (block.timestamp > commitTime + COMMIT_PERIOD + REVEAL_PERIOD) revert RevealExpired(); bytes32 expected = keccak256(abi.encodePacked(msg.sender, bid, salt)); if (commitments[msg.sender] != expected) revert InvalidReveal(); commitments[msg.sender] = bytes32(0); _processBid(msg.sender, bid); } ``` ## Flashbots Protect / Private Mempool Transactions submitted through Flashbots or similar services skip the public mempool, making them invisible to sandwich bots. ```typescript // Frontend integration: submit via Flashbots Protect RPC const provider = new ethers.JsonRpcProvider("https://rpc.flashbots.net"); const tx = await signer.sendTransaction({ to: routerAddress, data: encodedSwap, // Flashbots Protect: not visible in public mempool }); ``` **Limitations**: - Doesn't protect against validator-level MEV - Transaction may take longer to be included - Not all chains support Flashbots ## Transaction Ordering Dependence Any logic where the outcome depends on transaction order is vulnerable. ```solidity // VULNERABLE: first caller wins function claim(uint256 tokenId) external { require(!claimed[tokenId], "Already claimed"); claimed[tokenId] = true; _mint(msg.sender, tokenId); } // SAFER: randomized or committed selection // Use commit-reveal or Chainlink VRF for fair selection ``` ## MEV Protection for AMMs ### Concentrated Liquidity JIT Protection ```solidity // Track when liquidity was added to prevent JIT manipulation mapping(uint256 => uint256) public positionMintBlock; function mint(uint256 positionId, ...) external { positionMintBlock[positionId] = block.number; // ... } function collectFees(uint256 positionId) external { // Require liquidity existed for at least N blocks before fee collection if (block.number - positionMintBlock[positionId] < MIN_LIQUIDITY_BLOCKS) { revert LiquidityTooRecent(); } // ... } ``` ## Price Update Front-Running Oracle price updates can be front-run by MEV searchers who see the update in the mempool. ``` 1. Chainlink oracle update TX: ETH price changes from $2000 → $2100 2. Attacker front-runs: opens leveraged long at $2000 3. Oracle updates: price becomes $2100 4. Attacker closes: profit from $100 move with leverage ``` **Defense**: - Time-weighted or multi-block oracle consumption - Execution delay after position changes - Fee charged on rapid open/close cycles ## MEV Protection Checklist - [ ] Slippage protection (`minAmountOut`) on all swap functions - [ ] Deadline parameter on all time-sensitive operations - [ ] Commit-reveal for auctions, mints, and competitive actions - [ ] Frontend uses private mempool (Flashbots Protect) for swaps - [ ] No first-come-first-served mechanisms without mitigation - [ ] Oracle updates not exploitable via price front-running - [ ] Liquidity operations protected against JIT manipulation - [ ] Fee structures disincentivize atomic open/close (anti-sandwich) - [ ] Price impact limits on single-transaction trades
Ver en GitHub