Introduce Yearn Allowlist
Yearn 在 2022/5/6 宣佈他們建立 Yearn Allowlist 來增加產品的安全性。於是做了一些研究想了解 Allowlist 是如何來增加產品安全性。
應用場景
主要用來避免中間人 (man-in-the-middle) 攻擊。e.g., 一般來說使用者會呼叫 paraswap API 得到 txdata 並將把包成 transaction 並送出。若所回傳 txdata 有被中間駭客惡意竄改,可能會導致使用者的資產損失。此時就可以呼叫 paraswap 所定義的 allowlist 來判斷回傳 txdata 是否正確。(這邊只是舉例,筆者 paraswap 並不確定 paraswap 是否有使用 allowlist)
Allowlist 定義一個架構讓別人可以建立自己的 allowlist。allowlist 由複數個 condition 組成。當 txdata 符合其中一個 condition 的條件就算合法。
Flow
Condition
一個 condition 會對應一個 impelmenation contract 裡的 function。condition 定義了一連串資料(包含檢查的 function, implementation id…)每一個 condition 格式如下圖所示
id
: condition id。implementationId
: 一個 id 對應一個 implementation contract address。id 和 contract address 對應存放在 allowlist contract 中的imlementationById
map 中。methodName
: 要呼叫的 target contract 的 method name。paramTypes
: the types of the function arguments。requirements
: 有分成兩部份(type 和 verify function)。types 有分成target
(檢查 target contract)和params
(檢查 function 參數)兩種。verify function 則是指要用哪個 implementation function 檢查。
程式碼中 validateCalldataByAllowlist()
檢查每一個在 Allowlist 有註冊的 condition。 testCondition()
會去利用之前先註冊 condition 去做檢驗,包含 implemenationId, requirements 或 targetAddress 等。
檢查順序
檢查 function selector
用 condition 的 methodName
和 paramTypes
來算出 function selector 去比對 txdata 前四個 bytes
檢查 target address
如果 requirement type 是 target
就會呼叫 checkTarget()
。利用 methodSignature
和 targetAddress
去產生 txdata,並用 staticCall 去呼叫 implementation 的 verify function。
檢查 function parameters
如果 requirement type 是 params
就會呼叫 checkParams()
。利用 AbiDecoder.getParamFromCalldata()
以及 data
和 paramsTypes
去解出參數的值。
把verify function ( methodSignature
) 加上剛剛解出來 params 的值組成一個 txdata。使用 staticCall 去呼叫 implementation 的 verify function。
Connect Allowlist to website
建議可以使用 ENS/DNSSEC 來驗證 Allowlist 的正當性
Personal Thoughts
DApp 日漸複雜,若所有的計算都是在鏈上完成,想必會花費許多 gas。鏈下的 API 未來可能會變成一種替代方案,但這又會衍生出其他安全性的問題。 Allowlist 就是嘗試去解決鏈下資料和鏈上資料不一致的情形。當所有有提供 API 的服務,建議都有建立一套 Allowlist 機制來降低風險,以防有心人士攻擊而造成使用者資產損失。