ERC4626 保险库 PlatoBlockchain 数据智能的通用属性测试。 垂直搜索。 哎。

ERC4626 保险库的通用属性测试

随着 DeFi 的发展和成熟,可扩展的基础设施和可组合性是开发人员的首要考虑因素。 以太坊评论请求(或 ERC)——用于构建基于以太坊的应用程序的标准化工具包,例如广泛使用的令牌标准 ERC20 — 发挥重要作用,为开发人员提供一致的指导方针,让他们无需从头开始就为生态系统做出贡献。 今年早些时候, 代币化保险库标准 ERC4626 创建是为了鼓励产生收益的代币之间的交叉兼容性。 标准化实现细节还可以解决紧迫的可组合性问题,使协议集成更容易,最终不易出错。

几个 DeFi 项目已经 采用 该标准旨在提高其保险库的可组合性,我们预计在整个生态系统中得到更广泛的采用。 然而,调整现有的保险库确实会带来一些成长的痛苦; 至关重要的是,某些实施错误可能会暴露新的攻击目标。 即使是很小的错误(小到对标准界面的误解)也会对安全和用户体验产生重大影响,强调需要更多的安全工具和措施,特别是在更可组合的 DeFi 生态系统中。 

幸运的是,如果在被利用之前(理想情况下甚至在部署之前)就检测到简单的错误,则可以提供相对简单的解决方案。 为此,我们发布了 ERC4626 属性测试 用于模糊和符号执行,以帮助 Vault 构建者检测可能破坏集成或导致漏洞的标准违规行为。 在这篇文章中,我们解释了激励问题,介绍了我们的方法,并以一些可行的建议作为结尾。

首先介绍一下 ERC4626 标准的背景知识

三月定稿, ERC4626 是标记化保险库的标准。 它的引入是为了扩展广泛使用的 ERC20 标准(目前是数百个代币的基础),鼓励跨收益金库的标准化,并确保需要与其交互的应用程序和协议(例如收益聚合器)的可组合性。 这意味着在 ERC4626 保险库上构建的任何应用程序都可以轻松扩展以与任何其他 ERC4626 保险库一起使用。 

代币化金库允许用户自由存入资产以铸造金库股票,然后赎回这些股票以从金库中提取本金和利息。 这些金库股票是 ERC20 代币,因此可以轻松交易或用作抵押以借入其他资产。 例如,用户可以将他们的资产存入 Yearn 保险库以铸造 yVault 代币,然后可以在 Uniswap 上进行交易、抵押以获得额外收益,或用作贷款协议的抵押品。

生成和分配收益(以及确定股价)的业务逻辑可能因实现而异。 为了覆盖尽可能多的保险库(目标是使它们具有互操作性和相同性),ERC4626 标准侧重于描述用户界面,而大部分实现细节未指定。 只要保险库满足接口的特定要求,这允许业务逻辑的变化,并鼓励 跨许多不同类型的应用程序和 ERC4626 保险库类型的互操作性。

随着更多保险库的创建,我们希望从一开始就根据 ERC4626 标准实施它们; 但我们目前处于某种过渡阶段,希望利用更大可组合性的开发人员将需要更新现有的保险库、应用程序和协议以符合标准。 随着他们的升级,他们面临着许多复杂性和挑战。 

标准一致性的挑战(以及不符合的陷阱)

遵循新标准并不总是那么简单。 每个 ERC4626 保险库都必须忠实地(并且准确地)实现所描述的标准要求。 否则,ERC4626 保险库的集成会变得越来越复杂,以应对不同的变化。 这种复杂性使集成天生容易出错; 并且由于它们没有足够的未来证据,随着时间的推移,它们可能会导致安全漏洞。

非标准 ERC20 代币(例如,Tether USD)需要许多 DeFi 系统在执行代币转移时使用额外的库(例如 SafeERC20)以安全地处理不同的行为(例如,当转移成功时不返回而不是返回 true)。 这意味着如果系统的设计不能正确处理“丢失退货”的情况,任何与这些代币交互的系统都可能变得脆弱。 这些场景可能会引入一个常见的安全陷阱,并增加整体开发和维护成本(当考虑缓解问题所需的额外逻辑和依赖项时)。 因此,符合标准不仅对个人实施至关重要,而且对整个生态系统的安全也至关重要。 单个系统或依赖项中的一个漏洞可能会导致广泛的问题。

理想情况下,标准将被正式指定,没有歧义(例如, ERC20的正式规范),并且每个实现都可以根据标准规范进行正式验证。 然而,在实践中,由于需要社区的成本和努力,这在短时间内并不容易实现。

引入可执行的 ERC4626 属性以识别一致性问题 

当我们朝着理想状态努力时(每个保险库都根据严格的正式规范进行了正式验证),我们编写了 ERC4626 标准 捕捉标准要求的细微、容易遗漏的细节中的差异。  

Vault 开发人员可以在部署之前运行测试以检测其实施中潜在的标准违规行为。 保险库集成商可以检查给定的保险库是否符合标准,然后再将它们集成到他们的系统中。 这些属性也可以通过主网分叉测试针对已经部署在主网上的实时保险库进行测试。 测试实时保管库可能很有用——尤其是在最近部署或升级了保管库时——以确保所有系统参数都已正确设置。 

我们选择了基于属性的测试——用 Foundry 编写并准备好由其 fuzzer 运行——以使属性可执行(因此可测试)。 将来,它们也可能由符号执行或模型检查工具运行,以正式验证给定的保险库是否满足所有可能的输入和条件的属性。

我们编写的属性足够通用,可以应用于实现不同业务逻辑的各种保险库。 我们只使用公共接口函数来使它们与实现细节无关。 (但是,由于此限制,某些涉及特定于实现的内部数据的标准要求从属性中省略了。)

例如,以下属性对应于 convertToShares() 功能, ”不得根据调用者显示任何变化。” 给定两个帐户地址和金额,它会调用每个帐户 convertToShares() 数量相同,并确保两个返回值相等。 此属性独立于 convertToShares(),它因保险库而异,并且必须由任何实施 ERC4626 的保险库来满足。 可以通过提供特定输入值(用于单元测试)、许多随机输入(用于模糊测试)或符号值(用于符号执行和形式验证)来执行此属性。 它也可以在本地运行或针对主网分叉运行(用于集成测试)。

用例:测试舍入错误的属性

例如,舍入错误是一类重要的(看似轻微的)错误,可能会产生一些系列影响。 ERC4626 的基本会计逻辑,例如计算要铸造的股票数量,或要提取的资产数量,是使用定点算法实现的——舍入误差是不可避免的。 为了 保安但是,该标准明确指定了每个接口函数的首选舍入方向,同时未指定误差范围且取决于实现。 具体来说, deposit()redeem() 函数应该返回一个 - 精确值的近似值,而 mint()withdraw() 函数应该返回一个 超过-近似。 例如,如果当前股价(即每股资产数量)为 2,则 deposit() 拥有 3 wei 的资产最多只能铸造 1 wei 的股票(即, floor(3/2)),而 withdraw() 拥有 3 wei 的资产应该至少烧掉 2 wei 的股份(即, ceil(3/2)).

我们将舍入相关属性编写为独立于基础会计逻辑,将其视为黑匣子。 具体来说,我们将它们表述为所谓的“往返”属性,它描述了两个相反函数之间的关系。 例如,以下属性规定,通过铸造 N 股来提取刚刚托管的资产必须燃烧不少于 N 股。 换句话说,没有人可以通过反复铸造和提现来来回转换资产和金库股票来免费获利。

来自 ERC4626 属性测试的片段

事实上,我们发现主网上的几个 ERC4626 保险库由于舍入错误而无法满足上述属性。 这意味着,例如,任何人都可以通过简单(并反复)铸造和提取,慢慢地耗尽金库来赚取几个 satoshi BTC(在撰写本文时为 1 satoshi ~= 0.02 美分)。 这实际上可能会在享受非常低的汽油费的链(例如,Fantom)上获利,或者如果资产价格在未来变得足够高。

在野外测试 ERC4626 标准

我们在主网上针对约 100 个 ERC4626 保险库测试了我们的属性,发现许多保险库未能遵循标准要求——主要是由于舍入错误(例如,如我们所述,在需要天花板的地方使用地板舍入)。 具体来说,某些金库未能铸造出所要求的确切股份数量 mint() 功能,尽管标准明确要求 Free Introduction. 其中一些还发出了不一致的 Deposit 记录的数据与实际生成的数据不同的事件。 令我们惊讶的是,有些金库根本就没有在现场铸造过。 相反,他们只是将铸币请求放入队列中,稍后将它们作为单独的事务分批处理。

尽管这些不同的行为本身是不可利用的,但当它们集成到只期望标准行为的其他系统中时,它们可能会变得容易受到攻击。 这些问题将使保险库集成变得更加困难,可能会抵消正在进行的努力并推动标准化背后的动力。

使用我们的属性测试和其他可操作的步骤来实现标准一致性

严格遵循标准可以防止出现不同的行为(最好在部署之前)。 我们希望我们的属性提供帮助,以及一些额外的操作项。 对于那些正在开发和/或集成 ERC4626 保险库的人:

  • 我们强烈建议经营我们的财产 测试 反对你的保险库。 如果有任何明显违反标准的行为,他们会很快发现问题。
  • 我们还建议审查我们的 交叉检查您对标准要求的理解,如果有任何无意的差异,请调整您的实施。
  • 如果您的 Vault 必须偏离标准,我们建议明确记录非标准行为,以便其他人在与您的 Vault 集成时可以正确处理这些偏差。 请注意,这应该被视为最后的手段。

***
在可预见的未来,ERC4626 保险库有可能成为 DeFi 的重要组成部分——而且,为了可组合性,新的和现有的保险库都必须遵循该标准。 新的实现将遵循标准出现,因此现在是标准化现有保险库的最佳时机。 

当我们朝着理想状态(不同的保险库统一组合)努力时,可以运行 ERC4626 属性测试以更轻松地检测保险库实施中的标准违规行为。 属性测试(带有文档和示例)都在我们的 Github 中公开可用 知识库. 我们欢迎您的反馈和贡献!

***
此处表达的观点是引用的个人 AH Capital Management, LLC (“a16z”) 人员的观点,而不是 a16z 或其关联公司的观点。 此处包含的某些信息是从第三方来源获得的,包括来自 a16z 管理的基金的投资组合公司。 虽然取自被认为可靠的来源,但 a16z 并未独立验证此类信息,也不就该信息的当前或持久准确性或其在特定情况下的适用性做出任何陈述。 此外,该内容可能包含第三方广告; a16z 未审查此类广告,也不认可其中包含的任何广告内容。

此内容仅供参考,不应被视为法律、商业、投资或税务建议。 您应该就这些事项咨询您自己的顾问。 对任何证券或数字资产的引用仅用于说明目的,并不构成投资建议或提供投资咨询服务的要约。 此外,本内容并非针对也不打算供任何投资者或潜在投资者使用,并且在任何情况下都不得在决定投资于 a16z 管理的任何基金时作为依据。 (投资 a16z 基金的要约仅通过私募备忘录、认购协议和任何此类基金的其他相关文件提出,并应完整阅读。)任何提及、提及或提及的投资或投资组合公司所描述的并不代表对 a16z 管理的车辆的所有投资,并且不能保证这些投资将是有利可图的,或者将来进行的其他投资将具有类似的特征或结果。 由 Andreessen Horowitz 管理的基金进行的投资清单(不包括发行人未允许 a16z 公开披露的投资以及对公开交易的数字资产的未宣布投资)可在 https://a16z.com/investments 获得/。

其中提供的图表仅供参考,在做出任何投资决定时不应依赖。 过去的表现并不预示未来的结果。 内容仅在所示日期生效。 这些材料中表达的任何预测、估计、预测、目标、前景和/或意见如有更改,恕不另行通知,并且可能与他人表达的意见不同或相反。 有关其他重要信息,请参阅 https://a16z.com/disclosures

时间戳记:

更多来自 安德森霍洛维茨