本文首發于公眾號:Keegan小鋼
UniswapV4 與 UniswapV3 相比,算法上并沒有什么改變,依然還是采用集中流動性模型,但架構上變化很大,包括功能架構,也包括技術架構。相比之前的版本,UniswapV4 最大的創新主要包括四點:
- 引入 Hooks
- 改用單例模式
- 采用閃電記賬
- 支持原生 ETH
Hooks
引入 Hooks 機制是最核心的變動點,也大大擴展了其靈活性,使得定制化池成為了可能。
Hooks 本質上就是一個定制化的合約,當初始化一個交易池的時候,需要指定該池子所用的 Hooks 合約地址。Hooks 合約需要實現一系列回調函數:
- beforeInitialize / afterInitialize
- beforeModifyPosition / afterModifyPosition
- beforeSwap / afterSwap
- beforeDonate / afterDonate
其實就是分別在 initialize、modifyPosition、swap、donate 這幾個關鍵操作執行前和執行后都可以添加自定義邏輯。
以 swap 操作為例,加上 Hooks 的 swap 流程如下圖所示:
其他操作流程也是同理。
V4 的白皮書中有列舉出了可以使用 Hooks 實現的一些示例功能:
- 通過 TWAMM 隨時間執行大額訂單
- 按指定價格成交的鏈上限價單
- 隨波動率變化的動態費用
- 為流動性提供者內化 MEV 的機制
- 中位數、截斷或其他自定義預言機實現
目前,UniswapV4 官方也已經提供了幾個參考實現,包括 TWAMM、LimitOrder、FullRange、VolatilityOracle、GeomeanOracle。之后的文章我們會一一剖析講解這幾個示例實現。
Hooks 除了可以實現這些功能之外,還可以管理池的 swap 費用,以及還可以向流動性提供者收取提款費用。
對于費用的管理,不只是可以設置為靜態費用,還可以設置為動態費用。支持動態費用的話,那就可以實現和中心化交易所一樣,按用戶的不同等級設置不同的費率。還可以把費用分配給不同的人,比如添加邀請分傭機制,手續費部分分配給邀請人。
總而言之,Hooks 大大提高了 Uniswap 的可擴展性。
單例和閃電記賬
Uniswap 以前的版本,每個池子都是單獨的合約,是通過工廠合約來創建每個池子合約的。而 UniswapV4 改為了使用單例模式,所有池子全都由單個合約進行管理,即 PoolManager 合約進行統一管理。
使用單例模式,那新建池子時,就不再需要部署新合約實例,可以大大降低創建池子的成本。
另外,單例模式還結合了另一個機制叫閃電記賬,以及結合使用了 EIP-1153 中提議的瞬態存儲操作碼。EIP-1153 會在坎昆升級中支持,這就是 UniswapV4 到目前還沒有發布上線的主要原因,在等坎昆升級完成。
在以前的版本中,每次交易都需要計算所有相關倉位的余額,尤其涉及跨池交易,還需要在多個池子間多次執行 transfer,交易成本其實挺高的。而閃電記賬機制,每個操作前會先做一個鎖定,鎖定期間只會更新一個稱為 delta 的內部凈余額,僅在鎖定結束時才進行外部轉賬,這就大大節省了交易成本。
不過,在當前執行環境中,閃電記賬架構其實是挺昂貴的,因為需要在每次余額變化時進行存儲更新。但是,由于余額必須在事務結束時為 0,因此可以使用瞬態存儲實現對這些余額的記賬,從而減少 gas 消耗。
瞬態存儲操作碼是專門用來解決區塊內部通訊的解決方案。瞬態存儲不改變現有操作的語義,瞬態存儲的數據在每次交易后會被丟棄,不會訪問服務器磁盤,使用后也無需清除存儲槽,客戶端也不需要加載原始數據。因此,相對來說,使用瞬態存儲解決區塊內部之間通訊問題的優勢在于 Gas 較低,且未來的以太坊數據存儲設計中不需要考慮因臨時存儲而產生的操作費用退費的情況。
簡而言之,使用瞬態存儲,可以用低 gas 解決臨時存儲的問題。
原生 ETH 和其他
支持原生 ETH 是說,在底層池子里就支持原生 ETH 和其他代幣之間的直接交易。
其實在 UniswapV1 版本也是支持原生 ETH 的,但那時候的池子嚴格限制了只能是 ETH 和另一個 ERC20 代幣配對組成的,ERC20 代幣之間是通過跨池交易的。但從 UniswapV2 開始,支持任意 ERC20 代幣配對,但由于實施的復雜性,以及在 WETH 和 ETH 配對之間的流動性碎片化的擔憂,底層池子統一只支持 ERC20 代幣,只在上層合約里實現 ETH 和 WETH 的自動互換。增加了 ETH 和 WETH 互換的邏輯,其實增加了交易成本。如果只用原生 ETH 轉賬的話,gas 成本只約為 ERC20 轉賬的一半(ETH 為 21k gas,ERC20 約為 40k gas)。
現在,UniswapV4 因為使用了單例和閃電記賬模式,又能很好地支持原生 ETH 了,而且還允許同時支持 ETH 和 WETH 的配對。
UniswapV4 還引入了 ERC1155 代幣用于額外的代幣記賬。用戶可以將代幣保留在單例合約中,避免 ERC20 頻繁轉入和轉出合約。這一點對于頻繁交易者或流動性提供者非常有價值,因為他們會在多個區塊或交易中連續使用相同的代幣。
引入了 Hooks 機制之后,像 UniswapV2 和 UniswapV3 內嵌的價格預言機也變得不再必要了,因此,在 PoolManager 中再見不到價格預言機相關的數據存儲和邏輯處理了。因為預言機可以通過 Hooks 合約定制化實現了。
donate() 函數是 V4 新增的操作,允許用戶、集成者和 Hooks 直接支付給特定范圍內的流動性提供者,支付的方式可以是池中的任意一種或兩種代幣。
總結一下,UniswapV4 算法上并沒有改變,依然還是采用集中流動性,但通過 Hooks 實現了可定制的池,單例合約和閃電記賬大幅度降低了 gas 成本,對原生 ETH 的支持也同樣減少了 gas,還有對動態費用的支持、ERC1155 的支持等,都大大提高了 Uniswap 的靈活性、可擴展性。