Foundry 高级作弊码系列:第 7 部分 - Foundry 中的不变性测试

本文介绍了 Foundry 中的不变性测试(Invariant Testing),它是一种强大的模糊测试方法,通过定义必须始终成立的规则,让 Foundry 尝试通过随机调用序列来打破合约,从而发现潜在的错误。文章解释了不变性测试的原理、关键参数、测试结构、常见模式和一些注意事项,并提供了一个实际的例子。

Image

想象一下你的合约可能面临的每一个随机调用。现在测试它们全部。不变性测试就像打了兴奋剂的fuzzing,非常适合发现你从未想过的错误。深入了解!

简介

我们在 Part 6 中完成了对单个调用的压力测试;这最后一章将标准提高到有状态的序列。不变性测试允许你声明规则,例如“totalSupply 始终等于 balances”,并让 Forge 锤击你的协议,直到规则被打破或你的信心飙升。

不变性测试是状态化的模糊测试,它断言必须始终保持为真的“规则”,即使在任何合约调用序列之后也是如此。在实践中,你编写带有 invariant 前缀的测试函数,并且 Forge 将在你的合约上生成随机的交易(调用)序列,以尝试违反这些不变量。例如,ERC20 不变量可能是“totalSupply == 所有余额的总和”或“没有人可以凭空创建代币”。然后,Foundry 将进行随机调用(并 fuzz 输入),并在每次调用后检查这些条件。

"不变性测试允许针对预定义函数调用的随机序列测试一组不变表达式…… 不变性测试是一种强大的工具,可以暴露协议中的不正确逻辑。"

你可以将不变量定义为带有 invariant_ 前缀的函数。例如:

Image

在底层,Foundry 将部署你的合约,然后运行许多“runs”随机调用,直到达到某个“depth”。每次 run 都是一个最多 depth 个随机事务的序列。在每次事务之后,所有 invariant_ 函数都会根据新状态进行检查。如果任何断言失败,Forge 会报告一个反例序列。你可以通过配置(默认 256 runsdepth 15)或通过 CLI 标志来控制 runsdepth,例如:

Image

(文档指出你也可以将不变量拆分为多个“jobs”以并行运行。)

测试结构:不变性测试与单元测试并存。例如,如果你有 handler 合约或多个合约,则将它们捆绑在你的测试套件中。Forge 将检测 invariant_ 函数并运行特殊的不变性引擎。在每次 run 结束时,将执行一个可选的 afterInvariant() 函数(如果已定义)以进行清理或日志记录。

常见模式:通常,编写一个 handler 合约,该合约包装被测系统,以提供简化的函数以进行 fuzzing。例如,handler 可能会暴露函数 hDeposit(uint256 x) 和函数 hWithdraw(uint256 y),它们调用真实的合约。然后,不变量断言全局属性(例如“余额总和 = 可用资金”)。Foundry 将重复调用随机序列,如 hDeposit、hWithdraw 等。

陷阱:

  • 非确定性:不变量为每个不变函数创建新的 EVM 分叉,因此除非分组,否则不会在同一状态下检查不变量。如果你需要多个条件共同存在,请将它们分组在一个函数中。

  • Reverts:默认情况下,Forge 不会在不变运行期间因 reverts 而失败(除非你设置 fail_on_revert=true)。相反,reverts 只是终止该 run。你可以配置此行为。

  • 复杂状态:对于非常复杂的状态系统,你可能需要仔细限制输入或假设(如使用 fuzzing),以保持不变量有意义并提高测试效率。

Foundry 中的不变性测试对于具有不变量的协议(例如 AMM、借贷池)特别有价值。为了捕获“边缘情况下和高度复杂协议状态下的错误假设和不正确的逻辑”。通过指定必须始终存在的内容(例如,代币守恒,会计等式),你可以让 Forge 尝试以确定性测试可能无法捕获的方式来破坏你的合约。

在实践中,完整的 不变性测试 可能看起来像:

Image

运行 forge test --ffi(如果需要)或直接运行 forge test 将自动运行不变性引擎。如果 Forge 发现破坏 invariant_TotalSupplyEqualsBalances 的调用序列,它将报告所需的步骤。

总之,不变性测试是协议范围内属性的终极“fuzz”。定义尽可能多的不变量,配置适合你的 CI 预算的 runs/depth,并让 Forge 详尽地探索调用序列。此强大功能超越了单元/fuzz 测试,有助于确保你的智能合约在任何有效的使用序列下都能正确运行。

来源:Foundry 文档和社区资料提供了有关 cheatcodes 和测试的广泛指南。主要参考资料包括 cheatcodes 和高级测试的官方 Foundry Book,以及比较工具的社区文章。以上所有示例代码均遵循 Forge 标准库 (forge-std) 约定。

如果你喜欢这种类型的内容,请在 Twitter 上关注 @threesigmaxyz

并浏览我们的 blog

以获取有关区块链主题的更多见解。

  • 原文链接: x.com/threesigmaxyz/stat...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Three Sigma
Three Sigma
Three Sigma is a blockchain engineering and auditing firm focused on improving Web3 by working closely with projects in the space.