Back to Blog

#6:Hundred Finance 事件:催化易受攻擊分叉協議中精密漏洞利用的浪潮

Code Auditing
February 16, 2024
6 min read

2023 年 4 月 16 日,Compound V2 的分支協議 Hundred Finance 遭到攻擊,導致約 740 萬美元的損失。此次攻擊涉及兩個主要問題:

  • 精度丟失問題(導致錯誤捨入);
  • 空市場問題(允許駭客操縱 exchangeRate)。

根據 DeFiLlama 的數據,Compound V2 是被分叉次數最多的借貸協議,擁有超過 100 個分叉版本。其合約經過 OpenZeppelin 審計並經過實戰驗證,被認為是安全的。然而,Hundred Finance 的攻擊事件突顯了精度丟失(尤其是在低流動性情況下)如何嚴重影響 DeFi 協議的安全性,並隨後在 Midas 和 Radiant 等眾多著名分叉項目中引發了一系列類似的攻擊。

為了深入了解,建議您參考完整分析。以下我們對該事件進行簡要介紹,並將其列為 2023 年十大安全事件之一。

背景

Hundred Finance 概述

Hundred Finance 是 Compound v2 的一個分叉,在多個主網上運行,並使用 Chainlink 預言機。與傳統金融借貸做法不同,像 Compound 和 Aave 這樣的 DeFi 借貸協議不允許超額抵押借貸。 簡單來說,如果您存入價值 100 美元的代幣 A,您只能借出價值低於 100 美元的資產。根據大多數協議的風險控制係數,該比例通常在 50% 到 80% 之間。

對於借貸協議,常見的攻擊方法包括價格操縱和重入攻擊。有趣的是,Hundred Finance 此前曾遭受過 2022 年 3 月的重入攻擊,但這次事件產生了一個新的攻擊向量。

hToken

從 Compound 和 Aave 分叉出來的借貸協議會為每個基礎代幣(抵押品)創建相應的會計代幣。對於 Hundred Finance 而言:

  • USDC 對應 hUSDC
  • WBTC 對應 hWBTC

基礎代幣與 hToken 之間的匯率稱為 exchangeRate

  • 當存入資產時,用戶需呼叫 hToken 的 mint()
  • 當提取資產時,用戶需呼叫 hToken 的 redeem()

exchangeRate

以下是計算 exchangeRate 的公式: image

其中:

  • getCash():此 hToken 合約所擁有的基礎代幣餘額數量。這是一個可以被操縱的關鍵參數,請記住這一點。
  • totalBorrows():市場當前借出的基礎代幣總量,也是市場供應商獲得利息累計的基礎。
  • totalReserves():準備金是每個 hToken 合約中的會計條目,代表歷史利息中撥出的一部分現金,可通過協議治理進行提取或轉移。
  • totalSupply():目前在該 hToken 市場流通的代幣數量。

注意:hToken 與基礎資產之間的 exchangeRate(例如 dai vs hDai 或 eth vs hEth)始於 0.020,並以等於複利市場利率的速度增長。

清算 (Liquidation)

為了防止壞賬,借貸協議允許任何用戶清算他人的債務。我們用以下例子來說明:

  1. Alice 存入價值 100 美元的 BTC,並借出價值 70 美元的 ETH。
  2. 如果 ETH 價格上漲或 BTC 價格下跌,Alice 的資產可能會達到清算閾值。
  3. Bob 可以使用一定數量的 ETH 來清算 Alice 的 BTC,使 Alice 的債務回到健康水平,從而確保協議資金的安全(協議會獎勵發起清算的用戶)。

清算並非本次攻擊的重點,但它參與了攻擊過程。在此,我們只需知道任何用戶都可以用一種代幣來清算他人的債務,這會減少相應的 hToken。

漏洞分析

精度丟失問題

駭客在通過 redeem() 提取抵押品時,計算需扣除的 hToken 數量結果為 1.99999992(非常接近 2 但小於 2)。truncate() 中轉換為整數時,向下捨入導致最終結果為 1。

exchangeRate

如前所述,exchangeRate 的計算涉及 getCash(),即 hToken 合約所擁有的基礎餘額數量。通過直接將基礎代幣轉入合約(不通過 mint,僅轉帳),駭客可以操縱 exchangeRate 然而,值得注意的是,僅憑這個匯率問題並不會危及協議的安全性;駭客無法單獨從中獲利。 在本次攻擊的背景下,它主要被用來放大駭客的收益,使其能夠迅速耗盡資金池。否則,攻擊將從單次決定性的打擊變為一連串的小規模攻擊,需要多次迭代才能產生顯著影響。

總而言之,精度丟失是此次攻擊的關鍵問題。

攻擊流程

這是攻擊交易,我們將使用 Phalcon Explorer 來分析這一複雜的交易。

交易:0x6e9ebcdebbabda04fa9f2e3bc21ea8b2e4fb4bf4f4670cb8483e2f0b2604f451

  1. 通過閃電貸(Flashloan)從 Aave V3 借入 500 WBTC。

  2. Redeem 所有先前獲取的 hWBTC,將 hWBTC 的 totalSupply 重置為 0。

之前的目標是利用閃電貸準備儲備資金,並將 hWBTC 重置為一個新市場。

  1. Create 第二個攻擊合約(以下稱為攻擊合約 2),並將所有 WBTC(500.30063816 WBTC)轉移到攻擊合約 2。

  2. 使用 4 WBTC 進行 Mint() 以產生 200 hWBTC。

  3. Redeem() 199.99999998 hWBTC,使 hWBTC 總量剩下 0.00000002(2 wei hWBTC)。

  4. 將所有 WBTC(500.30063816 WBTC)轉入 hWBTC。注意,直接轉帳不會增加 hWBTC;這可以看作是向資金池捐贈 WBTC。此步驟的主要目的是操縱前述的 exchangeRate。此時,hWBTC 的 totalSupply 保持在 2 wei hWBTC,但現在有 500.30064194 WBTC,使得 exchangeRate 比初始值高出數百倍。

  5. 從 hETH 市場借入 1021 Ether。

  6. Redeem() 50030063815 WBTC,經計算理應扣除 1.9999992 hBTC,但由於精度丟失,僅扣除了 1 hBTC,產生了巨大的精度丟失(近 50%)。 此時,駭客擁有 500 WBTC + 1021 Ether,成功獲利 1021 Ether

  7. 攻擊者 liquidate() 剩餘的 hWBTC,將其 totalSupply 重置為 0,為後續對其他市場的攻擊做準備。鑑於 hWBTC 內幾乎所有的 WBTC 都已被提取,駭客僅用 0.000002 Ether 就完成了此操作。

  8. 繼續攻擊其他市場,耗盡整個協議。

  9. 歸還 Aave 的閃電貸。

安全建議

對借貸協議的緩解措施

此問題非常普遍,特別是在 Compound 和 Aave 的分叉中。一種主動的方法是:在啟動新市場時,鑄造少量會計代幣以確保 totalSupply 永遠不會變為 0

對精度丟失問題的緩解措施

為了更好地規避因精度丟失導致的一系列問題,在實踐中設置最小值是一個有效的方法。 該策略有助於避免在處理極小值時,由精度丟失帶來的重大影響。

閱讀本系列的其他文章:

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit