Каталог уязвимостей смарт-контрактов: 12 классических ошибок и защита от них
Обзор частых уязвимостей контрактов: реентерабельность, контроль доступа, переполнение, оракулы, повтор подписей, DoS. С примерами и защитой в эскроу.
В этой статье
Смарт-контракты - публичные программы, хранящие деньги, и потому за ними охотятся. Хорошая новость: бо́льшая часть взломов повторяет одни и те же схемы. Знание каталога - первый шаг и для разработчика, и для того, кто оценивает контракт (как проверить контракт). Для каждой уязвимости мы покажем суть, пример и защиту.
1. Реентерабельность
Суть. Контракт отправляет деньги внешнему адресу до обновления своего состояния. Получатель в ответ повторно вызывает контракт и «снимает» деньги ещё раз.
История. Взлом The DAO (2016, около 60 млн долларов) разделил сеть Ethereum на две.
Защита. Порядок «проверки - изменение состояния - внешние вызовы», защита nonReentrant, платежи «по запросу» (разбор).
2. Нарушенный контроль доступа
Суть. Критичная функция доступна тем, кому не должна: забыт onlyOwner, открыт инициализатор, tx.origin вместо msg.sender.
Защита. Явные проверки, принцип минимальных прав, мультиподпись для владельца (шаблоны).
3. Арифметика: переполнение и усечение
Суть. До Solidity 0.8 числа «переходили через ноль» без ошибки. В 0.8+ это проверяется, но явное приведение типов (uint96(x)) всё ещё обрезает молча.
Защита. Версия 0.8+, проверка диапазона перед приведением, SafeCast, внимательность в unchecked (целые числа).
4. Невыверенные внешние вызовы
Суть. Низкоуровневый вызов (call) возвращает false при ошибке, но не откатывает транзакцию. Если проигнорировать результат, контракт решит, что платёж прошёл.
Защита. Всегда проверять результат, использовать SafeERC20 для токенов, у которых transfer не возвращает значение (особенности токенов).
5. Манипуляция ценой и оракулами
Суть. Контракт берёт цену из источника, который можно исказить, например из текущего состояния пула. Атакующий с помощью флеш-займа (кредит на одну транзакцию) на мгновение сдвигает цену и забирает прибыль. Это стоило протоколам сотни миллионов долларов.
Защита. Надёжные оракулы, усреднённые цены, проверка свежести данных (проблема оракулов).
6. Фронтраннинг
Суть. Транзакции видны в mempool до включения в блок. Наблюдатель может вставить свою транзакцию перед вашей и заработать на этом.
Защита. Ограничения проскальзывания, схемы commit-reveal, приватные пулы транзакций (MEV).
7. Повтор и подделка подписей
Суть. Подпись, проверенная без nonce, срока и привязки к сети, может быть использована повторно или в другой сети. Подпись также «изменяема» (подписи).
Защита. EIP-712, nonce, deadline, chainId, библиотечная проверка.
8. Ошибки делегирования и прокси
Суть. delegatecall исполняет чужой код с хранилищем вызывающего. Несовпадение раскладок, незащищённый инициализатор или самоуничтожаемая библиотека приводят к катастрофе. В 2017 году из-за ошибки в библиотеке кошельков Parity заблокировали около 150 млн долларов в ETH.
Защита. Проверенные паттерны, защита инициализации, тесты раскладки (прокси).
9. Отказ в обслуживании (DoS)
Суть. Один «плохой» участник блокирует всех. Классика: цикл по списку получателей, где один отклоняет платёж, и вся операция откатывается. Либо неограниченный цикл, на который не хватает газа.
Защита. Модель «забери сам» (pull), ограничение газа на внешние вызовы, отсутствие неограниченных циклов.
В эскроу. Если выплата получателю не прошла (адрес заблокирован эмитентом токена или контракт не принимает ETH), сумма записывается ему как кредит, а сделка закрывается. Один проблемный получатель не блокирует остальных. Вызов получателя ограничен 50 000 газа (разбор).
10. Принудительная отправка эфира
Суть. Любой может отправить ETH контракту, даже если у него нет приёма (через selfdestruct или как получатель награды за блок). Если логика опирается на address(this).balance, её можно сломать.
Защита. Вести собственный учёт, а не полагаться на баланс. В эскроу учёт ведётся через reserved, а лишние поступления попадают в категорию «неучтённых» и не влияют на сделки.
11. Зависимость от времени и случайности
Суть. block.timestamp может отклоняться на секунды, а «случайные» значения из блока (хеши, время) предсказуемы и манипулируемы валидатором.
Защита. Не использовать время для ответственных проверок с малым допуском; случайность - только из надёжных источников.
В эскроу. Сроки измеряются сутками и более, секундная погрешность ни на что не влияет.
12. Ложные предположения о токенах
Суть. Контракт считает, что токен ведёт себя как эталонный ERC-20, а он берёт комиссию, меняет балансы, блокирует адреса или имеет ошибку.
Защита. Белый список токенов, сверка фактически полученной суммы с заявленной (токены). Эскроу принимает только разрешённые токены и отклоняет несоответствие сумм (AmountMismatch).
Бонус: данные «приватных» переменных читаемы
Любой слот хранилища публичен, даже у private переменной (раскладка хранилища). Секреты в контракте хранить нельзя.
Как эскроу применяет защиту: сводка
| Угроза | Мера |
|---|---|
| Реентерабельность | nonReentrant, состояние обновляется до выплат |
| Контроль доступа | проверки сторон сделки, Ownable2Step, пауза только новых сделок |
| Усечение числа | явная проверка AmountTooLarge |
| DoS через получателя | кредиты и ограничение газа |
| Принудительная отправка | учёт reserved вместо баланса |
| Нестандартные токены | белый список, проверка полученной суммы |
Не вся безопасность - в коде
Уязвимости бывают и вне контракта: взломанные ключи, подмена интерфейса, ошибочные подписи людей. Крупнейший взлом 2025 года (биржа Bybit, около 1,5 млрд долларов) начался с компрометации интерфейса, который показывал подписантам мультиподписи не те данные. Поэтому важны и личные правила, и аудит.
Что почитать дальше
Узнайте, как проверяют контракты перед запуском: аудиты и баг-баунти. Или как их защищают тестами: тестирование смарт-контрактов.
Читайте также
- 3 · Под капотом
Аудиты и баг-баунти: как проверяют смарт-контракты и как читать отчёт
Как проходит аудит смарт-контракта, какие бывают уровни серьёзности, чем аудит не является, как читать отчёт, а также как устроены баг-баунти и соревнования.
3 мин чтения - 3 · Под капотом
Реентрантность, checks-effects-interactions и pull-платежи
Как работает атака повторного входа, взломавшая The DAO, и как от неё защищаться: порядок операций, ReentrancyGuard и отложенные платежи на примере эскроу.
5 мин чтения
Упоминается в статьях
- Токены и NFT: что это, чем отличаются и где применяются
- Мосты между сетями: как переносят активы и почему это самое рискованное место
- Как проверить смарт-контракт перед использованием: пошаговая инструкция
- ERC-20 с нуля: пишем токен на Solidity и разбираем каждую строку
- Подписи в Ethereum: ECDSA, ecrecover, personal_sign и EIP-712
- Раскладка хранилища и упаковка переменных в Solidity
- Шаблоны контроля доступа в смарт-контрактах: owner, роли и стороны сделки
- Реентрантность, checks-effects-interactions и pull-платежи
- Нестандартные токены: USDT без return, fee-on-transfer, блэклисты и decimals
- Прокси и обновляемые контракты: delegatecall, UUPS и цена гибкости
- Деревья Меркла и доказательства: как проверять миллионы данных одним хешем
- Оракулы и проблема оракулов: как блокчейн узнаёт о внешнем мире
- Оптимизация газа в Solidity: 12 приёмов и когда они уместны
- MEV и фронтраннинг: кто и как зарабатывает на порядке транзакций
- Абстракция аккаунтов (ERC-4337): умные кошельки и спонсирование газа
- Тестирование смарт-контрактов: unit, fuzz, инварианты и статический анализ
- Аудиты и баг-баунти: как проверяют смарт-контракты и как читать отчёт
Готовы попробовать?
Создайте первую сделку за пару минут. Деньги блокируются в смарт-контракте и выплачиваются по правилам, которые видны заранее.

