Только в образовательных целях; не является инвестиционной рекомендацией. Инвестиции могут привести к убыткам.
Краткий ответ
Некоторые реализации ERC-20 отклоняют approve(spender, newAmount), когда и существующий allowance, и newAmount ненулевые. Для таких токенов сначала отправьте approve(spender, 0), дождитесь подтверждения и лишь затем отправляйте новое ненулевое разрешение.
Это ограничение обязательно не для всех токенов ERC-20. ERC-20 определяет approve как замену текущего allowance и рекомендует клиентским интерфейсам сначала обнулять его, чтобы снизить риск гонки при изменении разрешения. При этом ради совместимости стандарт говорит, что контракт токена не должен принуждать к такой последовательности. Некоторые развернутые токены все же делают это. Поэтому предварительное обнуление служит процедурой совместимости и полезной контрольной точкой, но не гарантирует, что старый allowance нельзя потратить до подтверждения обнуляющей транзакции.
Завершение этой проверки не доказывает безопасность актива, транзакции или системы.
Как это работает
- Проверьте сеть, контракт токена, владельца, spender и предполагаемую сумму. Читайте
allowance(owner, spender)из контракта токена, а не полагайтесь только на подпись в кошельке. - Если allowance уже равен
0, отправьте требуемое разрешение один раз. Если он ненулевой, прямая замена другим ненулевым значением может пройти в стандартной реализации или дать revert у токена с обязательным обнулением. - Для такого порядка отправьте
approve(spender, 0)и дождитесь успешной квитанции. Затем снова прочитайте allowance той же пары владелец-spender и подтвердите значение0. - Повторно проверьте баланс токена, spender и цель разрешения. Только после этого отправьте
approve(spender, newAmount)и дождитесь подтверждения, прежде чем считать новый allowance активным. - Проверьте итоговый allowance и промежуточные события
TransferиApproval. Успешная квитанция доказывает исполнение, а текущее состояние контракта показывает оставшееся разрешение.
SafeERC20.forceApprove от OpenZeppelin предоставляет контрактам запасной вариант совместимости: сначала он пробует требуемое значение, а при неудаче последовательно пробует 0 и требуемое значение. Эта функция меняет собственный allowance вызывающего контракта. Она не исправляет автоматически разрешение пользовательского кошелька и не отменяет необходимость проверять порядок транзакций и конечное состояние.
Пример
Владелец выдал spender allowance на 1000 токенов и хочет снизить его до 100. У токена с обязательным обнулением approve(spender, 100) дает revert, поэтому allowance в блокчейне остается равным 1000; отмененный вызов не обновляет состояние частично.
Вместо этого владелец отправляет approve(spender, 0). До подтверждения spender использует 400, и остается 600; затем подтвержденная обнуляющая транзакция заменяет остаток на 0. Проверив уменьшившийся баланс токенов, владелец может решить, выдавать ли новые 100. Если выдаст, spender уже использовал 400 и позднее сможет использовать еще до 100. Предварительное обнуление выявило промежуточное списание до выдачи нового разрешения, но не отменило его.
Риски
- Старый allowance доступен до исполнения обнуляющей транзакции. Spender может опередить ожидающую отмену или уменьшение.
- Отправка обнуления и замены без ожидания первого подтверждения устраняет контрольную точку и может скрыть промежуточное списание.
- Ошибка в сети, адресе токена или адресе spender может создать либо отменить не то разрешение. Символ токена не является уникальным идентификатором.
- Двухэтапный порядок требует оплаты двух транзакций, когда нужны обе; любая может завершиться неудачно, быть заменена или зависнуть. Не определяйте состояние только по отправленной подписи.
- Неограниченные разрешения, а также обновляемые или скомпрометированные spenders могут подвергнуть риску будущие поступления. Используйте минимальную практичную сумму и проверяйте остаток allowance после использования.
- Интеграции контрактов должны явно обрабатывать нестандартные возвращаемые значения и поведение разрешений. Обертка совместимости не делает ненадежного spender безопасным.
Распространенные заблуждения
- Каждый ERC-20 требует предварительного обнуления. Стандарт рекомендует последовательность на стороне клиента, но говорит не принуждать к ней в контрактах токенов; переход между двумя ненулевыми значениями отклоняют лишь некоторые реализации.
- Предварительное обнуление полностью устраняет гонку разрешений. Spender все еще может использовать старый allowance до подтверждения обнуления.
- Отмененная замена стерла старый allowance. Revert откатывает предпринятое изменение состояния, поэтому прежний allowance обычно сохраняется.
- Совместная отправка двух транзакций равнозначна ожиданию. Контрольная точка возникает при подтверждении и проверке нулевого состояния до решения о замене.
- Отключение сайта отменяет его разрешение. Состояние подключения кошелька и allowance в контракте токена независимы.
Связанные темы
Источники
- ERC-20: стандарт токена - Ethereum Improvement Proposals (дата обращения: 2026-08-21)
- ERC20 | Документация OpenZeppelin - OpenZeppelin (дата обращения: 2026-08-21)
- SafeERC20.sol - OpenZeppelin (дата обращения: 2026-08-21)