本文回顾了对Corn协议的安全性评估,其中重点讨论了发现的安全漏洞及所采取的模糊测试最佳实践。Corn是一个Layer 2网络,旨在通过以太坊的低交易成本和比特币的安全性,让用户利用比特币进行DeFi应用。文章总结了团队在模糊测试过程中的经验教训,并指出了在测试中的重要发现。
2024年9月17日
在这次回顾中,我们回顾了与 Corn 协议的合作,探索了一些发现的安全漏洞以及一些关键的经验教训,这些经验教训使团队能够构建一个更易于维护/升级的模糊测试工具。
Corn 是一个 L2 网络,为在以太坊上使用比特币作为担保资产提供基础设施。利用以太坊的低交易成本和比特币 L1 的安全性,用户可以将其比特币资本应用于以太坊上的 DeFi 应用。
Corn 以 Bitcorn (BTCN) 为中心,这是一个与 BTC 挂钩的 ERC20 代币。该参与中审查的主要合约是 CornSilo
,允许用户存入资产,通过 Bitcorn 赚取积分,然后在网络上线后将其桥接到 Corn 网络。
Corn 的合作持续了 2 个月,包含以下内容:
一名专注于模糊测试的工程师, Lourens
由 Alex The Entreprenerd 实施的 40 小时不变性引导
本文回顾了第一个月,团队为核心库设置并运行了不变性测试器。
在模糊测试阶段,我们实施了一些独特的方法和开发最佳实践,我们希望在此与社区分享。
在审查时,当前的 SwapFacility
合约仍在开发中,因此 Recon 团队实施的模糊测试脚手架必须足够通用,以便能够适用于不同实现的合约逻辑,仅需在目标函数参数值上进行小的更改,使测试可以在不同的接口上工作。
在开发模糊测试套件时,Recon 团队将模糊测试者关注的函数结构划分为三类:面向公共/外部用户的函数、管理函数和测试末日场景的目标(不应发生或仅在特定条件下发生的事件)。
这允许关注点的分离,使定位特定功能的测试变得更容易,并使测试套件在我们随着不同贡献者添加更多测试时,维护变得更简单。
将目标函数分离到不同的合约中允许更可维护的独立测试不同的功能/场景。
针对 SwapFacility
合约,团队决定将所有不变性测试实施为直接在目标函数合约中的断言测试。这与标准 Recon 测试工具的实现相反,后者使用在 TargetFunctions
合约中定义的断言和在 Properties
合约中定义的布尔属性的组合来测试不变性(有关标准 Recon 测试工具的更多信息,请参见 此 文章)。
在这种情况下,由于正在测试的不变性可以通过断言测试来定义,因此选择以这种方式定义它们是因为这会使得运行扩展作业时更加简单,因为 Medusa 能够同时在断言和属性测试模式下运行,而 Echidna 只能在断言 或 属性测试模式下运行。
这使得团队能够使用我们首选的方式,最初采用更快(但实验性)的 Medusa 进行覆盖,然后切换到 Echidna 进行更长时间的运行,以获得更高的正确性保证,同时只需使用一种测试模式进行运行。
在这次合作中,目的是创建一个测试套件,允许在本地评估主要系统不变性,以及一个分叉的测试套件,用于测试依赖于集成合约的不变性(主要与杂物和费用相关)。
为了尽可能简化测试套件接口以实现本地 + 分叉测试的目标,套件使用了一个共享的 setUp
函数来部署系统合约,然后扩展了一个 _setUpFork
函数,以设置已部署依赖合约的值。这是通过在必要时覆盖现有本地区部署的 Corn 系统合约与传入这些依赖合约的新部署实现的。
由于系统的某些部分(SiloZap
)具有仅能通过分叉测试进行的不可变性,因此实现了以下修饰符,以确保其目标函数在本地测试中永远不会被调用:
此修饰符检查在共享设置中本地部署的 SiloZap
是否被使用分叉值部署的版本覆盖(仅在使用分叉设置时为真)。
在存款和取款目标函数中,通常用户余额的增量会与一个跟踪的幽灵变量一起存储。
然而,在这种情况下,由于认识到实现逻辑会在传入的金额无效时回退函数调用,因此团队实施了“乐观会计”,使用一个累加器跟踪变量来累加传入的金额。
在实施分叉测试时,一个常见的问题是如何为测试行为者提供足够数量的特定 ERC20 代币以执行函数调用。
由于 ERC20 的铸造逻辑因代币而异,直接在代币上调用铸造以向特定用户供应并不是那么简单,通常需要创建一个正确实现模拟代币接口的模拟。如果在模拟中引入的任何逻辑使其表现不同于实际实现代币,这可能导致模糊测试套件无法正确模拟整个系统的功能,从而可能留下一些未发现的安全漏洞。
因此,在这次合作中,决定使用在分叉网络上持有大量代币(鲸鱼)的账户将代币转移给测试行为者。由于 ERC20 标准概述的转移和授权的逻辑,我们因此能够以更大的确定性测试系统功能,使其与实际系统行为匹配(请参见 这个很棒的工具 由 codeislight 开发以做到这一点)。
在模糊测试阶段发现了以下“奖项”(漏洞/意外行为)。
以下状态模糊测试识别了用于费用计算的错误公式,因为收到的费用与幽灵变量的预期不相符。
https://staging.getrecon.xyz/shares/9653d22a-e2e1-453c-8c67-b23912a578e3
从我们的 Medusa 运行输出中,我们获取以下通过损坏属性生成的测试,以便在 Foundry 中进行本地调试:
在手动审查中识别的一个无力偿债 bug 被修复,且实施了 以下状态属性,以确保 Silo 不会陷入无力偿债的境地:
手动审查可以在识别系统中的漏洞方面发挥重要作用,但当手动审查员是模糊测试专家时,这可以发现新颖的漏洞并实现确认修复措施确实有效的属性。此外,在开发初期实现的属性可以确认系统行为,以便在开发过程中所做的任何可能导致预期行为破坏的后续更改都可以很容易地识别出来。
需要帮助开发不变性测试套件吗?请在 这里 预约与 Recon 团队的通话。
- 原文链接: getrecon.substack.com/p/...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!