Apenas para fins educacionais; não constitui aconselhamento de investimento. Investir pode resultar em perdas.
Resposta direta
Algumas implementações de ERC-20 rejeitam approve(spender, newAmount) quando tanto o allowance existente quanto newAmount são diferentes de zero. Para esses tokens, envie primeiro approve(spender, 0), aguarde a confirmação e só então envie a nova aprovação diferente de zero.
Essa restrição não é obrigatória para todos os tokens ERC-20. O ERC-20 define approve como substituição do allowance atual e recomenda que interfaces de cliente o zerem primeiro para mitigar uma corrida na alteração da aprovação; também afirma que contratos de token não deveriam impor isso por compatibilidade. Ainda assim, alguns tokens implantados impõem a regra. Portanto, zerar primeiro é um procedimento de compatibilidade e um ponto de verificação útil, mas não garante que o allowance antigo não seja gasto antes da confirmação da zeragem.
A conclusão desta revisão não prova que um ativo, transação ou sistema seja seguro.
Como funciona
- Confira a rede, o contrato do token, o proprietário, o spender e o valor pretendido. Leia
allowance(owner, spender)diretamente do contrato do token em vez de confiar apenas em um rótulo da carteira. - Se o allowance já for
0, envie uma vez a aprovação desejada. Se for diferente de zero, a substituição direta por outro valor diferente de zero pode funcionar em uma implementação padrão ou reverter em um token que exija zeragem prévia. - Nesse fluxo, envie
approve(spender, 0)e aguarde um recibo bem-sucedido. Depois, leia novamente o allowance do mesmo par proprietário-spender e confirme que seja0. - Confira novamente o saldo do token, o spender e a finalidade. Só então envie
approve(spender, newAmount)e aguarde a confirmação antes de considerar o novo allowance ativo. - Verifique o allowance final e examine os eventos
TransfereApprovalocorridos no intervalo. Um recibo bem-sucedido comprova a execução, enquanto o estado atual do contrato mostra a permissão restante.
O SafeERC20.forceApprove da OpenZeppelin oferece aos contratos uma alternativa de compatibilidade: tenta o valor desejado e, se a chamada falhar, tenta 0 seguido do valor desejado. Esse utilitário altera o allowance do próprio contrato chamador. Ele não corrige automaticamente a aprovação da carteira de um usuário nem elimina a necessidade de verificar a ordem das transações e o estado final.
Exemplo
Um proprietário concedeu a um spender um allowance de 1000 tokens e quer reduzi-lo para 100. Em um token que exige zeragem prévia, approve(spender, 100) reverte, então o allowance on-chain permanece 1000; uma chamada revertida não atualiza parcialmente o estado.
Em vez disso, o proprietário envia approve(spender, 0). Antes da confirmação, o spender usa 400, restando 600; a transação de zeragem confirmada em seguida substitui o restante por 0. Depois de conferir o saldo menor, o proprietário pode decidir se concede os novos 100. Se conceder, o spender já usou 400 e depois poderá usar até mais 100. A zeragem prévia revelou o gasto intermediário antes da nova permissão, mas não o desfez.
Riscos
- O allowance antigo continua utilizável até a execução da zeragem. Um spender pode se antecipar a uma revogação ou redução pendente.
- Transmitir a zeragem e a substituição sem aguardar a primeira confirmação remove o ponto de verificação pretendido e pode ocultar um gasto intermediário.
- Rede, endereço de token ou endereço de spender incorretos podem criar ou revogar uma permissão diferente da pretendida. Símbolos de tokens não são identificadores exclusivos.
- O fluxo em duas etapas custa duas transações quando ambas são necessárias; qualquer uma pode falhar, ser substituída ou ficar pendente. Não deduza o estado apenas de uma assinatura enviada.
- Aprovações ilimitadas e spenders atualizáveis ou comprometidos podem expor depósitos futuros. Use o menor valor viável e confira o allowance restante após o uso.
- Integrações entre contratos devem tratar deliberadamente valores de retorno e comportamentos de aprovação fora do padrão. Uma camada de compatibilidade não torna seguro um spender não confiável.
Equívocos comuns
- Todo ERC-20 exige zeragem prévia. O padrão recomenda a sequência no cliente, mas diz que contratos de token não deveriam impô-la; apenas algumas implementações rejeitam a alteração entre dois valores diferentes de zero.
- Zerar primeiro resolve completamente a corrida de aprovação. O spender ainda pode usar o allowance antigo antes da confirmação da zeragem.
- Uma substituição revertida apagou o allowance antigo. Um revert desfaz a mudança de estado tentada, portanto o allowance anterior normalmente permanece.
- Enviar as duas transações juntas equivale a aguardar. O ponto de segurança vem de confirmar e inspecionar o estado zerado antes de decidir sobre a substituição.
- Desconectar um site revoga a aprovação. O estado da conexão da carteira e o allowance on-chain do contrato do token são separados.
Tópicos relacionados
- Corrida de aprovação do ERC-20
- Aprovação de carteira
- Nonce e deadline do Permit ERC-2612
- Risco de assinatura Permit2
Fontes
- ERC-20: padrão de token - Ethereum Improvement Proposals (acessado em: 2026-08-21)
- ERC20 | Documentação da OpenZeppelin - OpenZeppelin (acessado em: 2026-08-21)
- SafeERC20.sol - OpenZeppelin (acessado em: 2026-08-21)