Аудит безопасности DeFi-протокола
DeFi-аудит — это не формальность перед запуском. Это структурированный процесс выявления уязвимостей в коде, который будет управлять реальными деньгами без возможности экстренного патча. За последние три года через эксплойты в DeFi утекло более $5 миллиардов. Большинство взломов — не экзотические атаки нулевого дня, а классические уязвимости: reentrancy, integer overflow, неверная валидация состояния, манипуляция ценой через flash loan.
Хороший аудит находит эти проблемы до того, как их находят злоумышленники.
Что включает профессиональный DeFi-аудит
Manual code review
Автоматические инструменты (Slither, Mythril) находят ~30-40% типовых уязвимостей. Остальное — manual analysis. Аудитор читает код как атакующий: какие инварианты должны соблюдаться? Что происходит если каждый из них нарушен? Как можно вынудить контракт нарушить собственные инварианты?
Конкретные векторы, которые проверяются вручную:
Reentrancy. Включая cross-function reentrancy (атака через другую функцию того же контракта) и cross-contract reentrancy (контракт A реентрит контракт B через callback). Пример: в Curve в 2023 году reentrancy-уязвимость в Vyper компиляторе позволила атаковать несколько пулов, суммарные потери $62M.
// Уязвимый паттерн
function withdraw(uint256 amount) external {
balances[msg.sender] -= amount;
(bool success,) = msg.sender.call{value: amount}(""); // уязвимость если msg.sender — контракт
require(success);
}
// Правильно: CEI паттерн (Checks-Effects-Interactions)
function withdraw(uint256 amount) external nonReentrant {
require(balances[msg.sender] >= amount, "Insufficient");
balances[msg.sender] -= amount; // Effect сначала
(bool success,) = msg.sender.call{value: amount}(""); // Interaction последней
require(success, "Transfer failed");
}
Oracle manipulation. Протоколы, использующие spot price из AMM пула как oracle, уязвимы к flash loan атакам: злоумышленник в одной транзакции (1) берёт flash loan, (2) манипулирует ценой в пуле, (3) эксплуатирует протокол по искажённой цене, (4) возвращает loan. Mango Markets ($114M), Euler Finance ($197M) — oracle manipulation в числе векторов.
Проверка: использует ли протокол TWAP (time-weighted average price) из Uniswap v3, Chainlink, или собственный VWAP? Одноблочные манипуляции через flash loan возможны только против spot price.
Access control. Кто может вызывать privileged функции? Правильно ли настроены роли? Есть ли функции без onlyOwner/onlyRole, которые должны быть защищены? Номинальный паттерн: проверяем каждую external и public функцию на предмет того, должна ли она быть restricted.
Formal verification
Для критических математических инвариантов — формальная верификация через Certora Prover или Halmos (symbolic execution на Foundry). Пример инварианта lending протокола: «суммарная задолженность всех заёмщиков никогда не превышает суммарные депозиты плюс accumulated interest».
Certora Prover работает с CVL (Certora Verification Language) — декларативный язык для описания свойств:
rule totalDebtNeverExceedsDeposits {
uint256 totalDebt = getTotalDebt();
uint256 totalDeposits = getTotalDeposits();
uint256 accruedInterest = getAccruedInterest();
assert totalDebt <= totalDeposits + accruedInterest;
}
Если правило нарушается — Prover генерирует контрпример: конкретную последовательность вызовов, приводящую к нарушению. Это не просто тест — это математическое доказательство для всех возможных входных данных.
Economic attack analysis
Техническая корректность кода — необходимое, но недостаточное условие. Экономически грамотный атакующий может эксплуатировать protocol mechanics без единой технической уязвимости.
Price impact attacks. Если протокол использует on-chain pricing с недостаточным slippage protection — большие сделки могут двигать цену в невыгодную для протокола сторону.
Liquidation cascades. В lending протоколах: резкое падение цены залога → множество позиций под ликвидацию → liquidators не успевают → протокол накапливает bad debt. Анализируем: достаточна ли ликвидационная маржа? Как ведёт себя протокол при 50% падении цены залога за один блок?
MEV и sandwich attacks. Если frontend позволяет слишком высокий slippage tolerance — транзакции пользователей уязвимы к sandwich атакам. Аудит проверяет не только контракты, но и рекомендации для frontend.
Токен-специфические риски. Токены с transfer fee (deflationary), rebase токены (AMPL, stETH), токены с blacklist функцией (USDC, USDT) — все они нарушают стандартные ожидания ERC-20. Протокол, не учитывающий эти особенности, получает accounting ошибки.
Инструменты статического анализа
Slither
Slither (Trail of Bits) — наиболее мощный статический анализатор для Solidity. 90+ детекторов для известных паттернов уязвимостей. Запускается локально или в CI:
slither . --checklist --markdown-root https://github.com/project/repo/
Генерирует отчёт с классификацией по severity: High, Medium, Low, Informational, Optimization. Большинство High findings — false positives или уже известные паттерны, но их нужно верифицировать вручную.
Полезные detectors: reentrancy-eth, arbitrary-send-eth, controlled-delegatecall, msg-value-loop, tautology.
Mythril
Mythril (ConsenSys Diligence) — symbolic execution. Пытается найти пути выполнения, при которых assert нарушается. Медленнее Slither, глубже анализирует возможные execution paths.
Echidna (fuzzing)
Echidna (Trail of Bits) — property-based fuzzer для Solidity. Вы определяете инварианты как функции с echidna_ префиксом, Echidna генерирует случайные последовательности транзакций пытаясь нарушить их:
contract TestLendingPool is LendingPool {
// Invariant: totalBorrowed никогда не превышает totalDeposited
function echidna_debt_invariant() public view returns (bool) {
return totalBorrowed() <= totalDeposited();
}
// Invariant: баланс пользователя не уходит в минус
function echidna_no_negative_balance() public view returns (bool) {
return balanceOf(msg.sender) >= 0; // uint256, всегда true — но проверяем overflow
}
}
Echidna особенно эффективен для нахождения edge cases в математике: переполнение uint256, деление на ноль, потери precision при округлении.
Foundry invariant tests
Foundry имеет встроенный invariant fuzzing через invariant_ префикс. Интегрируется в существующий тестовый suite:
function invariant_totalSharesMatchTotalAssets() public {
assertApproxEqRel(
vault.totalAssets(),
vault.totalShares() * vault.sharePrice() / 1e18,
1e15 // 0.1% tolerance для rounding
);
}
Классификация уязвимостей
| Severity | Критерий | Примеры |
|---|---|---|
| Critical | Прямая потеря/кража funds | Reentrancy drain, access control bypass |
| High | Значительный ущерб при определённых условиях | Flash loan price manip, liquidation failure |
| Medium | Ограниченный ущерб или сложные conditions | Integer rounding errors, DoS через gas |
| Low | Минорные проблемы или best practice | Emit events missing, redundant checks |
| Informational | Нет impact, но улучшает код | Code style, gas optimization, comments |
Critical и High findings должны быть исправлены до деплоя. Medium — исправлены или явно задокументированы с обоснованием accepted risk.
Процесс и timeline
Pre-audit (1 неделя). Команда предоставляет: финальный код (freeze), документацию архитектуры, спецификацию инвариантов, известные ограничения. Аудитор готовит threat model и scope.
Audit phase 1 (2-3 недели). Каждый аудитор работает независимо. Manual review + автоматические инструменты. Без общения между аудиторами — предотвращение bias.
Audit phase 2 (1 неделя). Аудиторы обмениваются findings, совместный анализ спорных случаев, economic attack simulation.
Draft report (3-5 дней). Отчёт с классифицированными findings, proof of concept для критических уязвимостей, рекомендации по исправлению.
Remediation (1-3 недели). Команда исправляет findings. Аудиторы верифицируют исправления — это отдельный review pass.
Final report. Публичный или приватный отчёт с resolved/acknowledged/wont-fix статусами.
Выбор аудитора
Топ-тир компании: Trail of Bits, OpenZeppelin, ChainSecurity, Halborn, Certik (for larger projects), Spearbit. Независимые исследователи через Code4rena или Sherlock — хороший способ получить дополнительные глаза после основного аудита.
Красные флаги при выборе аудитора: нет публичных отчётов в портфолио, срок аудита менее 1 недели на >1000 строк кода, не проводят economic analysis.
Стоимость аудита (ориентир): простой ERC-20 + staking — $10-30K, средний DeFi протокол (1000-3000 LOC) — $40-100K, сложный lending/perp DEX — $100-300K+. Дорого? Сравните с $50-200M, потерянными в среднестатистическом DeFi exploit.







