老調重彈:解析「通縮型代幣」的兼容性問題

此次抽池的核心問題在於“通縮映射型代幣”與項目合約不兼容所導致的。

By:flush@慢霧安全團隊

據慢霧區情報,MDEX 的XSquid 和HT 代幣池子中HT 代幣在沒有進行swap 的情況下被頻繁抽取,慢霧安全團隊對此介入分析,並將簡要分析分享如下。

攻擊核心

本次攻擊的核心在於利用XSquid 映射通縮型代幣的模型,在轉賬後會發生通縮,自身合約所獲取的balanceOf 與通過Mdex pair 池所獲取到的reserve 不匹配的問題,使得攻擊者可以抽取池中的HT 代幣。

攻擊細節

由鏈上分析工具我們可以看到,這筆交易中Mdex pair 池最終向攻擊者轉移了0.003 枚WHT 代幣,而鏈上的交易記錄顯示還有很多筆這樣的交易與之相同。

圖片

接下來我們仔細觀察這筆交易的細節,這是一個XSquid 和HT 的Mdex Pair 池,在對XSquid 進行swap 轉賬前pair 合約通過getReserves 接口所獲取到池子中_reserve0 為1010.505640800917497232。但在下一步通過XSquid 合約的balanceOf 獲取pair 餘額後我們卻發現結果為1010.5060773394782 ,數量上存在明顯的差異。

圖片圖片

但是在最後一次更新reserve 之後並沒有用戶向合約中進行轉賬。於是我們就可以定位到,是在balancOf 獲取時造成的誤差。於是我們開始查看XSquid 合約,並定位到balanceOf 函數合約的715 行。通過函數的一步步跟踪balanceOf。

圖片圖片

其中balanceOf 調用了tokenFromReflection 來獲取。而tokenFromReflection 函數中傳入的是所映射的rAmount.div(currentRate)。 currentRate 又是由_getRate 函數決定的。通過_getRate 我們接著跟踪到_getCurrentSupply 函數。

圖片圖片

圖片圖片

根據一步步的定位我們發現,合約中代幣的_tTotal 總量是不會發生變化的,最終影響_getCurrentSupply 輸出結果的是由於_rTotal 值的變化而造成的。從合約我們發現XSquid 是映射通縮型代幣,而在每一次轉賬時計算_rTotal 都會由_reflectFee 產生通縮使得_rTotal 值減少,而造成currentRate 因此減少,而rAmount.div(currentRate) 增大,最終造成所獲取到的balanceOf 大於getReserves 所獲取到的值。

圖片圖片

圖片圖片

這樣就造成了一種假象,使得池子認為外部又多打入了XSquid 進來。這時攻擊者只需要調用Mdex Pair 合約的swap 函數根據上訴計算的差額來抽取代幣,或者是調用skim 函數直接轉走代幣。由此,可從池子中抽離這一小部分“多餘”而不屬於他的HT。對此,我們可以在每次轉賬最後通過調用sync 函數強制準備金與餘額匹配同步更新,來避免以上不匹配的問題。

總結

此次抽池的核心問題在於“通縮映射型代幣”與項目合約不兼容所導致的。而代幣與DeFi 項目合約代碼不兼容所導致的安全問題已是重複出現的老問題了,慢霧安全團隊再次提醒:由於DeFi 項目需要多個合約間進行交互,在進行設計時項目方應充分考慮不同合約間交互的兼容性問題,並確保交易對與項⽬是相互兼容的。

展開全文打開碳鏈價值APP 查看更多精彩資訊

Total
0
Shares
Related Posts