﻿---
title: "Почему некоторые разрешения токенов нужно сначала обнулять?"
description: "Некоторые токены ERC-20 отклоняют прямую замену одного ненулевого allowance другим. Узнайте, когда нужно предварительное обнуление, почему две транзакции подтверждают по порядку и какие риски сохраняются."
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Почему некоторые разрешения токенов нужно сначала обнулять?

> Только в образовательных целях; не является инвестиционной рекомендацией. Инвестиции могут привести к убыткам.

<a id="answer"></a>

## Краткий ответ

Некоторые реализации ERC-20 отклоняют `approve(spender, newAmount)`, когда и существующий allowance, и `newAmount` ненулевые. Для таких токенов сначала отправьте `approve(spender, 0)`, дождитесь подтверждения и лишь затем отправляйте новое ненулевое разрешение.

Это ограничение обязательно не для всех токенов ERC-20. ERC-20 определяет `approve` как замену текущего allowance и рекомендует клиентским интерфейсам сначала обнулять его, чтобы снизить риск гонки при изменении разрешения. При этом ради совместимости стандарт говорит, что контракт токена не должен принуждать к такой последовательности. Некоторые развернутые токены все же делают это. Поэтому предварительное обнуление служит процедурой совместимости и полезной контрольной точкой, но не гарантирует, что старый allowance нельзя потратить до подтверждения обнуляющей транзакции.

<a id="mechanism"></a>

## Как это работает

1. Проверьте сеть, контракт токена, владельца, spender и предполагаемую сумму. Читайте `allowance(owner, spender)` из контракта токена, а не полагайтесь только на подпись в кошельке.
2. Если allowance уже равен `0`, отправьте требуемое разрешение один раз. Если он ненулевой, прямая замена другим ненулевым значением может пройти в стандартной реализации или дать revert у токена с обязательным обнулением.
3. Для такого порядка отправьте `approve(spender, 0)` и дождитесь успешной квитанции. Затем снова прочитайте allowance той же пары владелец-spender и подтвердите значение `0`.
4. Повторно проверьте баланс токена, spender и цель разрешения. Только после этого отправьте `approve(spender, newAmount)` и дождитесь подтверждения, прежде чем считать новый allowance активным.
5. Проверьте итоговый allowance и промежуточные события `Transfer` и `Approval`. Успешная квитанция доказывает исполнение, а текущее состояние контракта показывает оставшееся разрешение.

`SafeERC20.forceApprove` от OpenZeppelin предоставляет контрактам запасной вариант совместимости: сначала он пробует требуемое значение, а при неудаче последовательно пробует `0` и требуемое значение. Эта функция меняет собственный allowance вызывающего контракта. Она не исправляет автоматически разрешение пользовательского кошелька и не отменяет необходимость проверять порядок транзакций и конечное состояние.

<a id="example"></a>

## Пример

Владелец выдал spender allowance на `1000` токенов и хочет снизить его до `100`. У токена с обязательным обнулением `approve(spender, 100)` дает revert, поэтому allowance в блокчейне остается равным `1000`; отмененный вызов не обновляет состояние частично.

Вместо этого владелец отправляет `approve(spender, 0)`. До подтверждения spender использует `400`, и остается `600`; затем подтвержденная обнуляющая транзакция заменяет остаток на `0`. Проверив уменьшившийся баланс токенов, владелец может решить, выдавать ли новые `100`. Если выдаст, spender уже использовал `400` и позднее сможет использовать еще до `100`. Предварительное обнуление выявило промежуточное списание до выдачи нового разрешения, но не отменило его.

<a id="risks"></a>

## Риски

- Старый allowance доступен до исполнения обнуляющей транзакции. Spender может опередить ожидающую отмену или уменьшение.
- Отправка обнуления и замены без ожидания первого подтверждения устраняет контрольную точку и может скрыть промежуточное списание.
- Ошибка в сети, адресе токена или адресе spender может создать либо отменить не то разрешение. Символ токена не является уникальным идентификатором.
- Двухэтапный порядок требует оплаты двух транзакций, когда нужны обе; любая может завершиться неудачно, быть заменена или зависнуть. Не определяйте состояние только по отправленной подписи.
- Неограниченные разрешения, а также обновляемые или скомпрометированные spenders могут подвергнуть риску будущие поступления. Используйте минимальную практичную сумму и проверяйте остаток allowance после использования.
- Интеграции контрактов должны явно обрабатывать нестандартные возвращаемые значения и поведение разрешений. Обертка совместимости не делает ненадежного spender безопасным.

<a id="misconceptions"></a>

## Распространенные заблуждения

- **Каждый ERC-20 требует предварительного обнуления.** Стандарт рекомендует последовательность на стороне клиента, но говорит не принуждать к ней в контрактах токенов; переход между двумя ненулевыми значениями отклоняют лишь некоторые реализации.
- **Предварительное обнуление полностью устраняет гонку разрешений.** Spender все еще может использовать старый allowance до подтверждения обнуления.
- **Отмененная замена стерла старый allowance.** Revert откатывает предпринятое изменение состояния, поэтому прежний allowance обычно сохраняется.
- **Совместная отправка двух транзакций равнозначна ожиданию.** Контрольная точка возникает при подтверждении и проверке нулевого состояния до решения о замене.
- **Отключение сайта отменяет его разрешение.** Состояние подключения кошелька и allowance в контракте токена независимы.

<a id="related"></a>

## Связанные темы

- [Гонка разрешений ERC-20](/ru/crypto/erc20-approval-race-condition/)
- [Разрешения кошелька](/ru/crypto/wallet-approval/)
- [Nonce и deadline в Permit ERC-2612](/ru/crypto/erc2612-permit-nonce-deadline/)
- [Риск подписи Permit2](/ru/crypto/permit2-signature-risk/)

<a id="sources"></a>

## Источники

- [ERC-20: стандарт токена](https://eips.ethereum.org/EIPS/eip-20) - Ethereum Improvement Proposals (дата обращения: 2026-08-21)
- [ERC20 | Документация OpenZeppelin](https://docs.openzeppelin.com/contracts/5.x/api/token/erc20) - OpenZeppelin (дата обращения: 2026-08-21)
- [SafeERC20.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) - OpenZeppelin (дата обращения: 2026-08-21)

Source: https://wiki.fcontext.com/ru/crypto/token-approval-zero-first/index.mdx
