Аудит безопасности смарт-контрактов: критерии оценки кода и уязвимостей

Сканер может вернуть чистый отчет по контракту, в котором цена залога читается из спотового пула, ликвидность пополняется в рамках одной транзакции, а решение governance опирается на моментальный снимок состояния.

Аудит безопасности смарт-контрактов: критерии оценки кода и уязвимостей

Ни один модуль по отдельности не обязан содержать очевидный баг. Уязвимость возникает на стыке: атакующий изменяет цену, использует заемный капитал и совершает действие до восстановления исходного состояния. Такой composition failure статический анализ обычно не видит.

Поэтому аудит безопасности смарт-контрактов и критерии оценки кода должны охватывать архитектуру протокола, бизнес-инварианты и последовательность транзакций. Рабочий отчет привязан к конкретному commit, содержит воспроизводимый путь эксплуатации и позволяет проверить, закрыла ли remediation исходную уязвимость.

Гибридная архитектура аудита

Полноценная проверка контракта состоит из автоматического анализа, ручного ревью, формальной верификации отдельных свойств и проверки эксплойтов. Эти слои решают разные задачи и потому не взаимозаменяемы.

Слой проверкиЧто он выявляетГраница применения
SlitherИзвестные паттерны уязвимостей, зависимости данных, граф вызовов, особенности inheritance и visibilityНе понимает полный бизнес-контекст и пропускает логические ошибки
MythXПоведение контракта по модели, потоки данных, нарушения заданных свойствКачество вывода зависит от модели и допущений анализатора
Ручное ревьюИнварианты, полномочия, порядок обновления состояния, экономические edge casesТребует времени и высокой квалификации аудитора
Формальная верификацияДостижимость состояний и сохранение свойств в ограниченной моделиДоказывает свойство только внутри заданных границ модели
Proof of ConceptФактическую достижимость эксплойта и его последствияТребует корректного окружения и воспроизведения состояния

По данным отраслевой практики, на ручной анализ приходится около 60–70% трудозатрат комплексного аудита. Это естественно: статический анализ хорошо локализует дефекты с известной сигнатурой, но бизнес-логика остается зоной ответственности человека.

Ручное ревью начинается с модели протокола. Аудитор восстанавливает роли, полномочия, допустимые переходы состояния и источники внешних данных. Затем проверяются call trace, порядок обновления storage, обработка revert, взаимодействие с прокси и зависимости от других контрактов. Только после этого дефекты из отчетов Slither и MythX классифицируются: часть находок оказывается ложными срабатываниями, часть объединяется с общей первопричиной.

Сканер показывает, где код похож на известную ошибку. Аудит устанавливает, можно ли нарушить инвариант протокола.

Типичная ошибка заказчика — оценивать аудит по числу страниц или количеству findings. Показательнееcoverage: какие модули проверялись, какие сценарии невозможны без внешней инфраструктуры и какие предположения лежат в основе каждой критической находки.

Стандарты верификации: SCSVS, SCWE и OWASP Top 10

Единого общемирового юридического или отраслевого норматива аудита смарт-контрактов не существует. Проекты строят внутренние процедуры на основе OWASP, SWC и отраслевых методик. Поэтому название «аудит» само по себе не задает глубину проверки.

В SCSVS v0.0.1 предусмотрено 35 контролей, распределенных по 11 категориям. Это удобная матрица покрытия: аудитор показывает, какие контроли выполнены, какие дали отрицательный результат, какие признаны неприменимыми и какие вынесены за границы scope. Простой итог «проверено 100%» здесь бесполезен. Нужны ссылки на конкретные проверки, коммиты и артефакты.

SCWE содержит 156 слабостей, а реестр SWC помогает сопоставлять находки с известными классами дефектов. Эти классификации решают задачу обмена информацией между аудиторами, но не определяют серьезность каждого инцидента.

В OWASP Smart Contract Top 10, представленном категориями SC01–SC10, отдельно выделены риски манипуляции ценовыми оракулами, использования флеш-займов и нарушений контроля доступа. Для рабочего аудита полезно разделять четыре сущности:

1. Контроль отвечает на вопрос, что именно требуется проверить.

2. Слабость описывает общий класс ошибки.

3. Finding фиксирует конкретную уязвимость в конкретной реализации.

4. Severity ранжирует риск для текущей архитектуры и бизнес-процесса.

Эти четыре уровня часто смешивают. Отчет может содержать сотню findings, при этом не покрывать критические категории SCSVS. И наоборот: один аккуратно описанный дефект в upgradeable-контракте опаснее десятка замечаний о читаемости кода.

Критические векторы угроз

Контроль доступа и инициализация

Ошибка доступа часто находится в жизненном цикле контракта, а не в его основной логике. Проверяются конструктор и initializer, состояние proxy, первоначальный admin, порядок вызовов при деплое, а также возможность повторной инициализации.

Отдельный класс находок связан с привилегированными функциями: изменение реализации proxy, настройка oracle, смена параметров, начисление вознаграждений, приостановление операций. Здесь нужна матрица ролей: кто может вызвать функцию, через какой адрес или multisig, существует ли timelock и как изменяется набор полномочий.

Централизация сама по себе редко является багом. Если владелец контролирует вывод средств по замыслу, это риск доверия и компрометации ключа. Дефектом это становится, когда документация обещает ограниченные полномочия, а код предоставляет расширенные.

Манипуляция ценовыми оракулами

Цена, взятая из спотового пула, является рыночной наблюдаемой величиной с конкретными границами ликвидности. Внутри одной транзакции она может быть кратно сдвинута внесением капитала, выводом ликвидности или исполнением крупного свопа.

Аудит должен проследить путь цены: источник, агрегатор, задержка обновления, обработка устаревших данных, точность decimals и поведение при недоступности источника. Отдельно проверяются fallback-сценарии и возможность использовать цену до обновления oracle.

TWAP и другие механизмы усреднения снижают зависимость от одного момента, но добавляют задержку и собственные допущения. Если протокол использует такой механизм, аудитору нужен анализ задержки, допустимого отклонения цены и поведения при резком изменении рынка.

Флеш-займы

Флеш-займ — не уязвимость, а усилитель экономических атак. Капитал доступен в рамках одной транзакции и должен быть возвращён до её завершения. Эта атомарность позволяет влиять на голосование, залог, ликвидацию или цену актива без длительного удержания позиции.

Проверяются сценарии, где значимая доля голосов зависит от временного баланса, collateral оценивается по изменяемой цене, ликвидация запускается при манипулируемом коэффициенте, либо экономическая целесообразность свопа зависит от заемных средств. Полезно также учитывать порядок исполнения транзакций в мемпуле и влияние private order flow.

PoC для такого класса должен показывать полный цикл: получение капитала, манипуляцию, выгодное действие, погашение займа и итоговый profit или loss. Демонстрация одного аномального значения цены недостаточна.

Reentrancy и порядок внешних вызовов

Реентранси остается классической уязвимостью, хотя с 2016 года, после атаки The DAO, разработчики активно применяют checks-effects-interactions и reentrancy guards. На уровне отдельных функций ошибка может выглядеть безобидно: внешний вызов происходит раньше обновления состояния, а callback успевает вернуться в исходный контекст.

Проверяются межфункциональная reentrancy, повторные входы через произвольный target, callbacks токенов с нестандартной логикой и ошибки, возникающие при частичном revert внешнего вызова. В call trace аудитор ищет конкретный путь, который нарушает инвариант до фиксации нового состояния.

Инварианты и композиционность

Сложные протоколы редко падают из-за одной неверной формулы. Ошибка возникает на пересечении депозита, mint, redemption, collateral ratio, liquidation, rewards и rounding. Например, локально корректное округление может позволить многократно извлечь остаток аккаунта или начислить вознаграждение без достаточного объёма залога.

Composability добавляет внешний контур доверия. Если контракт вызывает DEX, lending protocol или oracle, их код может лежать вне scope. Аудит фиксирует границу: проверяется интерфейс, предполагаемое поведение зависимости и обработка неожиданного ответа. Риск последующей эксплуатации чужого контракта остаётся резидуальным.

ВекторАртефакт аудитаЧто он должен доказать
Контроль доступаМатрица ролей и transition diagramКто способен изменить состояние, стоимость и цену привилегии
ОракулКарта источников ценыНасколько свежа, защищена и устойчива к отказам цена
Флеш-займЭкономическая трассировка сценарияДостижима ли атака при атомарном капитале
ReentrancyCall trace с callbackНарушается ли инвариант до обновления state
ИнвариантыНабор проверяемых свойствСохраняются ли платёжеспособность и корректность расчётов
Критический вектор возникает там, где протокол принимает внешнее значение за доверенное.

Матрица серьёзности дефектов

Оценка строится по трём осям: Impact, Likelihood и Exploitability. Такой подход связывает техническую находку с эксплуатационным риском и не позволяет объявлять Critical любую ошибку, найденную формальным анализатором.

Impact охватывает потерю средств, изменение полномочий, нарушение платёжеспособности, блокировку операций, порчу состояния и другие последствия. Likelihood зависит от достижимости состояния, необходимых полномочий, рыночных условий, доступного капитала и порядка транзакций. Exploitability показывает сложность атаки, число шагов, зависимость от race condition, flash loan или внешнего оракула.

ГрадацияImpactLikelihood и ExploitabilityОжидаемое подтверждение
CriticalНевосстановимая потеря средств, захват контроля, критическое нарушение инвариантаПуть достижим при реалистичных условиях, эксплуатация воспроизводимаПолный PoC, состояние до и после, оценка потерь
HighСущественный ущерб с ограниченной областью действияУсловия атаки достижимы, но требуют ресурсов или подготовкиPoC либо детальная трассировка с обоснованием эксплуатации
MediumОграниченное влияние на отдельные сценарии или пользователейЭксплуатация зависит от дополнительных условийВоспроизводимая последовательность действий
LowНезначительное влияние без прямого нарушения безопасностиСложная или маловероятная эксплуатацияОписание состояния и последствий
InformationalПроблема качества, документации или наблюдаемости без прямого security impactНеприменимоРекомендация без привязки к атаке
Gas OptimizationИзбыточный overhead, потенциальное удорожание или локальная потеря доступностиЗависит от модели использования и нагрузкиБенчмарк или расчёт overhead

Gas Optimization следует держать отдельно от эксплуатируемых уязвимостей. Неоптимальный расход газа сам по себе не равен потере средств, хотя плохое распределение газа способно блокировать вызовы.

Finding высокой серьёзности должен содержать предусловия, точные шаги, ожидаемое и фактическое состояние, затронутые функции и рекомендуемое исправление. Если PoC отсутствует, аудитор должен явно объяснить, почему воспроизведение нецелесообразно или невозможно в текущем scope.

Жизненный цикл проверки и приёмка отчёта

Для комплексного аудита контракта среднего масштара типичный таймлайн составляет 2–4 недели. Это ориентир для планирования, а не гарантия срока: количество ролей, внешних интеграций и моделируемых состояний способно изменить трудоёмкость.

1. Scoping. Фиксируются commit, compiler, зависимости, адреса, chain ID, proxy, deploy-конфигурация, права первоначального admin и внешние зависимости. Отдельно оценивается, соответствует ли проверяемый source задеплоенному bytecode.

2. Архитектурная модель. Описываются роли, trust boundaries, state machine, источники цены и критические инварианты. Этот артефакт нужен до запуска сканеров.

3. Автоматический анализ. Slither и MythX обрабатывают исходный код и граф зависимостей. Результаты переводятся в инженерные гипотезы, а не копируются в итоговый отчёт.

4. Ручное ревью. Построчно и по call path проверяются переходы состояния, контроль доступа, порядок вызовов и экономические допущения.

5. Классификация и PoC. Находки ранжируются по Impact, Likelihood и Exploitability. Для критических и высоких рисков подтверждается эксплуатационный путь.

6. Remediation. Разработчик вносит исправления. Аудитор проверяет diff, полноту исправления и отсутствие регрессий.

7. Fix verification. Изменённый commit повторно прогоняется через релевантные тесты и ручные сценарии. Финальный отчёт фиксирует статус каждой находки.

Приёмка результата аудита проводится по артефактам, а не по обещаниям. В пакете должны быть:

  • неизменяемый scope с commit hash, версией компилятора и перечнем исключений;
  • матрица покрытия SCSVS с обоснованием статуса каждого контроля;
  • модель ролей, trust boundaries и проверяемых инвариантов;
  • findings со ссылками на строки или участки кода, root cause и серьёзностью;
  • PoC либо техническая трассировка для критических и высоких находок;
  • описание remediation, diff и результат повторной проверки;
  • перечень остаточных рисков, включая composability, внешние oracle и компрометацию административных ключей.

Вердикт. Для production Web3-приложения приемлемая базовая конфигурация аудита сочетает автоматический анализ, ручное ревью, проверку PoC и верификацию исправлений. Один только отчет сканера не покрывает бизнес-логику и композиционные атаки. Для небольшого контракта можно сократить глубину формальной верификации и число моделируемых сценариев, сохранив ручной разбор.

Успешный аудит не гарантирует 100% отсутствие уязвимостей. Его вывод относится к согласованному commit, зафиксированной конфигурации и обозначенной модели угроз. Изменение кода, деплой с другими параметрами, компрометация oracle, изменение рынка или новая уязвимость во внешнем протоколе создают новый контур риска. Поэтому аудит снижает неопределённость на конкретной версии системы; репутация команды и заверения маркетинга эту неопределённость не устраняют.

Частые вопросы

Что такое composition failure в смарт-контрактах?
Это уязвимость, которая возникает на стыке нескольких модулей, когда атакующий изменяет цену, использует заемный капитал и совершает действие до восстановления исходного состояния, что обычно не видит статический анализ.
Какую долю трудозатрат комплексного аудита занимает ручной анализ?
По данным отраслевой практики, на ручной анализ приходится примерно 60–70% трудозатрат комплексного аудита.
Каковы четыре уровня для рабочего аудита смарт-контрактов?
Для рабочего аудита полезно разделять контроль, слабость, finding и severity.
Какие риски отдельно выделены в OWASP Smart Contract Top 10?
В OWASP Smart Contract Top 10 отдельно выделены риски манипуляции ценовыми оракулами, использования флеш-займов и нарушений контроля доступа.
По каким трем осям строится оценка дефектов при аудите?
Оценка дефектов строится по трем осям: Impact, Likelihood и Exploitability.