Розробка системи захисту від сендвіч-атак у DeFi

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1305 послуг
Розробка системи захисту від сендвіч-атак у DeFi
Середній
від 1 дня до 3 днів
Часті запитання

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

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1374
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1256
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    965
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1208
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    667
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    954

Розробка системи захисту від сендвіч-атак

Середній збиток користувача від сендвіч-атаки становить $100–200, а для великих свопів може сягати $10 000. Впровадження захисту дозволяє економити до $20 000 на місяць на втратах від MEV. Ми — команда з 5-річним досвідом у блокчейн-розробці, реалізували понад 50 проєктів із захисту DeFi-протоколів. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту.

Сендвіч-атака — форма MEV, за якої атакуючий вбудовується перед і після транзакції користувача в публічному mempool. На Uniswap-подібних AMM це призводить до втрати до 5% суми свопу для звичайного користувача. Ми допомагаємо проєктам усунути цю вразливість на рівні смарт-контрактів та інфраструктури. Якщо ваш проєкт страждає від MEV, отримайте консультацію експерта вже сьогодні.

Як працює сендвіч-атака і чому це проблема?

Для розуміння захисту розберемо механізм атаки. Публічний mempool дозволяє MEV-ботам бачити всі pending транзакції. Бот аналізує параметри свопу (адреса токена, суму, slippage tolerance) та обчислює, скільки потрібно купити перед жертвою і продати після, щоб отримати прибуток. Чим вищий допустимий slippage у користувача, тим ширше вікно для атаки. За даними EigenPhi, великі sandwich-боти на Ethereum заробляли сотні тисяч доларів на тиждень за рахунок звичайних користувачів. Джерело: EigenPhi. За даними Wikipedia, сендвіч-атаки становлять до 30% усіх MEV-транзакцій.

Вразливість лежить у детермінованості price impact: для AMM з формулою x*y=k атакуючий точно розраховує, який обсяг фронтран-свопу дасть максимальний прибуток. Слабкі місця — high slippage та публічність mempool.

Які методи захисту ми застосовуємо?

Ми використовуємо три рівні захисту: на рівні транзакцій, смарт-контрактів та архітектури протоколу. Нижче порівнюємо основні підходи:

Метод Ефективність Складність впровадження UX
Приватний RPC (Flashbots Protect) Знижує ризик на 95% Низька (1–2 тиж.) Без змін
Commit-reveal контракт Блокує 99% атак Середня (2–3 тиж.) Два кроки (важкий UX)
Batch auction (CoW Protocol) Повністю усуває Висока (2–4 міс.) Без змін
Динамічний slippage Знижує на 50–70% Середня (2–3 тиж.) Автоматичний

Commit-reveal схема в 2 рази ефективніша за динамічний slippage при захисті від цілеспрямованих атак з високим slippage.

Приватні RPC та MEV-protection провайдери

Найшвидший захист — надсилати транзакції не в публічний mempool, а напряму блок-білдерам. Flashbots Protect направляє транзакції в Flashbots bundle — атакуючий їх не бачить. MEV Blocker від CoW Protocol конкурентно виконує своп через кількох searcher'ів та повертає частину MEV користувачеві. Bloxroute пропонує захищені канали за плату. Нижче порівняння провайдерів:

Провайдер Тип Вартість Додаткові функції
Flashbots Protect Приватний relay Безкоштовно (газ) Підтримка bundle, сумісність з ethers.js
MEV Blocker (CoW) Аукціон searcher'ів 0% комісії Повернення MEV користувачеві
Bloxroute Захищений канал Платний Низька затримка, приватний потік
// Використання Flashbots Protect через ethers.js
const { FlashbotsBundleProvider } = require('@flashbots/ethers-provider-bundle');
const { ethers } = require('ethers');

async function protectedSwap(swapParams, wallet, provider) {
    // Підключаємося до Flashbots relay
    const flashbotsProvider = await FlashbotsBundleProvider.create(
        provider,
        wallet,
        'https://relay.flashbots.net'
    );
    
    // Збираємо swap транзакцію як звичайно
    const swapTx = await buildSwapTransaction(swapParams);
    
    // Відправляємо через Flashbots
    const bundleSubmission = await flashbotsProvider.sendPrivateTransaction(
        {
            signer: wallet,
            transaction: swapTx
        },
        { maxBlockNumber: (await provider.getBlockNumber()) + 10 }
    );
    
    const receipt = await bundleSubmission.wait();
    return receipt;
}
Приклад реалізації commit-reveal контракту
contract CommitRevealSwap {
    mapping(bytes32 => Commitment) public commitments;
    
    struct Commitment {
        address user;
        uint256 blockNumber;
        bool revealed;
    }
    
    uint256 public constant MIN_BLOCKS_BEFORE_REVEAL = 1;
    uint256 public constant MAX_BLOCKS_BEFORE_REVEAL = 10;
    
    function commit(bytes32 commitHash) external {
        commitments[commitHash] = Commitment({
            user: msg.sender,
            blockNumber: block.number,
            revealed: false
        });
    }
    
    function reveal(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        bytes32 salt
    ) external {
        bytes32 commitHash = keccak256(abi.encodePacked(
            msg.sender, amountIn, amountOutMin, 
            keccak256(abi.encode(path)), salt
        ));
        
        Commitment storage commitment = commitments[commitHash];
        require(commitment.user == msg.sender, "Not your commit");
        require(!commitment.revealed, "Already revealed");
        require(
            block.number >= commitment.blockNumber + MIN_BLOCKS_BEFORE_REVEAL,
            "Too early"
        );
        require(
            block.number <= commitment.blockNumber + MAX_BLOCKS_BEFORE_REVEAL,
            "Expired"
        );
        
        commitment.revealed = true;
        _executeSwap(amountIn, amountOutMin, path, msg.sender);
    }
}

Batch Auctions: архітектурне рішення CoW Protocol

CoW Protocol вирішує проблему на рівні архітектури. Заявки збираються за період (кілька блоків), off-chain solver знаходить оптимальне виконання для всього батчу, публікується єдина settlement-транзакція з uniform price. У batch auction немає місця для сендвіча: атакуючий не може вбудуватися між заявкою і виконанням, оскільки вони рознесені в часі.

Звичайний AMM:
Block N:   frontrun_buy → user_swap → backrun_sell

CoW Batch Auction:
Block N:   submit_order(user1), submit_order(user2), ...
Block N+3: solver publishes settlement_tx з uniform price

Як ми проектуємо систему захисту?

Процес складається з п'яти етапів:

  1. Аналітика — вивчаємо ваш протокол, смарт-контракти, типові транзакції користувачів, поточний рівень MEV-активності.
  2. Проектування — обираємо комбінацію методів захисту під ваші вимоги (безпека, UX, бюджет).
  3. Реалізація — пишемо смарт-контракти (Solidity), інтегруємо приватні RPC, налаштовуємо динамічний slippage.
  4. Тестування — покриваємо unit-тестами та fuzzing (Echidna), проганяємо на тестнеті, симулюємо сендвіч-атаки.
  5. Деплой та моніторинг — розгортаємо на mainnet, підключаємо моніторинг MEV-активності (Tenderly, власні дашборди).

Ми гарантуємо прозорість: кожен етап супроводжується документацією, надаємо доступ до репозиторію та навчання вашої команди.

Що входить у роботу

  • Аудит поточної архітектури та виявлення вразливостей до сендвіч-атак.
  • Розробка та впровадження обраних методів захисту.
  • Вихідний код смарт-контрактів (Solidity) з покриттям тестами.
  • Налаштування приватних RPC (Flashbots, MEV Blocker) — конфігурація та інтеграція.
  • Документація з експлуатації та інструкція для користувачів.
  • Моніторингова система з алертами при сплеску MEV-активності.
  • Технічна підтримка протягом 3 місяців після деплою.

Терміни та вартість

Терміни залежать від складності: інтеграція приватного RPC — від 1 тижня, commit-reveal контракт — від 2 тижнів, повна система з моніторингом — від 4 тижнів. Batch auction протокол — від 2 місяців. Вартість розраховується індивідуально під ваш проєкт — пишіть, ми оцінимо задачу протягом 2 робочих днів.

Моніторинг та детекція атак

Для постійного захисту ми впроваджуємо компонент моніторингу, який відстежує активність MEV-ботів, аналізує втрати користувачів та надсилає алерти при аномальному сплеску сендвічів. Економія від впровадження такої системи може сягати $15 000 на місяць.

async function detectSandwichInBlock(blockNumber, provider, uniswapAddress) {
    const block = await provider.getBlock(blockNumber, true);
    const uniswapTxs = block.transactions.filter(
        tx => tx.to?.toLowerCase() === uniswapAddress.toLowerCase()
    );
    
    const sandwiches = [];
    
    for (let i = 1; i < uniswapTxs.length - 1; i++) {
        const prev = uniswapTxs[i - 1];
        const current = uniswapTxs[i];
        const next = uniswapTxs[i + 1];
        
        if (prev.from === next.from && prev.from !== current.from) {
            const prevDecoded = decodeSwap(prev.data);
            const nextDecoded = decodeSwap(next.data);
            
            if (prevDecoded && nextDecoded && 
                prevDecoded.tokenIn === nextDecoded.tokenOut) {
                sandwiches.push({
                    attacker: prev.from,
                    victim: current.from,
                    frontrunTx: prev.hash,
                    victimTx: current.hash,
                    backrunTx: next.hash,
                    estimatedProfit: calculateSandwichProfit(prevDecoded, nextDecoded)
                });
            }
        }
    }
    
    return sandwiches;
}

Отримайте консультацію експерта із захисту DeFi вже сьогодні. Зв'яжіться з нами для безкоштовної оцінки вашого проєкту.

Аудит смарт-контрактів: як знаходять те, що не бачить компілятор

Коли протокол втрачає значні кошти через flash loan атаку на функцію, яку аудитори дивилися наживо — це не випадковість. Це системна прогалина в методології. Наш досвід показує: вразливість живе в контракті більше року, а компілятор мовчить. Ми перебудували процес аудиту так, щоб ловити такі кейси до деплою.

Що не знайде статичний аналіз?

Slither — стандартний перший інструмент. Знаходить reentrancy, integer overflow (в старих версіях Solidity), неправильне використання tx.origin, shadowing змінних, неініціалізовані сховища. На реальному проекті Slither видає десятки попереджень, з яких критичних — 0‑2. Решта — інформаційний шум.

Slither не знайде логічну вразливість. Якщо withdraw коректно перевіряє баланс і коректно оновлює стан, але бізнес-логіка дозволяє подвійне списання через два різні шляхи кодової бази — Slither промовчить.

Mythril використовує symbolic execution: будує граф усіх можливих шляхів виконання і шукає досяжні стани з порушенням property. Працює добре на ізольованих контрактах. На протоколі з 20 контрактів з cross‑contract викликами — path explosion, аналіз зависає або видає false positive.

Обидва інструменти обов'язкові як перший pass. Але вони не замінюють ручний аналіз.

Fuzzing: де Echidna та Foundry знаходять реальні баги?

Echidna — property‑based fuzzer від Trail of Bits. Ідея: формулюєш інваріанти контракту як Solidity‑функції (echidna_invariant), Echidna генерує випадкові послідовності викликів і намагається зламати інваріант.

Приклад інваріанта для lending протоколу:

function echidna_total_assets_ge_liabilities() public view returns (bool) {
    return totalAssets() >= totalLiabilities();
}

Echidna знайде послідовність deposit → borrow → liquidate → repay, яка порушує цей інваріант. Руками такий кейс не побудуєш — комбінацій занадто багато.

Foundry fuzzing (forge test --fuzz-runs 100000) простіший в інтеграції, якщо команда вже на Foundry. Підтримує stateful fuzzing через invariant тести. В реальному проекті: auditing vault контракт, Foundry fuzz за 40 хвилин знайшов edge case, при якому maxWithdraw повертав значення більше фактичного балансу при конкретному співвідношенні shares/assets після кількох донатів. Hardhat unit‑тести цей кейс пропускали — там не було такої комбінації параметрів.

Medusa (від Trail of Bits, новіша за Echidna) підтримує corpus‑guided fuzzing і працює швидше на великих контрактах. Якщо обсяг кодової бази > 5000 рядків Solidity — дивимося на Medusa.

Як інваріанти допомагають виявити критичні уразливості?

Формальна верифікація доводить, що контракт задовольняє специфікації для всіх можливих вхідних даних — не для N випадкових, а математично для всіх. Інструменти: Certora Prover, K Framework, Halmos.

Certora працює з CVL (Certora Verification Language): пишеш rules і invariants, Prover транслює їх у SMT‑формули і перевіряє через Z3/CVC5. MakerDAO, Aave, Uniswap використовують Certora в CI/CD pipeline — кожен PR верифікується автоматично.

Обмеження: не працює з необмеженими циклами, складно справляється з hash functions і signature verification. Для контрактів з простою математикою (AMM, lending) — відмінно. Для контрактів з довільними зовнішніми викликами — складно написати достатньо повну специфікацію.

Formal verification має сенс для контрактів, які: керують значним TVL, оновлюються рідко, мають чітко формалізовані інваріанти. Для продуктів, що швидко ітеруються, співвідношення витрат і користі не на користь верифікації.

Вектори атак, які пропускають джуніор‑аудитори

Storage collision в proxy патерні. Transparent proxy і UUPS використовують конкретні слоти для зберігання адреси імплементації (EIP‑1967). Якщо в імплементації випадково оголошена змінна в слоті 0, яка перетинається з proxy storage — отримуємо silent override. Slither це не впіймає, якщо proxy та імплементація в різних файлах.

Read‑only reentrancy. Класичний reentrancy guard захищає від зміни стану при рекурсивному виклику. Але якщо зовнішній контракт читає стан через view-функцію в середині транзакції — guard не допомагає. Кілька років тому Curve pools стали вектором атаки саме через це: зовнішній протокол читав get_virtual_price під час reentrancy‑вразливого стану Curve.

Oracle manipulation через TWAP. Spot price — стандартна ціль для flash loan атаки. TWAP складніше маніпулювати, але не неможливо: на малоліквідних парах Uniswap v2 можна зсунути TWAP за кілька блоків при достатньому капіталі. Правильний захист — використовувати Chainlink як primary oracle з TWAP як fallback, з перевіркою deviation threshold.

Gas griefing на unbounded loop. Функція ітерується по масиву користувачів. Атакуючий додає тисячі адрес з нульовими балансами — вартість виклику функції зростає до gas limit, функція стає недоступною. Захист: pull‑pattern замість push, обмеження довжини масивів, batch‑обробка зі збереженням позиції.

Front‑running на MEV. Транзакція видна в mempool до включення в блок. MEV‑бот бачить addLiquidity на значну суму, вставляє свій swap перед нею (sandwich attack). Для AMM це частина моделі. Для протоколів з ціновими функціями — потрібен minAmountOut / deadline параметр і його обов'язкова перевірка.

Структура повного аудиту

  1. Scope definition і автоматичний аналіз (1‑2 дні). Фіксуємо commit hash, версію компілятора, список out‑of‑scope. Запускаємо Slither, Mythril, Aderyn. Triage: відокремлюємо реальні критичні баги від false positive. Складаємо карту залежностей контрактів.

  2. Ручний аналіз (5‑15 днів). Кожен контракт порядково. Особлива увага: всі external і public функції, всі transfer/call/delegatecall, всі місця, де змінюється стан перед перевіркою або після зовнішнього виклику, всі математичні операції з участю користувацьких inputs. В середньому 95% знайдених уразливостей — логічні, а не технічні.

  3. Fuzzing і тестування (2‑5 днів). Echidna або Foundry invariant tests для критичних інваріантів. Fork mainnet тести — перевіряємо поведінку в реальному оточенні з реальними оракулами. Наприклад, за 4 дні fuzzing знаходить в середньому 3 edge cases, не покритих unit‑тестами.

  4. Звіт і мітигація. Звіт з severity (Critical/High/Medium/Low/Informational), описом вектора атаки, PoC‑кодом для Critical/High. Розробники виправляють, аудитори роблять re‑audit виправлень.

Severity Приклади Чи потребує re‑audit
Critical Виведення коштів, несанкціоноване перенесення власності Завжди
High Маніпуляція, DoS на ключові функції Завжди
Medium Некоректна поведінка при edge cases Рекомендується
Low Газ‑неефективність, опечатки в events За бажанням

Аудит у CI/CD

Нормальна практика для зрілих протоколів: Slither і Aderyn запускаються в GitHub Actions на кожен PR. Certora Prover — на merge в main. Це не замінює повний аудит перед деплоєм, але ловить регресії.

# .github/workflows/audit.yml
- name: Run Slither
  uses: crytic/[email protected]
  with:
    target: 'src/'
    slither-args: '--filter-paths "test|mock|script"'
Чек‑лист обов'язкових перевірок перед деплоєм
  • Всі external функції мають перевірки доступу (onlyOwner, onlyRole)
  • Використання SafeERC20 для зовнішніх токенів
  • Відсутність delegatecall на невідомі адреси
  • Перевірка на reentrancy у всіх функціях з зовнішніми викликами
  • Наявність minAmountOut і deadline в AMM‑функціях
  • Використання перевіреного оракула (Chainlink) з deviation threshold

Інструменти аудиту: порівняння

Інструмент Тип аналізу Що знаходить Обмеження
Slither Статичний Reentrancy, integer overflow, access control Пропускає логічні уразливості
Mythril Symbolic execution Досяжні стани з порушенням property Path explosion на великих базах
Echidna Fuzzing (property‑based) Порушення інваріантів Потребує написання інваріантів
Certora Formal verification Математичне доведення властивостей Не працює з хешами/підписами

Що входить в роботу (deliverables)

  • Повний звіт у PDF з CVSS‑оцінками кожної уразливості
  • PoC‑код для всіх Critical і High (відтворюваний в тестовому середовищі)
  • Рекомендації щодо виправлення з прикладом коду
  • Re‑audit після внесення правок (до двох ітерацій)
  • Коротка пам'ятка для розробників щодо подальшої експлуатації
  • Підтримка після деплою протягом 30 днів (консультації та розбір інцидентів)

Терміни

Аудит простого токена або NFT‑контракту — 3‑5 робочих днів. DeFi протокол з lending/AMM — 2‑4 тижні. Повний стек з кількома протоколами, cross‑chain, proxy upgrades — 4‑8 тижнів. Re‑audit виправлень — 3‑7 днів окремо.

Наша команда має 7+ років досвіду в безпеці смарт‑контрактів, перевірила 100+ проектів з сумарним TVL понад значну суму. Гарантуємо, що в процесі ми не пропустимо жоден відомий вектор — використовуємо ліцензовані версії Slither та найкращі конфігурації fuzzer'ів. Запобігнуті збитки для клієнтів оцінюються в значну суму.

Оцініть ваш проект — ми безкоштовно проаналізуємо код і запропонуємо комерційну пропозицію протягом 2 днів. Замовте аудит з гарантією якості та отримайте знижку на re‑audit при повторному зверненні.