Смарт-контракты могут использоваться не только в публичных блокчейнах, но и в корпоративных и permissioned‑EVM-сетях. При этом с аудитами безопасности по‑прежнему связано много упрощенных представлений: от веры в то, что они не нужны в приватной сети, до ожидания, что аудит способен гарантировать отсутствие уязвимостей.

Мы обсудили эти вопросы с нашим экспертом по аудиту смарт‑контрактов на Solidity, Владимиром Чечеткиным. Это интервью про рутинную работу, про то, как должен выглядеть зрелый код смарт‑контракта, где на практике возникают риски и почему ценность аудита часто понимают неправильно.

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

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

Владимир Чечеткин

Практикующий аудитор смарт-контрактов, специалист отдела безопасности распределенных систем Positive Technologies. Основная специализация — Solidity и EVM-сети. Работает с контрактами на разных стадиях жизненного цикла — от преддеплойных версий до развернутых on-chain-протоколов.

Про подход и мотивацию

🔻 Почему вы выбрали аудит смарт-контрактов, а не разработку?

🎙️ В каком-то смысле это призвание. Я из тех ребят, которые вечно указывают на мелкие неточности и неочевидные ошибки. В обычной разработке это часто раздражает окружающих, а в аудитах — наоборот, является ключевым навыком.

Кроме того, аудит дает то, чего мне не хватало бы в долгосрочной разработке: я не застреваю надолго в одном проекте, всегда есть элемент новизны и смены контекста. Плюс это редкая возможность совместить роли аналитика, программиста и тестировщика в рамках одной задачи.

🔻 Что для вас означает «хорошо написанный смарт-контракт»?

🎙️ Такой код в первую очередь хорошо читается. Он аккуратный, ровный, в нем понятно назначение каждого блока, а комментарии действительно помогают, а не дублируют очевидное. Код должен быть «привлекательным», вызывать ощущение правильности и завершенности.

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

🔻 Бывает ли код, к которому у аудитора почти нет вопросов?

🎙️ Как ни парадоксально, к совсем плохому коду вопросов обычно нет. В таких случаях все становится «понятно» довольно быстро — и по самому коду, и по уровню зрелости команды. Вопросы возникают как раз к хорошим контрактам, где решения неочевидны и требуют вдумчивого анализа. И чаще всего это вопросы вида: «Где же вы допустили ошибку?»

Про типичные ошибки и ложные предположения

🔻 Какие ошибки вы чаще всего видите в смарт-контрактах?

🎙️ Очень часто пренебрегают потерями при округлениях, считая их незначительными, — мол, кого интересует потеря нескольких wei? К сожалению, даже такие мелочи могут стать проблемой, которая эксплуатируется в пограничных состояниях протокола.

Часто встречаются ошибки в расчетах, невозврат лишних нативных токенов. Со стороны интерфейсов — некорректные значения в ивентах.

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

🔻 Какие предположения архитекторов чаще всего оказываются неверными?

🎙️ Пожалуй, самое типичное предположение — что пользователи будут действовать рационально, а любые ошибки пользователя останутся исключительно проблемами самого пользователя. В целом это допустимая позиция, но только до тех пор, пока такие ошибки не начинают влиять на работоспособность системы.

На практике пользовательские ошибки нередко приводят к состояниям, которые архитекторы не закладывали в модель угроз: блокировкам логики, неожиданным отказам или даже DoS-сценариям.

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

Приватные и permissioned-EVM-сети

🔻 Считается, что закрытые (или permissioned) сети существенно безопаснее. Согласны ли вы с этим?

🎙️ Здесь может скрываться психологическая ловушка. Когда на старте считается, что система «по определению защищена», это сильно снижает уровень внимания к остальным частям смарт-контрактов.

Фактически валидация вызовов полностью происходит в инфраструктуре. Но это убирает только часть рисков, которые проверяются при аудите.

🔻 Какие классы уязвимостей никуда не исчезают даже при контроле доступа на уровне нод?

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

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

Про управление и обновляемость

🔻 Где чаще всего ломается безопасность: в коде или в модели управления?

🎙️ В последние годы аудиторы уже перестали автоматически считать административные роли или владельцев протокола с расширенными полномочиями проблемой, принимая это как осознанный выбор. Здесь фокус смещается на техническую сторону: насколько такие функции вообще исполнимы, безопасно ли они выполняются и какие модели доверия к владельцам в них заложены.

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

🔻 Почему апгрейды и governance — один из самых сложных аспектов аудита?

🎙️ С governance я бы не стал обобщать — сами по себе модели управления редко являются основной проблемой. А вот изменений в протоколах — это действительно одна из самых сложных и неблагодарных частей аудита.

Когда говоришь коллегам, что делаешь diff-аудит, в ответ часто можно получить сочувственное похлопывание по плечу. Это самый неудобный и трудоемкий тип аудитов смарт‑контрактов. Почти всегда сложно корректно определить объем работы: помимо нового кода, приходится разбираться в логике всего потока, который был изменен или затронут апгрейдом.

По сложности с апгрейдами сопоставима разве что проверка фиксов по результатам аудита. Формально изменений может быть немного, но каждое исправление нужно рассматривать в контексте всей системы, чтоб�� убедиться, что оно не ломает существующие инварианты и не создает новых рисков.

Diff-аудит — аудит изменений в контракте, показывающий, что именно изменилось между старой и новой версией смарт-контракта и безопасны ли эти изменения.

Про идеальный код

🔻 Вы говорили, что хорошо написанный контракт выглядит привлекательно. Но что кроме внешнего вида указывает на качество кода?

🎙️ В хорошем коде даже в административных функциях входные параметры аккуратно валидируются. Первая мысль, конечно: «Фух, не придется писать раздражающее замечание про отсутствие валидации». Но именно из таких мелочей и складывается ощущение зрелого, продуманного контракта.

И уже после этого начинаешь разбираться глубже. Смотришь на код, цепляешься за какой‑то момент и сначала думаешь: «Ну как так, как это могли упустить?» А затем понимаешь, что все учтено, просто решение не лежит на поверхности. Это очень приятное ощущение.

🔻 Есть ли общие признаки, по которым это видно почти сразу?

🎙️ Да, такие признаки обычно хорошо заметны. У подобных проектов есть аккуратный README с понятными инструкциями по установке зависимостей и запуску тестов. Присутствует полноценная документация, часто с диаграммами, а тестами покрыт весь код, включая фаззинг‑тесты.

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

Про автоматизацию и подготовку команды к аудиту

🔻 Где заканчиваются автоматические инструменты и начинается работа аудитора?

🎙️ Я ожидаю, что команда использовала все доступные ей базовые инструменты проверки кода еще до начала аудита. Перекладывать тестирование и статический анализ на аудиторов — особенно в случае смарт‑контрактов — очень дорого, если речь идет о простых и доступных средствах. Если же говорить о дополнительном фаззинг‑тестировании и формальной верификации, то их едва ли можно отнести к автоматическим инструментам, так как они требуют настройки и участия специалиста.

Настоящая работа аудитора состоит в поиске кейсов, которые способны негативно повлиять на протокол. К этому моменту аудитор уже хорошо знаком с кодом и выполнил основные проверки. Результат принято измерять количеством найденных issues. При действительно чистом коде вместо списка уязвимостей аудитор ограничивается описанием перечня угроз, по которым код был проверен. Но это исключительные случаи. 

🔻 Что команда может сделать заранее, чтобы аудит был максимально полезным?

🎙️ Самые типичные проблемы — это мертвый код и копипаста известных библиотек. Если такие вещи убрать из скоупа аудита заранее, это экономит и время, и бюджет, а главное — повышает отдачу от самой проверки.

Отдельное внимание стоит уделять комментариям и документации. Они должны быть корректными и актуальными. Несоответствие между кодом и его описанием — частый источник ошибок и недопонимания, который сильно усложняет аудит.

Иногда по качеству кода проекта создается впечатление, что аудит используют как замену внутреннему ревью кода, привлекая аудиторов в роли приглашенных senior‑инженеров. Это редкие случаи, но они действительно встречаются.

Заключение

🔻 Если коротко: в чем главная ценность аудита смарт-контрактов?

🎙️ Основная ценность аудита проявляется, когда работа команды с аудиторами выстроена правильно. В таком формате аудит превращается в доверительное взаимодействие и дает эффект мультипликатора: команда получает независимую оценку своей работы, рекомендации по повышению надежности и новые идеи, которые сложно увидеть изнутри проекта.

При этом аудит нельзя переоценивать. Он не может гарантировать безопасность, но значительно снижает риск. Работа специалиста всегда ограничена по времени, при этом для отказа системы или успешной атаки достаточно одной‑единственной ошибки. В этом смысле закрытые (permissioned) сети действительно дают преимущество — у них есть дополнительный слой защиты.

Кроме того, для аудитора важно не навредить рекомендациями. Любое замечание должно улучшать систему в целом, а не просто формально «закрывать пункт» в отчете. В каком-то смысле аудиторы обучают команды, как делать код смарт-контракта безопасным.


Спасибо, что прочитали статью. Если есть вопросы по теме к Владимиру, пишите в комментариях.