Background
Recently, we detected an Arbitrum chain attack.
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb
The project attacked was Ramses Exchange , and the attack caused a total loss of about 27 ETH, about 70,000 USD. Ramses is a new decentralized automated market maker (AMM) launched on Arbitrum. The protocol runs through RAM tokens and veNFT.
Attack and incident analysis
This attack is divided into two transactions. The first transaction is the pre-operation, and the transaction hash is:
https://arbiscan.io/tx/0xa0795952a09f4aeaacf0abb213dedeaa7b7dd71c04eaa3fd22db33957e1c724c, which we call transaction A;
The second transaction is the formal attack transaction, and the transaction hash is
https://arbiscan.io/tx/0xb91c4e0debaf0feb1f20c979eebc1282c8024ae299ef5903591badcf1f4938bb, which we call transaction B.
The main actions of transaction A:
First, the attacker uses deposit to convert 0.0001 ETH into WETH.
The attacker then used 0.0001 WETH to redeem RAM using Ramses Exchange.
Finally, the attacker uses create_lock to lock 1 RAM and obtains a veNFT with id 18785 (which will be used in the attack) as a locking credential.
The main actions of transaction B:
The attacker first checked the WETH balances of all Ramses Exchange pools.
Then, I borrowed 12.2 WETH from uniswapV3 using a flash loan.
The attacker then used Ramses' Bribe mechanism to transfer WETH to each pool equal to its WETH balance (in order to withdraw all WETH from the pool later).
Then, the attacker votes for the corresponding transaction pool through vote.
Next, the attacker obtains the voting incentive through getPeriodReward.
Let's take a look at the specific implementation of getPeriodReward.
Since the attacker obtained the veNFT with id 18785 in attack transaction A, IVotingEscrow(_ve).isApprovedOrOwner(msg.sender, 18785) is true. Next, you can see the code of _getReward as follows:
Subsequently, the attacker used reset to withdraw the vote for the above transaction pool.
Next, split is used to split the 0.99999 RAM locked in the veNFT with id 18785 into a new veNFT with id 18787. This is where the vulnerability lies. When the attacker uses split to split a new veNFT, he can use the corresponding locked RAM to vote and get rewards without verifying whether the locked funds have been rewarded. Therefore, the attacker can repeatedly use reset to reset the vote, then use split to split a new veNFT, then use vote to vote, and finally use getPeriodReward to get the voting reward.
The attacker also carried out the same attack on the corresponding trading pairs of USDC and ARB.
Summarize
The cause of this vulnerability is that when Ramses Exchange issued rewards corresponding to lock RAM, it did not verify whether the locked funds had been used as rewards. As a result, attackers could use reset and split veNFT to repeatedly claim rewards. It is recommended that project owners conduct multi-party verification when designing economic models and code operation logic, and try to select multiple audit companies for cross-audit when auditing contracts before going online.