2021 年 11 ⽉ 30 ⽇,DeFi 平台 MonoX Finance 遭遇攻擊,損失共計約 3100 萬美元。
造成本次攻擊的漏洞主要有兩個:
移除流動性的函數未對調用者進行檢測,使得任何使用者都可以移除提供者的流動性。
代币交換函數未對傳入的币對進行檢測,可通過傳入相同的币種擡高該币價格。
攻擊者位址:0xecbe385f78041895c311070f344b55bfaa953258
攻擊合約:0xf079d7911c13369e7fd85607970036d2883afcfd
攻擊交易(block@13715025):
https://etherscan.io/tx/0x9f14d093a2349de08f02fc0fb018dadb449351d0cdb7d0738ff69cc6fef5f299
攻擊者位址 2:0x8f6a86f3ab015f4d03ddb13abb02710e6d7ab31b
攻擊合約 2:0x119914de3ae03256fd58b66cd6b8c6a12c70cfb2
攻擊交易 2:
https://polygonscan.com/tx/0x5a03b9c03eedcb9ec6e70c6841eaa4976a732d050a6218969e39483bb3004d5d
兩個網絡上的攻擊手段相同,在本文中隻對以太坊網絡的攻擊進行分析。
首先通過閱讀官方文檔對整個項目進行了解:MonoX docs
攻擊的交易資訊:【ethtx】0x9f14d093a2349de08f02fc0fb018dadb449351d0cdb7d0738ff69cc6fef5f299
以下是關鍵點摘要:
Single Token Liquidity pools function by grouping the deposited token into a virtual pair with our <code>virtual USD stablecoin (vCASH)</code>, instead of having the liquidity provider deposit multiple pool pairs, they only have to deposit one.
<code>All the pools/pairs are in the same ERC1155 contract</code>. Monoswap
In exchange for providing liquidity, the LP receives their share of the liquidity reserve and the <code>ERC1155 LP token</code>. Liquidity providers receive a share of the fees proportional to their share of the liquidity reserve.
When one removes liquidity from the pool for Token A, the price of the token stays the same. <code>The pool burns the liquidity provider’s ERC 1155 LP token</code>. In exchange, the pool transfers to the user their share of Token A’s virtual pair’s net value. When the vCASH balance is <code>positive</code>, the user will get their share of vCASH plus their share of Token A. When the vCASH balance is <code>negative</code>, the user will receive their share of Token A, minus their share of vCASH debt valued in Token A.
LPs providing liquidity in selected/promo pools will get non-transferrable <code>$MONO</code> shares. <code>MONO-ERC20</code>
Monoswap address: 0xC36a7887786389405EA8DA0B87602Ae3902B88A1
MonoXPool address: 0x59653E37F8c491C3Be36e5DD4D503Ca32B5ab2f4
MONO address: 0x2920f7d6134f4669343e70122cA9b8f19Ef8fa5D
vCASH address: 0x532D7ebE4556216490c9d03460214b58e4933454
攻擊的目的是極大地提高 MONO 的價格,然後用 MONO 通過 MonoSwap 換取其他代币
攻擊合約向 WETH 存 0.1 個 ETH,并授權給 Monoswap 的代理合約
用 0.1 WETH 從 Monoswap 中換出 79.986094311542621010 MONO
調用 Monoswap 的 pools 函數,查詢 MONO-vCash 的相關資訊
調用 MonoXPool 的 totalSupplyOf 函數, 查詢 MONO-vCash 池子中作為 LP 證明的 MONO 的總量。
調用 MonoXPool 的 balanceOf 函數,查詢提供大量流動性的使用者(要移除流動性的目标)在 MONO-vCash 池子中作為 LP 證明的 MONO 數量。提供流動性的使用者可以在其 token 頁面找到(隻有三位使用者提供了流動性)。
移除提供大量流動性的使用者的流動性,使得池中的 vCash 為 0 ,MONO 為 0 。
往 MONO-vCash 池中添加流動性 196875656 MONO 。獲得 927 liquidity .
調用 55 次 Monoswap.swapExactTokenForToken 函數, 其中 tokenIn=MONO, tokenOut=MONO 。此舉的目的是為了提高 MONO 的價格,使得 amountOut > amountIn 。此時的 MONO 價格已經大幅度上升到了 843741636512366463585990541128 。
然後通過調用 swapTokenForExactToken 函數,以高價的 MONO 換空池中的其他代币,達到獲利的目的。
removeLiquidity 函數未對調用者進行檢測,使得任何使用者都可以移除提供者的流動性。
整體的代碼流程如圖。通過傳入相同的代币(tokenIn=MONO, tokenOut=MONO),大幅拉升該代币的價格。
swapExactTokenForToken 函數
跟入 swapIn 函數
getAmountOut函數
_getNewPrice函數
_getAvgPrice函數
要設定 <code>-l</code> gas limit,否則會不夠用。
導入賬戶
部署合約,并往合約轉入 0.1 eth
依次調用攻擊合約中的攻擊函數
攻擊結果
【github】W2Ning/MonoX_Vul_
【慢霧】DeFi 平台 MonoX Finance 被黑分析
【MonoX】MonoX docs
【ethtx】0x9f14d093a2349de08f02fc0fb018dadb449351d0cdb7d0738ff69cc6fef5f299