本文介绍了Foundry框架中的vm.roll和vm.warp两个作弊码,它们允许开发者在测试中快速调整区块链的区块高度和时间戳,方便模拟时间锁、截止日期、权益归属等与时间相关的合约逻辑。通过结合这两个作弊码,开发者可以轻松地测试合约在不同时间点和区块高度下的行为。
有没有想过成为区块链时间领主?Foundry 的 vm.roll 和 vm.warp 让你能快进截止日期、跳过冷却期,并打破基于时间的逻辑。Cheatcode 第 4 部分来了。
在本系列的前一集中
我们掌握了负面测试和事件验证。今天我们要扮演时间领主:vm.roll 和 vm.warp 让你的测试可以跳到任何区块号或时间戳,非常适合截止日期、归属计划和基于区块的锁定。
将区块链的区块号跳到 newHeight(保持时间戳不变)。这对于测试基于时间或基于区块的逻辑非常有用。例如,许多合约会锁定功能直到某个区块,或者只允许在 n 个区块过去后才能执行操作。你可以轻松地模拟这种情况:
在测试中,在 N 部署后,你可以这样做:
由于 Forge 使用确定性的 EVM,上述调用确实会看到 block.number ≥ unlockBlock,从而允许操作成功。相反,如果你回滚到一个较小的数字,它将恢复。
重要的是,vm.roll 仅设置区块号,而区块时间戳 (block.timestamp) 保持不变。Foundry 还提供了 vm.warp 来设置时间戳(参见下一节)。通常,你可以结合使用两者来提前区块号和时间来模拟进展。这些作弊码让你能够轻松地“将 block.timestamp 和 block.number 推送到未来”。(例如,一个关于彩票合约的 Foundry 教程,使用 vm.warp(...) 和 vm.roll(...) 背靠背地模拟彩票间隔的过去。)
因为 block.number 通常是单调的,所以 vm.roll 也可以通过给出一个较小的数字来缩小(倒带)区块高度,但需要小心,因为合约可能会假设区块递增。
高级提示: 不变量或模糊测试可能在内部使用 roll 来探索块时间不变量。此外,如果你 fork 了主网,Forge 的区块操作可以在 forks 上无缝工作,vm.roll 仍然会覆盖测试环境的数字。总的来说,vm.roll 解锁了必须满足某个区块号条件的任何场景,而无需实时等待。
与 vm.roll 类似,vm.warp(uint256 newTime)
将区块链的当前 block.timestamp 设置为 newTime。这对于测试基于时间的逻辑(截止日期、归属、利息累积等)至关重要。例如,考虑一个时间锁:
在测试中,你可以这样写:
对 vm.warp(...) 的调用将时间跳转到 block.timestamp >= releaseTime 的时间点,因此 withdraw 逻辑通过。如果你尝试在 warp 之前调用,它会按预期恢复。将 vm.warp 与 vm.expectRevert 结合使用是一种常见的模式,用于测试截止日期前后的行为。
Foundry 还提供了方便的快捷方式:skip(x) 将时间提前 x 秒,而 rewind(x) 将时间向后移动(如果需要)。但核心作弊码是 vm.warp。与 roll 一样,时间戳更改仅对下一次交易有效;测试上下文继续使用新的时间。
在实际合约中,你可能需要测试随时间累积的利息、拍卖到期或 NFT 揭示截止日期。vm.warp 让你立即模拟长时间的等待。请注意:如果你的合约还依赖于区块号,你可能需要 vm.warp 和 vm.roll 一起使用(或使用 skip/rewind,它们仅影响时间)。在任何情况下,这些时间旅行作弊码使访问非常旧或未来的时间戳变得非常简单。
第 4 部分到此结束。在下一期中,我们将探讨如何将时间旅行与恢复测试、模糊测试和不变量检查相结合,以全面覆盖时间敏感型逻辑。
如果你喜欢这种类型的内容,请在 twitter 上关注 @threesigmaxyz,并浏览我们的博客以获取更多关于区块链主题的见解。
明天发布 第 5 部分:作弊码 vm.deal,资助账户
- 原文链接: x.com/threesigmaxyz/stat...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!