审计 Foundry 智能合约安全 是做什么的?
概述
已部署的智能合约是不可变的,并且托管着真实资金,因此一个部署到主网上的 bug 无法被修补——它只能被利用。大多数灾难性的 DeFi 损失都源于一小类反复出现的问题:重入、访问控制被破坏、预言机/价格操纵,以及未经检查的算术运算或外部调用。
本技能对一个 Foundry 项目执行纵深防御的预部署审计,分层应用四种独立的技术,每种技术都能捕捉到其他技术遗漏的问题:
- 静态分析 —
slither(90+ 检测器)和aderyn(Cyfrin,Rust)在数秒内扫描 AST/IR 以发现已知反模式。 - 符号执行 —
mythril(可选,较慢)探索执行路径并使用 SMT 求解器寻找深层的算术/重入 bug。 - 属性测试 — 使用模糊测试(
testFuzz_*)和不变性测试(invariant_*+ 带有幽灵变量的处理器合约)的forge test,在数百万个随机序列上证明协议级别的属性成立。 - 手动审查 + 密钥卫生 — 一个结构化的检查清单(参见
references/vulnerability-checklist.md)以及一次秘密/密钥存储审计,确保没有任何私钥以明文形式存在,并且部署使用加密的cast密钥库(参见references/secure-deployment-and-keys.md)。
该技能面向开发者且用于部署前——由构建合约的工程师执行,而不是安全运营中心在事故发生后执行。发现的问题会阻止部署:任何高/严重级别的静态发现、失败的测试、泄漏的密钥或过低的覆盖率 = 失败。
何时使用
- 在将任何 Solidity 合约部署到测试网或主网 EVM 链之前。
- 在编写或审查一个 Foundry 项目(
foundry.toml、src/、test/、script/)时。 - 当合约处理价值时:代币(ERC-20/721/1155)、金库、质押、AMM、桥接、治理。
- 当添加模糊测试或不变性测试,或当涉及价值转移的函数的覆盖率未知时。
- 当配置部署脚本时——以验证密钥存储在加密的密钥库中,而不是
.env明文。 - 当集成价格预言机、外部调用、
delegatecall或可升级代理时。 - 当分类 Slither/Aderyn 报告,需要区分真正的 bug 和误报时。
前置条件
- Foundry 已安装(
forge、cast、anvil):curl -L https://foundry.paradigm.xyz | bash && foundryup - Slither + solc:
pip install slither-analyzer和solc-select install <ver> && solc-select use <ver> - Aderyn(推荐):
cargo install aderyn(或npm i -g @cyfrin/aderyn) - Mythril(可选,符号执行较慢):
pip install mythril - gitleaks(密钥泄漏扫描):请参阅配套技能
implementing-secret-scanning-with-gitleaks - 一个编译通过的 Foundry 项目(
forge build成功)——分析器需要构建产物。 - 假设使用 Solidity ^0.8.x(内置溢出检查);pre-0.8 的合约需要额外的 SafeMath 审查。
在虚拟环境中安装 Python 工具(推荐用于外部管理的发行版)。切勿在存有已解锁的、持有资金的钱包的机器上对不受信任的合约源代码进行分析。
步骤
第 1 步:构建并检查项目
forge build # 分析器需要最新的构建产物
forge fmt --check # 样式门控(可选)
cat foundry.toml # 注意 solc 版本、优化器、重映射、evm_version
第 2 步:静态分析(快速,每次运行)
# Slither — 整个项目(自动使用 foundry.toml + 重映射)
slither . --json slither-report.json
# Aderyn — Cyfrin Rust 分析器,补充检测器
aderyn . -o aderyn-report.json
或者运行集成的编排器,它同时运行两者、去重并门控结果:
python3 scripts/agent.py --project . --output audit-report.json
第 3 步:对关键合约进行符号执行(可选,较慢)
# 只针对价值最高的合约 — Mythril 路径爆炸
myth analyze src/Vault.sol --solc-json mythril.config.json --execution-timeout 300 -o json
# 或者:python3 scripts/agent.py --project . --mythril src/Vault.sol
第 4 步:属性测试 — 模糊 + 不变性
forge test -vvv # 单元 + 模糊测试
forge coverage --report summary # 涉及价值转移代码的覆盖率
forge test --match-test invariant_ -vvv # 不变性测试套件(基于处理器)
每个涉及价值转移的合约都应该有基于处理器的不变性测试(输入边界、幽灵变量、targetContract(handler))——而不仅仅是单元测试。请参阅 references/api-reference.md 了解处理器模式,并为每个访问控制守卫编写一个 test_RevertWhen_*(配合 vm.expectRevert)。
第 5 步:根据检查清单进行手动审查
对每个合约逐一检查 references/vulnerability-checklist.md:重入(检查-效果-交互 / nonReentrant)、访问控制、预言机操纵、delegatecall/代理存储布局、未检查的返回值、tx.origin、弱随机性、拒绝服务、抢跑/MEV,以及特定 ERC 的陷阱(approve 竞态、收费代币、基数变动)。
第 6 步:密钥卫生与安全部署
gitleaks detect --no-banner # 确保没有私钥 / 助记词 / .env 被提交
git ls-files | grep -E '\.env$|keystore' && echo "警告:Git 跟踪了密钥文件"
# 将部署密钥一次性导入加密的密钥库 — 永远不要使用明文的 PRIVATE_KEY 环境变量
cast wallet import deployer --interactive
# 通过密钥库账户部署(先在测试网上),在 --broadcast 之前模拟
forge script script/Deploy.s.sol --account deployer --rpc-url <testnet> --broadcast --verify
请参阅 references/secure-deployment-and-keys.md 了解完整的加固规则(MetaMask 卫生、主网使用硬件钱包、RPC 信任、部署后验证)。
第 7 步:分类与报告
合并 Slither + Aderyn + Mythril + 测试结果,按(文件,行)去重,排除已确认的误报,按可利用性 × 财务影响排序,并将每个发现项映射到其 SWC ID。编排器输出带有通过/失败门禁的 audit-report.json。
预期输出
一份 JSON 格式的审计报告,其中包含发现项及其 SWC 标识符、严重等级、工具来源、受影响的合约/函数/行以及修复建议;还包括测试/覆盖率摘要和一个单一的 通过 / 失败 部署门禁。任何高/严重级别的静态发现、失败的测试、泄漏的秘密或涉及价值转移的代码覆盖率低于配置阈值,结果即为失败。