К основному содержимому

Введите слово из вопроса или названия статьи.

2 · Практика

ERC-20 и approve: зачем «разрешение» и чем опасен безлимит

Как работают токены ERC-20 (USDT, USDC, DAI), почему перед внесением денег нужна отдельная подпись approve и как безопасно управлять разрешениями.

3 мин чтенияОбновлено:
В этой статье

Когда вы вносите USDT или USDC в сделку, кошелёк просит две подписи: сначала «разрешение», потом само внесение. Новичков это сбивает: зачем две? Ответ кроется в том, как устроены токены.

Что такое токен ERC-20

Основная монета сети (ETH) встроена в протокол: переводить её умеет сама сеть. А токен - это контракт: простая программа с таблицей «адрес → баланс». Токен ERC-20 - стандарт такой программы, у неё есть набор функций: balanceOf, transfer, approve, transferFrom и ещё несколько. Благодаря единому стандарту кошельки и приложения умеют работать с тысячами токенов одинаково.

Важное следствие: когда вы «отправляете USDT», вы на самом деле вызываете функцию в контракте токена, и именно он меняет цифры в своей таблице. Переведённые монеты не «лежат» в кошельке - в кошельке лежит только запись в таблице токена.

Почему нельзя просто отправить токены в контракт

Когда вы отправляете токены в смарт-контракт простым transfer, контракт-получатель не узнаёт о поступлении: его код не вызывается. Деньги просто окажутся на адресе, а сам контракт не сможет связать их со сделкой. Поэтому нужен другой путь: пусть контракт сам заберёт токены у вас в момент, когда создаётся сделка.

Для этого и придуман двухшаговый механизм:

  1. approve(spender, amount) - вы разрешаете адресу spender (контракту сделок) забрать у вас до amount токенов. Деньги при этом остаются у вас. Меняется только запись «разрешено такому-то столько-то» (allowance).
  2. transferFrom(owner, to, amount) - контракт сделок вызывает эту функцию и забирает ровно ту сумму, которую вы разрешили и которая нужна для сделки.

Два шага - две подписи. Первая ничего не списывает, вторая выполняет внесение.

Точная сумма или безлимит

При разрешении вам предлагают два варианта.

Ровно эту сумму. Контракт сможет забрать только сумму сделки, и после внесения разрешение обнуляется. Безопаснее: если контракт когда-нибудь окажется скомпрометирован, он не сможет добраться до ваших остальных денег. Минус - для каждой следующей сделки нужна отдельная подпись.

Без ограничений. В поле суммы записывается огромное число (обычно 2^256 − 1). Удобнее: следующие сделки не потребуют разрешения. Но контракт получает возможность списать любую сумму в любой момент.

Распространённое мошенничество

Атакующие не взламывают сам токен - они просят вас выдать разрешение своему адресу. «Подпишите для получения аирдропа», «подтвердите кошелёк». Вы подписываете approve на огромную сумму - и мошенник забирает токены своим transferFrom, когда захочет. Кошелёк не списал ничего в момент подписи, поэтому ощущения опасности нет.

Признаки: запрос на разрешение от неизвестного адреса; сумма - «неограниченно»; контекст не связан с вашими действиями.

Как проверить и отозвать разрешения

Все выданные разрешения публичны. Их можно проверить:

  • в обозревателе блоков - разделы «Token Approvals» или аналогичные;
  • в специальных сервисах-ревокаторах;
  • в самом кошельке (некоторые показывают список).

Чтобы отозвать, нужно подписать новый approve с суммой 0 - это стоит небольшой комиссии, но обнуляет доступ. Делайте это периодически, особенно для давно неиспользуемых сервисов.

Особенность USDT в Ethereum

У USDT в сети Ethereum есть необычная защита: чтобы изменить уже выданное ненулевое разрешение на другое ненулевое, сначала надо обнулить старое. Поэтому, если у вас осталось частичное разрешение, понадобятся три подписи вместо двух: обнуление, новое разрешение, внесение. Интерфейс предупреждает об этом заранее.

В других токенах и сетях это ограничение обычно отсутствует. Подробнее об особенностях токенов - в статье про нестандартные токены.

Альтернативы: permit и Permit2

Существуют расширения, которые позволяют обойтись без отдельной транзакции approve: вы подписываете сообщение (бесплатно, вне сети), а контракт использует его в той же транзакции. Это экономит газ и шаги. Не все токены поддерживают такой механизм, поэтому классическая пара approve + transferFrom остаётся самой совместимой.

Резюме

  • Токен - это таблица балансов в контракте, а не «монеты в кошельке».
  • approve не списывает деньги, а даёт право списать.
  • Точная сумма безопаснее безлимита.
  • Не выдавайте разрешений неизвестным адресам.
  • Периодически проверяйте и отзывайте старые разрешения.

Что почитать дальше

Разрешения - любимая цель мошенников. Закрепите знания в чек-листе безопасности кошелька и в разборе атак: фишинг и отравление адресов. Всё, что вы подписываете, остаётся в блокчейне навсегда, и это можно изучать: как читать Etherscan.

Упоминается в статьях

Готовы попробовать?

Создайте первую сделку за пару минут. Деньги блокируются в смарт-контракте и выплачиваются по правилам, которые видны заранее.