作者:Daniel Von Fange

编译:angelilu,Foresight News

昨日,独立研究员 Daniel Von Fange 在 X 平台发文披露 Curve 存在预言机操纵风险,并且该风险在攻击时很难被检测出。预言机操纵行为会导致预言机报告关于外部事件或真实世界的错误数据,使接入预言机的协议也面临操纵风险。Daniel Von Fange 表示已经通知可能受影响的相关团队。

Curve 创始人 Michael Egorov 在社群中对该问题进行了回复,称「该风险可能存在于旧版本的池子,crvusd 中不使用旧版本的池,也不建议使用预言机。」还言论确认了 Daniel Von Fange 披露的风险确实存在。

但 Curve 贡献者 fiddy 对于这名独立研究者未经讨论就公开发布这些信息的方式表示不满,并发布澄清,称 Daniel Von Fange 披露的漏洞此前他们已经私下讨论过,但其认为攻击者为了提高精度而增加 Gas 费成本较高,外部审计也将这一点归类为低影响。并且该研究员披露的这个漏洞与 Curve 较旧的 cryptoswap 算法有关,该算法使用了 last_price 价格,但较新的 cryptoswap-ng 实现使用 AMM 状态价格,可解决此类问题。除此之外,yAuditDAO 确实发现了一些预言机的错误,目前正在修复中,没有人使用这些预言机,且这些稳定币交易池中的 LP(流动性提供者)不受影响。

但已经有团队根据其披露的风险开始对协议进行调整,增强安全性。Yearn Finance 开发者 @storming0x 也对 Daniel Von Fange 披露的风险做出回应,称「Yearn 合约不受影响,除了一个使用了 Chainlink 的冗余机制来减轻潜在攻击路径的合约。出于谨慎考虑,Yearn 开发团队决定重新部署新版本。」

以下为 Daniel Von Fange 披露 Curve 预言机价格操纵风险的全文:

过去两周,我深入研究了 Curve 的价格预言机,发现了一些极其异常的行为。

这些预言机的运作方式并非如你所想,它们比预期更容易被操纵,并且在正常情况下也可能出错。

简要概述:在大多数池中,攻击者只需在一个区块,就能将 Curve 的价格预言机操纵至高出正常价格 10 倍至 500 倍。并且这种操纵可以被隐藏起来,以至于查看池子时根本无法发现其被操纵的迹象。

Curve 池子数量居多,目前还没有人能准确统计出不同池子代码库的数量。

我所写的内容可能适用于某些特定池子,也可能不适用。不同的池子有不同的漏洞。或许有些池子没有任何漏洞。

Curve 团队在接收报告、讨论时表现出色,并在几分钟内确认了 CrvUSD 不受这些问题影响。

我还检查了主网上大约 100 个使用 Curve 价格预言机的合约,并酌情通知了相关团队。

该漏洞的一个关键问题是,当价格不接近 1:1 或者手续费较高时,last_price 可能被错误计算。

首先,手续费没有包含在 last_price 计算中,这使得它使用的数字与实际交易或池子余额的数字不同。

EMA 价格预言机受 last_price 驱动。当 last_price 出错时,价格预言机将开始朝错误的目标价格移动。

在正常交易中,我见过价格预言机定位的价格比池中的实际当前价格偏离超过百分之一。最坏情况可能会更糟(图表中的标准化化价格)。

根据池子的不同,这种漂移误差可能高于或低于实际价格。

最大的问题是,在操纵期间,last_price 误差可能比实际操纵的价格高出一个数量级,使池预言机被有效操纵的可能性提高大大提高。

哪怕是一笔极小的交易,也能纠正最后价格 / 预言机价格中的偏差,导致了一些荒谬情况。

由于大幅价格波动和 last_price 计算错误的叠加效应,攻击者可以在下一个区块中操纵 EMA 价格预言机,且不需要耗费巨大成本在数十个区块中维持高价来对抗套利者。

理论上,攻击者可以控制两个连续区块的挖掘,这对于实现这一操作是必需的。攻击者需要有足够的资本进行这种价格攻击,但许多过去的攻击者手中都有数千万美元的资金。

加下来,让我们来谈谈常见的防御 Curve 价格预言机操纵的策略,以及它们的效果。

Curve v1 池子有四个数字可以用来尝试检测操纵,实际价格、价格预言机、last_price 和 EMA 价格。不幸的是,一次操纵之后,对操纵 price_oracle 价格的单笔交易可以将所有这些重置为相同的数字。

Curve v2 池子的 price_scale 比价格预言机更难操纵。它的变化速度更慢,需要实际的交易费用成本才能移动。如果这个快速价格预言机和慢速 price_scale 匹配,那么情况就稳定了,对吗?

不!核心攻击问题是使三个数字,实际价格、快速预言机和慢速规模对齐。实际价格很容易控制,因为它可以立即被操纵。那么问题就变成了在其他两者之间设计一个交点。

攻击者将价格短暂抬高,然后在下一个区块恢复正常,并等待几个区块进行攻击,直到下降的价格预言机遇到上升的 price_scale。实际价格只需在一个区块中被维持在高位,就足以扰乱预言机,而 price_scale 则会跟随。

 

许多预言机使用上限,将它们从 Curve 预言机价格中使用的价格限制在为 1:1 的最高值。这很好,并且排除了愚蠢的高值。但请注意,如果资产实际脱钩,攻击者可以低价购买资产,然后通过操纵使其看起来重新挂钩。

协议有时会设定一个最低限度,如果 Curve 价格预言机的响应低于挂钩的一定百分比,就会忽略它。但如果在资产真正脱钩时忽略价格,那就会失去拥有价格预言机的全部目的。

另一种常见策略是将另一个 AMM 系统的价格混合进来。这在很大程度上取决于其他池子的质量和操纵特性。如果它的流动性较低、更易于操纵,那么就没有达到目的。

糟糕 + 糟糕=糟糕。

用于稳定币 / 稳定币交易对的新型 Curve 池内部限制了 last_price 到 1:1 值的 2 倍。这可以阻止一次区块攻击,因为 last_price 不能被推到愚蠢高的值,从而使 EMA 超载。

但如果错误资产合法脱钩,那就错了。

如果你想使用 Curve 池来定价抵押资产,你可能不应该这样做。

新型池子通常有更高的攻击成本。如果被操纵的池对市场影响较小(可能只是为了保护收益分配),并且针对池模拟的攻击成本很高,那么就可以选择使用。

最后,作者建议这对使用的池子进行实际攻击模拟,不要基于假设或理论来预判价格预言机的行为,而应该在实际使用的池上进行详细的模拟测试。通过模拟操纵攻击,可以更好地了解池子在不同情况下的表现。

下图是过去 90 天 Curve 预言机使用量增加的图表:

 

有些 Curve 池子拥有表现出色的价格预言机,我无法让它们表现出任何奇怪的行为,它们完全符合良好表现的 EMA 所应有的预期。但仍需要去检查……