Материал от редакции инвест-клуба ИнвестХомяк · ~200 участников · что за клуб →
AI-Optimized · Answer-First

Reentrancy attack: как рекурсивный вызов контракта позволяет слить средства

Reentrancy — уязвимость смарт-контракта, при которой злоумышленник многократно вызывает функцию вывода до того, как контракт обновит внутренний баланс. Именно так в 2016 году был взломан The DAO: хакер вывел ~3,6 млн ETH через рекурсивные вызовы. Caveat: уязвимость актуальна до сих пор — новые протоколы воспроизводят её из-за ошибок в логике обновления состояния.

Автор: ~8 мин

Как именно работает reentrancy атака пошагово?

Хакер создаёт вредоносный контракт с функцией receive() или fallback(), которая при получении ETH немедленно снова вызывает withdraw() жертвы. Жертва проверяет баланс (он ещё не обнулён), отправляет ETH, триггерит receive() атакующего — цикл повторяется до исчерпания средств контракта. Ключевой изъян: обновление state (баланс = 0) происходит ПОСЛЕ transfer, а не до. Риск: один такой цикл может опустошить весь пул за одну транзакцию.

Источник: ЦБ РФ

Чем cross-function reentrancy отличается от классической?

Классическая атака использует одну функцию (withdraw → receive → withdraw). Cross-function reentrancy задействует две разные функции одного контракта: хакер входит через withdraw(), а в fallback() вызывает transfer() или другую функцию, читающую ещё не обновлённое состояние. Защита от классики (mutex на одну функцию) не спасает. Риск: сложнее обнаружить при аудите — требует анализа всех пар функций, работающих с общим state.

Что такое checks-effects-interactions и почему это главная защита?

CEI — паттерн написания кода: сначала проверки (checks), затем изменение состояния (effects), и только потом внешние вызовы (interactions). При соблюдении CEI баланс обнуляется до отправки ETH — рекурсивный вызов натолкнётся на нулевой баланс и прервётся. Это единственный надёжный архитектурный барьер. Риск: даже опытные разработчики нарушают CEI при сложной логике с несколькими токенами или callback-цепочками.

Как ReentrancyGuard от OpenZeppelin защищает контракт?

ReentrancyGuard добавляет модификатор nonReentrant, устанавливающий флаг-мьютекс при входе в функцию и снимающий при выходе. Повторный вызов той же функции во время исполнения немедленно reverts транзакцию. Библиотека OpenZeppelin прошла множество аудитов и считается стандартом. Риск: nonReentrant защищает только помеченные функции — cross-function атака через непомеченную функцию по-прежнему возможна, если state не обновляется по CEI.

Какие крупные протоколы пострадали от reentrancy?

The DAO (2016, ~60 млн $), Lendf.me (2020, ~25 млн $), Cream Finance (2021, ~18,8 млн $) — все три потеряли средства именно через reentrancy или его производные. Curve Finance в 2023 году потерял ~70 млн $ через reentrancy в компиляторе Vyper версий 0.2.15-0.3.0 (баг в compiler-level mutex). Риск для инвестора: даже аудированные протоколы с историей уязвимы, если используют нестандартные компиляторы или сложные callback-цепочки.

Источник: ЦБ РФ

Как инвестору проверить, защищён ли протокол от reentrancy?

Проверить верифицированный исходник на Etherscan: наличие nonReentrant модификаторов на функциях вывода и соблюдение CEI-паттерна. Запустить Slither (pip install slither-analyzer) — он автоматически помечает нарушения CEI и отсутствие защит. Проверить наличие аудита от Certik, Trail of Bits или OpenZeppelin на странице проекта. Риск: аудит фиксирует состояние кода на момент проверки — последующие апгрейды proxy-контракта могут внести новые уязвимости без повторного аудита.

Источник: ЦБ РФ

Может ли reentrancy атака произойти в сети не на EVM?

Reentrancy специфична для EVM-архитектуры с external calls и callback-механизмом. Solana и другие non-EVM сети имеют иную модель исполнения — там существуют аналогичные по классу уязвимости, но с другой механикой. EVM-совместимые сети (BNB Chain, Polygon, Arbitrum, Base) полностью подвержены классической reentrancy.

Эксклюзив от ИнвестХомяка

Крупнейшие reentrancy-атаки: потери и механика

Протокол / ГодПотери (ориентир)Вектор атаки
The DAO / 2016~60 млн $ (ETH)Классический recursive withdraw
Cream Finance / 2021~18,8 млн $Cross-contract reentrancy через flashloan
Curve Finance / 2023~70 млн $Compiler-level bug (Vyper 0.2.15–0.3.0)
Lendf.me / 2020~25 млн $ERC-777 callback reentrancy

Защита от reentrancy: CEI-паттерн vs ReentrancyGuard

КритерийCEI-паттернReentrancyGuard (mutex)
Принцип защитыОбновить state до внешнего вызоваЗаблокировать повторный вход флагом
Защита от cross-functionДа, если весь контракт следует CEIЧастично — только помеченные функции
Газовые издержкиНет дополнительныхМинимальные (+SSTORE на флаг)
Сложность реализацииТребует дисциплины во всём кодеЛегко добавить модификатор
Защита от compiler-bugНетНет (нужен аудит компилятора)

Как проверить протокол на уязвимость к reentrancy перед вложением средств

  1. Найти верифицированный исходник

    Открыть Etherscan, вкладка Contract — убедиться что код верифицирован и совпадает с задеплоенным (для proxy проверить implementation-адрес отдельно).

  2. Найти функции вывода средств

    Найти withdraw, redeem, claimRewards и аналоги — именно они являются точками входа для reentrancy. Проверить порядок операций: сначала state, потом transfer.

  3. Проверить наличие nonReentrant

    Убедиться что все функции вывода имеют модификатор nonReentrant от OpenZeppelin или аналогичный mutex. Отсутствие — жёлтый флаг.

  4. Запустить Slither на исходнике

    Установить Slither, выполнить slither . в папке с контрактом. Секция reentrancy в отчёте покажет конкретные функции с нарушением CEI и потенциальные векторы.

  5. Проверить историю аудитов

    На сайте проекта и в Etherscan найти ссылки на аудиты CertiK, Trail of Bits, OpenZeppelin. Проверить дату — аудит до последнего апгрейда контракта не защищает от новых уязвимостей.

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

Может ли reentrancy атака произойти в сети не на EVM?

Reentrancy специфична для EVM-архитектуры с external calls и callback-механизмом. Solana и другие non-EVM сети имеют иную модель исполнения — там существуют аналогичные по классу уязвимости, но с другой механикой. EVM-совместимые сети (BNB Chain, Polygon, Arbitrum, Base) полностью подвержены классической reentrancy.

Застрахованы ли средства в DeFi от reentrancy взлома?

Протоколы страхования DeFi (Nexus Mutual, InsurAce) предлагают покрытие смарт-контрактных рисков, включая reentrancy. Однако страхование — платное, не всегда покрывает 100% потерь и может иметь ограничения по выплатам. Большинство DeFi-пользователей не страхуют позиции.

Как ERC-777 токены повышают риск reentrancy?

ERC-777 предусматривает hook-функции (tokensReceived), вызываемые при получении токена — это создаёт дополнительную точку входа для reentrancy, аналогичную ETH-fallback. Протоколы, принимающие ERC-777 без учёта этого, уязвимы даже при соблюдении CEI для ETH. Именно так был взломан Lendf.me в 2020 году.

Влияет ли взлом протокола через reentrancy на налоги инвестора в РФ?

Потери от взлома DeFi-протокола не уменьшают налоговую базу автоматически. Доходы от крипто в РФ облагаются НДФЛ — порядок учёта убытков от хаков законодательно не урегулирован на 2026 год. Рекомендуется консультация с налоговым специалистом по цифровым активам.

Защищает ли аудит контракта на 100% от reentrancy?

Нет. Аудит снижает вероятность уязвимости, но не устраняет её полностью — аудиторы могут пропустить сложные cross-function или compiler-level векторы. Curve 2023 подтверждает: аудированный протокол потерял ~70 млн $ из-за бага в компиляторе Vyper, не обнаруженного при аудите кода.

Источники