Auditoría de Seguridad de Smart Contracts con Foundry
Visión General
Los contratos inteligentes desplegados son inmutables y custodian fondos reales, por lo que un error enviado a mainnet no puede corregirse — solo puede ser explotado. La mayoría de las pérdidas catastróficas en DeFi provienen de un pequeño conjunto de clases recurrentes: reentrancia, control de acceso roto, manipulación de oráculos/precios, y aritmética o llamadas externas no verificadas.
Esta habilidad ejecuta una auditoría de defensa en profundidad previa al despliegue de un proyecto Foundry, superponiendo cuatro técnicas independientes que cada una detecta lo que las otras pasan por alto:
- Análisis estático —
slither(90+ detectores) yaderyn(Cyfrin, Rust) escanean el AST/IR en segundos en busca de anti-patrones conocidos. - Ejecución simbólica —
mythril(opcional, lento) explora caminos de ejecución y resuelve SMT para bugs profundos de aritmética/reentrancia. - Pruebas basadas en propiedades —
forge testcon fuzzing (testFuzz_*) y pruebas de invariantes (invariant_*+ contratos handler con variables fantasma) demuestra que las propiedades a nivel de protocolo se cumplen en millones de secuencias aleatorias. - Revisión manual + higiene de claves — una lista de verificación estructurada (ver
references/vulnerability-checklist.md) y una auditoría de secretos/keystore para que ninguna clave privada viva en texto plano y el despliegue pase por un keystore cifrado decast(verreferences/secure-deployment-and-keys.md).
La habilidad es del lado del desarrollador y previa al despliegue — la ejecuta el ingeniero que construye el contrato, no un SOC después de un incidente. Los hallazgos bloquean el despliegue: cualquier hallazgo estático alto/crítico, prueba fallida, clave filtrada o cobertura baja = FAIL.
Cuándo Usarla
- Antes de desplegar cualquier contrato Solidity a una testnet o cadena EVM de mainnet.
- Al escribir o revisar un proyecto Foundry (
foundry.toml,src/,test/,script/). - Cuando un contrato maneja valor: tokens (ERC-20/721/1155), vaults, staking, AMMs, puentes, gobernanza.
- Al agregar pruebas de fuzzing o invariantes, o cuando se desconoce la cobertura de funciones que mueven valor.
- Al cablear scripts de despliegue — para verificar que las claves están en un keystore cifrado, no en texto plano de
.env. - Al integrar un oráculo de precios, llamada externa,
delegatecallo proxy actualizable. - Al clasificar un informe de Slither/Aderyn y necesitar separar bugs reales de falsos positivos.
Prerrequisitos
- Foundry instalado (
forge,cast,anvil):curl -L https://foundry.paradigm.xyz | bash && foundryup - Slither + solc:
pip install slither-analyzerysolc-select install <ver> && solc-select use <ver> - Aderyn (recomendado):
cargo install aderyn(onpm i -g @cyfrin/aderyn) - Mythril (opcional, ejecución simbólica lenta):
pip install mythril - gitleaks (escaneo de fugas de claves): ver la habilidad complementaria
implementing-secret-scanning-with-gitleaks - Un proyecto Foundry que compile (
forge buildexitoso) — los analizadores necesitan artefactos de compilación. - Se asume Solidity ^0.8.x (con comprobaciones de desbordamiento incorporadas); los contratos pre-0.8 necesitan revisión adicional de SafeMath.
Instala las herramientas Python en un virtualenv (recomendado en distribuciones gestionadas externamente). Nunca ejecutes análisis contra código fuente de contratos no confiables en una máquina con billeteras financiadas desbloqueadas.
Pasos
Paso 1: Compilar y verificar el proyecto
forge build # los analizadores necesitan artefactos frescos
forge fmt --check # comprobación de estilo (opcional)
cat foundry.toml # nota la versión de solc, optimizador, remappings, evm_version
Paso 2: Análisis estático (rápido, ejecutar siempre)
# Slither — proyecto completo (usa foundry.toml + remappings automáticamente)
slither . --json slither-report.json
# Aderyn — analizador Cyfrin Rust, detectores complementarios
aderyn . -o aderyn-report.json
O ejecuta el orquestador empaquetado que corre ambos, desduplica y bloquea el resultado:
python3 scripts/agent.py --project . --output audit-report.json
Paso 3: Ejecución simbólica en contratos críticos (opcional, lento)
# Solo en el(los) contrato(s) de mayor valor — Mythril es explosivo en caminos
myth analyze src/Vault.sol --solc-json mythril.config.json --execution-timeout 300 -o json
# o: python3 scripts/agent.py --project . --mythril src/Vault.sol
Paso 4: Pruebas basadas en propiedades — fuzzing + invariantes
forge test -vvv # pruebas unitarias + fuzzing
forge coverage --report summary # cobertura del código que mueve valor
forge test --match-test invariant_ -vvv # suite de invariantes (basada en handler)
Cada contrato que mueva valor debería tener pruebas de invariantes con un handler (entradas acotadas, variables fantasma, targetContract(handler)) — no solo pruebas unitarias. Ver references/api-reference.md para el patrón handler, y escribe un test_RevertWhen_* (con vm.expectRevert) para cada guardia de control de acceso.
Paso 5: Revisión manual contra la lista de verificación
Recorre references/vulnerability-checklist.md para cada contrato: reentrancia (checks-effects-interactions / nonReentrant), control de acceso, manipulación de oráculos, delegatecall/layout de almacenamiento en proxies, valores de retorno no verificados, tx.origin, aleatoriedad débil, DoS, front-running/MEV, y trampas específicas de ERC (carrera de approve, fee-on-transfer, rebasing).
Paso 6: Higiene de claves y despliegue seguro
gitleaks detect --no-banner # sin claves privadas / mnemónicos / .env commiteados
git ls-files | grep -E '\.env$|keystore' && echo "WARN: secretos rastreados por git"
# Importa la clave de despliegue UNA VEZ en un keystore cifrado — nunca una variable PRIVATE_KEY en texto plano
cast wallet import deployer --interactive
# Despliega mediante la cuenta del keystore (primero en testnet), simula antes de --broadcast
forge script script/Deploy.s.sol --account deployer --rpc-url <testnet> --broadcast --verify
Ver references/secure-deployment-and-keys.md para las reglas completas de endurecimiento (higiene de MetaMask, hardware wallet para mainnet, confianza en RPC, verificación post-despliegue).
Paso 7: Clasificación e informe
Combina los resultados de Slither + Aderyn + Mythril + pruebas, desduplica por (archivo, línea), descarta falsos positivos confirmados, clasifica por explotabilidad × impacto financiero, y mapea cada uno a su ID SWC. El orquestador emite audit-report.json con una compuerta PASS/FAIL.
Salida Esperada
Un reporte de auditoría JSON que lista hallazgos con identificadores SWC, severidad, herramienta fuente, contrato/función/línea afectada, y remediación; más el resumen de pruebas/cobertura y una única compuerta PASS / FAIL para el despliegue. FAIL ante cualquier hallazgo estático alto/crítico, prueba fallida, secreto filtrado, o cobertura por debajo del umbral configurado en código que mueve valor.