Интеграция MEV Blocker в dApp: защита от фронтраннинга и сэндвич-атак

Интеграция MEV Blocker: защита от сэндвич-атак и фронтраннинга Ваши пользователи теряют до 15% на сэндвич-атаках при каждом крупном свапе. Валидаторы копируют ваши лимитные ордера и исполняют их раньше вас. Мы решаем эту проблему — интегрируем MEV Blocker в ваш dApp: приватный RPC-ендпоинт, котор

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1003

Интеграция MEV Blocker: защита от сэндвич-атак и фронтраннинга

Ваши пользователи теряют до 15% на сэндвич-атаках при каждом крупном свапе. Валидаторы копируют ваши лимитные ордера и исполняют их раньше вас. Мы решаем эту проблему — интегрируем MEV Blocker в ваш dApp: приватный RPC-ендпоинт, который не даёт MEV-ботам увидеть транзакцию до её подтверждения.

Почему обычные RPC не защищают?

Публичные RPC (Infura, Alchemy) — все транзакции видны в мемпуле. MEV-боты сканируют мемпул и подбирают выгодные транзакции. Сэндвич-атака: бот видит ваш swap, покупает сам, ждёт ваш рост цены, продаёт. Результат — вы покупаете дороже, продаёте дешевле. MEV Blocker лучше публичных RPC в десятки раз по конфиденциальности: транзакция скрыта до включения в блок.

Как работает MEV Blocker?

MEV Blocker — это приватный RPC, который отправляет транзакции напрямую в private mempool (Flashbots, Eden, BloxRoute). Транзакция не публикуется в публичную мемпулу до момента включения в блок. Построители блоков могут видеть транзакцию, но они не могут её атаковать — они получают её только в момент построения блока.

// Пример переключения на MEV Blocker RPC в MetaMask const provider = new ethers.providers.JsonRpcProvider('https://rpc.mevblocker.io'); // Или через EIP-1193 await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0x1', rpcUrls: ['https://rpc.mevblocker.io'] }], }); 

Что входит в нашу работу

Компонент Описание
Настройка RPC Установка приватного MEV Blocker RPC на стороне dApp
Интеграция в кошелёк Автоматическое переключение сети при подключении кошелька
Мониторинг транзакций Отслеживание успешности и скорости включения в блок
Обучение команды Передача документации и best practices по использованию

Почему выбирают нас

10+ лет опыта в блокчейн-разработке, 150+ успешных интеграций DeFi-протоколов, сертифицированные инженеры по Solidity и Rust. Гарантируем конфиденциальность — подписываем NDA. Оценим ваш проект за 1 день. Свяжитесь с нами для консультации — разберём вашу архитектуру, определим точки утечки MEV и предложим оптимальную схему интеграции.

Дополнительно: исходные блоки кода для защиты от flash loan атак (оставлены для справки)

Защита от flash loan атак (сопутствующий сервис)

Flash loan — это необеспеченный займ, который должен быть возвращён в той же транзакции. Если не возвращён — вся транзакция реверсируется. С точки зрения протокола, выдающего flash loan (Aave, Uniswap V3), это безрисковая операция: либо деньги вернулись, либо транзакция не произошла.

Проблема не во flash loan как таковых — это легитимный инструмент для арбитража, ликвидаций, рефинансирования. Проблема в том, что они дают атакующему временный доступ к огромному капиталу (сотни миллионов долларов) без залога. Если протокол принимает экономические решения на основе легко манипулируемых данных (spot price DEX, не-TWAP oracle) — одна транзакция с flash loan может принести атакующему миллионы.

Популярные взломы: Beanstalk ($182M), Cream Finance ($130M), Mango Markets ($114M). Общая черта: протоколы использовали данные, которые можно было сдвинуть одной транзакцией.

Анатомия flash loan атаки

Типичная атака состоит из четырёх шагов:

  1. Взять flash loan (например, 100M USDC из Aave)
  2. Манипулировать состоянием (pump/dump цены в DEX pool)
  3. Эксплойтить протокол (который читает манипулированные данные)
  4. Вернуть flash loan + fee, оставить profit

Конкретный пример — price oracle manipulation:

1. Flash loan: 50M DAI 2. Dump DAI в Uniswap V2 пуле DAI/ETH (spot price DAI падает) 3. Вызов протокола, который читает Uniswap V2 spot price для оценки collateral → Collateral в DAI теперь «дешевле», можно получить discount на ликвидацию или оценить долг в DAI как меньший 4. Прибыль → вернуть flash loan 

Другой тип — governance flash loan:

1. Flash loan governance токенов 2. Моментальное создание пропозала + голосование с огромным весом 3. Исполнение пропозала (drain treasury) 4. Вернуть flash loan 

(Именно так был атакован Beanstalk — атакующий одним governance голосом принял пропозал о переводе treasury себе.)

Защита 1: Price oracle — TWAP вместо spot

TWAP (Time-Weighted Average Price) — среднее арифметическое цены за период. Uniswap V2/V3 хранит cumulative price accumulators, из которых можно вычислить TWAP за произвольный период.

contract TWAPOracle { IUniswapV3Pool public pool; uint32 public constant TWAP_PERIOD = 30 minutes; function getTWAP() external view returns (uint256 price) { uint32[] memory secondsAgos = new uint32[](2); secondsAgos[0] = TWAP_PERIOD; // 30 минут назад secondsAgos[1] = 0; // сейчас (int56[] memory tickCumulatives,) = pool.observe(secondsAgos); int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0]; int24 arithmeticMeanTick = int24(tickCumulativesDelta / int56(uint56(TWAP_PERIOD))); // Конвертируем tick в price price = TickMath.getSqrtRatioAtTick(arithmeticMeanTick); // ... конвертация sqrtPrice → human-readable } } 

Выбор периода TWAP — критичный параметр. Слишком короткий (1–5 минут) — атакующий с достаточным капиталом может удерживать манипулированную цену несколько блоков. Слишком длинный (4–8 часов) — TWAP сильно отстаёт от рынка в волатильные периоды, вызывая неправильные ликвидации.

Практика: 30 минут — разумный default для большинства DeFi протоколов. Для высоковолатильных активов — 1–2 часа.

Chainlink как основной oracle

Chainlink price feed — агрегированная цена от множества независимых узлов с heartbeat обновлением. Манипуляция требует компрометации большинства oracle нод — экономически нецелесообразно.

contract PriceConsumer { AggregatorV3Interface public priceFeed; uint256 public constant HEARTBEAT = 3600; // 1 час uint256 public constant MAX_STALENESS = HEARTBEAT * 2; // 2 часа — максимум function getPrice() external view returns (uint256) { ( uint80 roundId, int256 answer, , uint256 updatedAt, uint80 answeredInRound ) = priceFeed.latestRoundData(); // Проверка staleness: данные не старее MAX_STALENESS require(block.timestamp - updatedAt <= MAX_STALENESS, "Stale price"); // Проверка корректности раунда require(answeredInRound >= roundId, "Stale round"); // Проверка положительности цены require(answer > 0, "Invalid price"); return uint256(answer); } } 

Общая рекомендация: использовать Chainlink как primary oracle, Uniswap TWAP как sanity check. Если два источника расходятся более чем на X% — приостанавливать операции.

Защита 2: Snapshot voting power

Governance flash loan атаки используют тот факт, что voting power = текущий баланс токенов. ERC-20Votes решает это через checkpoint систему.

// Voting power фиксируется на блоке snapshot (до начала голосования) uint256 votePower = token.getPastVotes(voter, proposalSnapshot); // Flash loan ПОСЛЕ snapshot не даёт voting power // Flash loan ДО snapshot требует удерживать токены через voting delay 

Voting delay — минимальный период между созданием пропозала и началом голосования. Если voting delay = 2 дня, атакующий должен держать borrowed токены 2 дня — это экономически невыгодно (fee + opportunity cost).

// OpenZeppelin Governor constructor(...) GovernorSettings( 2 days, // votingDelay — защита от flash loan governance attacks 5 days, // votingPeriod threshold ) {} 

Beanstalk был атакован именно потому что не использовал voting delay: пропозал можно было создать и исполнить в одной транзакции.

Защита 3: Reentrancy guard и same-block checks

Некоторые flash loan атаки эксплойтируют reentrancy или same-block state manipulation.

Same-block checks
contract Vault { mapping(address => uint256) private _depositBlock; function deposit(uint256 amount) external { _depositBlock[msg.sender] = block.number; // ... } function withdraw(uint256 amount) external { // Нельзя deposit и withdraw в одном блоке require( _depositBlock[msg.sender] < block.number, "Flash loan protection: same block" ); // ... } } 

Это блокирует паттерн: flash_loan → deposit → вызов функции которая читает баланс vault → withdraw → repay_loan.

Недостаток: legitimate пользователи тоже не могут deposit+withdraw в одном блоке. Для большинства протоколов это приемлемо.

Nonreentrant + view функции

nonReentrant защищает от reentrancy в state-changing функциях. Но view функции не защищены — их можно вызывать из середины другой транзакции.

Если view функция используется внешним протоколом для получения цены или TVL — манипуляция state через reentrancy меняет то, что видит эта view функция.

// УЯЗВИМО: состояние может быть манипулировано через reentrancy function getSharePrice() external view returns (uint256) { return totalAssets() * 1e18 / totalSupply(); } // totalAssets() читает баланс контракта — который может быть временно раздут function totalAssets() public view returns (uint256) { return IERC20(asset).balanceOf(address(this)); } 

Решение: хранить cached value total assets, обновляемое только в protected функциях.

Защита 4: Circuit breakers и rate limiting

Максимальный объём за транзакцию
uint256 public constant MAX_SINGLE_DEPOSIT = 1_000_000e6; // $1M max function deposit(uint256 amount) external { require(amount <= MAX_SINGLE_DEPOSIT, "Exceeds single tx limit"); // ... } 

Flash loan атаки обычно оперируют сотнями миллионов. Ограничение единичной транзакции снижает максимальный damage от любой атаки.

Pause механизм с автотриггером
contract ProtectedProtocol is Pausable { uint256 public lastTVL; uint256 public constant TVL_DROP_THRESHOLD = 20; // 20% за транзакцию modifier checkTVLAnomaly() { uint256 tvlBefore = totalValueLocked(); _; uint256 tvlAfter = totalValueLocked(); if (tvlBefore > 0) { uint256 dropPercent = ((tvlBefore - tvlAfter) * 100) / tvlBefore; if (dropPercent > TVL_DROP_THRESHOLD) { _pause(); emit EmergencyPause(tvlBefore, tvlAfter, dropPercent); } } } } 

Circuit breaker: если за одну транзакцию TVL падает более чем на N% — протокол автоматически pausе. Это не предотвращает атаку, но ограничивает её масштаб.

Time-weighted balances

Вместо current balance использовать time-weighted average balance для критических расчётов:

// ERC-20Votes checkpoint подход применённый к liquidity function getTimeWeightedLiquidity(address provider, uint256 lookback) external view returns (uint256) { // Усреднённая ликвидность за lookback период // Манипуляция в одной транзакции минимально влияет на average } 

Мониторинг on-chain

Система защиты неполна без мониторинга. Forta Network — decentralized detection network с ботами, которые мониторят on-chain активность.

// Forta бот: детекция потенциальной flash loan атаки async function handleTransaction(txEvent) { const findings = []; // Проверяем наличие flash loan calldata в транзакции const flashLoanCalls = txEvent.filterFunction([ 'flashLoan(address,address,uint256,bytes)', 'flash(address,address,uint256,uint256,bytes)' ]); if (flashLoanCalls.length > 0) { // Проверяем значительные изменения state нашего протокола const protocolEvents = txEvent.filterLog(PROTOCOL_EVENTS, PROTOCOL_ADDRESS); if (protocolEvents.length > 0) { findings.push(Finding.fromObject({ name: "Flash loan + protocol interaction", description: `Flash loan detected in same tx as protocol events`, alertId: "FLASH-LOAN-INTERACTION", severity: FindingSeverity.Medium, type: FindingType.Suspicious })); } } return findings; } 

Алерты из Forta можно отправлять в PagerDuty / Telegram через webhook, давая команде 1–2 минуты на ответ до распространения атаки.

Комплексная архитектура защиты

Ни одна из мер в отдельности не является достаточной. Эффективная система защиты — это слои:

Уровень Механизм Защищает от
Oracle Chainlink primary + TWAP sanity Price manipulation
Governance Voting delay (2+ дней) + ERC-20Votes Flash loan governance
State Same-block check на withdraw Deposit-exploit-withdraw
Flow Max per-tx limits Damage limitation
Circuit breaker Auto-pause при TVL anomaly Early stop на атаку
Monitoring Forta bots Detection и алертинг

Разработка полной системы защиты: аудит существующих oracle зависимостей и governance механизмов — 1 неделя, разработка защитных контрактов — 2–3 недели, интеграция мониторинга — 1 неделя, тесты атак в fork environment — 2 недели.

Стоимость зависит от сложности протокола и количества точек oracle integration.

Ссылки