通縮幣頻遭閃電貸攻擊,罪魁禍首竟是獎勵分配機制?

通縮幣頻遭閃電貸攻擊,罪魁禍首竟是獎勵分配機制?

近日,CertiK 監測到兩起針對 FETA 以及 BEVO 反射機制的通縮幣專案的閃電貸攻擊事件。為幫助讀者對此類攻擊事件有更全面的瞭解,本文將對此類通縮幣專案的背景、攻擊過程、攻擊原理以及防範方法進行具體分析並總結,期望各位讀者能對該型別攻擊有較為深入的理解和啟發。

背景

通縮幣是一種隨著交易進行不斷有 token 被銷燬,發行總量因此不斷減少進而實現潛在升值的數字貨幣。

隨著 2021 年 Safemoon 專案的一炮而紅,通縮幣專案在當時幾乎橫掃主流的 ERC 20 專案,備受矚目。

對於通縮機制本身,大部分專案都使用了 Reflect 這一最經典的通縮獎勵分配機制。Reflect 機制即“反射”機制,可以將通縮產生的收益讓所有的持幣者根據持幣量平均分配。在該機制下,使用者手裡的 token 有了兩種計量方式,即:“反射”前的實際 token 數量,和“反射”後的反射 token 數量。

該機制中,通縮的來源是對於 token 交易者的懲罰性稅收,在每次交易時對交易賬戶“反射”後的 token 數量進行一定比例的收稅和銷燬,從而改變了“反射”的比率,使得每個普通持幣者都可以獲得更多的“反射”前的 token 作為獎勵。

由此可見,Reflect 是一種靜態獎勵機制,為了鼓勵長期持幣者而懲罰頻繁交易者,使得更多使用者願意持有和參與,最終促使幣價趨於穩中有升的態勢。

有趣的是,包含 Reflect 機制的智慧合約很多都會加入一個函式,即`deliver()`。該函式的作用是呼叫者以“犧牲自我”的方式,直接銷燬自己的 token,從而改變“反射”機制的比率,使每一位持幣者得到獎勵。

這種犧牲自我利益為所有持幣者謀福利的做法不失為一種“慈善捐贈”,呼叫這個函式的人就好像“天使”一般。然而,天使的背後也有可能是魔鬼。CertiK 最近監測到的兩起攻擊事件,正是利用了`deliver()`函式改變“反射”機制的比率,對通縮幣在去中心化交易所的交易對地址發起了閃電貸攻擊,盜走交易對中的大額 WBNB。

攻擊案例分析

2023 年 1 月 31 日,CertiK 監測到通縮幣專案 FETA 遭受到閃電貸攻擊。攻擊者透過閃電貸借到 18.5 個 WBNB 後,透過呼叫 FETA 的`deliver()`函式以及去中心化交易所中 FETA-WBNB 交易對合約的`skim()`函式,在歸還閃電貸借款之後仍獲利 10.34 個 WBNB。

無獨有偶,在前一日,CertiK 還監測到另外一起類似的閃電貸攻擊事件,被攻擊物件是通縮幣專案 BEVO,攻擊者透過類似的方法獲利 144 個 WBNB。

這兩起攻擊事件看上去彷彿只需呼叫兩個十分普通的函式就可以攻擊成功,那麼這種“魔法”究竟是怎麼施展的呢?

我們不難發現,對於普通使用者地址而言,反射機制的邏輯以及`deliver()`函式的邏輯都是沒有問題的,甚至是非常高明的獎勵機制,否則通縮幣專案也不可能如此受到認可。問題恰恰在於“不那麼普通”的地址——下面我們看看如果對去中心化交易所的交易對地址使用了“反射”機制究竟會發生什麼。

首先,根據“反射”機制的程式碼可知,在“反射”前後,使用者的 token 數量是透過乘以一個比率 rate 來相互轉化的,若我們設“反射”前的 token 數量為 tAmount,“反射”後的 token 數量為 rAmount,則有

其中 rate 系兩種計量方式的總量之比,即

把 rate 帶入,我們可以得到使用者的實際 token 數量

對於所有加入“反射”機制的地址,由於每次有交易者在交易時都會交稅並透過銷燬減少一些 rTotal,根據公式,在 rAmount、tTotal 不變的情況下,tAmount 將會增加,即實現了靜態持有時的增值。

`deliver()`函式可以直接減少 rTotal,同時保持 tTotal 不變 ,此時 rate 將會極具下降。若此時關注該 token 在去中心化交易所的交易對地址 pair,則 pair 對應的 balance,即用 tAmount 衡量的 token 數量會大幅增長。

而去中心化交易所的交易對智慧合約作為數字貨幣的交換池,儲存了大量該交易對的兩種 token,例如 BEVO-WBNB。該智慧合約提供了一個函式`skim()`,可以讓使用者把合約中 token 的 balance 數值和交換池中實際儲存的 token 數量 reserve 的差值取出來,正是這個方法讓攻擊者發現了套利空間。

根據上文所述,當呼叫`deliver()`函式時,rTotal 減少會帶動 pair 的 balance,即用 tAmount 衡量的 token 數量的大幅增長,然而 pair 裡面實際儲存的 token 數量 reserve 並沒有發生變化,此時,兩部分的差值全部會被攻擊者呼叫`skim()`全部取出來。

然而想要呼叫`deliver()`函式,即完成初始的“捐款”,是需要啟動資金的。對於攻擊者來說,方法總比困難多——方法即為我們平時經常聽說的閃電貸。

也就是說,攻擊者只需在一個區塊之內將錢還上,就可以借到大量的錢用`deliver()`函式操縱交易對的 balance。最終,只要透過`skim()`取出來並換成 WBNB 的錢比借到的錢多,攻擊者就完成了一次無風險套利。

總攻擊過程如下圖所示:

攻擊防禦

知道了原理,那又該怎麼預防呢?

能夠帶來嚴重損失的漏洞,或許在事情發生前就進行預防,並不十分複雜。根據 CertiK 安全專家的分析,攻擊者要想鑽空子,需要能夠改變合約中 rTotal 的數量,進而操縱合約中交易對的 balance。

在此,CertiK 專家建議:

要麼在設計合約的時候直接剔除有風險的`deliver()`函式,要麼直接將交易對地址剔除 Reflect 機制,即在程式碼中或合約部署後,呼叫`excludeFromReward()`將 pair 地址填入,使其剔除反射獎勵機制即可。此時 pair 的 balance 將無法被攻擊者透過`deliver()`函式所操縱。

寫在最後

CertiK 透過兩起最近發生的通縮幣閃電貸攻擊事件,詳細講述了包含 Reflect 機制的通縮幣被攻擊的原理和預防方法,希望能給各位讀者有所啟示。

通縮幣作為最常見也是最經典的數字貨幣型別之一,至今仍然能被攻擊者抓住漏洞進行攻擊,主要原因也是專案方在智慧合約設計時僅考慮到數字貨幣自身的智慧合約邏輯,卻並未深入研究與去中心化交易所合約互動的過程,才釀成了如此的損失。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *