2022 年 4 月 30 日,攻擊者利用 Nerve Bridge 事件中同樣的漏洞攻擊了 Saddle Finance。總共有 4,900 Ether 處於被攻擊狀態。幸運的是,我們成功攔截並挽救了其中的 1,360 Ether。關於此事件的詳細描述,請參閱官方事後報告。


儘管利用的是相同的漏洞,但攻擊手法與之前有所不同。由於這種新的攻擊方法並不像預期的那樣簡單直觀,我們認為有必要進行深入調查。在本報告中,我們首先簡要說明該漏洞,然後回顧 Nerve Bridge 事件中的原始攻擊手法。隨後,我們將重點剖析 Saddle Finance 事件,透過拆解攻擊過程來揭開這種新攻擊方法的神秘面紗。
0x1. 關於已部署合約
相關合約地址列表如下:
- 受害者 MetaSwap 合約:0x824dcd7b044d60df2e89b1bb888e66d8bcf41491
- 存在漏洞的 MetaSwapUtils 合約:0x88Cc4aA0dd6Cf126b00C012dDa9f6F4fd9388b17
值得注意的是,已驗證 MetaSwap 合約關聯的 MetaSwapUtils 合約代碼,與在 Settings 中指定的已部署 MetaSwapUtils 合約並不等同,如下圖所示:

所以請不要搞混了這兩個 MetaSwapUtils 合約 :)
0x2. 漏洞分析
該漏洞合約屬於 MetaPool,我們已在之前的部落格中對其進行了詳細討論。 簡而言之,MetaPool 最初由 Curve 設計,旨在允許單一幣種與另一個(基礎)池中的所有幣種組成資金池,且不稀釋其流動性。它本質上是由一個穩定幣和一個基礎池的 LP 代幣組成的資金池,而基礎池則包含其他幾種穩定幣。 MetaPool 的設計存在一個問題,即 MetaPool 本質上是用於維持穩定幣價格的資金池,而基礎穩定幣池的 LP 代幣並非穩定幣。
實際上,基礎穩定幣池 LP 代幣的價格可以透過調用基礎池的 getVirtualPrice 函數獲得,且其價格會隨著基礎池收取費用的累積而穩定上漲。
為了處理這一點,MetaPool 在計算價格前會放大 LP 代幣的儲備量,如下圖所示。

因此,如果用戶使用 LP 代幣兌換穩定幣,LP 代幣的數量在計算價格前會被放大。 反之,如果用戶使用穩定幣兌換 LP 代幣,計算出的 LP 代幣數量在轉帳和記帳前會被縮小。

上述 swapUnderlying 函數的代碼片段用於在 MetaPool 中的穩定幣與基礎池中的穩定幣之間進行兌換。如圖中兩個紅色矩形所示,該函數放大了傳入的 LP 代幣數量,並縮小了被兌換的 LP 代幣數量。
然而,swap 函數的實現與 swapUnderlying 函數的實現並不一致。具體來說,該漏洞的根本原因在於 swap 函數(即 _calculateSwap 函數)中實現的錯誤計算,它沒有正確地縮小和放大 LP 代幣的數量。如下圖所示,左側為 MetaPool 的漏洞代碼,右側為修復後的版本。

Nerve Bridge 事件的攻擊者利用了 swap 函數和 swapUnderlying 函數之間的不一致。(請注意,Nerve Bridge 是 Saddle Finance 的分叉項目。)
事件發生後,Saddle Finance 立即修復了該漏洞並重新部署了新版本(即 V2)的 MetaSwapUtils 函式庫。
遺憾的是,由於某些未知原因,以太坊上的 sUSD V2 MetaPool 仍部署了舊的、存在漏洞的 MetaSwapUtils 函式庫。 結果,該漏洞在 4 月 30 日再次被攻擊者成功利用。有趣的是,與 Nerve Bridge 事件中使用的攻擊手法不同,攻擊者採用了另一種方式來攻擊這個存在漏洞的 MetaPool。
0x3. Nerve Bridge 事件的原始攻擊手法
我們再次使用下圖(參見之前的部落格)來回顧原始的攻擊手法。

由於存在漏洞的 swap 函數沒有縮小被兌換的 LP 代幣(Nerve 3-LP)的數量,步驟 3 中交換的金額(36,959)比正常情況要大。
隨後,攻擊者調用 swapUnderlying 函數(無漏洞)將這 36,959 份 Nerve 3-LP(在步驟 4 和 5 中)兌換成 51,494 fUSDT,從中獲利 1,143 fUSDT。
從邏輯上講,這種利潤可以解釋為:攻擊者在步驟 3 中獲取了更多的 Nerve 3-LP,然後利用 swap 函數和 swapUnderlying 函數之間的不一致,以「正常」價格賣出了它們。
0x4. Saddle Finance 事件的新攻擊手法
近期 Saddle Finance 事件的攻擊者在不涉及 swapUnderlying 函數的情況下,使用了一種不同的方式來攻擊同樣存在漏洞的 swap 函數。
這裡我們以一筆攻擊交易為例來說明該過程。

直覺上,似乎不應該存在任何利潤,因為步驟 3 和步驟 4 的任何影響都會相互抵消。
具體來說,在步驟 3 中,由於缺乏對被兌換的 LP 代幣(即 saddleUSD)進行縮小處理,攻擊者可以兌換出更多的 saddleUSD。
然而,在步驟 4 中,攻擊者必然會兌換出更少的 sUSD,因為脆弱的 swap 函數在計算價格前並沒有放大傳入的 saddleUSD 數量。
不過,如上圖所示,攻擊者透過步驟 3 和步驟 4 中的兩次兌換,獲利了 2,059,771 sUSD。 為了找出獲利的原因,我們必須深入研究其定價機制,並進行深入調查以理解攻擊過程。
0x4.1 定價機制
Saddle Finance 的 MetaPool 繼承了 Curve 的定價公式:

該公式的圖形(當 n 等於 2 時)如下圖中的藍色曲線所示。 (該公式的設計可參見 Curve StableSwap 白皮書。)

問題來了:MetaPool 如何使用這個公式計算每次兌換的價格?
假設 n 為 2,用戶使用 dx0 個 token0 來兌換 dx1 個 token1。
我們可以模擬 dx1 的計算過程。
在每次兌換中,A 可以視為一個常數,而 D 是唯一能影響價格曲線的變量。實際上,D 會隨著池中所收取費用的累積而增加。
具體而言,計算過程可歸納為以下三個步驟:
- 步驟 I:將當前資金池的儲備量(x0 和 x1)代入公式計算當前的
D,這決定了當前的價格曲線。 - 步驟 II:令 x0 增加 dx0,並將當前的
D和 x0 代入公式計算出新的 x1。 - 步驟 III:那麼,dx1 即為新的 x1 與舊的 x1 之間的差值。
如果 token0 是基礎池的 LP 代幣,則步驟 II 變成:

這裡在攻擊期間,baseVirtualPrice/1e18 約為 1.0033。 或者,如果該 token 是基礎池的 LP 代幣,則步驟 III 變成:

為了理解 D 是如何影響價格曲線的,我們也用一個例子來描述。
假設用戶首先用 dx0 個 token0 兌換 dx1 個 token1,然後再用 dx1 個 token1 兌換 dx0' 個 token0。

如上圖所示,由於步驟 ② 為第一次兌換收取了費用,D 增加使得價格曲線向上移動(從黑色曲線變成藍色曲線)。
此外,該圖清楚地說明了為什麼 dx0' 小於 dx0 的原因。
0x4.2 攻擊分析
為了分析獲利原因,我們在本地部署了易受攻擊且已修復的 MetaSwapUtils 函式庫,並使用當時受害者資金池的狀態來模擬這次攻擊。
此外,在此模擬過程中,我們記錄了一些有助於理解攻擊過程的數值:當時 A 為 10,000,x_sUSD 為 8,130,463,x_saddleUSD 為 9,688,608,且 D 為 17,818,392。

上圖描述了獲利兌換對的過程:
- 兌換 I:使用 14,800,272 sUSD 兌換 9,657,586 saddleUSD
- 兌換 II:使用 9,657,586 saddleUSD 兌換 16,860,043 sUSD
具體來說,兌換 I 可以分為以下兩個步驟:
- ①:使用 14,800,272 sUSD 兌換 9,625,654 saddleUSD。此刻,
D因收取費用增加至 17,931,435。 - ②:由於脆弱的 MetaPool 沒有縮小被兌換的 saddleUSD 數量,資金池損失了 31,932 saddleUSD。該損失使
D減少至 15,736,195,這進一步將價格曲線向下拉(從黑色曲線變成灰色曲線)。
類似地,兌換 II 也可以分為兩個步驟:
- ③:由於價格曲線向下移動,同樣 9,625,654 的 saddleUSD 可以兌換出 16,891,906 sUSD,遠大於其成本:14,800,272 sUSD。
- ④:由於脆弱的 MetaPool 在計算價格前沒有放大傳入的 saddleUSD 數量,MetaPool 中剩下了 31,863 sUSD,這將價格曲線向上移動(從灰色曲線變成藍色曲線)。 儘管如此,這組兌換操作仍然獲利了 2,059,771 sUSD。
顯然,上述分析清楚地闡述了為什麼攻擊者可以透過這種新的攻擊手法獲利。 此外,由於在兌換 II 中 sUSD 留在了 MetaPool 中,原始的攻擊手法似乎比這種新方法效率更高。當然,攻擊者可以發動多次攻擊以耗盡資金池,這種情況在真實環境中也已被觀察到。
0x5. 總結與啟示
調查表明,這兩起事件中獲利的根本原因是一樣的。具體來說,第一次兌換(兌換 LP 代幣)減少了脆弱 MetaPool 的 D 值,進而將其價格曲線向下移動。這種偏移嚴重影響了後續的定價,並成為後續獲利的主要原因。
關於 BlockSec
BlockSec 是一家開拓性的區塊鏈安全公司,由一群全球傑出的安全專家於 2021 年創立。公司致力於提升新興 Web3 世界的安全性和易用性,以促進其大規模採用。為此,BlockSec 提供智慧合約和 EVM 鏈安全審計服務、用於安全開發及主動攔截威脅的 Phalcon 平台、用於資金追蹤與調查的 MetaSleuth 平台,以及幫助 Web3 構建者在加密世界中高效航行的 MetaDock 擴充功能。
迄今為止,公司已服務超過 300 家知名客戶,如 MetaMask、Uniswap Foundation、Compound、Forta 和 PancakeSwap,並已從 Matrix Partners、Vitalbridge Capital 和分布式資本(Fenbushi Capital)等頂級投資機構獲得了兩輪數千萬美元的融資。
官方 Twitter 帳號:https://twitter.com/BlockSecTeam



