緣由#
AAVE 最近通過了一項更新利率的治理,結果卻把 Polygon 上 BTC ETH USDT MATIC 的池子給凍結了,影響 1.1 億美元的資金,詳情可見:BlockSec 推文 ,技術分析,官方聲明
官方宣稱只能通過治理投票的方式進行修復,必須等待至少 7 天,也不打算使用 emergencyAdmin 權限
所以自然地就好奇 AAVE 的跨鏈治理是怎麼做的?技術上又是如何實現的?真的必須等待 7 天嘛?
提案從提出到執行的全流程#
以本次出問題的這次提案 224 為例,看看這個提案的整個時間線
1. 2023/4/22 論壇討論#
2. 2023/4/29~2023/5/6 Snapshot 鏈下投票#
2023/4/29 開始,2023/5/6 結束
共計 15854 人參與投票,574K AAVE 贊同 (99.93%)
3. 2023/5/10 Payload 合約部署#
本次提案同時修改了 ETH 鏈和 Polygon 鏈的利率模型
2023/5/10 部署 ETH 上 Payload 合約 0x24bdacf6bbebaf567123da16cdb79a266597e92b 其中涉及的新的利率合約 例如USDT 的利率合約 在 2023/5/8 部署
2023/5/10 部署 Polygon 上 Payload 合約0xF22c8255eA615b3Da6CA5CF5aeCc8956bfF07Aa8 其中涉及的新的利率合約 例如USDT 的利率合約 在 2023/5/7 部署
4. 2023/5/11 鏈上提案提出#
本次鏈上提案由多簽錢包提出
https://etherscan.io/tx/0x05152e33582d861b7047254680588b249783be8d680936423f91bb90a74717cf#eventlog
提案提出的區塊高度為 17240283,投票開始高度 17247483 (相距 7200 個 block),結束高度 17266683(投票期間 19200 個 block)
Executor 為0xEE56e2B3D491590B5b31738cC34d5232F378a8D5 這個 Executor 實際上就是 AAVE 全局的 admin 合約
提案要執行的事情就兩個:
- 使用 delegatecall 執行 ETH 上的 Payload 合約 0x24db...e92b 的
execute()
- 使用 delegatecall 執行 ETH 上的 CrosschainForwarderPolygon 合約 0x158a...d45b 的
execute(0xF22C8255EA615B3DA6CA5CF5AECC8956BFF07AA8)
可以看到 Polygon 需要執行的 Payload 合約地址作為參數傳入
5. 2023/5/11 ~ 2023/5/15 鏈上投票#
https://app.aave.com/governance/proposal/?proposalId=224
投票通過需要滿足的條件們:
- Quorum 320K
- Differential 80K
一共 11 個地址完成投票,例如aavechan.eth 的投票交易
6. 2023/5/15 ETH 鏈上等待執行#
投票結束後需要調用queue(224)
將提案從投票成功狀態轉為 Queued 狀態:
https://etherscan.io/tx/0x7dbfef2616f1efa17328d4bfe97b7bfd7e72f05d9f413c64a3c934278f54d242
這個交易是 ChainLink Keeper 觸發的,然後等待時間到 1684280195 之後可以鏈上執行
注意到還有一個 grace period 的概念,如果提案可執行但超過 grace period(432000 秒 = 5 天)仍然沒有執行則進入 expired 狀態,提案就過期不可再執行
7. 2023/5/17 ETH 鏈上執行#
提案執行的交易: https://etherscan.io/tx/0xe0e0ab8f7524f0165e6cb1182db18cf3ffe1c4f7cb57f335b40a322d8026de3f 時間戳 1684284539
也是由 ChainLink Keeper 觸發的,由 EthRobotKeeper 負責調用 Goverance 合約的execute(224)
然後交給 Executor.executeTransaction 使用 delegatecall 去調用 payload 合約
還記得 Executor 合約就是全局 admin 嘛?所以通過這種方式就能執行任意操作了
ETH 上的執行的消息怎麼傳遞到 Polygon 上來執行呢?這就要用到 Polygon 官方橋了
CrosschainForwarderPolygon 會被 Executor 以 delegatecall 的方式調用,來調用 Polygon 官方橋 FX_ROOT_ADDRESS = 0xfe5e5D361b2ad62c541bAb87C45a0B9B018389a2 ,將消息傳遞給 Polygon 目標合約 POLYGON_BRIDGE_EXECUTOR = 0xdc9A35B16DB4e126cFeDC41322b3a36454B1F772
所以在 Polygon 官方橋看來消息的發送者還是 Executor 的地址 0xee56...a8d5 這個 admin 地址
Polygon 官方橋合約在收到這個調用之後就會發出StateSynced(counter, receiver, data)
事件,其中 counter 是全局遞增計數器,receiver 是固定的 fxChild,data 是(msg.sender, _receiver, _data)
的 abi 編碼,這裡的實例是:
對其中的 data 進行 abi 解碼可以得到:
msg.sender = 0xee56e2b3d491590b5b31738cc34d5232f378a8d5
receiver = 0xdc9a35b16db4e126cfedc41322b3a36454b1f772
data = 00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000f22c8255ea615b3da6ca5cf5aecc8956bff07aa800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000009657865637574652829000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001
這麼長的 data 是幹啥的呢
8. 2023/5/17 Polygon 鏈上接收消息#
Polygon 官方橋會以0x0000000000000000000000000000000000001001
地址的身份調用 FxChild 合約 0x8397259c983751DAf40400790063935a11afa28a,進而調用到 receiver 的processMessageFromRoot(stateId, rootMessageSender, data)
函數
https://polygonscan.com/tx/0x52ed6243fc44b0b3999685020ca4b7b42c2629582194789a25792c044743dd59
這個交易是 Polygon 系統交易 所以 sender 和 to 都是 0 地址 而且同時包含其他不相關的跨鏈交易
時間戳 1684285952 可以看到這個跨鏈消息傳遞用了 23 分鐘 還是挺快的
收到消息後就進入了 receiver PolygonBridgeExecutor 0xdc9a...f772 的 processMessageFromRoot 函數了,這個函數會校驗 msg.sender 必須是跨鏈橋 FxChild,消息的來源必須是_fxRootSender 也就是 ETH 上的 admin 合約
可以看到 data 實際上是 targets, values, signatures, alldatas, withDelegates 這五個數組的 abi 編碼,所以我們解碼一下就能得到:
targets: (('0xf22c8255ea615b3da6ca5cf5aecc8956bff07aa8',)
values: (0,)
signatures: ('execute()',)
calldatas: (b'',)
withDelegatecalls: (True,)
這裡的 targets 也就是 Payload 合約咯
收到消息後並不会立刻執行,還有一個 Delay 等待期 172800=2 天,同樣地也有一個 3 天的 GracePeriod
9. 2023/5/19 Polygon 鏈上執行#
https://polygonscan.com/tx/0x6172ae452fb2c6abab7aef013e33cf899e3de09e4933433eeeae5fa41be46457
也是由 ChainLink Keepr 負責觸發,使得 PolygonBridgeExecutor 以 delegatecall 的方式執行 payload 合約 完成參數變更
所以可見整個流程確實需要 7 天:
Considering governance times, if approved, the fix will be applied in approximately 7 days from now:
- 1 day of delay to start voting,
- 3 days of voting,
- 1 day of timelock on Ethereum
- and 2 extra days of timelock on Polygon.