WEB3DEV

Cover image for Hackeando o Etherscan: Trapaças com ERC20
Paulo Gio
Paulo Gio

Posted on

Hackeando o Etherscan: Trapaças com ERC20

Eu tenho uma pergunta interessante para você.

As informações que você vê no Etherscan são 100% válidas? Você pode confiar 100% no Etherscan para exibir tokenomia e saldos?

A resposta é, infelizmente, NÃO.

E VOCÊ pode modificar alguns dos valores para seu próprio benefício.

Hackeando o Etherscan?

Falaremos sobre tokens e como os saldos podem ser facilmente falsificados.

Para ver como vamos tentar implantar este contrato inteligente:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {   
   constructor() ERC20("MyToken", "MTK"{                                                                                              
      _mint(msg.sender,100*10**18);   
   }
}
Enter fullscreen mode Exit fullscreen mode

O remetente implantará um token chamado “TKN” na blockchain e obterá o fornecimento total (100 TKN). Se olharmos no Etherscan:

https://miro.medium.com/max/1100/1*kjNsfuNEl3Pi4y3ZurgePw.png

Página de token do contrato inteligente implantado

Não há nada suspeito. Até agora, está tudo bem.

Então vamos modificar um pouco o código.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {   
   constructor() ERC20("MyToken", "MTK"{      
      _mint(msg.sender,100*10**18);
      _balances[msg.sender] += 100*10**18;
      // não se esqueça de substituir "private" por "internal" na definição de _balances            
   }
}
Enter fullscreen mode Exit fullscreen mode

Eu adicionei uma nova linha de código, que adiciona ao remetente o mesmo número de tokens, mas sem usar _mint() (cunhagem).

Se olharmos para o Etherscan, o resultado NÃO é o mesmo que o esperado:

https://miro.medium.com/max/1100/1*59aXlSYkL2MFL5uymjbNZA.png

Ainda há 100MTK em totalSupply (fornecimento total) e 100MTK para o msg.sender em vez de 200MTK porque adicionamos 2 vezes 100MTK para este endereço…

Agora, se eu adicionar o token do MTK na metamask, obtenho o valor esperado (200 em vez de 100):

https://miro.medium.com/max/1100/1*bEGeu-hteMSwJjJIXTzgQA.png

Portanto, é possível ocultar nossos tokens do totalSupply e do etherscan não chamando _mint(), mas alterando diretamente os valores na variável de armazenamento balance.

Mas qual é a diferença com a função _mint()?

Se inspecionarmos a função mint:

https://miro.medium.com/max/1100/1*fplkXkhabzfCNnZ8DzdmTw.png

Vemos que existem apenas duas diferenças entre chamar a função _mint() e modificar a variável _balances:

  1. A variável totalSupply é aumentada
  2. O evento Transfer é emitido

Quando eu aumento _balances manualmente, essas 2 instruções NÃO são executadas, portanto:

  1. totalSupply não é aumentado, então é normal que no Etherscan o totalSupply ainda seja 100 TKN.
  2. Evento Transfer NÃO é emitido, então como o Etherscan está contando com eventos para contar os saldos de cada titular, o saldo de msg.sender pode ser FALSO.

Se você quiser ver o verdadeiro saldo de um endereço no Etherscan, você pode clicar em um detentor de token:

https://miro.medium.com/max/1100/1*4L6Z2I1HS5QM2ZCU2OBElw.png

Aqui você pode ver o verdadeiro saldo do msg.sender, problema resolvido certo?

Obviamente não.

Aqui está nosso terceiro exemplo de contrato inteligente:

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {   
   constructor() ERC20("MyToken", "MTK") {   
      _mint(msg.sender,100*10**18);
      _balances[msg.sender] += 100*10**18;
   }   
   function mintWithoutTransfer(address addr,uint amount) external{      
            _balance[addr] += amount;   
   }
}
Enter fullscreen mode Exit fullscreen mode

Eu criei uma nova função “mintWithoutTransfer” que cunha um token sem lançar um evento, aumentando totalsupply.

Eu posso chamar esta função enviando argumentos para um novo endereço que acabei de criar, mas que ninguém conhece e 1000….000 TOKENS.

Portanto, estarei totalmente oculto no explorador da blockchain e ninguém poderá ver quantos tokens eu tenho.

Conclusão

Cuidado com os golpes! Usar o Etherscan para verificar o fornecimento total de um token é uma maneira muito arriscada de avaliar os riscos de um contrato inteligente, especialmente se o contrato inteligente não for verificado ou se o token for suspeito.

Existem 4 maneiras de detectar se o saldo é “falsificado”.

  • Engenharia reversa do contrato inteligente, para inspecionar todas as funções de um contrato inteligente e ver se há uma função suspeita.
  • Tentar inspecionar as transações e as alterações de estado para ver se há alguma alteração suspeita.
  • Tentar adivinhar se um endereço tem saldo falso (por exemplo, se alguém da equipe abusar de seus privilégios).
  • Invista apenas em contratos inteligentes E construtores verificados (porque o construtor é removido no contrato inteligente implantado)

Artigo original publicado por TrustChain. Traduzido por Paulinho Giovannini.

Top comments (0)