﻿---
title: "Состояние гонки при одобрении ERC-20"
description: "Spender токена ERC-20 может использовать прежний allowance до подтверждения заменяющего одобрения, а затем воспользоваться новым 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.

# Состояние гонки при одобрении ERC-20

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

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

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

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

Поэтому спецификация ERC-20 рекомендует клиентским интерфейсам сначала установить allowance в `0`, а затем задать новое значение для того же spender. Каждая транзакция должна быть подтверждена по порядку. Если токен их поддерживает, атомарные вызовы `increaseAllowance` или `decreaseAllowance` позволяют не заменять ненулевой allowance напрямую.

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

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

В ERC-20 `approve` перезаписывает значение: успешный вызов `approve(spender, amount)` устанавливает allowance для spender равным `amount`. Отдельно вызов `transferFrom(owner, recipient, amount)` позволяет этому spender переводить токены владельца и обычно уменьшает оставшийся allowance. Ожидающие транзакции не закрепляют порядок исполнения, поэтому spender может отправить перевод, который будет исполнен до изменения одобрения владельцем.

Рискованным является переход `N -> M`, где одновременно `N > 0` и `M > 0`. Если spender израсходует `N` до исполнения заменяющего одобрения, последующее одобрение установит новый allowance в размере `M`. Поэтому максимальная сумма расходов в этой последовательности может составить `N + M` с учетом баланса токенов владельца и реализации токена.

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

## Пример

Alice разрешила протоколу потратить `100` токенов. Она отправляет `approve(protocol, 50)`, намереваясь снизить оставшийся allowance до `50`. До подтверждения этой транзакции spender протокола отправляет `transferFrom(Alice, recipient, 100)` и добивается того, чтобы этот вызов был исполнен первым. Затем одобрение Alice устанавливает allowance в размере `50`, который spender может использовать в другом переводе. В сумме два перевода составляют `150` токенов.

Более безопасная процедура замены: отправить `approve(protocol, 0)`, дождаться подтверждения, проверить получившиеся allowance и баланс и лишь затем отправить `approve(protocol, 50)`, если новое одобрение все еще уместно. Если spender использует прежний allowance до подтверждения обнуляющей транзакции, Alice увидит изменение баланса и сможет остановиться, не выдавая новые `50`.

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

## Риски

- Установка allowance в `0` не отменяет уже исполненные расходы и не предотвращает использование прежнего allowance до подтверждения обнуляющей транзакции.
- Если отправить обнуляющее и заменяющее одобрения вместе, не дожидаясь подтверждения первого, риск порядка исполнения возникнет снова.
- `increaseAllowance` и `decreaseAllowance` не входят в базовый стандарт ERC-20; используйте их только в том случае, если проверенный контракт токена их поддерживает.
- Неограниченный allowance может подвергать риску весь баланс токенов владельца, пока остается активным. Перед подписанием проверьте сеть, контракт токена, spender и сумму.
- Некоторые токены нестандартно обрабатывают одобрения. Изучайте симуляцию в кошельке и calldata транзакции, а после каждого шага проверяйте allowance в блокчейне.

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

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

- "Последняя транзакция одобрения сразу заменяет предыдущую." Она изменяет состояние только после исполнения в блокчейне.
- "Снижение allowance ограничивает все будущие расходы новой суммой." Spender может использовать прежний allowance до исполнения изменения.
- "Предварительное обнуление гарантирует, что токены больше не уйдут." Прежний allowance можно использовать до подтверждения обнуляющей транзакции.
- "В каждом ERC-20 есть `increaseAllowance` и `decreaseAllowance`." Это необязательные расширения, а не требования ERC-20.
- "Отключение веб-сайта отзывает одобрение токена." Состояние подключения кошелька и allowance в контракте токена в блокчейне не связаны друг с другом.

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

## Похожие темы

- [Как отличить канонические токены от обернутых](/ru/crypto/canonical-vs-wrapped-token/)
- [Мемпул](/ru/crypto/mempool/)
- [Риск подписи Permit2](/ru/crypto/permit2-signature-risk/)
- [Ордера reduce-only](/ru/crypto/reduce-only-order/)
- [Одобрение в кошельке](/ru/crypto/wallet-approval/)

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

## Источники

- [ERC-20: Token Standard](https://eips.ethereum.org/EIPS/eip-20) - Ethereum Improvement Proposals (дата обращения: 2026-08-20)
- [ERC20 | OpenZeppelin Docs](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20) - OpenZeppelin (дата обращения: 2026-08-20)

Source: https://wiki.fcontext.com/ru/crypto/erc20-approval-race-condition/index.mdx
