WEB3DEV

Cover image for Notas do auditor: Dicas de integração do ERC20
Rafael Ojeda
Rafael Ojeda

Posted on

Notas do auditor: Dicas de integração do ERC20

Notas do auditor: Dicas de integração do ERC20

Image description

Imagem: Canva X Photomosh

Continuaremos nossa série instrutiva com conselhos para a integração do ERC20 hoje. Esta postagem examinará as orientações necessárias para integrar tokens fungíveis em seu projeto, bem como auditar e até mesmo projetar essas integrações usando o ERC20 como exemplo!

*O ERC20 não é uma tecnologia, um software ou um trecho de código. É uma especificação técnica. Se um token implementa a especificação, ele é um token ERC20. O padrão de protocolo ERC20 contém funções básicas que qualquer token útil deve implementar para permitir a negociação. - James Seibel *

Você também encontrará uma lista de ferramentas e pesquisas para estudo individual, e recomendamos fortemente que você as leia separadamente para melhor compreensão! No entanto, também haverá conselhos para outras integrações. Prometo que será muito interessante, informativo e conciso, tudo ao mesmo tempo - sabemos que você não tem muito tempo livre e respeitamos isso.

Também compartilharei nossas próprias observações e darei alguns conselhos no próximo artigo da nossa série. Como nossa equipe está trabalhando desde 2016, acumulamos muitos deles!

Não deixe de ler o restante da série:

Mas, antes de tudo, gostaria de expressar nossa sincera gratidão aos autores de todos os materiais de pesquisa e, é claro, aos nossos auditores do pessimistic.io, que me ajudaram muito revelando informações necessárias e levantando o véu do segredo.

Acreditamos que ninguém duvida que a base de qualquer integração segura é uma abordagem especial para escrever código. Consequentemente, este artigo se concentrará apenas nos aspectos que podem ser realmente úteis para tornar seu código seguro e protegido.

Portanto, abaixo você verá não um artigo típico, mas uma Sistematização do Conhecimento (SoK), na qual me basearei em autores em quem confio nesse assunto e, é claro, em nossos auditores do pessimistic.io! Vamos começar!

A propósito, há algumas vagas disponíveis agora, portanto, se o seu projeto precisar de uma auditoria, sinta-se à vontade para nos escrever, visite nossa página de relatórios públicos aqui. Entre em contato conosco: [email protected]!

Especificações de Auditoria do ERC20

Uma vez que nossa equipe está trabalhando desde 2016, acumulamos várias observações (confira I — VII), que compartilharemos abaixo, juntamente com diversos conselhos de segurança.

Entendemos e respeitamos o seu tempo limitado, por isso criamos uma folha de dicas específica com apenas o essencial para você! Confira!

I — Questões Padrão

  • Você deve estar completamente familiarizado com o padrão e verificá-lo novamente;

  • O plugin Slither complementar é útil para verificar o padrão:

https://github.com/crytic/slither/wiki/ERC-Conformance

II — Verificações Padrão

Decimais — devem ser do tipo uint8, o fornecimento total (totalSupply) deve ser calculado corretamente — pode ocorrer estouro (overflow) em versões mais antigas do solidity;

Assinaturas de funções e eventos — verificar a presença e correção, incluindo a disponibilidade de retornos bool (booleanos) e também incluindo indexável (indexed) para os argumentos de endereço nos eventos;

Verificar a presença de eventos em funções, incluindo no construtor e de preferência quando ocorrer uma queima (burn);

A transferência de 0 tokens deve funcionar;

A maioria dos tokens se baseia em uma implementação do Open Zeppelin, de modo que: Se _beforeTokenTransfer ou _afterTokenTransfer forem sobrescritos, essas funções também devem ser virtuais e chamar super;

Em alguns casos, equipes de projetos podem implantar diferentes pares de tokens de seu projeto e outros tokens em várias exchanges devido a diferentes requisitos, mais informações sobre esse caso podem ser encontradas no seguinte artigo:

https://eocene.medium.com/erc20-protocol-security-best-practices-guide-d6c223588236

III - Transferência para si mesmo

  • Um caso de transferência para si mesmo geralmente não é tratado, podendo ocorrer duplicação de fundos:

uint a = balances[A];

uint b = balances[B];

balances[A] = a.sub(amount);

balances[B] = b.add(amount)

  • Isso também ocorre frequentemente quando há um "transferMany" (envio para vários endereços);

  • Esta é uma descrição de problemas do padrão de token ERC20, que é amplamente utilizado para ICOs Ethereum. A partir deste artigo, você pode aprender sobre o problema dos tokens perdidos:

https://dexaran820.medium.com/erc20-token-standard-critical-problems-3c10fd48657b

IV — Outras Verificações

  • Taxa de transferência embutida: Alguns tokens "cobram uma taxa" ao serem transferidos. A lógica é diferente, mas o ponto é que a afirmação "o saldo do remetente diminui pelo valor especificado, o saldo do destinatário aumenta pelo mesmo valor" não é cumprida;

  • Sem retorno: Em alguns casos, o Solidity permite programar sem retorno. Às vezes, isso é simplesmente esquecido nas transferências. Uma solução para isso é chamar super.transfer sem verificar ou lançar o valor de retorno;

  • Elastic Supply / Rebase / Taxa de armazenamento: Para alguns tokens, o saldo do usuário é recalculado ao longo do tempo. O totalSupply deve ser alterado para cada mudança. Eventos de criação/queima ( Mint/burn ) geralmente não são possíveis, mas podem ser relatados;

  • Às vezes, é especificamente necessário que o novo valor ou o valor antigo da permissão seja 0, mas isso é uma pequena violação do padrão. É assim que o USDT e o SafeERC20.safeApprove (agora obsoleto) se comportam. Agora considera-se que em 99% dos casos não podem haver problemas. Mas também é possível implementar increase/decreaseAllowance ou outros métodos não padrão;

  • Uma revisão detalhada de tokens com padrões de comportamento incomuns:

https://github.com/xwvvvvwx/weird-erc20

V — Verificações de Extensões

  • O Permit possibilita emitir uma aprovação por meio de assinatura. O padrão não é simples - ele é muito detalhado e descreve muitos detalhes importantes. Isso deve ser verificado com muito cuidado. Frequentemente usado para otimização da experiência do usuário (o usuário pode fazer com uma transação em vez de duas);

  • O DAI possui sua própria versão de "Permit" (não EIP2612). Ao lidar com USDT - considere que este token requer "safeApprove", e o "approve" normal quebrará quando emitido a partir de um valor não zero;

  • Um novo bug de "batchOverflow" pode ocorrer em vários contratos inteligentes ERC20 (CVE-2018–10299), leia mais sobre isso aqui;

  • Devemos verificar se o contrato verifica o valor de retorno de "transfer", "transferFrom" e "approve":

Image description

Leia mais aqui!

  • Como alguns tokens não estão em conformidade com o padrão e não retornam bool (por exemplo, USDT), geralmente é melhor usar SafeERC20 da OZ (ou análogos);

  • Neste artigo, você pode aprender sobre o problema da perda de tokens:

https://dexaran820.medium.com/known-problems-of-erc20-token-standard-e98887b9532c

VI - Verificações de mudança de equilíbrio e reentrada

  • Um padrão bastante comum é a verificação de alterações no equilíbrio:

uint oldB = token.balanceOf(address(this));

<some logic>

uint newB = token.balanceOf(address(this));

uint diff = newB - oldB;

<more logic with diff>

  • Se tiver uma chamada para um endereço arbitrário, você poderá entrar novamente nessa função a partir dele. Por causa disso, a primeira chamada terminará () com um newB duas vezes alterado;

  • Há alguns meses, concluímos nossa própria pesquisa sobre ataques de reentrada. De muitas maneiras, este artigo se baseará nas informações de nosso antigo artigo, portanto, leia-o se ainda não o fez:

https://blog.pessimistic.io/reentrancy-attacks-on-smart-contracts-distilled-7fed3b04f4b6

VII - Verificação prévia de Saldo/Permissão

  • É comum verificar primeiro balanceOf e/ou allowance ( Saldo e/ou Permissão ) antes de chamar transfer/transferFrom. Isso duplica efetivamente as verificações dentro do próprio token. Para o gás extra, na melhor das hipóteses, receberemos mensagens de reversão personalizadas;

  • Se o contrato tiver .transferFrom, os usuários não deverão controlar o parâmetro from. Caso contrário, você poderá usar as aplicações de outras pessoas e roubar outros usuários. (Em 99%, deveria ser transferFrom(msg.sender, ...));

  • O ERC777 é um dos padrões de token com ganchos nas transferências. Esses ganchos introduzem um novo vetor de ataque que pode afetar contratos inteligentes que não foram projetados para lidar com chamadas adicionais durante transferências de tokens. Este artigo fornece uma explicação abrangente do ERC777, cobrindo todos os detalhes necessários:

https://mixbytes.io/blog/one-more-problem-with-erc777

Esperamos que este artigo tenha sido informativo e útil para você! Obrigado pela leitura!

Nos últimos meses, temos desenvolvido ativamente nossos próprios detectores do Slither (confira nossa ferramenta Slitherin) para auxiliar no processo de revisão de código e auditoria. Por favor, informe-nos se você descobriu algum problema/bug/vulnerabilidade por meio de nossos detectores personalizados do Slither. Você pode entrar em contato conosco abrindo um PR/Issue ou diretamente, o que for mais conveniente para você!

Quais instrumentos deveríamos revisar? No que você estaria interessado em ler? Por favor, deixe seus comentários, ficaremos felizes em respondê-los, e as melhores respostas e perguntas podem ser incluídas no próximo artigo!

Não deixe de ler o restante da série:

https://blog.pessimistic.io/price-reward-manipulation-attacks-distilled-cfec2aa8feeb

A propósito, há algumas vagas disponíveis agora, portanto, se o seu projeto precisar de uma auditoria, sinta-se à vontade para nos escrever, visite nossa página de relatórios públicos aqui. Entre em contato conosco: [email protected]!

Fiquem seguros!

Este artigo foi escrito por Officer's Notes e traduzido para o português por Rafael Ojeda

Você pode ler o artigo original em inglês aqui

Oldest comments (0)