
Fuzzer de contratos inteligentes de Ethereum

Echidna es una criatura extraña que come insectos y es altamente electrosensible (con disculpas a Jacob Stanley)
Más en serio, Echidna es un programa en Haskell diseñado para fuzzing/pruebas basadas en propiedades de smart contracts de Ethereum. Utiliza sofisticadas campañas de fuzzing basadas en gramática, basadas en un ABI de contrato para falsificar predicados definidos por el usuario o afirmaciones de Solidity. Diseñamos Echidna teniendo en cuenta la modularidad, por lo que se puede extender fácilmente para incluir nuevas mutaciones o probar contratos específicos en casos específicos.
.. y un hermoso logotipo artesanal de alta resolución.
La funcionalidad principal de Echidna es un ejecutable llamado echidna, que toma como entrada un contrato y una lista de invariantes (propiedades que siempre deben cumplirse). Para cada invariante, genera secuencias aleatorias de llamadas al contrato y verifica si el invariante se cumple. Si encuentra alguna forma de falsificar el invariante, imprime la secuencia de llamadas que lo logra. Si no puede, tienes cierta seguridad de que el contrato es seguro.
Los invariantes se expresan como funciones de Solidity con nombres que comienzan con echidna_, no tienen argumentos y devuelven un booleano. Por ejemplo, si tienes alguna variable balance que nunca debe bajar de 20, puedes escribir una función adicional en tu contrato como esta:```solidity
function echidna_check_balance() public returns (bool) {
return(balance >= 20);
}
Para comprobar estos invariantes, ejecuta:```sh
$ echidna myContract.sol
Se puede encontrar un contrato de ejemplo con pruebas en tests/solidity/basic/flags.sol. Para ejecutarlo, debe ejecutar:```sh $ echidna tests/solidity/basic/flags.sol
Echidna debería encontrar una secuencia de llamadas que falsifique `echidna_sometimesfalse` y debería ser incapaz de encontrar una entrada falsificadora para `echidna_alwaystrue`.
### Modos de prueba
El ejemplo anterior usa el modo **property** predeterminado, pero Echidna admite varios modos de prueba, configurados mediante `testMode` en el archivo de configuración o `--test-mode` en la CLI:
* **`property`** (predeterminado): Prueba funciones con prefijo `echidna_` que devuelven `bool`.
* **`assertion`**: Detecta fallos de aserción de `assert()` y los ayudantes `assertX` de Foundry (`assertTrue`, `assertEq`, etc.).
* **`foundry`**: Ejecuta pruebas unitarias estilo Foundry con prefijo `test` e invariantes de estado con prefijo `invariant_`.
* **`overflow`**: Detecta desbordamientos de enteros (Solidity >= 0.8.0).
* **`optimization`**: Maximiza el valor de retorno de funciones con prefijo `echidna_` que devuelven `int256` (usa el mismo prefijo configurable que el modo property).
* **`exploration`**: Recolecta cobertura sin verificar propiedades.
### Recolectando y visualizando cobertura
Después de finalizar una campaña, Echidna puede guardar un **corpus** que maximiza la cobertura en un directorio especial especificado con la opción de configuración `corpusDir`. Este directorio contendrá dos entradas: (1) un directorio llamado `coverage` con archivos JSON que pueden ser reproducidos por Echidna y (2) un archivo de texto plano llamado `covered.txt`, una copia del código fuente con anotaciones de cobertura.
Si ejecutas el ejemplo `tests/solidity/basic/flags.sol`, Echidna guardará algunos archivos con transacciones serializadas en el directorio `coverage` y un archivo `covered.$(date +%s).txt` con las siguientes líneas:```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;
}
Nuestra herramienta señala cada traza de ejecución en el corpus con el siguiente "marcador de línea":
* si una ejecución terminó con un STOPr si una ejecución terminó con un REVERTo si una ejecución terminó con un error de falta de gase si una ejecución terminó con cualquier otro error (división por cero, fallo de aserción, etc.)Echidna puede probar contratos compilados con diferentes sistemas de compilación de contratos inteligentes, incluyendo Foundry, Hardhat, y Truffle, utilizando crytic-compile. Para invocar Echidna con el marco de compilación actual, use echidna ..
Además, Echidna admite dos modos de probar contratos complejos. En primer lugar, se puede aprovechar el estado de red existente y usarlo como estado base para Echidna. En segundo lugar, Echidna puede llamar a cualquier contrato con un ABI conocido pasando el código fuente de Solidity correspondiente en la CLI. Use allContracts: true en su configuración para activar esto.
Nuestro repositorio Building Secure Smart Contracts contiene un curso intensivo sobre Echidna, que incluye ejemplos, lecciones y ejercicios.
Hay una acción de Echidna que se puede usar para ejecutar echidna como parte de un
flujo de trabajo de GitHub Actions. Consulte el
repositorio crytic/echidna-action para
obtener instrucciones de uso y ejemplos.
La CLI de Echidna se puede usar para elegir el contrato a probar y cargar un archivo de configuración.```sh $ echidna contract.sol --contract TEST --config config.yaml
El archivo de configuración permite a los usuarios elegir la EVM y los parámetros de generación
de pruebas. Un ejemplo de un archivo de configuración completo y anotado con las opciones
predeterminadas se puede encontrar en
[tests/solidity/basic/default.yaml](https://github.com/crytic/echidna/blob/master/tests/solidity/basic/default.yaml).
Consulte la [documentación](https://secure-contracts.com/program-analysis/echidna/configuration.html)
para obtener información más detallada sobre las opciones de configuración disponibles.