
echidna v2.3.3
Fuzzer de contratos inteligentes Ethereum
Echidna: Um Fuzzer Rápido para Contratos Inteligentes 
Echidna é uma criatura estranha que come bugs e é altamente eletrossensível (com desculpas a Jacob Stanley)
Mais seriamente, Echidna é um programa em Haskell projetado para fuzzing/testes baseados em propriedades de contratos inteligentes Ethereum. Ele usa campanhas sofisticadas de fuzzing baseadas em gramática, fundamentadas em uma ABI de contrato, para falsificar predicados definidos pelo usuário ou asserções Solidity. Projetamos o Echidna com modularidade em mente, para que possa ser facilmente estendido para incluir novas mutações ou testar contratos específicos em casos específicos.
Recursos
- Gera entradas adaptadas ao seu código real
- Coleta opcional de corpus, mutação e orientação de cobertura para encontrar bugs mais profundos
- Desenvolvido com Slither para extrair informações úteis antes da campanha de fuzzing
- Integração com o código-fonte para identificar quais linhas são cobertas após a campanha de fuzzing
- Interface de terminal interativa, saída somente texto ou JSON
- Minimização automática de casos de teste para triagem rápida
- Integração perfeita no fluxo de trabalho de desenvolvimento
.. e um belo logotipo artesanal em alta resolução.
Uso
Executando o executor de testes
A funcionalidade central do Echidna é um executável chamado echidna, que recebe um contrato e uma lista
de invariantes (propriedades que devem sempre permanecer verdadeiras) como entrada. Para cada invariante, ele gera
sequências aleatórias de chamadas ao contrato e verifica se a invariante se mantém. Se conseguir encontrar alguma forma
de falsificar a invariante, ele imprime a sequência de chamadas que o faz. Se não conseguir, você tem alguma
garantia de que o contrato é seguro.
Escrevendo invariantes
As invariantes são expressas como funções Solidity com nomes que começam com echidna_, não têm argumentos e retornam um booleano. Por exemplo, se você tem alguma variável balance que nunca deve ficar abaixo de 20, você pode escrever uma função extra no seu contrato como esta:```solidity
function echidna_check_balance() public returns (bool) {
return(balance >= 20);
}
Para verificar essas invariantes, execute:```sh
$ echidna myContract.sol
Um exemplo de contrato com testes pode ser encontrado em tests/solidity/basic/flags.sol. Para executá-lo, você deve executar:```sh $ echidna tests/solidity/basic/flags.sol
O Echidna deve encontrar uma sequência de chamadas que falsifique `echidna_sometimesfalse` e deve ser incapaz de encontrar uma entrada falsificadora para `echidna_alwaystrue`.
### Modos de teste
O exemplo acima usa o modo **property** padrão, mas o Echidna suporta vários modos de teste, configurados via `testMode` no arquivo de configuração ou `--test-mode` na CLI:
* **`property`** (padrão): Testa funções com prefixo `echidna_` que retornam `bool`.
* **`assertion`**: Detecta falhas de asserção de `assert()` e dos auxiliares `assertX` do Foundry (`assertTrue`, `assertEq`, etc.).
* **`foundry`**: Executa testes no estilo Foundry, seguindo suas convenções de nomenclatura: testes unitários e de fuzz com prefixo `test` (os com prefixo `testFail` devem reverter) e invariantes stateful com prefixo `invariant` ou `statefulFuzz`. Funções com prefixo `check` e `prove` são pontos de entrada simbólicos, mas como este modo é uma campanha de fuzzing, elas são fuzzed como qualquer outra função de teste.
* **`verification`**: Verifica simbolicamente cada função do contrato usando uma única transação. Funções com prefixo `check` e `prove` são sempre usadas como pontos de entrada.
* **`overflow`**: Detecta over/underflows de inteiros (Solidity >= 0.8.0).
* **`optimization`**: Maximiza o valor de retorno de funções com prefixo `echidna_` que retornam `int256` (usa o mesmo prefixo configurável do modo property).
* **`exploration`**: Coleta cobertura sem verificar propriedades.
### Coletando e visualizando cobertura
Após finalizar uma campanha, o Echidna pode salvar um **corpus** de maximização de cobertura em um diretório especial especificado com a opção de configuração `corpusDir`. Este diretório conterá duas entradas: (1) um diretório chamado `coverage` com arquivos JSON que podem ser reproduzidos pelo Echidna e (2) um arquivo de texto simples chamado `covered.txt`, uma cópia do código-fonte com anotações de cobertura.
Se você executar o exemplo `tests/solidity/basic/flags.sol`, o Echidna salvará alguns arquivos de transações serializadas no diretório `coverage` e um arquivo `covered.$(date +%s).txt` com as seguintes linhas:```text
*r | function set0(int val) public returns (bool){
* | if (val % 100 == 0)
* | flag0 = false;
}
*r | function set1(int val) public returns (bool){
* | if (val % 10 == 0 && !flag0)
* | flag1 = false;
}
Nossa ferramenta sinaliza cada traço de execução no corpus com o seguinte "marcador de linha":
*se uma execução terminou com um STOPrse uma execução terminou com um REVERTose uma execução terminou com um erro de out-of-gasese uma execução terminou com qualquer outro erro (divisão por zero, falha de asserção, etc)
Suporte para sistemas de build de contratos inteligentes
O Echidna pode testar contratos compilados com diferentes sistemas de build de contratos inteligentes, incluindo Foundry, Hardhat e Truffle, usando crytic-compile. Para invocar o Echidna com o framework de compilação atual, use echidna ..
Além disso, o Echidna suporta dois modos de teste de contratos complexos. Primeiramente, pode-se aproveitar o estado de rede existente e usá-lo como estado base para o Echidna. Em segundo lugar, o Echidna pode chamar qualquer contrato com uma ABI conhecida passando o código-fonte Solidity correspondente na CLI. Use allContracts: true na sua configuração para ativar isso.
Curso intensivo sobre o Echidna
Nosso repositório Building Secure Smart Contracts contém um curso intensivo sobre o Echidna, incluindo exemplos, lições e exercícios.
Usando o Echidna em um workflow do GitHub Actions
Existe uma action do Echidna que pode ser usada para executar o echidna como parte de um
workflow do GitHub Actions. Consulte o repositório
crytic/echidna-action para
instruções de uso e exemplos.
