5 个预言机漏洞(来自真实审计)

文章深入探讨了区块链预言机集成中的五个常见安全漏洞,包括 Redstone 的时间戳操纵风险、多级价格源(如 wBTC-BTC-ETH)导致的偏差累积、硬编码预言机陈旧度阈值、忽视 Pyth 的置信区间以及硬编码稳定币价格的风险,并为开发者提供了相应的安全修复建议。

與其給你常見的 AI 廢話開場白(像你們大多數人做的那樣……),我寧願直接進入漏洞環節。請享用:

Redstone 時光倒流

在使用 Redstone(不是那個 Minecraft)時,你很可能會使用基於 pull 的機制(否則你會使用 ChainLink),就像這一個:

post image

非常簡單。用戶可以使用 msg.data 中的新價格來 updatePricegetOracleNumericValuesFromTxMsg 會使用它來驗證並返回價格。由於 Redstone 驗證了數據必須至少是 3 分鐘前的(且不超過未來 1 分鐘),我們在這裡不需要任何驗證。

然而,這裡仍然存在一個問題。我們可以(形象地說)在時間中來回穿梭。

由於我們在這裡不進行檢查,我們技術上可以將價格更新為直到 now 的值,然後再次將其更新為 now - 3min。例如:

  1. ETH 在 $T = now$ 時為 3k(我希望如此 D:)

  2. 借款人借入高達其最大額度的資產

  3. 清算人將價格更新為 $T - 3min$ 時的 2.9k

  4. 清算該用戶

當前價格為 $3000,我們的借款人不應該被清算,但我們確實清算了他。

Staking feeds

一些項目使用有趣的 Token 連接。在這個例子中,我們的項目是借貸,其中兩個資產是 BTC 和 UNI。

起初聽起來非常簡單,只需以 UNI 計價 BTC,或以 BTC 計價 UNI,並決定各項資產相對於另一項資產的價格。然而,這並非如此簡單,因為 ChainLink 沒有報告以 UNI 計價 BTC 或以 BTC 計價 UNI 的 feed。它只有 BTC/ETH 和 UNI/ETH。

所以我們必須使用 2 個 feed,為什麼這會是個問題?如果你知道如何處理它(就像在那裡的每個問題一樣),那就不是問題。但是,如果你不知道,它就是個問題。

這裡的問題是 2 個,或者在我們的案例中是 3 個 feed:wBTC -> BTC -> ETH -> UNI。我們從 wBTC → BTC 開始,因為我們在 ETH 上,無法直接訪問 BTC,且不應假設 1 BTC == 1 wBTC。

偏離閾值會隨著每個 feed 的增加而擴大。總計我們將有 4.5% 的偏離:

  • wBTC/BTC - 0.5%

  • BTC/ETH - 2%

  • UNI/ETH - 2%

這在哪裡會成為問題?

當你不知道總偏離可以堆疊,並設置了過於緊湊的清算邊際時。隨著 4.5% 的複利偏離(更現實一點是 4%,因為 BTC 不常偏離 wBTC),預言機價格與實際市場價格相比,在任何方向上都可能有高達 4.5% 的滯後。

這產生了兩個問題:

  1. 虛假償付能力 — 一個在實際市場價格下已經資不抵債的借款人,在協議看來仍然健康,因為預言機還沒有跨越其偏離閾值。到 feed 更新時,該倉位已深陷壞賬,清算人無法盈利地覆蓋它。

  2. 錯誤借貸 — 用戶存入抵押品,而預言機相對於市場高估了其抵押品。他們借入了超過其應能借入的資產。當下一次更新到來時,他們會立即被清算。

最糟糕的是,這兩者都不是「攻擊」,但偶爾可以且確實會發生。

修復方法非常簡單。確保檢查所有偏離,並根據它們降低 LTV。此外,我建議不允許借款人借到最大 LTV,而是留出一個缺口(這樣他們就不會在下一次更新中被清算)。

乏善可陳的一個

在這裡看到什麼有趣的東西嗎?有嗎?沒有嗎?

post image

我不得不把它包含進來。現在是 2026 年,甚至現在我還看到人們這樣做……AI 都知道不要這樣寫,為什麼開發者還要這樣做?

如果你不知道我在說什麼,那就是 feed 可能具有不同的過期時間戳(staleness timestamps)。有些可能只有幾個小時,而其他的有 24 小時。然而,如果你對所有 feed 都使用同一個值,那麼你不是在使用過期數據(對於時間容差比你給定值更小的 feed),就是將完全正常的數據標記為過期(對於容差更大的 feed)。

解決方案?只需使用一個 map 並為每個 feed 設置其專屬的過期時間。

post image

Pyth 置信度

我們回到了 Pyth 及其「神秘」的工作方式。大多數人會假設,既然 Pyth 是即時的,且他們自己獲取價格,那麼價格就是返回的那個值。很簡單對吧?

不完全是。Pyth 有置信度(不像你),置信度是一個價格可能所在的 +/- 區間。

最簡單的例子是,當你獲得 ETH 價格為 $2000,而 Pyth 返回 $2000 且置信度為 +/- 50。現在價格可以是 2k,或 1950,或 2050,或 1967(對於你們這些老傢伙來說是 1969……)。好吧,好吧,但這裡的問題是什麼?

問題是你的項目會假設價格是 X,並允許基於該價格 X 發生某些事情,無論是清算、允許借貸,還是讓你在「dickbut 是否會在週末前上漲 6.7%」的 YES 頭寸上開 50 倍槓桿(我在 X 上花了太多時間 D:)。

而事實上價格不是 X,而是 X+y 或 X-y……那麼你該如何修復它?

假設最壞的情況。在借貸時,項目應假設抵押 Token 價格為 X-y,而借入 Token 價格為 X+y,也就是說,始終有利於項目而非用戶。

1 USDC/USDT == 1 USD

你碰巧在你的金庫中使用穩定幣嗎?如果是的話,你如何為它們定價?當然是 $1,畢竟它是穩定幣!你為什麼會需要一個預言機?

現在是 2026 年,這樣的漏洞仍然存在(一些 Morpho 金庫可以證實)。

這裡的問題是,你要麼完全跳過了預言機,要麼使用了一個本質上將穩定幣金庫硬編碼為 1 USD 的預言機。別誤會我的意思,這在 99.99% 的時間裡都是有效的,然而當它失敗時,就是你完蛋的時候。

正確的方法是假設未來某個時候一切都會改變價格。資產價值會上漲和下跌,穩定資產會脫鉤,所有可能發生的事情都會發生。

預言機設置需要 2 個以上 feed,但也需要支持像 rETH → ETH 這樣的單 feed 資產。

僅限構建者

正在構建任何涉及預言機的東西嗎?

如果你在未來 60 天內有主網發布、升級或 Token 事件,且你的合約尚未重新審計,那麼你是在靠運氣運行。

在這裡與我們預約安全審計評審電話:

https://phagesecurity.com/request-audit

或者在我的 TG @Pyro3b 上聯繫我。

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

0 条评论

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