原文來源:BlockSec
相信Uniswap v4 不久就會和大家見面了!
這次Uniswap 團隊可謂目標宏大,計畫引入眾多全新功能[1],包括每個交易對支援無限數量的流動性池和動態費用、單例設計、閃電記帳、Hook,以及支援ERC1155 代幣標準。利用 EIP-1153 引入的瞬態存儲,Uniswap v4 預計將在以太坊坎昆升級之後發布。
在許多創新中,Hook 機制因其強大潛力引起了廣泛關注。 Hook 機制支援在流動性池生命週期中的特定點執行特定程式碼,大大增強了池子的可擴展性和靈活性。然而,Hook 機制也可能是一把雙面刃。雖然它功能強大且靈活,但安全使用 Hook 同樣是一個不小的挑戰。
Hook 的複雜性不可避免地帶來了新的潛在攻擊向量。因此,我們希望撰寫一個系列文章,來系統介紹與 Hook 機制相關的安全問題與潛在風險,以此推動社區的安全發展,相信這些見解將有助於建立安全的 Uniswap v4 Hook。作為本系列文章的開頭之作,本文介紹了與 Uniswap v4 中 Hook 機制相關的概念,並概述了 Hook 機制存在的安全風險。
在深入探討之前,我們需要對Uniswap v4 的機制有基本的了解。
根據官方公告[1] 和白皮書[2],Hook、單例架構和閃電記帳是實現自訂流動性池和跨多個池子實現高效路由的三個重要功能。 1.1 HookHook 指的是流動性資金池生命週期的不同階段運作的合約,Uniswap 團隊希望透過引入 Hook 讓任何人都能做出權衡決策。透過這種方式,可以實現原生支援動態費用、添加鏈上限價單、或透過時間加權平均做市商 (TWAMM) 分散大訂單。
目前有八個Hook 回調,分為四組(每組包含一對回呼):
- beforeInitialize/afterInitialize
- beforeModifyPosition/afterModifyPosition
- beforeSwap/afterSwap
- beforeDonate/afterDonate
下文是白皮書[2] 中介紹的交換Hook 的流程。
圖1:交換Hook 流程
Uniswap 團隊用一些範例(例如TWAMM Hook [3])介紹了操作方法,社區參與者也做出了一些貢獻。官方文件 [4] 也連結到了 Awesome Uniswap v4 Hooks[5] 倉庫,該倉庫收集了更多的 Hook 範例。
單例(singleton)架構和閃電記帳(flash accounting)旨在透過降低成本和確保效率來提高效能。它引入了一種新的 singleton 合約,即所有流動性池都保存在同一個智能合約中。這個單例設計依賴一個 PoolManager 來儲存和管理所有池子的狀態。
在Uniswap 協議的早期版本中,兌換或添加流動性等操作涉及直接代幣轉移,v4 版本則有所不同,在於其引入了閃電記帳和鎖機制(lock mechanism)。
鎖機制的運作方式如下:
1.某個locker 合約在 PoolManager 上要求lock。
2. PoolManager 將該 locker 合約的位址加入 lockData 佇列,並呼叫其 lockAcquired 回呼。
3. 此 locker 合約在回呼中執行其邏輯。在執行過程中,locker 合約與池子的互動可能會導致非零的貨幣增量。然而,在執行結束時,所有增量必須結算為零。另外,如果 lockData 佇列不為空,只有最後一個 locker 合約可以執行操作。
4. PoolManager 檢查 lockData 佇列和貨幣增量的狀態。驗證後,PoolManager 將刪除該 locker 合約。總結來說,鎖機制防止了並發訪問,並保證了所有的交易都能被清算。而 locker 合約依序申請 lock,然後透過 lockAcquired 回呼執行交易。在每次池操作前後會觸發對應的 Hook 回呼。最後,PoolManager 會檢查狀態。
這種方法意味著操作調整的是內部淨餘額(即 delta),而不是執行即時轉帳。任何修改都會記錄在池子的內部餘額中,實際的轉帳則在操作(即 lock)結束時進行。這個過程保證了沒有未清算的代幣,從而維持了資金的完整性。
由於鎖定機制的存在,外部所有帳戶 (EOA) 不能直接與 PoolManager 進行互動。相反,任何互動都必須透過一個合約進行。該合約作為一個中間的locker,在進行任何池操作之前都需要請求lock
主要存在兩種合約互動場景:
某個locker 合約來自官方的程式碼庫,或由使用者部署。在這種情況下,我們可以將互動視為透過路由器進行。
某個 locker 合約和 Hook 整合到同一個合約中,或由第三方實體控制。對於這種情況,我們可以將互動視為透過 Hook 進行。在這種情況下,Hook 既扮演了 locker 合約的角色,又負責處理回調。
在討論相關的安全性問題之前,我們需要確定威脅模型。我們主要考慮以下兩種情況:
威脅模型 I:Hook 本身是良性的,但有漏洞。
威脅模型 II:Hook 本身就是惡意的。
在接下來的部分,我們將根據這兩種威脅模型討論潛在的安全問題。
威脅模型I 關注的是與Hook 本身相關的漏洞。這個威脅模型假設開發者及其 Hook 是無惡意的。然而,智能合約現有的已知漏洞也可能出現在 Hook 中。例如,如果 Hook 是作為可升級合約實現的,那麼它可能會遇到類似於 OpenZeppelin 的 UUPSUpgradeable 漏洞的相關問題。
鑑於上述因素,我們選擇聚焦在 v4 版本特有的潛在漏洞。在 Uniswap v4 中,Hook 是能夠在核心池操作(包括初始化、修改位置、交換和收集)之前或之後執行自訂邏輯的智慧合約。雖然 Hook 預計將實現標準的接口,但它也允許包含自訂邏輯。因此,我們的討論範圍將限制在涉及標準 Hook 介面的邏輯。然後,我們將嘗試找出可能的漏洞來源,例如,Hook 可能如何濫用這些標準 Hook 函數。
具體來說,我們將關注以下兩種Hook:
第一種hook , 保管用戶資金。在這種情況下,攻擊者可能會攻擊這個 hook 來轉移資金,造成資產損失。
第二種 hook, 儲存使用者或其他協定所依賴的關鍵狀態資料。在這種情況下,攻擊者可能會試圖改變關鍵狀態。當其他使用者或協定使用錯誤狀態時,可能會帶來潛在風險。
請注意,這兩種範圍以外的 hook 不在我們的討論範圍內。由於本文撰寫時還沒有 Hook 的真實用例,我們將從 Awesome Uniswap v4 Hooks 倉庫中獲取一些資訊。在對 Awesome Uniswap v4 Hooks 倉庫(提交哈希為 3a0a444922f26605ec27a41929f3ced924af6075)進行深入研究後,我們發現了幾個嚴重的漏洞。這些漏洞主要源自於 hook、PoolManager 以及外部第三方之間的風險交互,主要可分為兩類:存取控制問題和輸入驗證問題。具體發現請見下表:

總的來說,我們發現了22 個相關項目(排除與Uniswap v4 無關的項目)。在這些專案中,我們認為有 8 個(36%)項目是存在漏洞的。在這 8 個有漏洞的專案中,6 個有存取控制問題,2 個容易受到不受信任的外部呼叫。
2.1.1 存取控制問題
在在這部分討論中,我們主要關注的是 v4 中的回呼函數可能導致的問題,包括8 個hook 回呼和lock 回呼。當然,還有其他情況需要驗證,但這些情況因設計而異,暫不在我們的討論範圍之內。
這些函式應該只能被 PoolManager 調用,不能被其他位址(包括 EOA 和合約)呼叫。例如,在獎勵由資金池金鑰分發的情況下,如果相應的函數可以由任意帳戶調用,那麼獎勵可能會被錯誤地領取。
因此,對於hook 來說,建立強大的存取控制機制是至關重要的,尤其是它們可以被除了池子本身之外的其他方調用。透過嚴格管理存取權限,流動性池可以顯著降低與 hook 未授權互動或惡意互動的風險。
2.1.2 輸入驗證問題
在Uniswap v4 中,由於存在鎖定機制,用戶在執行任何資金池操作之前必須透過合約取得一個lock。這確保了目前參與交互的合約是最新的 locker 合約。儘管如此,仍然存在一個可能的攻擊場景,即由於在一些易受攻擊的Hook 實作中輸入驗證不當而導致的不受信任的外部呼叫:
其次,一些關鍵的 hook 函數允許任意的外部呼叫。
不受信任的外部呼叫極為危險,因為它可能導致各種類型的攻擊,包括我們熟知的重入攻擊。為了攻擊這些易受攻擊的 hook,攻擊者可以為自己的假代幣註冊一個惡意資金池,然後呼叫 hook 在資金池執行操作。在與資金池互動時,惡意代幣邏輯劫持控制流以便進行不良行為。
2.1.3 針對威脅模型 I 的防範措施
為了規避與hook 相關的此類安全問題,透過適當執行對敏感的外部/公共函數的必要存取控制,並對輸入參數進行驗證,從而對互動進行驗證是至關重要的。此外,重入保護可能有助於確保 hook 不會在標準邏輯流程中重複執行。透過實施適當的安全防護措施,資金池可以降低與此類威脅相關的風險。
在這個威脅在模型中,我們假設開發者及其hook 是惡意的。鑑於涉及範圍很廣,我們僅關注與 v4 版本相關的安全問題。因此,關鍵在於提供的 hook 是否能夠處理使用者轉帳或授權的加密資產。由於存取hook 的方法決定了可能賦予hook 的權限,我們據此將hook 分為兩類:
託管型Hook(Managed Hooks):hook 不是入口點。使用者必須透過路由器(可能由 Uniswap 提供)與 hook 進行互動。
獨立型 Hook(Standalone Hooks):hook 是入口點,允許使用者直接與之互動。
圖2:惡意Hook 的範例
2.2.1 託管型 Hook
在這種情況下,用戶的加密資產(包括原生代幣和其他代幣)被轉帳或授權給  ;router 。由於 PoolManager 執行了餘額檢查,惡意 hook 不容易直接竊取這些資產。然而,仍然存在潛在的攻擊面。例如,v4 版本的費用管理機制可能會被攻擊者透過 hook 進行操縱。
2.2.2 獨立型 Hook 當 Hook 被用作入口點時,情況就更加複雜。
在這種情況下,由於使用者可以直接與 hook 進行交互,hook 獲得了更多的權力。理論上,hook 可以透過這種互動執行想要的任何操作。在 v4 版本中,程式碼邏輯的驗證是非常關鍵的。主要問題在於是否可以操縱程式碼邏輯。如果 hook 是可升級的,這意味著一個看似安全的 hook 可能會在升級之後成為惡意的,從而構成重大風險。這些風險包括:
可升級的代理程式(可以直接攻擊);
帶有自毀邏輯。在聯合呼叫 selfdestruct 和 create2 的情況下可能會被攻擊。
2.2.3 針對威脅模型 II 的防範措施
p>
至關重要的一點在於評估hook 是否是惡意的。具體來說,對於託管型 hook,我們應該關注費用管理的行為;而對於獨立型 hook,主要的關注點在於它們是否可升級。 - 3 -結論在本文中,我們首先簡要概述了與 Uniswap v4 的 Hook 安全問題相關的核心機制。隨後,我們提出了兩種威脅模型並簡要概述了相關的安全風險。在後續文章中,我們將對每種威脅模型下的安全問題進行深入分析。敬請關注!
參考資料
[1] Our Vision for Uniswap V4
https://blog.uniswap.org/uniswap-v4
[2] Uniswap v4 whitepaper draft
https://github. com/Uniswap/v4-core/blob/main/whitepaper-v4-draft.pdf
[3] Unswap v4 TWAMM Hook
v4 TWAMM Hook
https://blog .uniswap.org/v4-twamm-hook
[4] Hook Examples
https://docs.uniswapfoundation.org/hooks/hook-examples
[5] Awesome Uniswap v4 Hooks
https://github.com/fewwwww/awesome-uniswap-hooks
[6] USUpgradeabledeable; Vulnerability Post-mortem
https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680
原文連結
< /p>
歡迎加入律動 BlockBeats 官方社群:
Telegram 訂閱群:https://t.me/theblockbeats
Telegram 交流群:https://t.me/BlockBeats_App
Twitter 官方帳號:https://twitter.com/BlockBeatsAsia