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.

Aller à l'installation

Informations de source

Dépôt
ccashwell/evm-cortex
Dernière activité de la source
10 avril 2026 à 16:31
Langue détectée de SKILL.md
anglais
Étoiles
131
Forks
18

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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
Voir sur GitHub