The recent Curve pool vulnerability is different from previous cryptocurrency hacks we have seen because this time the problem was not directly related to a vulnerability in the smart contract itself, but rather to the underlying compiler of the programming language used, Vyper.
Vyper is a smart contract programming language that uses a Python-like style and is specifically designed to interact with the Ethereum Virtual Machine (EVM).
The impact of this vulnerability was so severe that there were news reports of huge losses every day. The situation seems to be under control now, but not before hackers stole more than $70 million. According to LlamaRisk's post-assessment, some DeFi project pools were also hacked, including PEGD's pETH/ETH pool, which lost $11 million, Metronome's msETH/ETH pool, which lost $3.4 million, Alchemix's alETH/ETH pool, which lost $22.6 million, and Curve DAO pool, which lost about $24.7 million.
The vulnerability is called a reentrancy error, and it mainly appears in some versions of the Vyper programming language, especially v0.2.15, v0.2.16, and v0.3.0. So projects using these specific versions of Vyper may become targets of attacks.
What is reentrancy?
To understand why this vulnerability occurs, let's first understand what reentrancy is and how it works.
Reentrancy means that a function can be interrupted during execution and can be safely called again before the previous call is completed. This mechanism is often used in applications such as hardware interrupt processing and recursion.
In order for a function to be reentrant, it needs to meet a few conditions:
First, it cannot use global and static data. This is a convention that means that when a function is executed, do not rely on global data or static variables. Because if a function is interrupted during execution and then called again, global and static data may be destroyed or lose information.
Second, it cannot modify its own code. Whenever a function is interrupted, it should be able to continue executing in the same way. If a function modifies its own code during execution, errors may occur when it is called again.
Finally, it cannot call other functions that are not reentrant. In other words, in a reentrant function, other functions that may not be reentrant should not be called. Because if you do so, it may cause unpredictable results, causing the program to crash or errors.
It's too hard to understand, so we won't go into detail.
How was it exploited?
Let’s explain how reentrancy attacks lead to stolen funds and the loss of $70 million in the Curve attack.
First of all, we know that a reentrancy attack is a method where a malicious contract repeatedly calls a function in a smart contract. In the Curve attack, this function is used to withdraw the user's liquidity in the pool. This function has a vulnerability that does not do enough checks before updating the amount.
Let's look at the attack flow:
Assume a vulnerable smart contract has 10 ether.
The attacker calls the deposit function and deposits 1 ether.
The attacker then calls the withdrawal function to withdraw 1 ether. In this function, it checks whether there is 1 ether in the attacker's account.
However, this function did not update the balance in the contract before transferring 1 ether to the attacker's account. This means that the contract still believes there are 10 ether in it.
The attacker calls the withdrawal function again (re-enters the market) and prepares to withdraw 1 ether again.
Because the contract still thinks there are 10 ethers in it, it will transfer 1 ether to the attacker again.
This process repeats until there is no more liquidity in the contract.
In this way, the attacker can repeatedly call the withdrawal function and transfer almost all the liquidity in the contract to his own account, resulting in the theft of funds in the contract.
This vulnerability is very advantageous for attackers, because the amount in the contract is not updated in real time, allowing attackers to repeat the attack until there is no more funds to withdraw from the contract. #Crv