According to NUMEN’s on-chain monitoring, on February 9th, 2023 at 11:10:22 PM +UTC, dForce on the Optimistic and Arbitrum chains were attacked through flash loans, resulting in the loss of 2,364 ETH, 1.03 million USDC, and 720,000 USX, valued at approximately $5.4 million.
Attacker’s address: 0xe0d551017c0111ac11108641771897aa33b2817c
Attacker’s contract: 0xee29b6aee6e4783db176946e4e8f1e5fdcd446a7
Attack transaction: 0x5db5c2400ab56db697b3cc9aa02a05deab658e1438ce2f8692ca009cc45171dd
The attacker first obtained an initial fund of 68,000 ETH through nine flash loan attacks. Then, they added liquidity through the Vyper contract ‘AddLiquidity’ to acquire 65,000 wstETHCRV.
He then staked 1,900 wstETHCRV to receive 1,900 wstETHCRV-gauge and 2.08 million USX.
Then, the attacker called the ‘raw_call(msg.sender)’ attack contract in the Vyper contract’s ‘remove_liquidity’ operation, and subsequently called ‘vMUSX.liquidateBorrow’ through the attack contract to perform two liquidations.
Next, he called the function ‘remove_liquidity’ on the Vyper contract to extract the profitable liquidity funds. He converted the funds into ETH, repaid the flash loan, and exited the market with a profit.
Core of the Vulnerability
The crucial inquiry lies in the Vyper contract’s ‘remove_liquidity’ and ‘get_virtual_price’ functions, which can be found at the following address: https://arbiscan.io/address/0x6eb2dc694eb516b16dc9fbc678c60052bbdd7d80#code.
Start by examining the ‘remove_liquidity’ function.
Upon removing liquidity, the caller will first receive ETH, followed by the destruction of their LP Token.
The attacker takes advantage of two issues:
- When sending ETH to the attacker’s contract, the fallback function is triggered, which calls other methods.
- During the callback, the LP Token total has not been updated, resulting in an incorrect price calculation.
The attacker utilized the ‘get_virtual_price’ method from the Vyper contract to retrieve the price when calling the ‘liquidateBorrow’ function on vMUSX.
Next, review the ‘get_virtual_price’ function.
Since the LP Token was not destroyed before withdrawing liquidity, the attacker was able to use the ‘get_virtual_price’ as the price when executing the liquidation. This is because the LP Token total was not decreased when calculating the price, meaning the token supply increased, leading to a smaller final price.
The attacker took advantage of the LP Token total that had not been updated, and ultimately liquidated it.
After the flash loan callback is executed, log the amount of profit.
Use consistent call stack data.
NUMEN Lab reminds the project stakeholders to maintain strict control over token prices. When aggregating multiple feed prices, it’s important to evaluate the reasonableness of price calculation and assess the risk of being influenced by feed prices.
First, examine the logic of the contract code, then write variables, and finally make external calls following the Checks-Effects-Interactions pattern, to enhance the security and stability of the project.
Before the contract goes live, multiple security audits are required to minimize contract risks off-chain.
If you wish to audit and ensure that your projects are free from exploits such as these, please reach out to us here.
Numen Cyber Labs is committed to facilitating the safe development of Web 3.0. We are dedicated to the security of the blockchain ecosystem, as well as operating systems & browser/mobile security. We regularly disseminate analyses on topics such as these, please stay tuned or visit our blog here for more!