Система виявлення sandwich та front-running: захист DeFi від вилучення цінності
Уявіть: користувач відправляє swap на Uniswap з slippage 5%, а бот-перехоплювач витягує 3% вартості угоди. Для протоколу це не лише репутаційні ризики — регулярні MEV-атаки знижують TVL на 15-20% за квартал. Прямі фінансові втрати від sandwich-атак на протоколах з TVL > $10 млн можуть перевищувати $500 000 на рік. Щорічні збитки від MEV на Ethereum перевищують $1 млрд. Ми розробили систему, яка постфактум аналізує ланцюжки транзакцій та проактивно блокує MEV-патерни. Система використовує комбінацію публічного та private mempool даних, що підвищує точність детекції до 85%. Наш досвід — понад 5 років у блокчейн-розробці та десятки реалізованих протоколів. Замовте безкоштовний аудит вашого протоколу — ми виявимо вразливості та запропонуємо рішення.
Чому MEV-атаки небезпечні для DeFi-протоколів?
Типова ситуація: користувач відправляє swap on Uniswap з slippage 5%, бот-searcher перехоплює транзакцію в mempool, front-run піднімає ціну, жертва втрачає 3-4% вартості угоди. Для протоколу це не лише репутаційні ризики — регулярні атаки знижують TVL на 15-20% за квартал, оскільки користувачі йдуть на захищені платформи. Ми запобігаємо цьому. Згідно з Flashbots MEV-Share, близько 90% всіх MEV-транзакцій проходять через private mempool.
Типи MEV-атак, які ми детектуємо
- Sandwich attack (класика): три транзакції в одному блоці: front-run купівля — жертва — back-run продаж з тим же атакуючим. Ідентифікація за патерном
sender == back.senderта інвертованим токенам. Типовий збиток — 0.3–0.5% від суми угоди. - Liquidation front-running: на Aave або Compound боти бачать позицію під ліквідацією і змагаються за нагороду. Більш небезпечний варіант — flash loan маніпуляція оракулом.
- Arbitrage MEV: корисне явище, арбітраж вирівнює ціни на DEX. Ми детектуємо його для розуміння потоків ліквідності.
- JIT liquidity: в Uniswap v3 атакуючий додає концентровану ліквідність прямо перед великим swap і забирає комісію, завдаючи шкоди чесним LP.
- Time-bandit attack: рідкісна загроза, реорганізація ланцюга заради вилучення MEV з минулих блоків. На Ethereum post-Merge практично неможлива економічно.
Як детектувати MEV через mempool у реальному часі?
Використовуємо API boost-relay.flashbots.net для історичних даних про MEV-bid. Для детального вмісту — MEV-Share API, де builder'и публікують bundle post-execution. Це дає доступ до даних, які не видно в публічному mempool.
Підключаємося через eth_subscribe("pendingTransactions"):
import { createPublicClient, webSocket } from 'viem'; const client = createPublicClient({ transport: webSocket('wss://mainnet.infura.io/ws/v3/KEY'), }); const unwatch = client.watchPendingTransactions({ onTransactions: async (hashes) => { for (const hash of hashes) { const tx = await client.getTransaction({ hash }); if (tx && isLargeSwap(tx)) { await analyzeMevRisk(tx); } } }, }); Однак більшість MEV-ботів використовує private mempool (Flashbots bundles). Публічний mempool бачить лише частину картини — приблизно 20-30% всіх MEV-транзакцій. Тому ми комбінуємо його з даними MEV-Share, що підвищує точність детекції до 85%.
Детекція sandwich: алгоритми та симуляція
from dataclasses import dataclass from typing import Optional import pandas as pd @dataclass class SwapEvent: tx_hash: str block_number: int tx_index: int sender: str token_in: str token_out: str amount_in: int amount_out: int pool: str def detect_sandwiches(swaps_in_block: list[SwapEvent]) -> list[dict]: sandwiches = [] by_pool = {} for swap in swaps_in_block: by_pool.setdefault(swap.pool, []).append(swap) for pool, pool_swaps in by_pool.items(): pool_swaps.sort(key=lambda s: s.tx_index) for i, front in enumerate(pool_swaps[:-2]): victim = pool_swaps[i + 1] back = pool_swaps[i + 2] is_sandwich = ( front.sender == back.sender and front.sender != victim.sender and front.token_in == victim.token_in and back.token_in == front.token_out and back.token_out == front.token_in ) if is_sandwich: attacker_profit = back.amount_out - front.amount_in sandwiches.append({ 'front_tx': front.tx_hash, 'victim_tx': victim.tx_hash, 'back_tx': back.tx_hash, 'attacker': front.sender, 'pool': pool, 'attacker_profit_tokens': attacker_profit, 'block': front.block_number, }) return sandwiches Для точного розрахунку збитку симулюємо транзакцію жертви на стані блока до front-run. Різниця між реальним amount_out та симульованим — MEV, вилучене у користувача.
Як захистити протокол від MEV: приклад реалізації
Commit-reveal для чутливих операцій
Користувач публікує хеш транзакції, потім відкриває параметри. Атакуючий не знає деталі до reveal.
contract CommitRevealSwap { mapping(bytes32 => uint256) public commits; uint256 public constant REVEAL_DELAY = 2; function commit(bytes32 commitment) external { commits[commitment] = block.number; } function reveal( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, bytes32 salt ) external { bytes32 commitment = keccak256( abi.encodePacked(msg.sender, tokenIn, tokenOut, amountIn, minAmountOut, salt) ); require(commits[commitment] != 0, "No commit"); require(block.number >= commits[commitment] + REVEAL_DELAY, "Too early"); delete commits[commitment]; // виконати swap } } TWAP oracle замість spot price
Uniswap v3 TWAP не можна зсунути за один блок — ідеально проти оракульних маніпуляцій.
function getTWAP(address pool, uint32 secondsAgo) public view returns (uint256 price) { uint32[] memory secondsAgos = new uint32[](2); secondsAgos[0] = secondsAgo; secondsAgos[1] = 0; (int56[] memory tickCumulatives,) = IUniswapV3Pool(pool).observe(secondsAgos); int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; int24 arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(secondsAgo))); price = TickMath.getSqrtRatioAtTick(arithmeticMeanTick); } Порівняння методів захисту від MEV
| Метод | Захист від sandwich | Складність інтеграції | Вплив на UX |
|---|---|---|---|
| Tight slippage + deadline | Знижує втрати на 50-70% | Низька | Високий (користувач вказує точні параметри) |
| Commit-reveal | Повний захист (100%) | Середня | Середній (затримка на 2 блоки) |
| MEV Blocker (Flashbots Protect) | Запобігає front-run на 99% | Низька (зміна RPC) | Немає |
| TWAP oracle | Стійкий до flash loan | Середня | Немає |
Commit-reveal схема в 10 разів надійніша за простий tight slippage проти sandwich-атак, але потребує зміни UX.
Процес роботи та терміни
| Етап | Результат |
|---|---|
| Аналіз поточних контрактів | Звіт про вразливості до MEV |
| Розробка детектора | Інтегрований модуль детекції з API |
| Налаштування дашборда | Дашборд з візуалізацією атак |
| Інтеграція захисту | Підключення MEV Blocker / commit-reveal |
| Навчання команди | Документація та воркшоп |
Терміни:
- Базова детекція sandwich post-hoc: 4-6 тижнів.
- Повна система з real-time моніторингом та дашбордом: 10-16 тижнів.
- Інтеграція Flashbots Protect у frontend: 1-2 дні.
Стек:
- Backend: Python (detection engine), TypeScript (real-time mempool), PostgreSQL, Dune Analytics.
- Для точних симуляцій використовуємо self-hosted Erigon або Alchemy Archive.
Замовте аудит вашого протоколу для виявлення вразливостей до MEV. Зв'яжіться з нами для впровадження системи детекції — ми безкоштовно оцінимо ризики та запропонуємо оптимальне рішення. Отримайте консультацію вже сьогодні.







