On 30 July, reports surfaced of vulnerabilities in Vyper versions 0.2.15, 0.2.16 and 0.3.0 which left many pools on Curve vulnerable to a reentrancy attack. This exploit was possible due to a reentrancy vulnerability which allowed the attackers to call the add liquidity function during the remove liquidity process. In total $69.3 million was affected, with $16.7 million returned by white hat hackers. However, this still means that approximately $52 million was stolen, making it the largest reentrancy attack so far in 2023.
On July 30, 2023 Vyper, a contract-oriented programming language designed for the Ethereum Virtual Machine (EVM), announced that Vyper compiler versions 0.2.15, 0.2.16 and 0.3.0 were vulnerable to malfunctioning reentrancy locks. As a result, several DeFi projects were affected by the vulnerability resulting in a total loss of $52 million. Upon investigation, CertiK found the reentrancy attack targeting the pETH-ETH-f pool.
CertiK has identified six wallets involved in the incident. The first wallet (0x172) failed to exploit the vulnerability in block 17806056. The original exploiter withdrew 0.1 ETH from Tornado Cash and proceeded to create the attack contract. However, a front runner (0x6Ec21) paid more gas and was able to execute their transaction first to acquire approximately 6.1k WETH worth over $11.4 million.
Image: Failed exploit transaction that was front run by a MEV bot. Source: Etherscan
The vulnerability led to further losses, with EOA 0xDCe5d acquiring approximately $21 million worth of assets. A break down of the involved wallets is shown below.
Table: Assets transferred with associated wallets. Source: CertiK
In total, six projects were affected, approximately $69.3 million was taken and $16.7 million has been returned, resulting in a total loss of $52 million.
Vyper is a contract-oriented, pythonic programming language for the Ethereum Virtual Machine (EVM). Beta versions of Vyper have been around since 2017, but its first non-beta release came with version 0.2.1 in July 2020.
Solidity is the dominant language within the Ethereum ecosystem as it has existed much longer than Vyper, which has ultimately led many community members to create tools that operate specifically with Solidity. According to DeFiLlama, Vyper smart contracts make up $2.17 billion of the roughly $70 billion worth of Total Value Locked (TVL) in DeFi protocols. Solidity, on the other hand makes up the vast majority at $67.49 billion.
Image: TVL by programming languages. Source: DeFiLlama
As of 10 May, 2023 Vyper’s usage dominance was down to 6.27% from its high of 30% in August 2020. Despite the TVL dominance of Vyper being significantly lower than Solidity, this incident still led to $62 million being impacted.
Image: TVL dominance by programming languages. Source: DeFiLlama
A compiler version refers to a specific release of a programming language's compiler, which translates human-readable source code into machine-readable code. Vulnerabilities were found in versions 0.2.15, 0.2.16, and 0.3.0 of Vyper, resulting in a reentrancy attack that impacted several DeFi projects, causing a total loss of $52 million. Compiler versions are periodically updated to introduce features, fix bugs, and enhance security. The Vyper language does not currently provide a white hack bug bounty program.
The earliest vulnerable version of Vyper, v0.2.15, was released on 23 July, 2021. However, by December of the same year version 0.3.1 was released at which point the previous vulnerability was no longer present.
The incident began at 13:10 +UTC with the initial exploiter’s transaction targeting the JPEG'd pool on Curve failing due to a front run transaction.
JPEG’d acknowledged that the pETH-ETH Curve pool had been exploited at 14:17 UTC.
Vyper then announced that versions 0.2.15, 0.2.16 and 0.3.0 contained a malfunctioning reentrancy lock.
Following Vyper’s tweet, Metronome and Alchemix were impacted.
Metronome DAO then announced:
At 8:23 PM UTC, Curve Finance made an announcement on Discord stating that remaining pools are safe and unaffected by the Vyper bug.
On 31 July, Curve Finance announced on Twitter that there was a potential for a pool on Arbitrum to be affected, however there is no profitable exploit for malicious actors to execute, meaning that it's unlikely the pool will be attacked. CertiK has not detected any other attack exploiting the Vyper bug.
On 4th August, Alchemix announced on twitter that the Curve Finance exploiter had returned a total of 4,819 $alETH and 2259 $ETH so far. That they are also looking forward for the remaining funds to be returned.
This example is based on the transaction that targeted JPEG’d.
Attacker: 0x6ec21d1868743a44318c3c259a6d4953f9978538
Attack Contract: 0x466b85b49ec0c5c1eb402d5ea3c4b88864ea0f04#code
The attacker started by borrowing 80,000 WETH (~$149,371,300) from Balancer: Vault.
The attacker then unwrapped the WETH and called pETH-ETH-f.add_liquidity()
and added 40,000 ETH (~$74,685,650) into the pETH-ETH-f pool. In return the attacker received 32,431 pETH (pETH-ETH-f).
The attacker called remove_liquidity()
to remove the liquidity added in step 2. 3,740 pETH and 34,316 ETH was transferred to the attack contract which triggered the fallback()
function, giving control to the attacker. In the fallback function, the attacker added another 40,000 ETH to the pETH-ETH-f pool and received 82,182 pETH.
The attacker called remove_liquidity()
again and removed 10,272 pETH, receiving 47,506 ETH and 1,184 pETH. The attacker then exchanged 4,924 pETH for 4,285 ETH in the pETH-ETH-f pool.
In total, the attacker obtained 34,316 ETH from step 3 and 47,506 and 4,285 from step 4 for a total of 86,107 ETH. After repaying the 80,000 ETH flash loan the attacker was left with 6,107 ETH ($11,395,506).
This exploit was possible due to a reentrancy vulnerability which allowed the attacker to call the add liquidity function during the remove liquidity process.
Although the functions should have been protected by the @nonreentrant('lock')
, testing of the add_liquidty()
and remove_liquidity()
functions has proven it did not prevent reentrancy.
Image: Vyper_contract for Curve.fi Factory Pool Source: Etherscan
Following the exploits on JPEG’d, Metronome, and Alchemix, Vyper confirmed that versions v0.2.15, v0.2.16 and v0.3.0 were vulnerable to reentrancy protection failing.
Projects that have been built using the vulnerable Vyper versions should reach out to Vyper, who can assist in mitigations. If possible, projects should upgrade to the latest version of Vyper which does not contain this bug.
The incident affecting Vyper is the largest reentrancy exploit that we've detected in 2023. It accounts for 78.6% of such instances in terms of funds lost. Unfortunately, the two largest reentrancy incidents this year have affected contracts written in Vyper, albeit different vulnerabilities.
2023 has now seen over $66 million lost due to reentrancy attacks across all chains. This is approximately $4 million more than all of 2020 and just $1 million behind the amount lost in 2021. Notably, the total for 2023 also represents a 259.45% increase the amount lost to reentrancy attacks in 2022.
Losses to reentrancy attacks had been declining due to an increased understanding of security practices. However, July has now seen a total of four reentrancy attacks. Total losses caused by reentrancy attacks during the month of July have now reached $58.4 million.