Rollup Bridge 介紹(五):Hop Protocol part 2

Hop Protocol 是一個讓使用者可以快速在各個不同 Rollup 間轉移資產的協議

NIC Lin
imToken
13 min readApr 7, 2022

--

Photo by Alex Radelich on Unsplash

本篇是 Rollup Bridge 介紹的第五篇,主要用來補充第二篇 Hop Protocol part 1 的運作細節,建議先從第二篇看起:

https://medium.com/imtoken/rollup-bridge-%E4%BB%8B%E7%B4%B9-%E4%BA%8C-hop-protocol-48f8140bb9a8

  • 以下所稱的 L2 皆指 Rollup 而非 Plasma 或 sidechain
  • 以下所稱『資產』和『代幣』兩個詞指的是一樣的東西
  • 以下所稱『七天』和『Rollup 挑戰期』兩個詞指的是一樣的東西
  • 以下示意圖中 Arbitrum 會是 Rollup A,Optimism 會是 Rollup B,使用者要將資產從 Rollup A 跨到 Rollup B
  • Hop Protocol part 1 中用 fast transfer 代指跨 Rollup 的 transfer,來和第一篇 Maker Bridge 的 fast withdraw(回 L1)做區隔,不過本文裡會用 transfer/withdraw 代指一樣的事情

Recap: Relay transfer 資料

為什麼要 relay transfer 資料?

因為 transfer 資料是客觀的資料,Hop 合約不能隨便相信流動性提供者(Bonder) 說他替誰先墊付了某筆 transfer 就撥款給 Bonder,Hop 合約只會認 transfer 資料來確認實際上 transfer 是否發生,所以 Hop 合約只有等到 transfer 資料真的抵達 Rollup B 時才會撥款給 Bonder。

對使用者來說,如果 Bonder 幫他墊付了,則他完全不需擔心 transfer 資料的 relay 過程(畢竟他已經在 Rollup B 收到代幣了)。但如果 Bonder 下線了,使用者就要自己把 transfer 資料 relay 到 Rollup B 來向 Hop 合約證明並取回自己應得的代幣。
註:Hop 把 transfer 資料從 Rollup 送到 L1 的過程叫做 commit

Recap: Batch Transfer

Hop Protocol part 1 有提到為了節省 Bonder 的成本,Hop 設計讓 transfer 可以以 batch 的方式一次 commit 回 L1,不需每一筆都 commit 一次。而 batch 的條件分別是
(1) 累積 512 筆 transfer 或 (2) 離上一次該 Bonder commit 的時間已經過了一天
註 1:條件 (2) 是為了在不打擾 Bonder 前提下讓使用者能夠自己完成 relay 的條件:當 Bonder 下線太久時,使用者可以自己把 transfer 資料 commit 到 L1,再 relay 到 Rollup B
註 2: Bonder 自己來 commit 時可以不受 (1) 限制,不管累積幾筆 transfer,隨時都可以 commit

而 batch transfer 也不會真的把 batch 裡面所有 transfer 資料都 commit 進去,而是把 transfer 資料組成一個 Merkle Tree,然後只 commit Merkle Root。當要使用到 transfer 資料時,再提供 Merkle Proof 來證明 transfer 存在於該 Merkle Tree 裡。
註:實際上 commit 的函式名稱為 commitTransferRoot 。這裡看到 Hop 用的是 transfer 的字眼,而待會可以看到在 Rollup B 上的操作 Hop 會用 withdraw,但其實兩個指的是一樣的

接下來會搭配圖示介紹使用者和 Bonder 的操作流程及 challenge 機制

使用者視角的運作流程

對使用者來說,使用 Hop 會有兩種結果:(一) Bonder 為你在 Rollup B 上墊付,或是 (二) Bonder 沒有墊付,導致使用者必須自己完成把 transfer 資料從 Rollup A relay 到 Rollup B 的旅程。

結果一:Bonder 有墊付

Happy case: Bonder 完成墊付

1st Tx

使用者發起 withdraw,他有兩個選擇:如果使用者有 hUSDT,則他直接觸發 L2_Bridge 合約的 send函式(Opt 2);如果他沒有 hUSDT,則觸發 AMM_Wrapper 合約的 swapAndSend 函式,先用 USDT 去換成 hUSDT(Opt 1)。L2_Bridge 合約會銷毀 hToken(也就是 hUSDT),表示資產從 Rollup A 離開,並 emit event,讓 Bonder 知道。

2nd Tx

接著 Bonder 執行墊付,如果使用者要收 hUSDT,則合約會直接鑄造 hUSDT 給使用者,如果使用者要收 USDT,則會多一步,把鑄造的 hUSDT 去換成 USDT 再給使用者。

結果二:Bonder 沒有墊付

Unhappy case: 使用者要自己 relay transfer(i.e., withdraw) 資料到 Rollup B 來領取資產

這邊的步驟是接續在使用者已經透過 L2_Bridge 合約申請 withdraw 並銷毀 hToken 之後。

1st Tx

如果使用者的 withdraw 剛好是第 512 筆 withdraw,則會直接觸發 commitTransferRoot 函式,將 TransferRoot 送到 L1(那就不需要 1st Tx)。
如果不是的話,則他需要等到離 Bonder 上次 commit 時間的一天後才能自己去執行 commitTransfercommitTransfer 會去觸發 commitTransferRoot 函式,將 TransferRoot 送到 L1。

2nd Tx

接著就要等到 Rollup A 的挑戰期過後,才能完成 TransferRoot 到 L1 的寫入。假設今天該 TransferRoot 已經經過了七天挑戰期,則任何人都可以去把 TransferRoot 的跨鏈訊息 relay 到 L1_Bridge 合約,這筆交易會同時把 TransferRoot relay 到 Rollup B。

3rd Tx

通常等個五到十分鐘,TransferRoot 就會被 relay 到 Rollup B 上的 L2_Bridge 合約。等到 TransferRoot 被寫進 L2_Bridge 合約後,使用者就可以觸發合約的 withdraw 函式,提供 Merkle Proof 去證明自己的 withdraw 存在在這個 Merkle Tree 裡,這時合約就會直接鑄造 hUSDT 給使用者,完成 withdraw。

Bonder 視角的運作流程

第一步:流動性提供者先墊付

第一步是 Bonder 發現使用者在 Rollup A 上申請 withdraw (1st Tx)後,他在 Rollup B 去觸發 bondWithdrawalAndDistribute 函式(2nd Tx),墊付給使用者(看使用者是要收 USDT 或 hUSDT)。

你可能會以為墊付是 Bonder 將自己的 hToken 轉給使用者。但實際上的過程是:合約會鑄造新的 hToken 給使用者,然後在合約的帳本上記錄下該 Bonder 因為這筆墊付所新增的負債。

第二步:等待 TransferRoot 被 commit

Bonder 可以等待湊滿 512 個 withdraw 再開始 relay withdraw 資料。或是提前去 Rollup A 的L2_Bridge 合約觸發 commitTransfer,開始 relay withdraw 資料。當 Bonder 在 Rollup B 的負債多到他沒辦法再墊付後,他就可能會提前去觸發 commitTransfer

第三步:在 TransferRoot 被寫進 L1_Bridge 合約前,先為該 TransferRoot 做擔保

因為等待 Rollup A 挑戰期結束才能 relay TransferRoot 的時間可能太久了,會影響 Bonder 的資本效率(Bonder 在 Rollup B 上的負債要等到 TransferRoot 抵達才能抵銷),所以 Hop 做了一個 trade-off:引入一個 challenge 機制。

Bonder 可以為自己的 TransferRoot 擔保:不需要等到 Rollup A 挑戰期結束並把 TransferRoot 寫入 L1_Bridge 合約,就可以直接去觸發 bondTransferRoot1st Tx),把 TransferRoot relay 到 L2 的合約。等待五到十分鐘 TransferRoot 寫進 L2_Bridge 合約後,Bonder 就可以觸發 settleBondedWithdrawal2nd Tx),將之前墊付所累積的負債抵銷。

Bonder 在執行 bondTransferRoot時要順便抵押 TransferRoot總金額的 110%(10% 是當作 challenge 的獎金)。因此當一個 Bonder 擔保一個假的 TransferRoot,意圖在 Rollup B 抵銷負債被抓到時,他在 L1 會被沒收的金額會是他在 Rollup B 抵銷負債金額的 110%(也就是會賠 10%),所以想要造假是有風險在的。
註:TransferRoot總金額指的是這一批 withdraw 金額的加總

但如同其他 challenge 機制,challenge 也是有時效性的。目前如果 Bonder 觸發 bondTransferRoot 後,經過一小時都沒有人 challenge 的話,則該 TransferRoot 就會被視為合法,不能再被 challenge。

第四步(optional):Bonder 完成 TransferRoot 的 relay,將 TransferRoot 寫進 L1_Bridge 合約

等到 Rollup A 挑戰期過後,Bonder 就可以將 TransferRoot 的跨鏈訊息 relay 到 L1_Bridge 合約。但如果 Bonder 沒有被 challenge 的話,其實他沒有動機要完成 relay。不過只要 Bonder 擔保的是正確的 TransferRoot 或是 Bonder 造假 TransferRoot 都有被抓到的話,沒有完成 TransferRoot relay 不會影響系統的安全性。

當 TransferRoot 被 challenge

第一步:bondTransferRoot

首先,從 BonderbondTransferRoot 開始。

第二步:challenger 抵押 TransferRoot 總金額 10% 來挑戰 TransferRoot

如果 challenger 發現 Bonder 產生的 TransferRoot 不合法,例如裡面偷偷夾帶了不存在的 withdraw,則 challenger 可以透過抵押 TransferRoot 總金額的 10% 來進行 challenge(要在 bondTransferRoot 的一小時內進行 challenge)。

Challenge 被申請後,L1_Bridge 合約會把 Bonder 擔保的金額(TransferRoot 總金額的 110%)新增到 Bonder 的負債。
註:如果沒有被 challenge,系統就會放行,不以增加 Bonder 負債的方式來扣住 Bonder 資產。

如果 challenge 成功,則負債會保留,表示 Bonder 的錢被系統沒收;如果 challenge 失敗,系統會從 Bonder 負債中減去原本擔保的金額,表示系統將錢還給 Bonder。

第三步:等待 Rollup A 挑戰期結束,將真正的 TransferRoot 寫進 L1_Bridge 合約

等到 Rollup A 挑戰期過後,Bonder 或 Challenger 就可以將 TransferRoot relay 到 L1_Bridge 合約。但還不能 resolve challenge,Hop 有設定一個 challengeResolutionPeriod 來確保 challenge 可以 resolve 時,Rollup 挑戰期已經結束,意即確保 TransferRoot 已經被寫入 L1_Bridge 合約裡了。
註:目前 challengeResolutionPeriod是十天(要大於挑戰期)

第四步:等待 challengeResolutionPeriod 結束

真正的 TransferRoot 訊息抵達後就可以驗證 Bonder 當初擔保的 TransferRoot 是不是對的,決定 challenge 是否成立。

如果 challenge 不成立,系統會從 Bonder 負債中減去原本擔保的金額,表示系統將錢還給 Bonder。而 Challenger 的抵押則會被沒收。

如果 challenge 成立,則 Bonder 的負債會保留,表示 Bonder 的錢被系統沒收。Challenger 除了拿回自己的押金,還會獲得 Bonder 擔保金額當作 challenge 獎金的那 10%。
註:獎金其中有一半會被銷毀,目的是避免 Bonder 自己 challenge 自己,同時拿回完整的押金和獎金。

風險評估

使用者風險

如果 Bonder 有墊付給使用者,則使用者成功完成 withdraw,皆大歡喜。
如果 Bonder 沒有墊付給使用者,則使用者必須要自行完成 TransferRoot 的 relay,這會需要訊息能夠正確地從 Rollup A -> L1 -> Rollup B 傳遞。

不過只要 Hop 合約和 Rollup L1<->L2 messege bridge 都有順利接上,且 Rollup 都正常運作,就能夠達成,這是一個相對可靠的安全假設。所以對使用者來說,風險是相對小很多的。

Bonder 風險

因為 Bonder 們的錢都鎖在同一個合約,所以假設有 challenge 沒被抓到,則代表攻擊者可以憑空降低自己的負債、提走不該提走的錢,這對所有 Bonder 都會造成損失(但使用者不會被影響)。

而目前一小時的 challenge window 其實是相對短暫的,再加上一個 withdraw 可以是從任意 Rollup 轉任意資產到任意其他 Rollup,要假設整個系統內所有的 withdraw 都能被監控會是一個具有挑戰性的要求(例如某些 Bonder 可能只會在某些 Rollup 上提供流動性,所以他們可能只會監控那些 Rollup 之間的 withdraw)。

--

--