作者:Sina Pilehchiha
编译:深潮 TechFlow
TLDR: ERC-4626 是用于代币化保险库 (Vault) 的标准。
在引入 ERC-4626 之前,每个保险库都有其各自的规范和实现细节。这使得集成变得困难、容易出错且浪费资源。
ERC-4626 试图通过标准规范来解决这个问题,以降低集成工作量,并创建更一致和强大的实现模式,就像 ERC-20 一样。
什么是 ERC-4626 ?
ERC-4626 是一种标准,它改进了收益型保险库的技术参数。它为代表单个底层 ERC-20 代币份额的收益保险库提供标准 API。
代币化保险库已经成为 DeFi 中极为常见的模式。收益聚合器、借贷市场、质押衍生品等许多 dApp 都利用和依赖于代币化保险库。代币化保险库的示例包括 Yearn 和 Balancer。作为一个收益聚合器,Yearn 保险库使用户可以存入数字资产并获得收益。Balancer 是一个自动化的组合管理器和流动性提供商,其业务逻辑的核心依赖保险库。这些保险库管理各种池中的代币。同时,它们将代币管理与池子本身的逻辑分离开来。
协议通过代币化其保险库来增强流动性和灵活性。代币化保险库可以轻松进行交易,并在 DeFi 平台上使用资产。此外,它们还能够创建多样化、相互连接的金融产品。该行业一直倡导这种范式,通常称为“货币乐高”。
然而,没有适当的适应性或标准化的可组合性会带来挑战。它不仅使开发人员难以遵守 ERC-20 等行业标准,而且还会使新开发人员感到困惑。如果没有适当的适应性或标准化,就很难审查新的变化并验证集成的实施细节。
于是 ERC-4626 被提出来解决这个问题,并简化集成,同时允许 DeFi 参与者最终采用更安全和强大的统一保险库规范。这反过来也将减少协议可能遭受的攻击面,同时在多个协议之间集成代币。
ERC-4626 可以预防哪些安全问题?
通过提供统一的标准,ERC-4626 加速了跨协议集成的构建速度。熟悉的、统一的标准也更容易让开发人员理解,从而减少编码错误的可能性。这有助于防止可组合性问题。标准化还可以防止工作重复,因为社区只需要设计一次保险库,而不是为每个协议单独设计。由于这种设计工作通常容易出错,它有助于避免重复已经建立但普遍存在的设计缺陷。
我们将在这里介绍两个案例研究,以展示 ERC-4626 可以预防哪些问题。
Rari Capital 事件
Rari Capital 被盗取了价值约 1100 万美元的代币,这相当于 Rari Capital Ethereum 池中所有用户资金的 60 %。
总的来说,Rari Capital 被黑客攻击是由于不安全的跨协议实现。其 Ethereum 池通过将 ETH 存入 Alpha Finance 的 ibETH 代币合约作为产出策略。这种特定策略通过某些合约及公式(具体如 ibETH.totalETH / ibETH.totalSupply 函数)跟踪其 ibETH/ETH 汇率的价值,在此攻击场景中可能会有错误的输出,例如在调用 ibETH.work()函数时,债务价值可能会被人为地膨胀。
攻击者只需重复调用 RariFundManager 合约中的 deposit 和 withdraw 函数,就可以耗尽 Rari Fund Manager。deposit 和 withdraw 函数需要获取池子的余额以计算要发行给调用者的 REPT 代币数量,或要发放给调用者的 ETH 金额,这个操作会分别调用 Alpha 池的 getBalance 函数,调用 ibETH 合约及其 totalETH 函数。Rari 不知道操纵此函数的可能性。
ibETH 合约中还有另一个函数:ibETH.work 。该函数可以调用用户指定的任何合约。这使得 Rari 的 deposit 和 withdraw 函数可以变得可重入并被多次调用。
work 函数是一个可支付的函数,意味着用户可以通过 work 函数控制 ibETH 合约中的 ETH 数量,从而改变 totalETH 函数返回的值。更糟糕的是,work 函数还支持调用任何其他合约,例如 RariFundManager。
通过这个函数,攻击者可以再次发送 ETH 并增加 ibETH 合约中的 totalETH 金额,同时调用 RariFundManager 合约中的 withdraw 来赎回更多资产。
这次事件突显了 DeFi 合约中集成不足和不兼容的设计所带来的重大风险。它强调了像 ERC-4626 这样的标准通过增加关键的安全和可预测性层可以防止这样的攻击,并促进统一行为和相互理解。
Cream Finance 事件
Cream Finance 遭受了一场复杂的攻击,利用了平台中两个基本弱点:可操纵的混合预言机和没有上限的代币供应。攻击的关键部分是对混合预言机的操纵,这影响了 yUSD 代币的感知价值。当攻击者向 yUSD 保险库发送大量 Yearn 4-Curve 代币时,他改变了保险库报告的汇率,因此还影响到了预言机对 yUSD 代币的感知价值。
这里的关键教训是一个强大且无法操纵的价格预言机对于 DeFi 协议的稳定性至关重要。按时间加权平均价格(TWAP)预言机可以帮助防止此类黑客攻击,因为他们对突然的价格操纵更具有韧性。
这些问题,以及其他脆弱的设计模式,可以通过谨慎采用和实施 ERC-4626 来加以缓解。
ERC-4626 中的潜在安全风险
使用新的协议总有一些取舍。对于代币化的保险库,将其集成到智能合约中可能存在潜在问题,需要特别注意。
管理 feeOnTransfer 代币
如果保险库旨在支持 feeOnTransfer 代币,请在转移资产时检查保险库中的金额和份额是否处于预期范围内。
适当使用 decimals 变量
尽管 convertTo 函数应该无需使用 EIP-4626 保管库的 decimals 变量,但仍强烈建议在可行的情况下镜像底层 Token 的 decimals 。这种做法有助于消除潜在的混淆来源,并简化各种前端和链下用户的集成。
四舍五入
根据规范,保险库实现者应意识到在不同的可变和视图方法中需要特定且相反的舍入方向,因为在计算过程中更安全的做法是优先考虑保险库本身而不是其用户:
– 如果它正在计算要发行给用户的股票数量,以获得他们提供的某些基础代币的金额,或者它正在操作将特定份额的基础代币转移给用户,则应向下舍入。
– 如果它正在计算用户必须提供多少份额才能获得一定数量的基础代币,或者正在计算用户必须提供多少基础代币才能获得一定数量的份额,则应向上舍入。
其中首选舍入方向将是模棱两可的是 convertTo 函数。为确保在所有 EIP-4626 保险库实现中保持一致性,指定这些功能必须始终向下舍入。集成者可以自己模仿舍入方向向上的版本,例如通过添加一个 Wei 到结果来实现。
一个用户通过赎回他们在保险库中的股份(previewRedeem)来获得基础资产的数量,可能会与发行相同数量的股份(previewMint)时需要付出的数量有很大差异。这些差异可能很小(例如由于舍入误差),也可能很大(例如保险库实现了提款或存款费用)。因此,集成者应该注意使用最适合他们用例的预览函数,并且永远不要假设它们是可互换的。
覆盖核心功能
为了实现或扩展预期的功能,建议使用现有的挂钩而不是更改核心功能。这种做法可确保更易于管理的跟踪,以进行有效的代码测试和审核。
零份额
ERC-4626 的原始规范没有概述如何处理保险库中没有份额的极端情况,以及保险库是否应该像正常情况一样工作或者回滚。这可能会成为混淆和错误的潜在来源。
保险库作为价格预言机
关于预言机价格操纵攻击的风险,这些 preview 方法返回的值尽可能接近准确。因此,它们可以通过更改链上条件进行操作,并且不总是安全用作价格预言机。 ERC-4626 规范包括允许不精确的 convert 方法和 totalAssets 方法,因此可以实现为强大的价格预言机。例如,在资产和股份之间转换时,使用时间加权平均价格来实现 convert 方法是正确的。
具体实施问题
在进一步集成之前,集成者必须审查任何代币化保险库的实现,因为可能存在恶意实现,看起来符合接口规范,但其核心函数由完全不同的设计规范组成。
EOA 直接访问
如果要直接访问一个保险库,则其实现需要具备可用于容纳滑点损失或意外存款/提款限制的功能。与智能合约不同,EOA 没有交易回滚的故障保护机制,如果在调用核心函数时没有实现精确输出,则无法回退。
扩展保险库
随着越来越多的参与者开始采用 ERC-4626 标准,我们将看到为该标准实施的更多扩展。例如,Superform 开发了一个试验性的 Multi 保险库扩展,支持在一个保险库合约内使用不同的计算。自然而然,实现越偏离原始标准,引入新漏洞的可能性就越高。开发人员和审计人员可以根据用例找到自己的最佳选择,以确定实际风险值。
需要注意的是,导致灾难性事件的不是每个协议的最小添加,而是它们集成在一起时的总和。
上面提到的潜在攻击向量是围绕 ERC-4626 标准讨论较多的一些问题。随着采用率的增加,我们肯定将探索更多实现用例,以及更多与 ERC-4626 保险库集成的合适场景。
文章来源于互联网:一文读懂ERC-4626:DeFi代币化保险库的新标准