The vulnerability exploited by Curve may have opened up new avenues for hackers.

Jaleel加六and others2Authors
编辑
Jack
23-08-02 16:05
Read this article in 26 Minutes
总结 AI summary
View the summary 收起
Author: Jaleel, BlockBeats 
Editor: Jack, BlockBeats


With the occurrence of a vulnerability exploitation event, the DeFi industry has fallen into chaos. Curve Finance, a giant in the DeFi industry, has become a serious target of "attacks", and multiple stablecoin pools such as alETH/msETH/pETH are at risk. According to incomplete statistics, this vulnerability exploitation event has caused a cumulative loss of $52 million for Alchemix, JPEG'd, MetronomeDAO, deBridge, Ellipsis, and CRV/ETH pools, severely shaking the confidence of the entire market.


The re-entry lock of Vyper versions 0.2.15, 0.2.16, and 0.3.0 is invalid, and the version recommended on the Vyper official documentation installation page is also incorrect. Other projects using the Vyper compiler have also conducted self-inspections in an attempt to ensure that they will not become the next victim. As the source of the vulnerability exploitation event is gradually revealed, the market is gradually realizing that this crisis does not only mean a normal hacker vulnerability exploitation event, but also reveals the potential huge risks of the entire underlying stack to the entire DeFi industry.


Compared with the past, the number of hacking incidents has been decreasing recently, which is closely related to the prosperity of the market. During the DeFi summer and NFT summer periods, new billion-dollar protocols were launched every week, but now the market has shrunk significantly. At the same time, the market opportunities for hackers to find vulnerabilities or create large-scale attack incidents are also gradually shrinking, which means that hackers need to explore new, undeveloped entry points.


Hackers who return to the "first principles" have found a perfect entry point on a lower-level compiler to feast on the huge and delicious "cake" in the DeFi market. The lower-level compiler has become a "smarter" choice for hackers. Regarding this incident and the related issues it exposed, BlockBeats interviewed smart contract developer Box (@BoxMrChen) and BTX researcher Derek (@begas_btxcap).


The founder of Aave and Lens, Stani (@StaniKulechov), shared his thoughts on the incident on social media: "This is an unfortunate setback for Curve and DeFi. Although DeFi is an open space where contributions can be made, it is difficult to be absolutely correct and the risks are high. In the case of Curve, they did the right thing at the protocol level."


The vulnerability exploitation event encountered by Curve is one of the oldest and perhaps most common forms of Ethereum smart contract attacks, reentrancy attacks. Reentrancy attacks allow attackers to repeatedly call a certain function of a smart contract without waiting for the previous call of that function to complete. This allows them to continuously exploit the vulnerability and withdraw funds from the victim contract until the funds are depleted.


Take a simple example to illustrate the re-entry attack: a bank has a total of $100,000 in cash. However, this bank has a big loophole. Whenever people withdraw money, the bank staff does not update the account balance immediately, but waits until the end of the day to check and update it. At this time, someone found this loophole, opened an account in the bank, deposited $1000 first, then withdrew $1000, and then withdrew $1000 again after 5 minutes. Since the bank did not update the balance in real time, the system would think that his account still had $1000 before checking and updating. Through repeated operations, the user finally withdrew all the $100,000 cash in the bank. The bank only found out that this loophole had been exploited at the end of the day.


The complexity of a reentrancy attack lies in its exploitation of the feature of mutual invocation between contracts and the logical vulnerabilities of contracts themselves, achieving fraudulent behavior by deliberately triggering exceptions and fallback functions. Attackers can repeatedly exploit the logical vulnerabilities of contracts to steal funds. The solution to prevent reentrancy attacks is also common, which is to set up a targeted special code content in advance for protection, using such protection mechanisms to ensure fund security, which is called a reentry lock.


Solidity has established a "CEI principle" (Check Effects Interactions) for smart contract programming, which can effectively protect functions from re-entry attacks. The content of the CEI principle includes:


2. Before interacting with external entities, all state variables should be updated first. This is called "optimistic accounting", which means that the impact is written before the interaction actually occurs.

3. The check should be performed at the beginning of the function to ensure that the calling entity has the permission to call the function.

4. State variables should be updated before any external calls to prevent reentrancy attacks.


According to the document, CEI principles help limit the attack surface of contracts, especially in preventing reentrancy attacks. CEI principles can be easily applied by following the order of functional code, without changing any logic. The well-known exploit of The DAO vulnerability that caused the Ethereum fork also ignored the "CEI principles" and allowed the attacker to carry out a reentrancy attack, resulting in catastrophic consequences.


However, the attacked Curve pool did not follow this CEI principle, because Curve uses the Vyper compiler. As a vulnerability in the Vyper code, the re-entry lock was invalidated, allowing the hacker's re-entry attack to succeed.


Most people are familiar with Solidity, but Solidity is not the only language for creating smart contracts. The popular alternative to Solidity currently is Vyper. Although Vyper's functionality and popularity are not as good as Solidity, it is an ideal choice for developers familiar with Python because Vyper can transpile Python-like code into the Ethereum smart contract programming language.


According to information from GitHub, the top contributor to Vyper's GitHub code repository is also a developer for Curve. This also explains why Curve uses Vyper instead of Solidity.



In this attack incident, what exactly went wrong with Vyper? Why did the reentrancy lock fail? Was it because of lack of testing? BlockBeats interviewed smart contract developer Box826.eth (@BoxMrChen), who revealed that the Vyper reentrancy lock had been tested with use cases. However, the reason for the failure was that the test cases were result-oriented, meaning that the test cases were also incorrect.


In short, the main reason for the failure of Vyper reentrancy locks is that the person writing the test cases wrote them based on the results, without considering why the slot would inexplicably skip 1.



In the Vyper code shared by Box, there are obvious issues. When the lock name appears for the second time, the number of storage slots will be overwritten. This means that in the "ret" function, the slot for the first lock retrieval is 0, but after another function uses the lock, the slot for the lock is incremented. Using the wrong slot after compilation results in the reentrant lock being ineffective.


Left is the attacked code, and right is the fixed code.

"Expected incorrect test results, of course, cannot verify errors. For example, let's say we are doing a math problem, 1+1=2, but the given correct answer is wrong and says 1+1=3. At this point, a student answering 1+1=3 would be considered wrong, but it matches the pre-given correct answer, so the program cannot determine that the test result is incorrect." Box said in an interview with BlockBeats.


悬了两年的「达摩克利斯之剑」


"The 'Sword of Damocles' that has been hanging for two years."In the first recorded re-entry attack in history, the attacker of the WETH Attack intentionally created the attack to raise awareness of re-entry attacks among developers, with the aim of reducing the possibility of more projects being vulnerable to such attacks. In the context of smart contracts, developers should use different triggering mechanisms, such as calling a state-changing function, to implement protection. This requires developers to fully consider possible attack scenarios and take appropriate preventive measures when designing contracts.


In order to gain a deeper understanding of the Vyper editor, BlockBeats interviewed BTX researcher Derek (@begas_btxcap), who stated that for developers familiar with Python, Vyper is a more ideal choice than Solidity, with a more comfortable UI and faster learning curve. However, it is clear that some versions of the Vyper editor code have not undergone reliable third-party audits. Even some audit work may have been completed by the developers themselves. "This kind of thing wouldn't happen in the traditional IT industry, because when a new language comes out, countless audit companies will be looking for your vulnerabilities."


Not to mention, it can allow an error to exist for two years without being noticed.


Vyper contributor fubuloubu also stated that the compiler has not been subject to censorship or audit as people might imagine. Most compilers undergo significant and frequent changes, which makes auditing difficult. Even with a complete codebase audit, the more versions added afterwards, the more outdated it becomes. Auditing the compiler is not a good way to go because auditing the final product (i.e. raw EVM code) generated by the tool that end users use is more meaningful.


All of this points to one final issue: incentives. That is to say, no one has the motivation to search for critical vulnerabilities in compilers, especially older versions. Fubuloubu previously proposed a suggestion to improve Vyper by adding a bounty program sponsored by users, but it was not approved.


Hackers are returning to "first principles"


For developers working on protocols and projects, this is another vivid example of secure contract development practices. But most importantly, the Curve incident serves as a warning to all of us that security issues with underlying compilers have been seriously overlooked, and hackers who return to "first principles" have found a perfect entry point in lower-level compilers.


Afterwards, Stani, the founder of Aave and Lens (@StaniKulechov), also posted a long article on social media expressing his thoughts: the recent Curve attack incident means that DeFi risks have always involved the entire underlying stack, programming languages, EVM, etc. This warns us to be more cautious and sensitive, especially when using customized EVMs and application chains in the future.



来自更底层的攻击


translates to

Attacks from deeper levels


For vulnerabilities in compilers, it is difficult to discover them solely through auditing the logic of contract source code. Merely studying the differences between versions is also a major undertaking. It is necessary to combine specific compiler versions with specific code patterns for analysis in order to determine whether smart contracts are affected by compiler vulnerabilities.


"Currently, only two compilers are considered the best. Vyper has a smaller codebase, making it easier to read and requiring fewer changes for historical analysis. This may be why hackers targeted it. Solidity's codebase is slightly larger." Fubuloubu even suspects that state-sponsored hackers may have been involved in the Curve attack: "Finding this vulnerability would take weeks to months of time and resources, so it may have been carried out by a small group or team."


As the most widely used programming language in the encryption industry, the security of Solidity is a major concern for users. After all, if the Solidity compiler experiences a re-entry lock failure, the entire history of the DeFi industry may be rewritten.


According to the regular security alerts released by the Solidity development team, security vulnerabilities have also been found in multiple versions of Solidity compilers. The content of the security alert is available for reference.


The most recent compiler error record was on June 26th. An error was discovered in the Solidity compiler's old code generation pipeline while investigating a security report related to using the abi.decode with side-effecting ternary expressions as type parameters. The old code generator did not evaluate complex expressions such as assignments, function calls, or conditionals, whose .selector was being accessed. This caused side-effects of such expressions to not be executed, potentially resulting in incorrect behavior of contracts compiled with the old pipeline.


We can also see that Solidity's Github repository contains a file that lists some known security-related bugs on the Solidity compiler. This list dates back to version 0.3.0, and bugs that existed only before this version are not included. Here, there is also another bugs_by_version.json file. This file can be used to query which bugs will affect a specific compiler version.


Luckily, it is precisely because of the widespread use of the Solidity language and the assistance of the Ethereum Foundation behind it that many existing issues have been identified and addressed by projects and protocols during deployment, completing modifications and improvements faster than Vyper. From this perspective, this is also one of the reasons why Solidity is more standardized and secure than Vyper.


In order to help Solidity developers conduct better testing and prevent similar incidents from happening, SunSec (@1nf0s3cpt), co-founder of @UnitasProtocol, released a DeFiVulnLabs Solidity security testing guide after the Curve attack. The guide supports 47 types of vulnerabilities, including vulnerability descriptions, scenarios, defenses, vulnerability code, mitigation measures, and how to test.


How to Avoid Low-Level Attacks as Much as Possible?


On this Curve incident, Box believes that the lesson all developers should learn is: do not be tempted to follow immature solutions just because they are trendy; do not approve your code without writing test cases (even the test cases of several versions of Vyper that had issues were incorrect); never approve your own code; some wealth may take years to be discovered; being un-upgradable is arrogance towards oneself and contempt towards others.


Developers usually don't think about the pitfalls here, and they may compile a version without considering the risks of differences between versions. Even a minor version upgrade can introduce significant changes, which is especially important when developing decentralized applications.


This Curve incident serves as a warning to developers: use newer versions of compiler languages. It is crucial to keep your codebase, applications, and operating systems up-to-date, while also building a comprehensive security defense mechanism. Although new versions may introduce new security issues, known security issues are usually fewer than older versions. Of course, it is also important to keep an eye on community and official version update announcements. Understanding the changes brought by each version and updating your codebase and runtime environment as needed may greatly reduce security incidents caused by compiler errors.


In addition, it is necessary to improve the unit test cases of the code. Most compiler-level errors can cause inconsistent code execution results, which are difficult to detect through code review alone, but can be exposed in testing. Increasing code coverage helps avoid these types of issues. Also, it is important to avoid using complex language features such as inline assembly and multidimensional array encoding and decoding, unless there is a clear requirement. Most of the historical Solidity language vulnerabilities have been related to these advanced features. Developers should avoid using experimental language features just to show off, unless there is a specific need.


For protocol and security personnel, the potential risks brought by compiler versions cannot be ignored during code audits. It is foreseeable that hackers have opened up new ideas, and in the future, more low-level vulnerability exploitation events will occur. At the same time, as the underlying infrastructure, low-level stacks, programming languages, EVM, and other aspects need to be audited carefully. The market for auditing companies will become larger in the future, and the market for white-hat bounties will also become larger. The Vyper team also plans to launch a vulnerability bounty program after the formal review is completed.


Of course, we don't need to overly panic about the risks that exist in the underlying infrastructure. Currently, most compiler bugs are only triggered in specific code patterns, and the actual impact needs to be evaluated based on the project situation. Regularly upgrading compiler versions and conducting sufficient unit testing can help prevent risks.


Reference:
1.https://www.quicknode.com/guides/ethereum-development/smart-contracts/a-broad-overview-of-reentrancy-attacks-in-Solidity-contracts
2.https://github.com/pcaversaccio/reentrancy-attacks/issues/1
3.https://nipunp.medium.com/5-8-21-rari-capital-exploit-timeline-analysis-8beda31cbc1a
4.https://docs.Soliditylang.org/en/v0.8.21/


欢迎加入律动 BlockBeats 官方社群:

Telegram 订阅群:https://t.me/theblockbeats

Telegram 交流群:https://t.me/BlockBeats_App

Twitter 官方账号:https://twitter.com/BlockBeatsAsia

举报 Correction/Report
This platform has fully integrated the Farcaster protocol. If you have a Farcaster account, you canLogin to comment
Choose Library
Add Library
Cancel
Finish
Add Library
Visible to myself only
Public
Save
Correction/Report
Submit