背景介紹
近期,我們監測到一次Arbitrum 鏈上攻擊事件,
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb
被攻擊的項目是Ramses Exchange ,攻擊總造成約27 ETH 的損失,約70,000 USD 。 Ramses是在Arbitrum 上推出的新型去中心化自動做市商(AMM) 。該協議透過RAM 代幣和veNFT 運行。
攻擊及事件分析
本次攻擊共分為兩筆交易,第一筆交易為前置的操作,交易hash為:
https://arbiscan.io/tx/0xa0795952a09f4aeaacf0abb213dedeaa7b7dd71c04eaa3fd22db33957e1c724c,我們稱為交易A;
第二筆交易為正式的攻擊交易,交易hash為
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb,我們稱為交易B。
交易A的主要行為:
首先,攻擊者將0.0001 ETH 利用deposit 兌換成WETH,
隨後,攻擊者使用0.0001 WETH 使用Ramses Exchange 兌換成RAM。
最後,攻擊者利用create_lock 將1 RAM 鎖定,並獲得一個id 為18785 的veNFT (在攻擊時會用到),作為鎖定憑證。
交易B的主要行為:
攻擊者首先查看了Ramses Exchange 所有池子的WETH 餘額,
接著,利用閃電貸從uniswapV3 上貸了12.2 WETH,
隨後,攻擊者利用Ramses 的Bribe機制向每個池子轉入與之WETH 餘額相等的WETH (為了後面將池子中所有的WETH 取出)。
然後,攻擊者透過vote 給對應的交易池投票,
接著,攻擊者透過getPeriodReward 獲取投票的激勵,
我們來看看getPeriodReward 的具體實現,
由於攻擊者在攻擊交易A中,獲得了id為18785的veNFT,所以IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, 18785) 為true。接著,可以看到_getReward的程式碼如下:
隨後,攻擊者利用reset 撤回針對上述交易池的投票。
接著,再利用split 將id 為18785 的veNFT 其中lock 的0.99999 RAM 分割出一個的id 為18787 的新的veNFT 。漏洞就出在這裡,當攻擊者利用split 分割出一個新的veNFT 時,又可以利用對應lock 的RAM 進行投票,獲取獎勵,沒有驗證這筆lock 的資金是否已經領取過獎勵。所以攻擊者可以重複利用reset 重置投票,再利用split 分割出一個新的veNFT ,再利用vote投票,最後用getPeriodReward 取得投票的獎勵。
攻擊者針對USDC 和ARB 對應的交易對同樣實施了相同的攻擊。
總結
這次漏洞的成因是在Ramses Exchange 在發放lock RAM 對應的獎勵時,並沒有驗證這筆lock的資金是否已經領過獎勵。導致攻擊者可以利用reset 和split 切分veNFT 重複領取獎勵。建議專案方在設計經濟模型和程式碼運作邏輯時要多方驗證,合約上線前審計時盡量選擇多個審計公司交叉審計。