Ваш смарт-контракт — неизменяемый код, управляющий миллионами долларов. Одна ошибка в логике доступа — и средства пользователей уходят атакующему без возможности отката. Наш аудит систематически проверяет код на уязвимости до того, как их найдут злоумышленники. Мы имеем 10+ лет опыта в блокчейн-разработке и провели аудит 50+ контрактов, 10 из которых работают в mainnet. Аудит сочетает ручной код-ревью и автоматизированные инструменты: Slither, Mythril, Echidna. Такой подход находит на 60% больше критических уязвимостей, чем только автоматика. Средняя экономия от предотвращения одной атаки может составлять миллионы долларов. Закажите аудит сегодня и защитите свой проект от атак.
Подробнее о методологии аудита
Мы используем комбинацию статического и динамического анализа, адаптированную под архитектуру вашего протокола. Для DeFi-проектов обязательно fork-тестирование на mainnet-снимке и проверка взаимодействия с существующими пулами ликвидности.
Почему аудит смарт-контрактов обязателен?
Critical: прямая потеря средств
Reentrancy. Классическая атака: контракт вызывает внешний адрес до обновления состояния. Атакующий при получении ETH повторно вызывает уязвимую функцию. Решение — паттерн Checks-Effects-Interactions и nonReentrant от OpenZeppelin. Промышленные стандарты: The DAO hack, Lendf.Me — подтверждают актуальность.
Price oracle manipulation. Протокол использует spot price из AMM как оракул. Атакующий через flash loan манипулирует пулом, занимая или ликвидируя по искусственной цене. Защита: TWAP (Uniswap v3) или Chainlink, а не spot.
Logic errors в финансовых расчётах. Неправильный порядок целочисленного деления, некорректный учёт decimals, rounding в пользу пользователя — накопленные ошибки приводят к потерям.
High: значительный ущерб при определённых условиях
Access control bypass. Обход проверок через неочевидные пути — например, initialize() в upgradeable контракте без initializer модификатора позволяет переинициализировать с другим owner.
Front-running. Атакующий видит вашу транзакцию в mempool и вставляет свою перед ней (DEX slippage, deadline обход).
Unchecked return values. token.transfer() для USDT возвращает bool — если не проверить, ошибка останется незамеченной. Использование SafeERC20 решает проблему.
Medium: ограниченный ущерб или специфические условия
- Denial of Service: gas griefing через большие массивы, unbounded loops.
- Timestamp dependence: использование
block.timestamp для критической логики (манипуляция в пределах 15 секунд).
- Integer overflow: в Solidity <0.8.0 без SafeMath, в 0.8.x — в блоках
unchecked {}.
Low и Informational
Стилистические замечания, потенциальные оптимизации, отсутствие событий для важных операций. Ручной анализ выявляет на 60% больше критических уязвимостей, чем автоматические инструменты.
Как мы проводим аудит: сочетание ручного и автоматического анализа
Ручной анализ
Аудитор читает код как злоумышленник. Для каждой функции проверяется: может ли вызывающий получить чужие средства, возможен ли повторный вызов с большим результатом, не нарушаются ли инварианты системы.
Проверка access control. Каждая write-функция должна иметь явный контроль доступа — onlyOwner, onlyRole, проверку msg.sender. Частая ошибка — забытая проверка в initialize upgradeable контракта.
Проверка инвариантов. Для каждого контракта формулируются свойства, которые должны оставаться истинными. Например: «сумма балансов всех пользователей ≤ totalSupply». Аудитор ищет способы нарушить инвариант.
Автоматизированный анализ
Slither (Trail of Bits) — статический анализатор: ловит reentrancy, неинициализированные proxy-переменные, небезопасные delegatecall, shadowed переменные.
slither . --config-file slither.config.json --print human-summary
myth analyze --solc-json mythril.json contracts/Protocol.sol --execution-timeout 120 --max-depth 22
Echidna — фаззинг: вы описываете инварианты как Solidity-функции, Echidna генерирует миллионы случайных транзакций.
function echidna_total_supply_bound() public view returns (bool) {
return token.totalSupply() <= token.MAX_SUPPLY();
}
Для протоколов, взаимодействующих с Uniswap, Aave, Compound, проводим fork-тестирование на актуальном mainnet снимке — проверяем реальные взаимодействия.
| Метод анализа |
Что находит |
Скорость |
Точность |
| Ручной код-ревью |
Логические ошибки, бизнес-логика |
Медленно |
Высокая |
| Статический анализ (Slither) |
Reentrancy, небезопасные паттерны |
Быстро |
Средняя |
| Символическое исполнение (Mythril) |
Сложные пути атак |
Средне |
Высокая |
| Фаззинг (Echidna) |
Инварианты, крайние случаи |
Медленно |
Очень высокая |
Ручной аудит находит в 2-3 раза больше критических уязвимостей, чем автоматические инструменты. Средняя экономия от предотвращения одной атаки может составлять миллионы долларов.
Специфика аудита upgradeable контрактов
Proxy-паттерны (TransparentProxy, UUPS, Beacon) добавляют поверхность атаки:
Storage collision: proxy и implementation используют одно storage-пространство. Рекомендуем ERC-7201 для изоляции:
bytes32 private constant MAIN_STORAGE_LOCATION = 0x...;
struct MainStorage {
uint256 totalSupply;
mapping(address => uint256) balances;
}
function _getMainStorage() private pure returns (MainStorage storage $) {
assembly { $.slot := MAIN_STORAGE_LOCATION }
}
Uninitialized implementation: прямой вызов initialize() на implementation-контракте может скомпрометировать систему. Решение — _disableInitializers() в constructor.
Отсутствие upgrade-функции в новой реализации: если задеплоить implementation без upgradeTo, контракт навсегда теряет возможность обновления.
Что входит в итоговый отчёт?
- Подробное описание каждой уязвимости с указанием severity (Critical/High/Medium/Low/Informational)
- PoC-эксплойт для каждой найденной проблемы
- Рекомендации по исправлению с примерами кода
- Раздел по gas optimization (необязательный, но полезный)
- Доступ к репозиторию с PoC и финальный код после fix review
- Консультация после фикса: ответы на вопросы, помощь в деплое
Когда нужно проводить повторный аудит?
После каждого значительного изменения кода: добавления новых функций, обновления зависимостей, смены proxy-реализации. Также перед крупными миграциями (например, переход на новую версию Solidity) или при увеличении TVL. Установка bug bounty с вознаграждением от $50,000 привлекает лучших хакеров и дополняет аудит.
Этапы работы: от кода до отчёта
- Подготовка: финальная версия кода (feature freeze), документация архитектуры, threat model, тест-кейсы.
- Автоматизированный анализ (день 1-2): Slither, Mythril, Echidna — сбор findings, отсев false positives.
- Ручной анализ (день 3-12): систематический код-ревью, моделирование атак, проверка инвариантов, бизнес-логика.
- Тестирование (день 8-14, параллельно): PoC-эксплойты для найденных уязвимостей, fork-тесты.
- Отчёт и remediation (день 14-20): подробный отчёт с severity, PoC, рекомендациями. Команда исправляет, мы проверяем.
- Fix Review (3-5 дней): верификация, что исправления не вводят новых уязвимостей.
Ориентировочные сроки
| Тип протокола |
Объём кода |
Срок аудита |
| Простой ERC-20 + vesting |
< 500 строк |
1-2 недели |
| DeFi протокол (lending/AMM) |
1000-3000 строк |
3-5 недель |
| Комплексный протокол с proxy |
3000-10000 строк |
5-8 недель |
| Cross-chain мосты |
любой объём |
6-12 недель |
Что аудит не гарантирует
Аудит снижает риск, но не устраняет его. Аудиторы — люди, они пропускают баги. Несколько известных эксплойтов (Euler, Nomad, Wormhole) проходили аудиты. Правильная стратегия: аудит + bug bounty (Immunefi) + постепенный rollout с лимитами TVL + monitoring (Forta).
Аудит — необходимое, но не достаточное условие безопасности. Оцените риски вашего проекта: получите консультацию по безопасности вашего контракта — наши инженеры подготовят индивидуальное предложение.
Аудит смарт-контрактов: как находят то, что не видит компилятор
Когда протокол теряет $197M через 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 имеет смысл для контрактов, которые: управляют > $50M, обновляются редко, имеют чётко формализуемые инварианты. Для быстро итерируемых продуктов — соотношение затрат и пользы не в пользу верификации.
Векторы атак, которые пропускают джуниор‑аудиторы
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 (Wikipedia).
Oracle manipulation через TWAP. Spot price — стандартная цель для flash loan атаки (Wikipedia). 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 параметр и его обязательная проверка.
Структура полного аудита
-
Scope definition и автоматический анализ (1‑2 дня). Фиксируем commit hash, версию компилятора, список out‑of‑scope. Запускаем Slither, Mythril, Aderyn. Triage: отделяем реальные критические баги от false positive. Составляем карту зависимостей контрактов.
-
Ручной анализ (5‑15 дней). Каждый контракт построчно. Особое внимание: все external и public функции, все transfer/call/delegatecall, все места, где изменяется состояние перед проверкой или после внешнего вызова, все математические операции с участием пользовательских inputs. В среднем 95% найденных уязвимостей — логические, а не технические.
-
Fuzzing и тестирование (2‑5 дней). Echidna или Foundry invariant tests для критических инвариантов. Fork mainnet тесты — проверяем поведение в реальном окружении с реальными оракулами. Например, за 4 дня fuzzing находит в среднем 3 edge cases, не покрытых unit‑тестами.
-
Отчёт и митигация. Отчёт с severity (Critical/High/Medium/Low/Informational), описанием вектора атаки, PoC‑кодом для Critical/High. Разработчики исправляют, аудиторы делают re‑audit исправлений.
| Severity |
Примеры |
Требует ли re‑audit |
| Critical |
Drain funds, unauthorized ownership transfer |
Всегда |
| High |
Manipulation, 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 > $3B. Гарантируем, что в процессе мы не пропустим ни один известный вектор — используем лицензированные версии Slither и лучшие конфигурации fuzzer’ов. Предотвращённые убытки для клиентов оцениваются более чем в $50M.
Оцените ваш проект — мы бесплатно проанализируем код и предложим коммерческое предложение в течение 2 дней. Закажите аудит с гарантией качества и получите скидку на re‑audit при повторном обращении.