近來以太坊上最火爆的領域就是 DeFi。主要的 DeFi 應用包括 ERC20 代幣的借貸、質押和交易,若想在 Uniswap、Aave 和 Yearn 等DeFi 協議上使用 ERC20 代幣,你需要授權 dApp 來使用這些代幣。這就是所謂的 *ERC20 授權* 。這些授權對于 DeFi 平臺的運作來說必不可少,但是如果不加以控制,那將是非常危險的,
ERC20 授權的必要性
有了以太坊上的原生代幣 ETH,你就可以將 ETH 發送至該智能合約,同時調用智能合約功能。這是通過所謂的可支付函數(payable funtion)實現的,但是,由于 ERC20 代幣本身就是智能合約,你無法通過直接將代幣發送到智能合約來調用其函數,
因此,ERC20 標準讓智能合約使用 transferFrom() 函數代表用戶轉移代幣,為此,用戶需要允許智能合約代表他們轉移代幣。
這樣一來,用戶就可以將代幣“存入”智能合約,同時智能合約會更新其狀態來顯示這筆存款,相反,如果你將 ERC20 代幣發送至該智能合約,則合約不會更新其狀態(例如,將這筆存款記入你的賬戶),
例如,如果你將 DAI “存入” Aave 來賺取利息,你首先要允許 Aave 合約從你的錢包中取出一些 DAI,然后你調用 Aave 合約里的函數,指定你想要存入的 DAI 的數量,然后,Aave 合約使用 transferFrom() 函數從你的錢包中取出相應數量的 DAI,并將同等數量的 aDAI 代幣記入你的賬戶,
無限 ERC20 授權的危害
將特定數量的 ERC20 代幣(如 100 DAI)存入合約時,你就可以選擇將授權額設成這個數量。然而,許多應用會向用戶要求無限授權。
這會帶來極好的用戶體驗,因為用戶不需要在每次存款時重新授權。設置無限授權后,用戶只需要同意一次,之后存款時就不會再重復這一過程,
但是,該設置存在很大的弊端,眾所周知,即使是成熟的項目,也有可能存在漏洞。一旦你給了這些平臺無限授權,不只是你的存款會陷入風險之中,你的錢包中的代幣也是如此,
在 Devcon 5 上,我第一次與 Paul Berg 談到了這個問題。在這次大會上,Paul 就本文所討論的問題做了陳述,在開發 Sablier 時,Paul 在他的智能合約中發現了一個漏洞(已經修復了!),不僅所有存入該智能合約的 DAI(100 美元)有風險,所有測試者的錢包中的 DAI(1 萬美元) 也是如此!
實際風險
長期以來,無限授權的風險主要是理論上的。在 Paul 所開發的 Sablier 平臺正式上線之前,這個漏洞就被修復了,當時,還沒有出現利用 ERC20 授權的攻擊,但是只要平臺繼續要求無限授權,遲早會出狀況,
去年,我們已經看到了幾起利用 ERC20 授權的攻擊事件。
意外漏洞
今年早些時候,Bancor 出現了一個漏洞,危及用戶資金,執行 ERC20 transferFrom() 函數的函數變成了 public 屬性(不再是 private 合約私有屬性),因此任何人都可以執行該函數,并取走用戶錢包中的資金。Bancor 執行了一次白帽黑客攻擊,控制了損失,并將資金還給了用戶,
惡意利用漏洞
除了 Bancor 的意外漏洞之外,還有很多惡意利用漏洞的情況。在今年夏天的 DeFi 熱潮中,人們都在為各種以食物命名的 DeFi 分叉產品狂歡,其中也包括一些騙局,即使人們為了規避風險只存入少量代幣,他們錢包中的代幣也會因為無限授權而陷入風險,
ZenGo 就在一個名為 UniCats 的項目中發現了可利用漏洞。人們可以存入 Uniswap(UNI)代幣,然后通過流動性挖礦獲得 MEOW 代幣(MEOW 代幣是無法偽造的)。但是如果要存款,用戶必須提供 無限授權。如果項目遭到攻擊,攻擊者不僅可以拿走項目的存款,還可以拿走用戶錢包內的所有 UNI 代幣,
另一個例子是 Degen Money 項目,Degen Money 項目采用了一種不怎么高明(但還挺 “有效”)的辦法,這個項目沒有開發自己的智能合約,而是創建了一個前端來進行兩次授權交易,一次是向一個運行中的智能合約,另一次是向完全不同的地址。
由于很多人沒有專門檢查錢包地址,這就導致攻擊者可以取走用戶錢包中的代幣,
那硬件錢包呢?
總的來說,硬件錢包比行動電話、手提電腦和基于瀏覽器的錢包安全的多。原因是,控制資金的私鑰安全地存儲在硬件錢包中,并且永遠不會離開該設備。因此,通過硬件錢包,你可以確保沒人能竊取你的私鑰。
ERC20 授權的問題在于,沒人需要竊取你的私鑰才能從你的錢包中取走代幣。因此,硬件錢包也無法防范本文所討論的惡意利用漏洞問題,
使用硬件錢包依然是一種好習慣,因為硬件錢包確實能保護你免受其它漏洞攻擊。但是,你需要注意的是,硬件錢包不能抵御授權漏洞和其它很多智能合約漏洞,
dApp 開發者可以做些什么?
在 Devcon 的講話中,Paul 提到了一些關于無限授權問題的解決方案,這些方案各有優缺點,其中最實用的方案是即批即用模式。在這種模式下,應用只會要求用戶授權確切的數額,而非不限額。
這種方案的用戶體驗確實會差一些,因為每當用戶想要發送交易時,都需要發送一筆新的授權交易,不能再像無限授權那樣一勞永逸。這個模式的缺陷是會增加交易費成本,如果交易費像去年那樣暴漲,就會帶來很大的麻煩,
另一種替代型方案是,可以讓用戶選擇僅授權當下需要花費的數額,還是授權更高的數額以便后續進行更多交易。已經有多個項目采用這種策略,例如 1inch.exchange 和 Curve.fi。
另一個減少交易成本的解決方案是,采用 EIP2612 之類的標準,讓用戶可以通過簽署消息來(免費)設置其授權額度,無需再通過發送交易的形式。但是,這類標準并未得到廣泛采用,而且圍繞該標準打造的工具也不多。
用戶可以做些什么?
由于 ERC20 授權是很多智能合約所不可或缺的部分,完全停止授權的方案并不可行。但是在可能的情況下,請盡量避免無限授權。
人們已經比一年之前更加了解這一問題,因此有些 dApp 可以讓用戶選擇只授權當前需要花費的數額,但是大多數 dApp 依然不行。盡管如此,高端用戶還可以通過 Metamask 的界面來降低其授權額度。
在使用 dApp 時,請你思考一下是否需要經常使用這個 dApp,以及你是否信任這個項目(如果是,選擇無限授權),還是說你只會偶爾使用這個 dApp,或者根本不信任這個項目(如果是,選擇小額授權)。無論是哪種情況,你最好都要定期(如,每月)查看你的授權額度,并取消對不再使用的 dApp 的授權,
為便于檢查并撤銷這些授權,我開發了一種名為 revoke.cash 的工具。通過這個工具,你可以查看地址的代幣余額和授權額度,之后就可以輕而易舉地撤銷或降低授權,類似的工具還有 approved.zone 等。
結論
許多去中心化應用的運行都離不開授權,但是無限授權通常并不利于安全性,2020 年已經出現過幾起利用 ERC20 授權的漏洞事件,人們對這個問題的認識比一年前深得多。作為一名用戶,你可以采取一些措施來降低上文所述風險,包括定期查看并撤銷多余授權。