Post Mortem Vyper Reentrancy 0-Day: What we know so far
- Kevin Costello
- Aug 1, 2023
- 3 min read
Summary
On July 30th 2023, a critical vulnerability affecting the Vyper source code compiler was used to exploit a Curve Finance pETH/ETH/f pool created by JPEGd (https://jpegd.io/). The vulnerability used was a re-entrancy attack exploiting a malfunctioning re-entrancy lock security feature in Vyper compiler versions 0.2.15, 0.2.16, and 0.3.0. Once the original transaction was submitted, several MEV bots, copy cat hackers, and white hat security researchers took notice, expanding those caught up in the carnage to Metronome (https://metronome.io/), Alchemix (https://alchemix.fi/), and other Curve Finance pools. At time of writing the total value lost is around close to 70M USD however given all the white hat and MEV activity, it appears that at least a portion of the total value will be returned. Let’s take a closer look at the full timeline of events, vulnerability, and community response.
The vulnerability
Vyper (vyperlang.org) is a contract-oriented, pythonic programming language that targets the Ethereum virtual machine as an alternative to Solidity. The Vyper team’s goal is to improve on the security, simplicity, and auditability compared to the Solidity language by using python-like syntax that makes it easy for developers to start building EVM products and has security features built in the compiler. One of the security features of Vyper is protections for rentrancy attacks. A reentrancy attack occurs when a smart contract function makes an external call to another contract. If not properly protected against, the external contract could make a recursive call back to the original function which could have unintended consequences, such as draining liquidity pools, if not properly handled. The vulnerability that was exploited was introduced In Vyper compiler v0.2.15 in the set_storage_slots function in what looks like was an attempt to fix a different bug in the nonreentrant feature of Vyper (source). When this change was made the storage slots used to track reentrant calls were incorrectly implemented, resulting in the nonreentrant feature malfunctioning allowing the smart contract function to be re-entered. This vulnerability persisted in v0.2.16 - v0.3.0 before being fixed in v0.3.1 (source).
Figure 1: Vulnerable set_storage_slots Vyper v0.2.15
The exploit
On July 30th at approx 13:10 UTC, JPEGd Curve pool pETH/ETH was the first victim targeted by an exploit taking advantage of this vulnerability to manipulate the price of ETH in the liquidity pool. While each exploit transaction was slightly different in terms of the how the exploited the vulnerability all of them followed the same steps:
Obtain flash loan of ETH
Provide ETH liquidity to the target Curve pool and receive LP tokens
Remove pool liquidity by burning LP tokens
Swap any remaining LP tokens for ETH
Repay flash loan and keep any profits
This series of transactions performed via re-entrancy prevents the Curve pool from updating price variables which causes inaccurate price pair information resulting in profits for the attacker. Once the exploit was seen in the Ethereum public mempool the transaction from the malicious JPEGd contract was frontrunned by MEV trading bot with the ENS name c0ffeebabe.eth. This MEV trader also frontrunned another potential attack on Metronome In addition in appears there were two exploit attempts on Alchemix’s Curve liquidity pool from an unknown actor and a white hat security research operation before spreading to CRV/ETH pairs. The Curve Finance team and Vyperlang teams confirmed the vulnerability via X the issue during the response as well as security research firms Blocksec and Hypernative
Conclusion
Reentrancy attacks continue to haunt the EVM ecosystem and are king when it comes to total value loss to hacking activity in 2023. This type of exploit is a prime example of why securing and getting assurance over your software supply chain is very important in all industries. This is especially challenging in web3 due to the lack of common package managers, standardization, and robust development and release practices.
Comments