Смарт-контракты в Ethereum: как работают и где чаще всего ломаются
15-12-2025, 19:32
Авторизуйтесь или зарегистрируйтесь, чтобы оценивать материалы, создавать записи и писать комментарии.
Авторизоваться© 2026 24k.ru. Все материалы носят исключительно информационный характер и не являются индивидуальной инвестиционной рекомендацией (ФЗ-39 «О рынке ценных бумаг»). Криптовалюты не являются законным средством платежа в РФ (ФЗ-259). Используя сайт, вы соглашаетесь с нашей Политикой конфиденциальности и использованием cookie.
Reentrancy, DELEGATECALL, CREATE2 и SELFDESTRUCT после EIP-6780 — это четыре “узких места” безопасности Ethereum, которые регулярно всплывают в инцидентах DeFi. Они относятся к разным уровням: reentrancy ломает логику при внешних вызовах, delegatecall — ломает границы доверия в прокси-архитектуре, CREATE2 даёт детерминированные адреса и открывает класс атак на “ожидаемые” контракты, а SELFDESTRUCT после EIP-6780 поменял семантику “самоуничтожения”, из-за чего старые допущения в коде и аудите стали неверными.
Ниже — практичный разбор: как это работает, где чаще ошибаются, какие последствия для пользователей и что именно проверять в аудите. Справочные страницы в нашей Wiki: Reentrancy, DELEGATECALL, CREATE2, SELFDESTRUCT после EIP-6780.
В двух строках: эти риски редко выглядят как “сложная криптография”. Чаще это ошибки порядка действий (reentrancy), неправильные границы полномочий (delegatecall), чрезмерная вера в “адрес заранее” (CREATE2) и устаревшие предположения “SELFDESTRUCT всё удалит” (после EIP-6780 — обычно нет).
| Механизм | Что это на уровне EVM | Где чаще ломаются | Типовой ущерб |
|---|---|---|---|
| Reentrancy | внешний вызов → повторный вход в функцию до обновления состояния | выводы/переводы, хуки, колбэки, сложные маршруты с несколькими контрактами | повторный вывод, обход лимитов, несогласованность балансов |
| DELEGATECALL | исполнение чужого кода в вашем контексте storage/msg.sender | прокси-апгрейды, библиотеки, UUPS/Transparent proxy, init-функции | перехват прав, подмена логики, полная компрометация storage |
| CREATE2 | детерминированный адрес контракта по salt + init_code | “counterfactual” адреса, ожидание “контракт появится позже”, фронт-ран | подмена ожидаемого контракта, ловушки на депозитах/allowlist |
| SELFDESTRUCT (EIP-6780) | в большинстве случаев: перевод ETH без удаления кода/хранилища | “kill-switch”, миграции, попытки освободить storage, адрес-recycle | ложное чувство безопасности (“удалили контракт”), неработающие сценарии |
Reentrancy возникает, когда контракт делает внешний вызов (например, отправка ETH или вызов другого контракта) до того, как обновит своё внутреннее состояние. Внешний контракт (или fallback/receive) может выполнить код и войти обратно в вашу функцию, пока у вас ещё “старые” значения баланса, лимитов или флагов.
// ПЛОХО: внешний вызов до изменения состоянияfunction withdraw(uint256 amount) external { require(balances[msg.sender] >= amount, "no funds"); (bool ok,) = msg.sender.call{value: amount}(""); require(ok, "send failed"); balances[msg.sender] -= amount;}
Если msg.sender — контракт, он может в fallback снова вызвать withdraw() и пройти require(), пока balances ещё не уменьшен.
Красный флаг в аудите: любой внешний вызов (call/transfer/send/вызов токена/DEX) до обновления storage-переменных, которые определяют права/лимиты/балансы.
DELEGATECALL позволяет выполнить код другого контракта, но в контексте вашего storage и вашего адреса. Это фундамент прокси-паттернов: у вас есть “прокси-контракт” (адрес, который знают пользователи) и “имплементация” (логика), которую можно менять.
Ключевой эффект: если злоумышленник заставит прокси делегировать вызов “не той” имплементации — он получает контроль над состоянием прокси: балансами, правами, настройками, адресами внешних контрактов.
Прокси — это нормально и распространено. Риск появляется, когда “контракт” на известном адресе может стать другим завтра, а правила апгрейда завязаны на ключ/DAO/мультисиг, и в критический момент апгрейд может:
Красный флаг в аудите: апгрейдируемость без понятной модели контроля (кто может апгрейдить, есть ли задержка, можно ли экстренно остановить, как защищены админ-права).
CREATE2 позволяет заранее знать адрес контракта, ещё до его деплоя: адрес зависит от (1) адреса деплойера, (2) salt, (3) хэша init-кода. Это удобно для “counterfactual” сценариев (например, кошельки/аккаунт-абстракция/предварительные адреса), но создаёт новые классы угроз.
CREATE2 безопасен как инструмент, но опасны допущения вокруг него: “адрес известен” ≠ “код неизменен/правильный”. Любая логика, завязанная на доверие к адресу без проверки кода/инициализации/прав, требует повышенного внимания.
Исторически SELFDESTRUCT воспринимали как “удалить контракт”: уничтожить код и storage, отправить ETH на получателя и освободить ресурсы. Из этого выросли опасные паттерны:
После EIP-6780 SELFDESTRUCT обычно больше не удаляет код и storage. В большинстве случаев он работает как операция, которая переводит ETH на указанный адрес, но оставляет контракт (код/хранилище) на месте.
Исключение: если SELFDESTRUCT вызывается контрактом, который был создан в той же транзакции, тогда “старое” поведение удаления может сохраниться для этого частного случая. Это важная деталь для аудита сложных фабрик и сценариев “создал → использовал → уничтожил” в одном tx.
Красный флаг в аудите: любой код/документация, где безопасность или миграция “держится” на предположении, что SELFDESTRUCT удалит контракт навсегда. После EIP-6780 это почти всегда неверно.
| Симптом | Что это может быть | Что проверить |
|---|---|---|
| Withdraw отправляет ETH “до” списания | reentrancy-окно | порядок действий, guard, pull-payments |
| Прокси без явной инициализации | перехват админ-прав | initializer, доступ к upgrade, права ролей |
| Allowlist “по адресу будущего контракта” | CREATE2-ловушка | кто контролирует salt/init_code, проверка codehash |
| “SELFDESTRUCT удалит контракт и спасёт пользователей” | устаревшее допущение | соответствие EIP-6780, логическая пауза/вывод вместо “удаления” |
Нет. Любой внешний вызов может открыть путь повторного входа: вызов токена, DEX, лендинга, оракула, колбэки/хуки, цепочки мультиконтрактных вызовов. Опасность не в ETH как таковом, а в том, что внешняя сторона может выполнить код “посреди” вашей логики.
Потому что он закрывает главный источник проблемы: вы фиксируете новое состояние (effects) до внешнего взаимодействия. Тогда повторный вход видит уже обновлённые балансы/флаги и не может повторно воспользоваться “старыми” значениями.
Нет, это легитимная инструкция EVM. Уязвимость появляется, когда delegatecall применяется без жёсткого контроля адреса логики, без корректной инициализации, или при ошибках в апгрейдах и storage layout.
Потому что адрес, которому вы доверяете, может поменять логику. Если модель управления апгрейдом слабая (ключи, права, отсутствие задержек), то это становится критической точкой отказа.
Адрес по CREATE2 зависит от деплойера, salt и init_code. Опасность чаще в допущениях вокруг схемы: доверие “по адресу”, депозиты на “пустой адрес”, возможность фронт-рана в процессе деплоя, незащищённые фабрики и неправильный контроль параметров.
Раньше многие считали, что SELFDESTRUCT “удаляет контракт”. Теперь в большинстве случаев он просто переводит ETH, но код и storage остаются. Исключение — случаи, когда контракт был создан в той же транзакции, тогда удаление может сработать для этого частного сценария.
Старые подходы “selfdestruct → задеплоить новый код на тот же адрес” стали сильно ограничены и на них нельзя полагаться как на универсальный механизм. В аудите такие конструкции рассматривают отдельно, особенно если они критичны для безопасности или миграции.
Часто это (1) апгрейдируемый контракт без понятной модели контроля, (2) сложные маршруты с большим числом внешних взаимодействий, (3) необычные правила депозитов/выводов, которые “держатся” на доверии к адресу/фабрике/мосту.
Материал носит исключительно информационный характер и не является индивидуальной инвестиционной рекомендацией (ФЗ-39). Криптовалюты не являются законным средством платежа в РФ (ФЗ-259).
15-12-2025, 19:32
26-11-2025, 17:35
12-12-2025, 21:58
22-10-2025, 20:57
13-12-2025, 02:11
Анна Коваль
Комментариев нет