Reentrancy
Класс уязвимостей смарт-контрактов, при котором внешний вызов возвращается в исходный контракт до завершения его текущего исполнения, и атакующий получает возможность повторить опасное действие. Архитектура TON делает классический reentrancy невозможным.
Синонимы: реентрансия, реентерабельность, reentrancy attack
Reentrancy — самая известная уязвимость в истории Ethereum: эксплойт DAO в 2016 году, приведший к hard fork сети, был именно reentrancy. В классической EVM-модели это работает так: контракт A вызывает контракт B (или передаёт ETH), B в callback вызывает A повторно до того, как A завершит свою функцию, и A повторно выполняет уязвимое действие — например, второй раз снимает баланс.
Почему это работает в EVM
EVM-контракты исполняются синхронно: вызов другого контракта блокирует вызывающий контракт, и управление возвращается только после исполнения вызванного. Если вызванный контракт исполнит «обратный» вызов, он попадёт в state исходного контракта до того, как тот завершит обновление своих данных.
Почему это невозможно в TON
В TON принципиально другая архитектура — асинхронные сообщения между контрактами:
- Контракт A не вызывает контракт B напрямую — он отправляет ему сообщение.
- Сообщение попадает в очередь и обрабатывается в следующей транзакции.
- Текущая транзакция A завершается. State обновляется атомарно.
- Только потом B обрабатывает сообщение и, если хочет ответить, отправляет своё сообщение в очередь.
То есть «повторно вызвать A до завершения текущего вызова» физически нельзя — текущий вызов уже завершился до того, как B вообще начнёт обработку. Это закрывает классический reentrancy на уровне модели исполнения.
Что вместо этого может пойти не так
Асинхронность даёт другие классы багов, специфичных для TON:
- Race conditions между сообщениями. Контракт ждёт ответа от B, а тем временем приходит сообщение от C, которое меняет state. Если разработчик не учёл этот сценарий — баг.
- Bounce-сообщения. Если транзакция выполнится, но B не сможет её принять (например, его кода не хватит газа), сообщение «отскакивает» обратно к A. Корректно обработать bounce — отдельная задача.
- Out-of-order delivery. Сообщения между разными shard-ами могут прийти не в том порядке, в котором отправлены. Логика контракта должна это предусматривать.
Что значит для пользователя
Если кто-то говорит, что в TON «нет reentrancy и поэтому смарт-контракты безопасны» — это упрощение. Reentrancy действительно нет, но классы уязвимостей в TON есть свои, не менее серьёзные. Аудит контрактов всё равно обязателен; список того, что аудитор смотрит, просто другой.