Onchain Security: Dissecting Smart Contract Audits

Security

May 23, 2024

Introduction

In this article, we cover why smart contract audits are essential for the security and integrity of blockchain applications. We’ll take you through the steps involved in the auditing process, from understanding the protocol to identifying vulnerabilities using manual review, automated testing, and formal verification techniques. We’ll look at common smart contract vulnerabilities and provide a real-world example of a smart contract audit. By the end of this article, you’ll have a comprehensive understanding of how smart contract audits contribute to the sustainability and success of web3 projects.

Understanding Smart Contract Audits


What makes smart contracts a focal point in so many blockchain security conversations? Smart contracts act like a set of rules that all parties of a transaction adhere to without the need for an intermediary. Their immutable nature ensures that once a contract is deployed, it cannot be altered. As powerful as this feature is, it is a double-edged sword. The immutable nature of blockchains means that any vulnerabilities in the contract code can have irreversible consequences. This is where smart contract audits come into play.

A smart contract audit, also known as a smart contract security review, is an in-depth review of a protocol’s codebase. This process aims to identify security vulnerabilities, inefficient code, and potential improvements such as gas optimizations. It involves both automated tools and manual review by experts to scrutinize the contract’s code, which is crucial in the blockchain ecosystem where deployed code is immutable and cannot be altered without redeployment.

Why Conduct a Smart Contract Audit?

1. Increase security of the protocol

The primary goal of a smart contract audit is to increase the security and integrity of the code. Blockchain applications often handle significant financial transactions. A single vulnerability can be exploited to cause financial losses worth millions of dollars. Auditors thoroughly examine the code to identify and rectify potential security risks before they can be exploited by malicious actors.

2. Cost Efficiency

Addressing vulnerabilities in smart contracts post-deployment can be technically challenging and expensive. Once a contract is deployed on the blockchain, modifying it often requires deploying a new contract and migrating all existing data, a process that can be both costly and risky. Conducting an audit before deployment can prevent these issues, saving time and money in the long run.

3. Investor and User Confidence

Audits serve as an extra layer of defense, demonstrating to investors and users that the smart contract has undergone rigorous testing and verification. This transparency builds trust in the protocol, which is crucial for the adoption and success of any blockchain project. An audited codebase assures users that the contract is more secure and reliable. This does not mean that if the codebase was audited, it is bug-free. By looking at the Rekt leaderboard, ~42% of protocols getting hacked were actually audited, while ~57% were not, but the big difference lies in the amounts that were hacked. Audited protocols hacked since 2020 lost a cumulative amount of 1.3 billion $, while unaudited protocols lost almost 3.7 billion $.

According to this data, the evidence is clear that audited protocols get hacked less, and even if they do happen to get hacked, the amount of money lost is almost 3X less than it is for unaudited protocols.

4. Optimization of Contract Performance

Beyond security, smart contract audits assess the efficiency of the code. This includes optimizing gas costs, improving error handling, reducing the contract’s size, etc. Efficient contracts save costs for users and provide a better user experience.

Smart Contract Audit Process

Now that we’ve gone over why a protocol needs an audit, let’s take a look at how a typical security review is performed.

1. Protocol overview and documentation

Before diving head-first into the code, security researchers review all available documentation to understand the intended functionality of the protocol. In this step, auditors familiarize themselves with the different actors of the protocol (manager, owner, users, and any other roles), the architecture of the protocol, the cross-contract interactions, and more.

2. Manual Review

In this step, security researchers examine the code manually, line by line to understand its logic and identify potential security issues. This is a time-intensive endeavor because auditors need to go through each line of code in every smart contract of the protocol. The bigger the codebase, the more time it will require to audit. The length of the codebase will also impact the audit’s price. Auditing 300 lines of code for an NFT project is not the same as reviewing a new AMM DEX that has 3500 lines of code.

3. Automated Testing

Besides manual review, there are tools out there that assist auditors when reviewing a codebase. These tools are not meant to replace the manual review process, but they can enable security researchers to find bugs that they might’ve missed. These tools will speed up the process because they can also generate automated reports for some of these issues. By freeing up some time, auditors can focus on uncovering the not-so-obvious vulnerabilities in the codebase. You can see some of the most commonly used tools below.

  • Slither is a Solidity & Vyper static analysis framework. It runs a suite of vulnerability detectors, prints visual information about contract details, and provides an API to easily write custom analyses.
  • Aderyn is a Rust-based solidity smart contract static analyzer designed to help protocol engineers and security researchers find vulnerabilities in Solidity code bases.
  • Echidna is a Haskell program designed for fuzzing/property-based testing of Ethereum smart contracts.

4. Formal verification

Formal verification is a mathematical method used to prove or disprove the correctness of a smart contract’s intended functionality. This technique goes beyond traditional testing by attempting to prove that the code fulfills its specifications and is free from bugs.

Formal verification involves creating a mathematical model of the smart contract code, which explains its actual behaviour, and stating its specifications, which represent its desired behaviour. It is thereafter mathematically proven that the model conforms to the specifications. This process helps in identifying discrepancies between the intended behaviour and the written code without having to run the code.

For most audits running Fuzz tests will be enough, but there will be cases when Fuzz testing will miss very niche edge cases that an auditor can uncover through formal verification. The most popular formal verification tools for smart contracts out there today are Halmos and Certora.

5. Issue classification and recommended mitigations

After going through the codebase manually a couple of times, running Fuzz tests and invariant tests, and using some tools auditors will typically end up with a list of vulnerabilities. These vulnerabilities will be classified based on their severity. The severity is normally established by looking at the “likelihood” of the bug to occur, and also at its impact. When assessing the impact, a security researcher will explain who, what, how does a bug impact the protocol and its users. If a bug has a high chance of occurring, meaning high likelihood, and the impact of it is also high, meaning (for example) a malicious actor could steal funds from the protocol, then this would be a high-severity vulnerability.

In this step, all identified vulnerabilities are classified based on a matrix such as the one depicted below.

5. Final audit report

A report is prepared by the auditors who reviewed the codebase, outlining the vulnerabilities found and the steps that can be taken to mitigate the bugs.

For each identified bug, a security researcher will also provide a recommended fix. The fix may sometimes not be obvious or a straight-up answer, and in these cases the auditor will have to collaborate with the protocol’s developers.

Common Smart Contract Vulnerabilities

Below you will find a list with some common smart contracts vulnerabilities. This is not an exhaustive list. We will dive deeper into different attack vectors in a different article.

  • Reentrancy Attacks: A reentrancy attack occurs when a contract calls another contract before it finishes updating its internal state. This opens up the door for the contract that is being called to reenter, meaning to call the same function again during its execution, allowing it to be run multiple times in a single transaction.
  • Oracle/Price Manipulation: Smart contracts often rely on oracles, such as Chainlink in order to access real-world data, to trigger contract functions. If these oracles are compromised or the data source is manipulated, it can lead to erroneous contract execution, such as incorrect payments or settlements based on inaccurate price data.
  • Denial of Service (DoS) Attack: DoS attacks can occur when smart contracts are intentionally overloaded with excessive operations or requests or when a malicious actor can partially or completely block certain functionalities of the contract. For example, a malicious user can block other users from withdrawing their funds from the contract. Even if the attacker cannot steal the money they caused a DoS attack.
  • Division before multiplication: This order of operations can cause errors because Solidity’s integer division truncates. In Solidity the following arithmetic operation will be equal to zero instead of one ( 5 / 10 ) * 2 = 0. It is generally advised to re-arrange arithmetic operations to perform multiplication before division in Solidity.
  • Weak Randomness: Smart contracts that use pseudo-random number generators (PRNGs) are vulnerable if the seed used for the generator can be guessed or influenced by an external observer. This can particularly affect contracts that rely on randomness for critical functions like lotteries or gaming.

Nethermind Security’s Approach

At Nethermind Security, we understand the importance of thorough and collaborative smart contract audits. We value open and frequent communication with our clients throughout the auditing process. Our team meets twice a week with clients to discuss findings, address concerns, and ensure a thorough understanding of the protocol. This close collaboration allows us to provide tailored solutions and address any issues promptly.

Furthermore, our audits are always conducted by multiple auditors, enabling cross-checking of potential vulnerabilities. This collaborative approach combines diverse perspectives and expertise, enhancing the overall quality and comprehensiveness of the audit.

Example of a Smart Contract Audit
The majority of the audits performed by Nethermind Security are publicly available and can be found in our GitHub repository. Public audit reports contribute to the overall security of the ecosystem and provide valuable insights for developers, researchers, and other stakeholders. Explore them to learn more about our auditing methodology, the types of vulnerabilities we identify, and the recommendations we provide to mitigate risks.

Conclusion

In this article, we went through the necessity of smart contract audits, the detailed steps involved in auditing, some common vulnerabilities, and special auditing techniques like formal verification. As you can see, smart contract audits are a crucial step for the security, and integrity of blockchain applications. Security reviews help in preventing financial losses while also increasing users’ and investors’ confidence in a certain protocol. Conducting thorough audits should be an ongoing and a must-do for the sustainability and success of any web3 project.

Latest articles