大家好,
我想針對一個暫定名為 「代幣化金庫的強制執行」(Mandated Execution for Tokenized Vaults) 的新 ERC 提案發起初步討論。
流程說明: ERC 提案需提交至 ethereum/ERCs (而非 ethereum/EIPs)。此 EthMagicians 討論串是建議的第一步,並將透過 discussions-to 連結至草案。
### 連結
工作草案(規範):https://github.com/tabilabs/mandated-vault-factory/blob/master/docs/erc-xxxx-spec.md
參考實現(Foundry):mandated-vault-factory/src/MandatedVaultClone.sol at master · tabilabs/mandated-vault-factory · GitHub
測試:mandated-vault-factory/test at master · tabilabs/mandated-vault-factory · GitHub
### 摘要 (TL;DR)
此 ERC 為 ERC-4626 代幣化金庫 上的委託策略執行 定義了一個極簡且具互操作性的介面,使外部執行者(代理/求解器)能夠在不持有授權方私鑰 的情況下提交鏈上執行,同時由金庫在鏈上強制執行嚴格的風險限制 。
核心概念:
金庫公開一個標準化的 execute(…) 入口點。
授權方(Authority) 簽署一份 EIP-712 授權書(Mandate) ,定義:
適配器白名單承諾(針對 (adapter address, adapter codehash) 的 Merkle 根),
最大**單次執行回撤(drawdown)**限制,
最大週期累計回撤 限制(高水位線),
可選的預定動作批次綁定(payloadDigest),
哈希承諾的擴展內容(extensionsHash)。
執行者(Executor) 提交 execute(mandate, actions, signature, adapterProofs, extensions)。
金庫僅透過 CALL 執行適配器調用,隨後透過比較執行前後的 totalAssets() (ERC-4626) 來強制執行**斷路器(circuit breaker)**機制。
### 極簡介面(節錄)
struct Action { address adapter; uint256 value; // 在 Core v1 中必須為 0 bytes data; } struct Mandate { address executor; uint256 nonce; uint48 deadline; uint64 authorityEpoch; uint16 maxDrawdownBps; uint16 maxCumulativeDrawdownBps; bytes32 allowedAdaptersRoot; bytes32 payloadDigest; bytes32 extensionsHash; } function execute( Mandate calldata mandate, Action[] calldata actions, bytes calldata signature, bytes32[][] calldata adapterProofs, bytes calldata extensions ) external returns (uint256 preAssets, uint256 postAssets);
### 設計目標 / 非目標
目標:
為金庫原生委託執行提供極簡的「細腰(thin waist)」介面,並具備強大的鏈上風險邊界。
同時支持外部帳戶(EOA, ECDSA)與合約授權方(ERC-1271)。
保持核心功能與 ERC-4626 金庫會計語義兼容。
非目標(至少在 Core v1 中):
### 動機
DeFi 正日益從「用戶手動調用合約」轉向「代理/求解器執行策略」。ERC-4626 標準化了池化託管與會計,但尚未標準化一種信任最小化的方式,讓金庫能將受限的執行權限 授予第三方執行者。
現有標準涵蓋了鄰近層級(委託管道、意圖表達、智能帳戶執行),但缺乏一個針對金庫原生、風險受限的委託執行 的極簡介面,且該介面需滿足:
### 規範概覽 (核心)
核心概念:
動作 (Action) :對適配器的底層調用:{ adapter, value, data }。
核心協議禁止原生價值轉移:action.value 必須為 0。
僅透過 CALL 執行調用(不使用 DELEGATECALL)。
授權書 (Mandate) :具備 nonce/deadline 重放保護的 EIP-712 簽名授權。
支持 EOA 和 ERC-1271 合約授權方。
包含 authorityEpoch 以在授權更迭時進行簽名域隔離。
適配器白名單 :針對 (adapter, extcodehash(adapter)) 的 Merkle 根,因此白名單會鎖定運行時字節碼。
斷路器 (Circuit breaker) :
單次執行損失限制:比較 preAssets = totalAssets() 與 postAssets。
累計損失限制:比較 epochAssets(高水位線)與 postAssets。
epochAssets 會更新為該週期內觀察到的最大 totalAssets()。
授權方可以 resetEpoch() 來開啟新週期。
擴展 (Extensions) :
透過 extensionsHash = keccak256(extensions) 進行哈希承諾。
規範編碼:extensions = abi.encode(Extension),並帶有嚴格遞增的唯一 id。
未知的必要擴展將導致回退(revert);未知的可選擴展可能被忽略。
擴展示例:SelectorAllowlist@v1 用於限制每個動作的 (adapter, selector) 配對。
### 安全模型與注意事項
totalAssets() 的可操縱性: 此 ERC 的斷路器假設 totalAssets() 能夠抵抗執行者在同一筆交易中的原子操縱。估值可能被閃電操縱的金庫(例如使用現貨價格預言機)不應僅依賴此機制,而應增加額外的防護措施(例如 TWAP、預言機擴展)。
可升級代理適配器: 字節碼哈希(codehash)鎖定通常無法鎖定代理的實現合約;除非增加額外的鎖定機制,否則代理型適配器是不安全的。
重入 / 金庫忙碌: 參考實現使用共享互斥鎖(mutex)來防止重入 execute,並防止在 execute 期間進入份額鑄造/銷毀入口點(deposit/mint/withdraw/redeem)。
禁止無限制的開放授權: 若 executor == address(0),則 payloadDigest 必須為非零(綁定至預定的 actions)。
審計狀態: 參考實現未經審計 ,僅供討論參考。它尚未經過正式的第三方安全審查。在未經獨立審計前,請勿用於生產環境。
### 預期問題 (FAQ)
Q1: totalAssets() 是否能在同一筆交易中被操縱,從而規避斷路器?
是的,斷路器的強度取決於金庫 totalAssets() 的實現。從現貨價格(如 AMM 儲備)獲取估值的金庫容易受到同筆交易內的閃電貸操縱。這是規範中的明確注意事項(安全模型 §1)。建議的緩解措施是使用 TWAP 或基於預言機的估值,這可以透過擴展(如 OracleValuation@v1 擴展)來強制執行。對於具有抗操縱會計的金庫(如借貸協議的 aTokens、質押封裝代幣),斷路器提供了有意義的邊界。
Q2: 適配器白名單中的 codehash 鎖定對可升級代理適配器無效嗎?
正確。對於 ERC-1967 或類似代理,extcodehash 返回的是代理合約的字節碼哈希,而非實現合約的。代理升級會在不改變白名單字節碼哈希的情況下改變行為,因此升級後先前有效的 Merkle 證明依然有效。這在草案和參考實現倉庫的 SECURITY.md 中均有記錄。建議的操作緩解措施為:(1) 對於長期授權,優先選擇不可變適配器;(2) 當代理實現更改時,撤銷並重新簽署白名單根。未來的擴展可以增加實現層級的鎖定(如 ImplementationPin@v1),但這明確超出了核心協議的範疇。
Q3: 為什麼這應該是一個 ERC 而非應用層的約定?
在 ERC 層級進行標準化可以為整個執行者/代理生態系統提供共享介面:
SDK 可組合性 :代理框架和求解器網絡可以與任何合規金庫集成,無需為每個金庫開發適配器。
審計複用 :單一經過審計的參考實現可降低每次部署的審計成本。
工具鏈 :區塊瀏覽器、監控儀表板和風險分析工具可以統一解析所有金庫的 MandateExecuted 事件。
互操作性 :存款人可以透過通用的鏈上介面評估金庫的風險限制(回撤限制、適配器白名單),無論金庫運營者是誰。
若無標準化,每個金庫都會以不兼容的介面重新發明執行委託,導致代理層碎片化。
Q4: 為什麼核心協議禁止 action.value != 0?這是否限制太大?
核心協議將 action.value == 0 作為基準線有三個原因:
會計清晰度 :ERC-4626 的 totalAssets() 追蹤 ERC-20 餘額。原生 ETH 流動會產生斷路器難以推算的會計盲點。
減少攻擊面 :允許透過適配器轉發任意 ETH 會引入重入和 Gas 操縱(gas-griefing)向量,使安全模型複雜化。
擴展路徑 :若金庫需要 ETH 流動,可以實現一個帶有明確選擇加入(opt-in)機制的擴展(如 NativeValueForwarding@v1)。這能在支持該用例的同時保持核心協議極簡。
### 徵求反饋 (開放問題)
Merkle 葉節點編碼安全性: 目前草案使用 leaf = keccak256(abi.encode(adapter, codeHash))(64 字節前像)。OpenZeppelin 警告 64 字節的葉節點在某些構造中可能被誤認為內部節點。核心協議是否應該:
原生 ETH 價值轉移: 將核心協議保持為 value == 0 並將 ETH 流動推至明確的擴展中,是否為正確的基準做法?
回退數據大小 / Gas 操縱: 實現是否應該限制回退數據(revert-data)的複製大小(代價是失去完整的診斷字節),還是像參考實現一樣保留完整數據?
輸入大小限制: 是否應要求(而非僅建議)某些限制(動作數量/證明深度/擴展字節數)?
額外的標準化擴展: 我們是否應該標準化常見的擴展(預言機/TWAP 估值、滑點規則、適配器功能內省),還是保持核心協議極簡並讓生態系統自行定義?
### 後續步驟 (ERC 提交工作流)
建立 EthMagicians 討論串(即本帖)。
發布/確認公開的參考實現倉庫(規範 + 代碼 + 測試),以便評審者閱讀草案。
填寫草案中剩餘的元數據(author, discussions-to 等)。
Fork ethereum/ERCs。
加入由草案轉換而來的 erc-XXXX.md。
開啟 PR;編輯將分配正式編號。
追蹤狀態進展:Draft → Review → Last Call → Final。
預先感謝各位的反饋。
— tabilabs (tabilabs ) (lancy@tabilabs.org)
1 則貼文 - 1 位參與者 [閱讀完整主題](https://ethereum-magicians.org/t/erc-xxxx-mandated-execution-for-tokenized-vaults-erc-4626-risk-constrained-delegated-strategy-execution/27877)