【項目學習】ERC-4337 抽象賬戶項目審計過程中需要注意的安全問題
抽象賬戶是什么
抽象賬戶(也有叫合約錢包)是 EIP-4337 提案提出的一個標準。簡單來說就是通過智能合約來實現一個“賬戶(account)”,在合約中自行實現簽名驗證的邏輯。這樣,就使得該合約擁有了“簽發交易”的能力。通過抽象賬戶簽發的“交易”我們叫做用戶操作(UserOperation,簡稱Op)。用戶對Op進行簽名以后,將其發給一個叫Bundler的鏈下程序,它負責將所有抽象賬戶所提交的Op打包,然后提交到鏈上合約EntryPoint中。EntryPoint合約收到Op后,會調用對應的抽象賬戶來驗證其簽名,驗證通過后會將Op中的calldata取出,對抽象賬戶進行調用。整個簡化版的流程就是這樣,省略了諸如paymaster和aggregator之類的角色,想要更全面的了解的話可以閱讀以下的文章。
參考文章:
- EIP提案:https://eips.ethereum.org/EIPS/eip-4337
- 中文萬字詳解:https://www.panewslab.com/zh/articledetails/2tx7w80g.html
- 一文讀懂新上線的「ERC-4337」:https://www.tuoluo.cn/article/detail-10105986.html
- EIP 4337 核心概念:https://aandds.com/blog/eip-4337.html
- Unleashing Account Abstraction with EIP-4337:https://web3edge.io/newsletter/unleashing-account-abstraction-with-eip-4337/
- Unipass Wallet 兼容 ERC-4337:https://docs.wallet.unipass.id/zh/introduction/erc-4337
- ERC-4337 Overview:https://docs.stackup.sh/docs/erc-4337-overview
當你閱讀完上面的文章后,此時你應該對抽象賬戶有了一個大概的了解了,這時我們再來簡單整理一下整個業務流程吧。
流程如下:
- 用戶將 Op 進行簽名,并發送給 Bundler;
- Bundler 調用 Entry Point 中的 handleOps 函數;
- EntryPoint 將 UserOperation 作為參數調用 Wallet Contract 中的 validateUserOp,驗證所有需要驗證的交易。只有在驗證成功的情況下才會繼續執行后續操作;
- 此時 Entry Point 會先確認 UserOperation 中指定的 Paymaster 的狀況,例如是否擁有足夠的 ETH 來支付這筆交易的手續費;
- 接著,Entry Point 調用 Paymaster Contract 中的 validatePaymasterUserOp,確認 Paymaster 愿意支付這筆交易的手續費。如果 Paymaster 愿意支付,那么這筆交易就會繼續,否則就會失敗;
- 然后調用 Wallet Contract 并執行 UserOperation 本身指定的內容;
- 接著調用 Paymaster Contract 的 Post-Op,Post-Op 處理直接贊助或劃扣用戶 ERC20 代幣代付等自定義邏輯;
- Entry Point 在 Paymaster 質押的 ETH 余額中扣減交易所需支付的 gas fee;
- 最后 Entry Point 收集所有交易所需支付的 gas fee 總額 refund 給 Bundler ,交易執行完畢。
同時引用兩張Stackup的流程圖,幫助大家更直觀的了解整個過程:
整個抽象賬戶項目的架構,各個角色之間的關系:

當用戶發起一筆Op的時候,整個業務流程是如何運作的:

在審計過程中需要注意的安全問題
針對抽象賬戶這個項目的特點,在審計過程中有一些關鍵點需要特別留意一下。當然,具體的情況根據每個項目的不同而不同,這里只是拋磚引玉,審計工作還是要落實到具體的代碼上。
簽名問題
抽象賬戶發送一筆Op,需要進行兩次簽名檢查。
- 第一個是在抽象賬戶中對Op進行簽名檢查,確保該Op是對應的抽象賬戶簽發的。這個檢查是必須要的。
- 第二個是用戶使用paymaster的時候,需要提供paymaster所簽名的信息進行校驗。這個檢查只有在使用paymaster服務的時候需要進行,不是必須的。
當進行以上這兩種的簽名與檢查時,我們需要注意以下的問題:
- 簽名是否能夠避免重放攻擊:具體包括抽象賬戶的重放攻擊,跨鏈的重放攻擊,針對仿盤的重放攻擊,硬分叉的重放攻擊。在進行審計時要留意簽名內容是否包含抽象賬戶的 nonce 值, chianID,項目合約地址等信息。
- 簽名的打包方式:在對簽名內容進行打包時是否嚴謹,是否會出現不同的Op進行打包后得到相同字節碼的情況。
- 抽象賬戶的簽名驗證實現:由于Op的簽名是需要抽象賬戶自行實現的,需要針對其具體的實現方法進行分析,確保驗證簽名的過程嚴謹準確。
gas計算問題
Gas計算問題始終貫穿整個項目,Op 中采用了多個變量來規定gas上限,gas priority,gas 價格等。具體可以參考以下樣例:
UserOperation 結構體,用于表示用戶在智能合約中的操作請求:
- sender:發送此請求的賬戶地址。
- nonce:請求的唯一標識符,用于防止重復請求攻擊。
- initCode:如果設置了此字段,則表示要創建一個新的賬戶合約,并將其初始化為指定的字節碼。
- callData:要在此操作期間執行的方法調用數據。
- callGasLimit:用于限制此調用允許使用的最大 gas 數量。
- verificationGasLimit:用于驗證此用戶操作是否有效的所需 gas 量。
- preVerificationGas:在 handleOps 方法中計算 gas 費用之前,添加到付款總額中的附加 gas 數量。這是為了覆蓋批處理的開銷。
- maxFeePerGas 和 maxPriorityFeePerGas:與 EIP-1559 中的 gas 相關參數相同,用于計算最終的 gas 費用。
- paymasterAndData:如果設置了此字段,則表示支付方地址和特定于支付方的數據。支付方將為交易支付費用,而不是發送請求的賬戶。
- signature:發件人驗證的簽名,涵蓋整個請求、EntryPoint 地址和鏈 ID。
審計過程中要確認每個gas的相關設置是否經過檢查,取值是否安全。為了確保gas消耗在limit范圍內,所以會在交易執行過程中計算實際gas消耗。在審計過程中需要確認gas消耗的計算是否嚴謹,是否與對應的limit值進行對比檢查。其次是Op中的參數設置過大或過小時是否會造成資損或運行錯誤等問題。
代幣計價問題
代幣計價問題通常發生在EntryPoint提供了使用ERC20代幣來支付gas費用,或paymaster合約提供了使用ERC20代幣來代付gas費用的情況下。首先計算得出執行Op所需要總的gas消耗,然后通過預言機/Defi/簽名中的價格來計算等價的ERC20代幣,最后從抽象賬戶獲取所需要的ERC20完成gas的代付。
在審計的過程中要注意的問題有:
- 用來代付的token是否在白名單的范圍內,是否為正規的代幣,是否存在使用惡意代幣進行支付的隱患。
- 從預言機渠道獲取代幣價格時,需要注意價格的 decimal 和 token 對應的 decimal 在計算過程中是否使用正確。預言機地址是否限制在白名單中。預言機獲取的價格是否具有時效性,避免獲取到過時的價格。
- 從Defi中獲取代幣價格或兌換代幣時,是否對滑點進行了限制,是否存在閃電貸影響代幣兌換價格的風險。在swap操作中,tokenIn和tokenOut的計算與使用是否恰當。
- 在簽名中獲取價格時,要注意簽名價格是否具有時效性,在價格劇烈波動的場景下這種策略是否會造成用戶或者項目方的資產損失。簽名的價格是否與代幣一一對應。是否存在中心化風險。
錢包邏輯問題
合約錢包/抽象賬戶至少需要實現下面兩個函數,在對錢包部分進行審計時,要重點關注以上兩個函數的實現情況,以及驗簽是否有問題,有沒有做好權限管理,在調用的過程中是否存在重入風險等。
- 校驗 User Operation 簽名的函數,以供 EntryPoint 在 validation loop 中調用。其中的簽名方法由合約錢包自行實現。
- 發起交易的函數,以供EntryPoint 在 execution loop 中調用。
還有一個重點就是對錢包的代理模式進行檢查,了解清楚其代理模式。
- 明確implement合約(邏輯合約)的替換方式。
- EntryPoint是否對錢包合約的implement有限定的要求,是否要求implement合約要在白名單的地址中選取,在與錢包進行交互時是否對implement進行檢查,implement是否會在Op執行的過程中進行替換。
- 在錢包Proxy合約中的變量,是否能夠通過修改implement的方式進行修改。如果能夠被修改,是否會對業務流程造成影響,是否會存在安全隱患。
后記
以上就是在抽象賬戶審計過程中總結歸納的一些經驗,不能說是一個全面的審計Check List,但是希望能夠給初次接觸此類項目的同學一下入手的角度。由于抽象賬戶這個概念涉及的內容很多,局限于個人的學識,這篇文章還存在很多沒能覆蓋到的方面,也希望各位師傅能夠提出您的看法與建議,大家一起交流學習。

浙公網安備 33010602011771號