1️⃣ Handler(操作生成器)的核心概念
作用:模拟系统中的多种可能行为序列
目标:通过随机化或系统化调用智能合约的函数,生成各种可能状态变化
特征:包含多个函数(通常是合约的核心外部接口)
每个函数内部对输入参数进行随机化(例如使用 bound() 或者 seed % array.length)
可以选择 StopOnRevert 或 ContinueOnRevert
StopOnRevert:遇到 revert 立即停止 → 快速定位错误
ContinueOnRevert:忽略 revert 继续运行 → 更大覆盖范围,适合 invariant 检查
核心思想:Handler 是一个“智能 fuzz 测试代理”,负责生成操作序列并调用合约接口。
| 特性 / Handler | StopOnRevertHandler | ContinueOnRevertHandler |
|---|---|---|
| 核心设计理念 | 任何函数 revert → 测试立即失败 |
函数 revert 也允许继续运行测试 |
| fail_on_revert | 配合 true 使用 |
配合 false 使用(或计划支持 per-function customization) |
| 输入处理 | 对可能导致 revert 的操作做提前检查,如:if (amount == 0) return;
|
直接调用函数,不过滤输入,可能触发 revert |
| 函数调用 |
mintAndDepositCollateral, redeemCollateral, burnDsc, liquidate 等,提前防护 |
同样函数,但不做提前防护,允许 revert 继续统计 |
| DSC 铸币方式 | 仅通过 dscEngine 铸币,遵循协议规则 |
直接调用 dsc.mint,绕过 dscEngine,测试白盒潜在漏洞 |
| 模拟场景 | 偏向“合法操作路径”测试协议不变量 | 偏向“极端 / 异常操作路径”,收集更多失败统计数据 |
| 价格喂价处理 | 可以正常更新 Mock Price Feed,遵守协议逻辑 | 价格可以置零,模拟极端价格波动(黑天鹅事件) |
| 适用场景 | 想验证协议在合法操作下不破产、不低抵押 | 想统计不同异常输入或极端情况对协议的影响,探索潜在漏洞 |
| 输出行为 | 一旦发生非法调用或 revert → 立即 FAIL | 发生 revert 也继续执行,记录统计数据(如调用次数、失败次数) |
总结
StopOnRevertHandler
用于严格 invariant 测试
强制协议在所有合法操作下都不能触发 revert
更适合生产环境前的安全验证
ContinueOnRevertHandler
用于探索性 fuzz 测试
收集异常操作统计,模拟极端情况
更适合漏洞挖掘和压力测试
2️⃣ Invariant(不变量检查)的核心概念
作用:定义协议在任意状态下必须满足的全局规则
目标:确保系统在随机操作下不会进入不安全状态
特征:
通常是 view 函数或 assert 语句
可以是:
余额约束(totalCollateral ≥ totalDebt)
系统规则(用户不能超额借贷)
状态不可变性(某些 getter 永远不能 revert)
检查机制:
每次 handler 调用之后执行 invariant
发现 invariant 失败 → 测试报告异常操作序列
核心思想: Invariant 是一个“安全网”,确保系统在各种状态下都满足关键规则。