利用Renzo-Fuzzing库发现真实漏洞

  • Recon
  • 发布于 2024-08-08 18:18
  • 阅读 23

本文介绍了Renzo协议与EigenLayer的集成,以及通过eigenlayer-fuzzing Repo进行系统不变量测试的重要性。文章详细讨论了几个高严重性漏洞的发现过程,并展示了如何利用renzo-fuzzing Repo进行有效的测试和漏洞发现,从而加强系统安全性。通过这些示例,读者可以了解如何使用不变量测试工具及其在实际协议中的应用。整体上,文章技术性强,有实践指导意义。

2024年8月6日

2

介绍

Renzo 是一个与 EigenLayer 集成的协议,旨在简化在 EigenLayer 中重新质押 ETH(本地或通过流动质押代币)的过程,抽象掉与存款/取款以及处理质押者重新质押 ETH 的运营商分配相关的复杂性。

为了简化与 EigenLayer 集成的协议的系统不变性模糊测试过程,我们最近创建了 eigenlayer-fuzzing repo。该仓库提供了所有系统设置和有效不变性测试所需的组件。

作为一个概念证明,我们使用 eigenlayer-fuzzing repo 为 renzo-fuzzing repo 构建了一个测试工具,使任何人都可以 在 Renzo 系统上模糊测试属性

现在,随着 Renzo 的 Code4rena 竞赛发布的 审计报告 的发布,我们将展示在竞赛中发现的三个高严重性漏洞(与 EigenLayer 集成相关)如何通过在 renzo-fuzzing 套件中定义的属性来识别。

发现

这里讨论的所有发现都与 Renzo 方面对 EigenLayer 集成的不当处理有关。应当注意的是,这些漏洞并不是通过 renzo-fuzzing 套件发现的,因为在竞争期间该套件并未完成,但我们希望强调一个良好模糊测试套件在通过简单属性发现高严重性漏洞方面的力量,现在有一种简单的方法来评估它们。

H02 - 排队取款的错误计算会降低 TVL 并增加 ezETH 铸造率

这个漏洞 突出了在计算用户存入本地 ETH 或流动质押代币(LST)时铸造的 ezETH 流动质押代币(本地于 Renzo)数量时,OperatorDelegator::getTokenBalanceFromStrategy 中的计算没有正确考虑排队从 EigenLayer 提取的代币。这是因为 EigenLayer 不允许即时提取作为安全功能,而是要求用户先排队提取,然后在 7 天的托管期后才能完成他们的提取。

这导致在排队从 EigenLayer 取款时铸造 ezETH 的用户由于错误膨胀的汇率而比应得的收到更多的 ezETH,类似地,期间提取的用户(通过销毁他们的 ezETH)在 ETH/ezETH 或 LST/ezETH 之间收到一个更优的汇率(对于 Renzo 目前支持的 LST 是 stETH 和 wbETH)。

为了捕捉这个漏洞,我们可以扩展 renzo-fuzzing repo 提供的现有框架,为 Renzo 管理员用来从 EigenLayer 提取质押 ETH 的 OperatorDelegator 合约中的函数定义一个新的目标函数合约。

通常我们会为 OperatorDelegator 合约中的所有公共的非视图函数添加处理器,以测试完整功能,但为了捕捉这个漏洞,我们可以定义一个单一的目标函数: operatorDelegator_queueWithdrawals,我们可以在此函数上添加一个断言,确保在排队提取后,Renzo 系统的 TVL 不应改变。

当我们执行带有上述断言的 Echidna 运行时,我们得到了一个违反我们断言的反例,表明我们的属性不成立。

如果使用 Recon 运行器运行该任务,我们会自动获得一个 Foundry 单元测试,允许我们在本地重现断言违规,并允许我们调试问题的根源,前提是问题的原因并不明显。

这个代码片段展示了重现漏洞所需的调用,生成的单元测试中省略了额外的调用。

H03 - EigenLayer 的 ETH 提取由于 OperatorDelegator 的 nonReentrant 收益而总是失败

这个漏洞 指出 OperatorDelegator::completeQueuedWithdrawal 函数 中实现的 nonReentrant 修饰符阻止管理员成功调用它,因为该函数对 EigenLayer 系统的调用最终会回调到 OperatorDelegatorreceive 函数,而该函数使用相同的 nonReentrant 修饰符,这在初始调用时已被锁定。因此,该函数总是回滚,资金被卡在 EigenLayer 中,无法恢复。

虽然这个漏洞可以通过一个简单的单元测试发现,但也可以通过一个属性发现,即如果提取已成功排队,调用 completeQueuedWithdrawal 必须始终成功。

为了为这个属性实现断言,我们需要为 OperatorDelegatorTargets 合约添加 completeQueuedWithdrawal 函数的处理程序,该合约是为前一个漏洞定义的。

operatorDelegator_queueWithdrawals 函数中,我们还需要定义以下鬼变量,以简化将有效提取传递给 OperatorDelegator::completeQueuedWithdrawal 函数,因为排队的提取仅在 Renzo 中存储其哈希数据的字节数组,但该函数接收一个 Withdrawal 结构作为参数。

这个 eigenLayerWithdrawalRequestsGhost 还用于在 operatorDelegator_completeQueuedWithdrawal 函数中防止不必要浪费模糊测试运行,禁止评估 Withdrawal 结构每个成员的所有可能输入值。

此外,我们可以将其用作断言的前提,因为我们知道要将一个 Withdrawal 排队到 eigenLayerWithdrawalRequestsGhost,必须已成功排队,并且如果它被成功排队,当管理员在 7 天的提取期后调用 completeQueuedWithdrawal 时,该函数永远不应回滚。

通过使用 try/catch 块,我们可以断言调用回滚意味着管理员无法完成提取过程。

报告中对该漏洞的描述没有包含 POC,因为它需要过多步骤,但 Recon 运行器的 Echidna 作业的输出给出了一个简单的 POC,我们可以用来在本地重现和调试问题:

这个片段显示了与破坏属性相关的函数调用,单元测试中省略了不必要的调用。

H05 - 重新基准代币的提取可能导致破产和协议储备的不公平分配

这个漏洞 与 EigenLayer 上的罚没事件在处理用户从 Renzo 提取中的逻辑中未被合理考虑有关。

当用户通过 WithdrawQueue::withdraw 从 Renzo 发起提取时,他们因销毁一部分 ezETH 而收到的 _assetOut 数量是基于当前从 renzoOracle::lookupTokenAmountFromValue 返回的代币价值。

然而,因为 EigenLayer 的提取需要经过 7 天的托管期才能进行索取,所以在排队提取和实际索取之间,代币价值可能会发生变化。

特别是,如果在正在提取的代币的 EigenLayer 端发生罚没事件,将导致系统的代币余额减少,因此用户的余额份额应该成比例减少,但是由于他们的提取请求是在余额变化之前提出的且在罚没后其份额没有更新,他们可能会索取多于自己公平份额的代币余额。

renzo-fuzzing repo 自带支持通过 EigenLayerSystem 合约处理 EigenLayer 上的罚没事件,因此设置这个属性进行测试将更加简单。此外,RestakeManagerTargets 公开了我们需要在系统中存款和更新价格的所有功能,模糊器将需要调用这些功能以启用有效的罚没。

因此,为实现用户无法提取超过其公平份额的属性,我们只需添加一个 WithdrawQueueTargets 合约,包含 withdrawQueueTargets_withdrawwithdrawQueueTargets_claim 功能,使模糊器能够排队和索取退还请求,正如用户所做的那样。

withdrawQueueTargets_claim 函数中,我们定义一个断言,检查用户在索取请求前(取自他们排队提取时设置的 amountToRedeem)和索取后的金额(使用在罚没事件中变化的当前 totalTVL 计算):

从带有此断言的运行的 Recon 作业页面中,我们看到又一个违规,表明如果发生罚没事件,用户确实可以索取超过其公平份额的质押 ETH:

在上述内容中,对 restakeManager_LST_discount 的调用更新了价格,以便对 withdrawQueueTargets_claim 函数的调用不会因价格过时而回滚。

总结

我们在上面展示了如何通过最小增加扩展 renzo-fuzzing repo 来测试为 Renzo 系统定义的属性。同样,对于任何与 EigenLayer 集成的协议,你可以扩展 eigenlayer-fuzzing repo,以访问整个 EigenLayer 系统,并具有内置的处理外部因素(如罚没)的功能,并使用 Recon 构建器创建一个测试工具,以允许你测试特定于集成协议的属性。


订阅 Recon

十个月前启动

Recon 帮助你构建和运行不变性测试

订阅

通过订阅,我同意 Substack 的 使用条款,并确认其 信息收集通知隐私政策

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

0 条评论

请先 登录 后评论
Recon
Recon
江湖只有他的大名,没有他的介绍。