我們開發了 EIP7702Proxy,這是一個輕量級的 ERC-1967 proxy 合約,旨在用作 EOA 的 EIP-7702 委託代理基本邏輯轉發….可解決 EIP-7702 委託帳戶特有的一些挑戰。本文源自 登鏈社區 所著文章,由 foresightnews 整理、編譯及撰稿。
(前情提要: 以太坊Pectra升級「駭客爽翻」,Wintermute警告:EIP-7702使大量合約部署自動化攻擊)
(背景補充:以太坊基金會「一兆美元安全計畫」發佈首份報告:梳理智能合約、基礎設施與雲安全…六大生態挑戰 )
EIP-7702 使簡單的以太坊錢包(EOA)能夠升級為智慧合約錢包,從而提供更高的安全性、高階功能、Gas 贊助的機會和其他好處。從歷史上看,智慧錢包必須從頭開始建立,但隨著 EIP-7702 的引入,傳統的錢包可以升級,並保留其所有的資產和鏈上歷史記錄,且保持相同的錢包地址。這就像從座機切換到智慧手機而無需獲得新號碼一樣。
EOA 通過設定 「委託指定(delegation designation)」,即指向委託智慧合約(delegate smart contract)的指標來進行升級,然後委託智慧合約的邏輯來管理 EOA。因此,升級後的 EOA 可以擁有函式、設定儲存、發出事件以及執行智慧合約可以執行的所有其他操作。EOA 可以隨時通過新的、已簽名的 EIP-7702 授權來更改或刪除此委託。雖然這解鎖了許多新的可能性,但這個強大的功能也引入了新的安全挑戰,需要仔細考慮和創新解決方案。
為了使 EOA 能夠充當智慧合約錢包,我們開發了 EIP7702Proxy,這是一個輕量級的 ERC-1967 proxy 合約,旨在用作 EOA 的 EIP-7702 委託。除了代理執行的基本邏輯轉發之外,EIP7702Proxy 還包含其他功能和設計選擇,可以解決 EIP-7702 委託帳戶特有的一些挑戰。設計 EIP7702Proxy 的一個目標是使 「標準部署」 的 Coinbase 智慧錢包和 EIP-7702 委託的 Coinbase 智慧錢包之間儘可能地保持對等性,這意味著將 EIP-7702 機制所需的額外複雜性抽象到專用代理中,並繼續依賴 CoinbaseSmartWallet 的原始實現。這種挑戰的解決方案可以有效地應用於任何實現邏輯,而不僅僅是 CoinbaseSmartWallet 實現,同時還有助於 EOA 在啟用 7702 的環境中保持安全。
下面我們將介紹具體的挑戰和相應的設計解決方案,這些解決方案使我們能夠安全地調整任何現有的智慧合約錢包實現,以用於 EIP-7702 升級。
挑戰 #1:強制執行安全初始化
實現 EIP-7702 的第一個主要障礙來自其初始化約束。傳統的智慧合約錢包(包括 CoinbaseSmartWallet)通常通過單獨的工廠合約在其部署期間原子地處理安全初始化(建立帳戶所有權)。這種原子性意味著許多此類實現都具有未受保護的 initializer 函式,這些函式只能被呼叫一次。但是,EIP-7702 的設計不允許在程式碼委託過程(與 「部署」 相當的步驟)期間執行初始化 calldata,因此無法原子地完成此操作。
這種步驟分離會產生一個關鍵的漏洞視窗。當通過 EIP-7702 將實現合約 「部署」 到 EOA 時,無法保證此 7702 升級和初始化錢包的標準 EVM 交易將原子地執行。從技術上講,即使同時提交,設定授權的程式碼也可以獨立於初始化交易應用,這可能允許攻擊者搶先執行初始化交易並宣告智慧帳戶的所有權。
解決方案:需要 EOA 簽名以原子地設定 implementation 並初始化
請注意,現有的 Coinbase 智慧錢包部署在帶有 UUPSUpgradeable 實現(實際的 CoinbaseSmartWallet 邏輯)的 ERC-1967 proxy 之後。實際帳戶地址中的程式碼是一個代理,該代理使用 ERC-1967 定義的常規儲存位置來儲存指向其實現邏輯的指標。我們針對 7702 上下文中的初始化漏洞的解決方案包括認識到任何實現邏輯只有在代理實際建立與其的連線時才會變為活動狀態(因此才有危險)。因此,如果我們不能強制執行原子性的部署和初始化,我們可以強制執行原子性的實現設定和初始化。
EIP-7702CoinbaseSmartWallet合約架構和邏輯委託流程
在 EIP-7702 的上下文中,EOA 本身是對其帳戶進行任何更改的初始許可權,並且必須提供簽名以授權初始化並建立新智慧帳戶的任何所有者。我們的 EIP7702Proxy 合約實現了一個 setImplementation 函式,該函式可以原子地設定新的邏輯實現並初始化帳戶。setImplementation 函式:
驗證來自 EOA 的簽名,其中包括關鍵資料,例如新 implementation 合約的地址、初始化 calldata、將評估最終帳戶狀態的安全性的驗證器合約的地址,以及基本的簽名可重放保護,例如 nonce 和過期時間。
將 ERC-1967 指標的值設定為新的 implementation,並針對新的邏輯 implementation 執行提供的 calldata。
呼叫 validateAccountState 函式,該函式必須由簽名中包含的驗證器實現。
驗證器是一個特定於 implementation 的合約,其中包含用於評估其是否認為最終帳戶狀態安全的邏輯。例如,對於 CoinbaseSmartWallet,CoinbaseSmartWalletValidator 將檢查帳戶的所有權狀態是否為非空,因此不再容易受到任意初始化的影響。
挑戰 #2:跨 EIP-7702 委託的共享儲存
EIP-7702 最複雜挑戰可能與儲存管理有關。EOA 可以隨時自由地將其邏輯重新委託給不同的合約,或完全刪除委託。所有委託共享 EOA 地址上的相同儲存空間。隨著時間的推移,多個合約共享對同一儲存的訪問可能會導致 「儲存衝突」 問題。當兩個合約對同一儲存位置進行不同的更改或做出不同的假設時,會發生儲存衝突,這可能會導致不可預測的錯誤。
儲存衝突的管理已經是代理設計領域中一個熟悉的問題,在該領域中,可變的 implementation 邏輯用於管理共享儲存。即使可升級代理可以更改 implementation,代理程式碼本身(對於非 7702 地址)也無法更改。這給升級過程帶來了確定性和保證。7702 重新委託為可以管理此共享儲存的潛在邏輯引入了另一層完全可變性。這基本上消除了圍繞任意委託可能對儲存產生的影響的任何保證。例如,如果 EOA 從委託 A 委託到 B 並再次委託回 A,則返回的委託無法對其儲存的狀態做出假設,委託 B 可能已擦除或將其操縱為僅通過委託 A 的邏輯無法實現的狀態。對於任何 7702 委託都是如此,無論委託模式如何,因為先前的委託可能已在任何儲存位置儲存或刪除任何內容。
由 A → B → A 委託模式引起的委託 A 的無效狀態示例
解決方案:安全關鍵儲存值的外部化
EOA 委託會任意影響帳戶狀態。如果 EOA 委託給惡意或破壞性合約,則任何現任委託都無法防範這種情況。與簽署 drainer 交易一樣,授權惡意 7702 委託可能會造成災難性後果,而防範這些結果超出了我們的設計範圍。
我們設計的 EIP7702Proxy 旨在對多錢包、啟用 7702 的生態系統中可預見的問題具有自我防禦能力,該生態系統由善意但可能混亂的參與者組成。它無法保護授權真正惡意或有錯誤的委託的 EOA。
一個可預見的問題涉及 setImplementation 呼叫的簽名以及可變帳戶狀態帶來的風險。EIP7702Proxy 依賴於 EOA 簽名來設定 implementation 邏輯並初始化為安全狀態。如果這些簽名可以重放,它們可能會成為負擔。例如,如果簽名授權了一個初始所有者,該所有者後來遭到入侵並被刪除,則可重放簽名可能會重新建立遭到入侵的所有者或強制降級 implementation。
防止簽名重放的常見保護措施是在簽名訊息中使用 nonce,並在驗證後標記為已使用。7702 帳戶的風險:其他委託可能會破壞此 nonce 追蹤儲存。如果追蹤 nonce 使用情況的儲存被刪除,則 EOA 的 setImplementation 簽名(在 mempool 中公開可用)可以在委託回 EIP7702Proxy 時重新應用。
為了保證簽名不可重放,我們實現了一個單獨的 NonceTracker 單例,它在帳戶儲存之外的不可變合約位置維護 nonce 狀態。只有 EOA 才能影響其 nonce(僅以遞增方式),從而防止其他委託操縱這些安全關鍵值。無論帳戶儲存發生什麼變化,NonceTracker 都能確保每個 setImplementation 簽名僅工作一次。
挑戰 #3:共享傳統儲存位置的風險增加
像 ERC-1967 定義的標準儲存槽特別容易受到潛在儲存衝突的影響,因為它們是多個委託實現可能使用的常規位置。ERC-1967 implementation 槽是 EIP7702Proxy 中使用的唯一標準儲存位置,它儲存著代理指向的邏輯 implementation 的地址。我們的設計保證,無論此儲存位置的值如何(該值決定了帳戶中可用的大部分邏輯),EIP7702Proxy 始終能夠成功地將其 implementation 邏輯設定為 EOA 期望的合約。
為了更清楚地說明正在解決的問題,請注意,當一個帳戶在不同的委託之間轉換 (A→B→A) 其中兩個委託都實現了 ERC-1967 代理模式,委託 B 自然會使用與委託 A 用於儲存其 implementation 地址的同一儲存槽。在其任期內,委託 B 可能會修改或覆蓋此插槽,無論是故意的還是作為其自身代理操作的正常部分。在 UUPSUpgradeable 代理模式中,升級 implementation 的邏輯在 implementation 合約本身上定義。如果委託 B 放置在此指標位置的 implementation 不包含 implementation 上預期的 upgradeToAndCall 介面,那麼當返回到委託 A 時,更改其 implementation 的機制可能不存在於當前可用的邏輯上。
新委託覆蓋共享的傳統儲存位置的示例
解決方案:EIP7702Proxy 上可用的升級機制
我們的 EIP7702Proxy 通過其 setImplementation 函式解決了這個問題,該函式直接在代理本身上提供了一個獨立於 implementation 的升級機制。這確保即使中間委託已將 ERC-1967 implementation 指向無效的 implementation(或完全刪除了它),在委託回 EIP7702Proxy 後,原始 EOA 仍保持重新配置代理的 ERC-1967 指標的能力,以指向他們選擇的邏輯 implementation。
挑戰 #4:與標準 EOA 行為的向後相容性
EIP7702Proxy 的一個設計目標是除了新的智慧合約功能外,還要保持與帳戶 EOA 功能的向後相容性。地址上程式碼的存在或不存在會影響與該地址互動的協議的執行流程,因為它們以此特性來區分 EOA 和智慧合約。這需要考慮兩個主要行為:簽名驗證和代幣接收行為。
簽名驗證
智慧合約的簽名驗證標準與標準 EOA 不同。智慧合約實現了 ERC-1271 定義的 isValidSignature 介面,並且可以自由地定義任意邏輯來確定合約是否認為簽名有效。對於標準 EOA,簽名通過標準的 ecrecover 檢查進行驗證,該檢查確保簽名者恢復到預期的 EOA 地址。
為了確保在 7702 升級後,現有或未來的 EOA 簽名將繼續在 EOA 上被認可,EIP7702Proxy 實現了 isValidSignature 的一個版本,該版本首先將簽名驗證委託給應該在邏輯 implementation 上定義的 isValidSignature 函式,但如果驗證失敗,則會執行最終的 ecrecover 檢查。如果此檢查通過,則認為簽名有效。通過這種方式,使用 EIP7702Proxy 的 EOA 可以保證,無論其智慧合約錢包的 isValidSignature 實現如何,簡單的 EOA 簽名始終將在其地址上被認可。
代幣接收
一些代幣標準(特別是 ERC-1155 和 ERC-721)試圖防止代幣卡在可能無法管理它們的智慧合約中。這些代幣要求任何將接收此類代幣的智慧合約通過實施標準代幣接收器介面來宣告此能力,這些介面由代幣合約在代幣傳送期間呼叫。同樣重要的是,升級後的 EOA 上的邏輯包含標準的 receive 函式或 payable 回退,以便能夠接收原生代幣。帳戶不應處於無法接收 ETH 或其他代幣的狀態,即使是很短的時間。
由於我們的代理缺少初始 implementation,因此我們包含了一個不可變的 DefaultReceiver implementation 作為 EIP7702Proxy 在缺少 ERC-1967 指標時的預設邏輯。此接收器實現了接收函式和這些常見代幣標準的接收器 Hook,確保帳戶可以在顯式設定新 implementation 之前接受代幣轉帳。
結論
EIP7702Proxy 設計使我們能夠與標準部署的 CoinbaseSmartWallets 保持緊密一致,並繼續使用現有的 CoinbaseSmartWallet implementation,同時解決 EIP-7702 上下文中出現的獨特安全挑戰。通過仔細考慮初始化安全性、儲存暫時性和干擾的影響、對不間斷代幣處理的需求以及與標準 EOA 簽名驗證的向後相容性,我們建立了一個用於安全地委託和管理 EIP-7702 智慧合約錢包的代理。雖然 EIP7702Proxy 的設計考慮了 CoinbaseSmartWallet V1 implementation,但此代理最終與 implementation 無關。我們鼓勵開發人員評估此解決方案,以對其他智慧合約錢包 implementation 進行 7702 防護。
原文連結:https://blog.base.dev/securing-eip-7702-upgrades
登鏈社群 AI 助手,為大家轉譯優秀英文文章,如有翻譯不通的地方,還請包涵~
登鏈社群是一個 Web3 開發者社群,通過構建高品質技術內容平臺和線下空間,助力開發者成為更好的 Web3 Builder。
登鏈社群網站 : learnblockchain.cn
開發者技能認證 : decert.me
B 站 : space.bilibili.com/581611011
YouTube : www.youtube.com/@upchain