WEB3DEV

Cover image for Solidity: Como fazer uma auditoria interna em contratos inteligentes em 3 etapas.
Dimitris Carvalho Calixto
Dimitris Carvalho Calixto

Posted on

Solidity: Como fazer uma auditoria interna em contratos inteligentes em 3 etapas.

Se você está aqui provavelmente trabalha com contratos inteligentes e não quer (gastar dinheiro para auditoria externa) arruinar seu trabalho vazando vulnerabilidades, então estou aqui apresentando uma lista fácil de fazer para verificar seu código Solidity.

A programação inteligente de contratos requer uma mentalidade de engenharia diferente da que você possa estar acostumado. O custo da falha pode ser alto... - Consensys

Stonks

Agora vamos ao trabalho. Quando faço uma auditoria interna, sigo 3 etapas:

Etapa 0.

Se você fizer uma auditoria interna em um contrato desconhecido, você deve entender profundamente a lógica do contrato. Isto garantirá que algumas vulnerabilidades (como bugs aritméticos) sejam falsas bandeiras ou não.

Por favor, esteja ciente também das vulnerabilidades que existem com base em sua versão do Pragma.

Etapa 1. Análise Estática.

Esta etapa deve ser fácil e rápida. A análise estática é feita com ferramentas automatizadas. Elas detectam todos os tipos de comportamentos. Com base em um relatório de ferramentas, sua tarefa é resolver cada problema detectado. Algumas das questões são bandeiras falsas, mas elas têm que ser observadas e marcadas como bandeiras falsas se forem. Algumas ferramentas fáceis que eu recomendo são Remix, MythX, Solhint.

Um pequeno exemplo do que a análise estática pode encontrar. Por exemplo, você tem um contrato que lhe permite passar um array com múltiplos endereços para uma whitelist (lista branca). O administrador chama a função addWhitelist(), mas ele recebe uma negação de serviço. Por quê? porque o desenvolvedor não estabeleceu limitações para o array.

contract Whitelist {

    address[] public whitelist;

    function addWhitelist(address[] memory users) public {

        for(uint256 i=0; i < users.length; i++){

            whitelist.push(users[i]);

        }

    }

}
Enter fullscreen mode Exit fullscreen mode

Análise Estática de Solidez Remix para Whitelist.sol

Podemos observar que a ferramenta de Análise Estática do Solidity Remix encontra 2 vulnerabilidades potenciais em nosso código. Ambas nos informam sobre o limite do bloco de gás, portanto devemos levar em consideração as advertências e modificar o código para limitar o comprimento máximo do array.

Fase 2. 100% de cobertura de teste.

Para contratos inteligentes, uma cobertura de teste 100% é imprescindível!

Esta fase deve ser feita separadamente, antes da auditoria interna, mas como os desenvolvedores vêm com mentalidades diferentes, acontece que a cobertura não seja tratada com seriedade. Lembre-se: "o custo do fracasso pode ser alto...".

Minha recomendação é fazer isso em 2 etapas:

  • Testes unitários: Pegue cada função e crie um arquivo de teste para ela. Agora, com base no código de função, tente pensar em todos os cenários possíveis a serem atravessados. Esta abordagem forçará sua mente a "quebrar o código" em vez de apenas escrever testes baseados em relatórios de cobertura.
  • Teste de integração: Aqui você pode criar cenários mais complexos para testar seu código. Como os testes unitários foram feitos antes desta etapa, os testes de integração devem passar sem erros, mas você nunca sabe em um contexto complexo, então é por isso que eu recomendo também este tipo de teste.

A melhor abordagem é pensar em todos os tipos de cenários e tocar todos os branches (ramos) sem ver o relatório de cobertura.

Branches

Fase 3. Verificar as vulnerabilidades conhecidas (o verdadeiro negócio)

Esta fase pode ser literalmente um livro inteiro, então tentarei apenas dar algumas dicas e algumas instruções para estudar.

Antes de mais nada, isto deve ser feito com base na versão do contrato inteligente em Solidity. Devido às atualizações, muitas vulnerabilidades foram resolvidas, mas ainda é um longo caminho para uma linguagem de código segura.

A fase de verificação das vulnerabilidades conhecidas também pode ser feita em etapas separadas:

  • Vulnerabilidades do Solidity. Minha recomendação é começar com o SWC Registry. Este registro contém as vulnerabilidades de conhecimento do contrato inteligente. Pegue as vulnerabilidades do SWC uma a uma, entenda-as profundamente e depois procure por elas em seu código. É um processo longo, mas com o tempo será muito mais fácil e rápido, portanto,sem pressa.
  • Vulnerabilidades da blockchain podem afetar os contratos inteligentes.

Uma classificação das vulnerabilidades do Ethereum e seus tratamentos de última geração

Na imagem acima, as vulnerabilidades são marcadas com quadrados:

  • quadrados pretos - significa que as vulnerabilidades foram resolvidas devido a atualizações do pragma do Solidity.
  • quadrados meio pretos e meio brancos - são vulnerabilidades que podem ser evitadas através da escrita de código seguro. Por exemplo, para o Ataque de Reentrância (o mais assustador), uma das soluções conhecidas é usar o padrão check-effect-pattern + Reentrancy Guard do Openzeppelin.
  • quadrado branco - representa vulnerabilidades que ainda não têm uma solução padrão, mas posso dar dois exemplos de alternativas seguras: contrato atualizável e gerando aleatoriedade.

    Contrato atualizável - O Openzeppelin oferece várias soluções seguras para implementar a capacidade de atualização em contratos inteligentes, mas minha preferida é a Padrão Diamante (Diamond Standard) EIP2535. Você pode ler sobre o conceito do padrão de diamante aqui. Uma característica muito legal do EIP2535 é que uma vez que você termina de atualizar o projeto você pode torná-lo imutável e isso dá muita confiança aos usuários.

    Gerando aleatoriedade - A Chainlink resolve este problema com a solução VRF (Verifiable Random Function ou Função aleatória verificável) que permite que contratos inteligentes acessem números aleatórios em um modo seguro.

Eu sei, pode parecer assustador, mas com a representação acima eu queria ter certeza de como as coisas podem ser complexas com qualquer recurso extra que você acrescente em seu contrato. Portanto, esteja ciente da complexidade de seu contrato e não se esqueça de codificar contratos inteligentes como a programação web2 é uma péssima idéia.

Como você pode observar, há uma longa lista que pode se equivocar no devido processo de desenvolvimento. Agora é hora de obter o código linha por linha e observar se algo pode criar uma quebra de segurança. Sem pressa e não se esqueça, contratos inteligentes não podem ser imutáveis após a implementação.

Recomendação: gere um relatório baseado no que você verificou e no que você encontrou, como fazem todos os auditores externos. O relatório o ajudará a ver o processo de revisão do contrato inteligente devido a mudanças.

Uma vez terminadas estas 3 etapas e nada deve mudar, você está pronto para a implantação. Se seu relatório contém modificações necessárias para um contrato inteligente, então todo o processo deve ser refeito.

Em minha carreira fiz a auditoria interna seguindo estas etapas e isso me garantiu que não foram encontradas grandes/críticas vulnerabilidades nas auditorias externas, por isso quis compartilhar com vocês.

Não esqueça: contrato inteligente significa código que "não pode prejudicar". Dê o melhor de si para ser assim.

Você pode me seguir no twitter se estiver interessado na minha atividade tecnológica. Compartilharei com você meus conhecimentos.

Lista de artigos que o ajudarão a passar pelo processo:

*Vindo em breve com uma lista consistente

Artigo escrito por Balut Catalin. A versão original pode ser encontrada aqui. Traduzido e adaptado por Dimitris Calixto.

Top comments (0)