Lição: 293: Teste de Fuzz com Echidna
Os testes de fuzz são uma técnica poderosa para descobrir vulnerabilidades em contratos inteligentes, fornecendo entradas aleatórias e observando o comportamento do contrato. No ecossistema Ethereum, o Echidna é uma ferramenta popular projetada especificamente para esse propósito. Nesta aula, vamos explorar como usar o Echidna para realizar testes de fuzz em contratos inteligentes Solidity.
O que é o Echidna?
Echidna é um testador de fuzz para contratos inteligentes Ethereum escritos em Solidity. Ele foi desenvolvido para gerar entradas de teste aleatórias, o que pode ajudar na identificação de problemas como:
- Ataques de reentrância
- Overflow e underflow de inteiros
- Transições de estado incorretas
O Echidna opera criando um conjunto de propriedades que você deseja verificar em seu contrato inteligente. Ele executa testes para ver se essas propriedades são válidas para entradas geradas aleatoriamente.
Instalando o Echidna
Para começar a usar o Echidna, você precisa instalar a ferramenta Echidna. Você pode fazer isso usando git
e cargo
(gerenciador de pacotes do Rust).
Primeiro, verifique se você tem o Rust instalado em sua máquina. Você pode conferir isso executando:
rustc --version
Se você não tiver o Rust, instale-o usando rustup
:
curl --proto '=https' --scheme 'https' -sSf https://sh.rustup.rs | sh
Uma vez que o Rust esteja instalado, clone o repositório do Echidna:
git clone https://github.com/crytic/echidna.git
cd echidna
Depois, construa e instale o Echidna:
cargo build --release
cargo install --path .
Escrevendo um Contrato Inteligente
Vamos escrever um contrato inteligente Solidity simples que possamos testar usando o Echidna. O exemplo a seguir é um contrato de token simples com um limite na quantidade de tokens que podem ser criados.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SimpleToken {
string public name = "SimpleToken";
string public symbol = "STK";
uint256 public totalSupply;
mapping(address => uint256) public balances;
uint256 public constant MAX_SUPPLY = 1000;
constructor() {
totalSupply = 0;
}
function mint(uint256 amount) public {
require(totalSupply + amount <= MAX_SUPPLY, "A mintagem excede o suprimento máximo");
balances[msg.sender] += amount;
totalSupply += amount;
}
}
Neste contrato, temos uma função mint
que permite aos usuários criar novos tokens, se o suprimento total não exceder o suprimento máximo.
Escrevendo Propriedades para o Echidna
Para usar o Echidna de forma eficaz, precisamos especificar certas propriedades que gostaríamos de verificar. Vamos criar uma série de propriedades que garantam que nosso contrato se comporte como esperado.
Crie um novo arquivo EchidnaTest.sol
:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./SimpleToken.sol";
contract EchidnaTest {
SimpleToken token;
constructor() {
token = new SimpleToken();
}
// Propriedade: O suprimento total nunca deve exceder MAX_SUPPLY
function echidna_total_supply_never_exceeds_max() public view returns (bool) {
return token.totalSupply() <= token.MAX_SUPPLY();
}
// Propriedade: Após a mintagem, o saldo de um usuário deve refletir as mintagens
function echidna_balance_reflects_minting() public view returns (bool) {
// Você pode usar um endereço pré-definido ou o seu próprio para teste
address user = msg.sender;
return token.balances(user) <= token.totalSupply();
}
}
Executando o Echidna
Agora que temos nosso contrato e propriedades definidos, é hora de executar o Echidna. Certifique-se de compilar seu código Solidity para que o Echidna possa analisá-lo.
Você pode executar o Echidna na linha de comando especificando os contratos que deseja testar:
echidna-test . --contract EchidnaTest
O Echidna gerará entradas aleatórias para testar seu contrato inteligente em relação às propriedades definidas. Se alguma das propriedades falhar, o Echidna fornecerá detalhes sobre a entrada que causou a falha, permitindo que você identifique potenciais vulnerabilidades.
Exemplo de Saída
Após executar o Echidna, você pode ver uma saída semelhante a:
Echidna encontrou uma violação na propriedade: echidna_total_supply_never_exceeds_max
Isso indica que sua propriedade echidna_total_supply_never_exceeds_max
foi violada, significando que houve um caso em que o suprimento total excedeu o limite máximo de suprimento.
Conclusão
Os testes de fuzz com o Echidna são uma técnica valiosa para garantir a confiabilidade e a segurança de seus contratos inteligentes Solidity. Ao escrever propriedades contra as quais deseja testar seus contratos, você pode expor vulnerabilidades que podem não ser descobertas com testes unitários regulares.
Com prática e experimentação, você pode utilizar o Echidna para avaliar minuciosamente seus contratos inteligentes e ajudar a proteger suas aplicações descentralizadas. Boas práticas de teste!