Ревокация разрешений и чистка кошелька после дегена: гигиена approve
Если вы хоть раз подключали кошелёк к новой бирже, фармиле эйрдропы или тестили мем-коины на свежих контрактах — у вас накопились approve-разрешения. Большинство из них вы не помните. Часть контрактов, которым вы доверили тратить свои токены, уже мертва, часть — написана плохо, а некоторые созданы специально, чтобы однажды выстрелить. При эксплойте или скаме забытый approve — это открытая дверь в ваш кошелёк: атакующему не нужна ваша сид-фраза, достаточно одной транзакции.
Плохая новость: список разрешений не истекает сам. Approve, выданный три года назад анонимному контракту, действует до тех пор, пока вы его не отзовёте. Хорошая новость: ревокация — это дешёвая рутинная операция, которая делается за 15–20 минут раз в квартал.
В этом практикуме разберём, как устроены approve, чем опасен unlimited-вариант, как массово чистить разрешения через Revoke.cash и Breadcrumbs, и как встроить аудит в регулярную гигиену кошелька.
Как работает approve и почему он опасен
Approve (ERC-20) — это разрешение смарт-контракту тратить ваши токены через transferFrom. Механизм нужен для DeFi: чтобы Uniswap мог свапнуть ваш USDT, вы сначала даёте контракту роутера право списывать его.
Ключевая деталь — лимит. Есть два стиля:
- Точный лимит: «разрешаю списать 250 USDT». После свапа остаток разрешения — ноль или близко к нему.
- Unlimited (∞): «разрешаю списывать сколько угодно, всегда». Так делают большинство фронтендов «для удобства», чтобы вы не платили газ за новый approve при каждом свопе.
Проблема в том, что approve живёт в хранилище токен-контракта, а не в вашем кошельке. Сменили кошелёк, забыли про dApp — разрешение осталось. И если контракт-спендер скомпрометирован, атакующий заберёт всё, что вы разрешили.
Правило: unlimited-approve — это кредитная карта без лимита, которую вы выдали анониму в интернете. Никогда не оставляйте её «на потом» — отзывайте сразу после операции.
Практический пример: сколько стоит забытый approve
Сценарий из жизни. Кошелёк с долгосрочным портфелем на 420 000 ₽: 1 200 USDT (~114 000 ₽), 0,15 ETH (~42 000 ₽) и стейкинг-позиция на остаток. В 2022 году владелец пофармил токен на свежем проекте и выдал контракту unlimited-approve на USDT.
Проект оказался скамом, но «тихим»: контракт просто лежал полтора года. Затем 12 марта разработчик вызвал transferFrom и списал 1 150 USDT (50 оставил — вероятно, чтобы не спугнуть до конца, но в классической схеме уходит всё). Ущерб: ~110 000 ₽ по курсу (при цене USDT ~95 ₽).
Расчёт цены профилактики: ревокация одного approve на Ethereum в непиковое время — ~35 000–60 000 gas при цене газа 8–15 gwei и курсе ETH ~280 000 ₽ — это примерно 80–250 ₽ за транзакцию (нижняя граница: 35 000 × 8 gwei = 0,00028 ETH ≈ 78 ₽; верхняя: 60 000 × 15 gwei = 0,0009 ETH ≈ 252 ₽). Чистка 15 разрешений за раз обойдётся в 1 200–3 750 ₽. Плюс 20 минут времени раз в квартал. Итого профилактика: ~5 000–15 000 ₽ в год против риска потери 110 000 ₽ в одну транзакцию. Асимметрия очевидна.
Инструменты ревокации: пошагово
Revoke.cash — основной инструмент
- Откройте revoke.cash, подключите кошелёк.
- Фильтруйте список по сетям: Ethereum, Arbitrum, Base, Polygon и т.д. — разрешения не переносятся между сетями, чистить нужно везде, где вы были активны.
- Сортируйте по сумме и дате. Приоритет отзыва: unlimited-разрешения старше 6 месяцев, неизвестные контракты, мёртвые проекты.
- Жмёте «Revoke», подтверждаете транзакцию. Токены не двигаются — меняется только запись о разрешении.
Breadcrumbs.app — для детального анализа
Breadcrumbs показывает не только approve, но и всю историю трансферов по адресу. Полезно, когда подозреваете, что разрешение уже использовалось без вашего ведома, или хотите понять, откуда взялся контракт-спендер.
Замечания по безопасности
- Ревокация на мёртвом токене не нужна: если баланс токена ноль, спендеру нечего списать. Чистите разрешения на активах, которые лежат в кошельке.
- В сети с дорогим газом (Ethereum mainnet) ревоцируйте выборочно. Для мелочи делайте пакетную ревокацию через мультизапрос или дождитесь низкого газа (ночь выходных по UTC).
Чек-лист регулярного аудита разрешений
- Раз в квартал: полный проход по Revoke.cash во всех сетях, где есть баланс.
- После каждой деген-сессии: отзыв разрешений на контрактах, которыми больше не пользуетесь.
- Сразу после свапа: если фронтенд выставил unlimited и не даёт выбрать лимит — после операции отзовите и в следующий раз используйте альтернативу с точным лимитом.
- Перед переводом крупной суммы на кошелёк: чистка разрешений до пополнения, а не после.
- Проверка новых контрактов: адрес спендера через Etherscan → вкладка Contract → верифицирован ли код, когда создан.
- Ведите «белый список»: 3–5 контрактов (роутер Uniswap, Aave и т.п.) можно оставить, всё прочее — под нож.
Типичные ошибки
- Ревокация «на автомате» без проверки сети — вы отозвали разрешение в Arbitrum, а опасное осталось в Ethereum.
- Доверие сайту из поисковой рекламы: фишинговые «revoke-сервисы» существуют. Проверяйте домен: revoke.cash, breadcrumbs.app — буква в букву.
- Подпись permit вместо approve: некоторые токены (USDT старой версии, DAI через
permit) позволяют списание через подпись сообщения — она не видна в Revoke.cash. Не подписывайте непонятные сообщения от незнакомых dApp. - Отзыв разрешений на биржах-кастодиалках — их не существует: на CEX токены лежат на балансе биржи, approve тут ни при чём.
FAQ
Удаляет ли ревокация разрешение навсегда? Да, для конкретного токена, конкретного спендера и конкретной сети. Но если вы снова подключите кошелёк к этому dApp и совершите операцию — выдадите новый approve. Ревокация — не прививка, а уборка: её нужно повторять.
Сколько это стоит и стоит ли чистить всё сразу? На L2 (Arbitrum, Base, Polygon) ревокация стоит центы — чистите всё без раздумий. На Ethereum mainnet считайте: 10 ревокаций при высоком газе (30–35 gwei) могут обойтись в 3 000–5 000 ₽. Разделите на сессии по важности: сначала unlimited и крупные суммы, потом остальное в окно дешёвого газа.
Есть ли способ вообще не выдавать unlimited? Да. Некоторые интерфейсы (например, отдельные агрегаторы и «продвинутый режим» свопов) позволяют указать точную сумму approve. Разница — одна лишняя транзакция на ~100–250 ₽ при каждом пополнении лимита. Для долгосрочного кошелька это дешёвая страховка; для быстрой деген-сессии на отдельном кошельке с минимальным балансом unlimited допустим — при условии, что основной капитал лежит в другом месте.