Разрешение на списание токенов. Как работает Token Approval
При обмене токенов на децентрализованной бирже, внесении средств в кредитный протокол или пул ликвидности кошелек часто предлагает подтвердить дополнительную операцию. Пользователь может воспринимать ее как технический шаг перед обменом, хотя на самом деле разрешает определенному смарт-контракту распоряжаться заданным количеством конкретного токена.
Например, пользователь хочет обменять 100 USDT. Сначала он подключает кошелек к сервису. Затем подтверждает разрешение контракту использовать USDT и только после этого — сам обмен. Эти действия похожи в интерфейсе, но имеют разный смысл.
Подключение, разрешение и списание
Подключение кошелька позволяет сайту увидеть публичный адрес и предложить пользователю операции. Само по себе оно не дает права переводить токены.
Разрешение работает иначе. В стандарте ERC-20 владелец токенов может указать адрес, которому разрешено расходовать их в пределах определенного лимита. Для этого используется функция approve. После выдачи разрешения уполномоченный адрес может инициировать перевод через transferFrom.
При этом токены никуда не уходят. Если пользователь разрешил контракту расходовать 1000 USDT, все 1000 USDT остаются на его адресе. Реальное движение средств произойдет только при отдельном списании. Поэтому разрешение можно выдать сегодня, а воспользоваться им контракт сможет значительно позже.
Какой доступ получает контракт
Разрешение относится к конкретному токену и конкретному адресу. Если контракту разрешено списывать USDT, это не дает ему автоматически распоряжаться USDC, ETH или другими активами кошелька.
Есть и ограничение по сумме. Допустим, контракт получил право расходовать до 1000 USDT. Если он использовал 200 USDT, оставшийся лимит может продолжить действовать еще на 800 USDT.
Некоторые сервисы вместо нужной для операции суммы запрашивают очень большой или фактически неограниченный лимит. Это удобно при регулярных операциях: не нужно каждый раз заново выдавать разрешение и платить комиссию. Но одновременно увеличивается потенциальная сумма потерь.
Причем лимит может превышать текущий баланс. Пользователь способен иметь на адресе 200 USDT и разрешение на 10 тыс. USDT. Сегодня больше 200 USDT списать нельзя, но если позже баланс пополнится, старое разрешение продолжит действовать. MetaMask позволяет вручную уменьшать предложенный сервисом лимит расходов.
Почему отключение сайта не отменяет разрешение
Одна из частых ошибок — считать, что кнопка Disconnect закрывает доступ к токенам. Подключение сайта и разрешение на списание существуют отдельно.
Отключив сервис, пользователь прекращает обычное взаимодействие его интерфейса с кошельком. Но уже выданное разрешение записано в блокчейне и продолжает действовать. У стандартного разрешения ERC-20 нет встроенного срока окончания. Если лимит не был исчерпан, изменен или отозван, он может сохраняться годами.
Например, пользователь когда-то дал контракту доступ к 5000 USDT, провел обмен и больше сервисом не пользовался. Через год на тот же адрес поступили новые USDT. Если старое разрешение по-прежнему действует, контракт снова получает возможность распоряжаться средствами в пределах оставшегося лимита.
Как разрешение превращается в риск
Само по себе большое разрешение не означает, что средства обязательно украдут. У легитимного сервиса оно может годами не приводить ни к каким проблемам. Риск появляется, если доступ был выдан мошенническому контракту или законный контракт впоследствии оказался скомпрометирован.
В таком случае злоумышленнику не обязательно снова убеждать владельца подписать перевод непосредственно перед списанием. Если действующее разрешение уже существует, контракт может использовать его в пределах установленного лимита.
Допустим, пользователь когда-то дал неизвестному контракту право расходовать до 10 тыс. USDT. Тогда на кошельке лежало только 100 USDT. Через несколько месяцев баланс вырос до 8000 USDT, а разрешение осталось прежним.
Это отличается от кражи приватного ключа или сидфразы. Разрешение дает определенному адресу право работать с конкретным токеном. Получив приватный ключ, злоумышленник получает контроль уже над самим кошельком.
Как проверить и отозвать старый доступ
Действующие разрешения можно посмотреть через кошелек, обозреватель блокчейна или специальный сервис. Они показывают токен, адрес, которому дан доступ, и размер установленного лимита.
Проверять нужно каждую используемую сеть отдельно. Разрешение на USDT в Ethereum не дает автоматически такого же доступа к USDT в другой сети. Отзыв не удаляет старую транзакцию из блокчейна. Пользователь отправляет новую операцию, которая меняет действующий лимит — обычно на ноль.
Например, контракту разрешено списывать до 5000 USDT. Пользователь отправляет транзакцию отзыва с новым лимитом 0. Только после того, как эта транзакция будет подтверждена сетью, прежний доступ можно считать закрытым.
До подтверждения старая запись еще остается действующей. Поэтому при подозрении на вредоносный контракт недостаточно просто нажать кнопку отзыва — важно убедиться, что транзакция действительно попала в блокчейн.За обычный отзыв также приходится платить комиссию сети. Уже списанные токены он не возвращает.
Как уменьшить риск до подтверждения
Самый простой вариант — не выдавать контракту больше прав, чем требуется для операции. Если нужно обменять 200 USDT, лимит в 200 USDT ограничивает возможное списание этой суммой. Разрешение на весь баланс или огромную сумму оставляет значительно больше пространства для ущерба.
Второй вопрос — кому именно выдается доступ. Название сайта на экране само по себе ничего не гарантирует. Мошеннический сервис может выглядеть почти как настоящий, но запросить разрешение в пользу другого контракта.
При сомнениях адрес контракта стоит сверить с официальным сайтом или документацией проекта. Особенно внимательно нужно относиться к большим разрешениям после перехода по ссылке из рекламы, сообщения или случайной поисковой выдачи.
Отзывать все разрешения после каждой операции необязательно. Для регулярно используемого сервиса это добавит новые транзакции и комиссии. Но старые приложения, неизвестные контракты и ненужные большие лимиты имеет смысл периодически проверять.
Подпись тоже может дать право на списание
Разрешение не всегда выглядит как обычная транзакция с комиссией. Некоторые механизмы позволяют выдавать права с помощью подписи в кошельке. Один из примеров — Permit2 от Uniswap. Он позволяет ограничивать разрешение по сумме и времени действия, а также использовать подписи для отдельных переводов. При этом для обычных токенов ERC-20 сначала требуется базовое разрешение самому контракту Permit2.
Для пользователя важнее другое: отсутствие комиссии еще не означает, что подпись безопасна или ничего не меняет. Перед подтверждением нужно понимать, какой токен затрагивается, какой адрес получает права, на какую сумму и на какой срок.
Почему ETH ведет себя иначе
Эта механика относится прежде всего к токенам стандартов вроде ERC-20. Сам ETH — нативная монета Ethereum, поэтому обычный перевод ETH не требует предварительного разрешения ERC-20. WETH — уже отдельный токен ERC-20. При работе с ним смарт-контракт может запросить такое же разрешение, как при операциях с USDT или другими токенами.
Именно поэтому перед двумя похожими операциями один сервис может попросить сначала подтвердить доступ к активу, а в другой ситуации такого шага не будет.
Когда отзыва недостаточно
Если пользователь обнаружил подозрительное разрешение до списания средств, его нужно как можно быстрее отозвать. Если проблема ограничивается этим доступом, подтвержденный нулевой лимит закрывает возможность дальнейшего использования разрешения.
Но неизвестные исходящие транзакции могут означать более серьезную проблему — утечку приватного ключа или seed-фразы. Тогда отзыв отдельных разрешений не лишит злоумышленника контроля над адресом.
В такой ситуации безопаснее создать новый кошелек с новой seed-фразой и перенести туда оставшиеся активы.
Подключить кошелек, разрешить списание и перевести токены — три разных действия. Именно действующие разрешения стоит проверять в первую очередь, если токены ушли без новой подтвержденной пользователем транзакции.