Обучение

Как найти timelock, pause и аварийные права DeFi-протокола

Практическая проверка DeFi-протокола: как найти timelock, роли pause и unpause, определить охват остановки, проверить события и возможные обходные пути.

Как найти timelock, pause и аварийные права DeFi-протокола

Надпись «управляется DAO» не отвечает на главный вопрос безопасности DeFi-протокола: какой адрес прямо сейчас может изменить код, остановить операции или вывести систему из паузы. Для проверки нужно пройти цепочку от пользовательского контракта до конечного EOA, multisig, timelock или governance executor.

Timelock и pause решают разные задачи. Timelock откладывает заранее запланированное действие, чтобы участники увидели его до исполнения. Pause позволяет быстро остановить заданные функции при аварии. У одного протокола могут одновременно существовать DAO timelock, guardian с мгновенным pause, отдельный proxy admin и технические роли для рынков или oracle.

Шаг 1. Зафиксировать сеть и адреса

Начинайте не с сайта проекта, а с точного chain ID и адреса контракта, с которым взаимодействует пользователь. Один бренд может иметь разные deployments в Ethereum, L2 и sidechains. Роли и задержки в них необязательно совпадают.

Составьте таблицу целей: router, vault, lending pool, market controller, bridge, oracle adapter, token и governance executor. Запишите источник каждого адреса и номер блока проверки. Без этого легко исследовать старую implementation или контракт другой сети.

Проверьте, является ли адрес proxy. Если да, найдите текущие implementation, admin или beacon и повторите анализ для них. Пошаговый способ чтения ERC-1967 slots и событий Upgraded есть в руководстве по проверке proxy admin и implementation.

Шаг 2. Найти механизм остановки

В verified source и ABI ищите не только функции pause и unpause. Проекты используют названия emergencyShutdown, freeze, close, suspend, disableMarket, setGuardian или setTargetClosed. Затем посмотрите, какое условие доступа стоит у каждой функции: onlyOwner, onlyRole, restricted, проверка конкретного адреса или кастомный modifier.

Если контракт наследует OpenZeppelin Pausable, публичная функция paused() показывает глобальное состояние этого модуля, а события Paused и Unpaused помогают восстановить историю. Но само наследование ничего не останавливает автоматически. Разработчик должен вызвать внутренние механизмы паузы и поставить whenNotPaused или соответствующую проверку на конкретные операции.

Поэтому найдите все места, где читается флаг паузы. Отдельно запишите, затронуты ли deposits, withdrawals, borrowing, repayments, liquidations, transfers, claims, bridge messages и административные действия. «Протокол на паузе» может означать запрет новых депозитов при сохранении вывода или полную блокировку даже возврата средств.

Некоторые системы используют OpenZeppelin AccessManager. Его setTargetClosed способен закрывать restricted-функции выбранного target. Это не универсальный выключатель: функции без restricted и контракты, подключённые к другому manager, продолжат работать.

Шаг 3. Проследить роль до конечного владельца

Для Ownable прочитайте owner(). Для AccessControl проверьте DEFAULT_ADMIN_ROLE и роли, которые указаны в modifiers. Для AccessManager определите authority, role ID, участников роли, execution delay и guardian. Не останавливайтесь, если полученный адрес сам является контрактом.

Адрес может вести к Safe, DAO executor, TimelockController или ещё одному permission manager. Для Safe проверьте owners, threshold, modules и guard. Инструкция по владельцам multisig показывает, почему подписи 3 из 5 мало оценивать без типов владельцев и подключённых модулей.

Итоговая цепочка должна выглядеть конкретно: «pause может вызвать guardian Safe 2 из 3», «unpause доступен governance timelock», «upgrade выполняет ProxyAdmin, которым владеет другой Safe». Если в конце остаётся EOA, риск зависит от одного ключа, даже когда промежуточный контракт называется governance.

Шаг 4. Проверить TimelockController

У OpenZeppelin TimelockController прочитайте getMinDelay(). Затем проверьте участников PROPOSER_ROLE, EXECUTOR_ROLE, CANCELLER_ROLE и DEFAULT_ADMIN_ROLE. Proposer планирует операцию, executor исполняет её после готовности, canceller может отменить ожидающую операцию. Admin способен управлять ролями, поэтому его нельзя игнорировать.

Сам timelock часто является собственным admin, чтобы изменение ролей тоже проходило через задержку. На этапе настройки дополнительный admin мог быть оставлен у deployer. Проверьте текущий состав роли, а не предполагайте, что bootstrap-доступ уже отозван.

Нулевой адрес в EXECUTOR_ROLE обычно означает permissionless execution: после истечения задержки готовую операцию может отправить любой аккаунт. Это не даёт всем право планировать произвольные действия. Напротив, открытое исполнение уменьшает зависимость от доступности одного executor, но делает особенно важной корректность уже запланированной calldata.

Проверьте не только номинальную задержку. Событие MinDelayChange покажет её изменения, а смена delay в корректной конфигурации сама должна проходить через timelock. В кастомных реализациях найдите минимальный и фактически выбранный delay для каждого типа операций.

Шаг 5. Прочитать очередь и calldata

События CallScheduled раскрывают target, value, data, predecessor, salt и delay запланированной операции. Сопоставьте идентификатор операции с состоянием Pending, Ready, Done или Unset. Затем декодируйте первые четыре байта data как selector и оставшиеся параметры по ABI целевого контракта.

Название proposal может говорить об обновлении риска, тогда как calldata одновременно меняет implementation, выдаёт роль и переводит актив. Проверяйте каждый внутренний вызов batch-операции. Predecessor создаёт зависимость от другой операции, а salt различает одинаковые вызовы.

События CallExecuted и Cancelled показывают, чем закончились старые предложения. Полезно просмотреть несколько месяцев истории: фактический delay иногда длиннее минимума, а guardian может регулярно отменять и перепланировать действия. Отдельно ищите RoleGranted, RoleRevoked, OwnershipTransferred, Upgraded, AdminChanged, Paused и Unpaused.

Шаг 6. Найти обходы timelock

Timelock защищает только те действия, для которых он действительно является конечным владельцем. Если proxy admin принадлежит отдельному Safe без задержки, участники Safe могут заменить implementation и получить любые полномочия внутри proxy. Архитектурные различия таких обновлений разобраны в материале о Transparent, UUPS и Beacon Proxy.

Другие обходные пути – прямой guardian, admin AccessControl, роль выдачи новых ролей, beacon owner, module multisig, emergency upgrade, смена oracle или закрытие рынка через отдельный controller. Они могут быть оправданы оперативной безопасностью, но должны учитываться как реальные полномочия.

Проверьте и обратное направление. Быстрый pause у guardian полезен, если unpause или upgrade требуют timelock. Если тот же один EOA мгновенно останавливает и возобновляет все функции, задержка DAO не защищает пользователей от его решений.

Шаг 7. Оценить выход пользователя

Задержка полезна только при наличии рабочего пути выхода. Измерьте интервал между scheduling и execution, затем сравните его со временем вывода, cooldown, epoch, bridge finality и ликвидностью. Номинальные 48 часов не помогают позиции, которую разрешено закрывать лишь раз в неделю.

Для pause определите, можно ли погасить долг, внести collateral, избежать ликвидации, вывести неиспользуемые средства и отозвать approvals. Безопасная аварийная схема часто блокирует новые рисковые действия, но сохраняет repay и withdrawal там, где это возможно без ущерба учёту.

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

Краткий чек-лист

  • Записаны chain ID, адреса targets и номер блока проверки.
  • Найдены proxy, implementation, admin и beacon.
  • Определены все функции pause, freeze, close и emergency shutdown.
  • Проверен точный охват остановки для deposits, withdrawals, debt и liquidations.
  • Каждая роль прослежена до EOA, multisig, DAO или timelock.
  • Для multisig проверены owners, threshold, modules и guard.
  • Для timelock прочитаны delay, proposer, executor, canceller и admin.
  • Проверены scheduled operations, calldata и история событий.
  • Найдены прямые upgrade, oracle и role-management пути в обход задержки.
  • Понятно, какие действия доступны пользователю во время delay и pause.

Итог

Проверка timelock и pause – это построение графа полномочий, а не поиск одного адреса. Начните с пользовательских контрактов, раскройте proxy, найдите modifiers и роли, затем идите до конечных ключей. После этого сопоставьте формальную задержку с реальной очередью операций и доступным временем выхода.

Хорошая конфигурация делает мгновенными только узкие аварийные действия, оставляет пользователю безопасный путь сокращения риска и проводит обновления через наблюдаемую задержку. Если отдельный admin способен обойти timelock через upgrade или выдачу роли, именно этот путь определяет реальную модель доверия протокола.