Back to blogs
Written by
Travis Montgomery
Published on
March 22, 2024

10 Steps to Systematically Approach A Smart Contract Audit

In this article, we will go through 10 key steps to systematically approach a smart contract audit, independently of code size or complexity, as security researchers.

Table of Contents

You've put in the time, familiarized yourself with common attack vectors, and participated in CodeHawks First Flights. You are ready for your first real audit. 

You sit down, clone the contest repo. Next thing you know, you find yourself staring at 10,000 lines of overbearing confusion and the job application in your trash is looking appealing again.

It's important to approach large or intimidating tasks as systematically as one can. Breaking the process into compartmentalized chunks will be far more approachable, allowing us to recognize our own progress as we go. 

Here we willoutline 10 steps a security researcher can take to mitigate those questions of 'Where do I start?'.

1. Gain Context

Your first step should almost always be diving into the documentation. 

Take some time to understand the audit's scope and invest time grasping the business logic that underpins the protocol. 

This foundational step is crucial; skipping it is like navigating a labyrinth without a map. The documentation is your map, offering insights into the protocol's intended functionality and objectives.

If they're available, ask questions of the development team and engage in conversations with them about their architecture decision-making. The more insight you gain into what a protocol is supposed to do, the easier it will be to spot when it is doing something else.

2. Try It Out

Your next action should be to test drive the protocol and clone the audit repo locally. Most protocols being audited will provide the steps required to build in a local testing environment.

Try out the primary functions of the protocol and familiarize yourself with its flow when working in an ideal state. Compile the contracts, play with the commands shared in the README. 

The more familiar you are with things working properly, the more easily bugs will be picked out.

3. Analyze the Test Suite

Tests are the protocol's heartbeat, revealing what the developers value and consider critical. 

By examining the test coverage, you can identify the protocol's more vulnerable segments. This step not only highlights the areas well-trodden by developers, but also shines a light on the darker, perhaps neglected, corners of the codebase through what tests have been omitted.

Take a close look at what tests already exist and be prepared to write more that cover blindspots that may have been overlooked.

Note: Each framework is different, but the Foundry command forge coverage will give you an at-a-glance view into areas for which tests have been written. Use this as a guide only to know how much time and effort a protocol has put into testing their codebase!

4. Visualize the Protocol

It can often be helpful to see a visual representation of how the “seemingly-disparate” parts of a protocol interact with one another. 

Creating (or leveraging tools to create) protocol diagrams is a great way to gain understanding into how one part of a protocol may affect another. An amazing (and free) online tool for creating your own simple diagrams would be Excalidraw!

Tools like Solidity Metrics also allow insight into which areas of a protocol are external, or make state changes through the diagrams it generates, allowing a researcher to focus on the most vulnerable areas.

5. Version Verification

Assess the solidity of the protocol — literally. 

Check which version of Solidity is in use, as each version carries its own set of known bugs and idiosyncrasies. Determine if the protocol is using up-to-date versions of Solidity, and if not, delve into understanding why.

It's possible that using older versions can be fine, within the scope of the protocol, but understanding this situation and how version choices may impact the code can help you pinpoint potential vulnerabilities.

You can stay up-to-date with Solidity version changes here.

6. Use Solodit

Solodit serves as a treasure trove of past bugs and vulnerabilities discovered in smart contracts. Navigate to Solodit and familiarize yourself with vulnerabilities found in similar protocols.

Solodit consolidates thousands of verified security review findings from across the industry into one convenient location. It provides unparalleled knowledge into the weaknesses in code across Web3 and is an invaluable tool for any auditor serious about their craft.

Additionally, make sure to leverage Solodit’s audit checklist - a comprehensive list of common attacks to look for, questions to ask, and examples to study from.

7. Protocol Anatomy

Great places to start assessing a codebase are its more vulnerable points, the weakest links.

These areas may include:

  • Roles
  • Access Controls
  • Function Parameters
  • Public/External Functions
  • Payable Functions
  • State Changes
  • Dependencies

All of these are potential vectors for malicious attacks. Understanding these elements is crucial for identifying security risks.

By leveraging tools like Solidity Metrics (mentioned in #4) you can visualize a clear snapshot of where in a protocol these areas of interest reside.

8. Static Analysis Tools like Aderyn or Slither

While using auditing tools such as Aderyn or Slither might not uncover unique or critical findings, they are invaluable in pinpointing weaker areas of the codebase. Static analysis  tools offer a preliminary sense of where vulnerabilities might lie, guiding further manual inspection.

As these tools get better and better at detecting vulnerabilities, security researchers are able to spend more time narrowing their focus on more severe findings.

Implementing static analysis into a security workflow is something protocols should be doing before even going to audit as well!

9. Look At The Code Line-By-Line

This is the “getting your hands dirty” part! Take all that you've learnt about what the protocol is meant to be and assess each function for its contribution towards that goal.

Compare the intended versus actual functionality of code segments. Often, vulnerabilities aren't hidden in complex code but in mismatches between the expected business logic and the code's execution. This analysis can reveal subtle bugs that could have profound implications.

Leverage auditing methods like "The Tincho" or an Auditing Checklist (courtesy of Tincho Abbate and Hans Freise respectively) to assure thorough, systematic assessment of the codebase.

10. Craft a Compelling Report

Your audit report is your magnum opus. It's not enough to identify bugs; you must convincingly demonstrate their existence and potential impact

Employ proofs of code (PoC), articulate titles, and thorough documentation to make your findings impossible to ignore.

Utilize report templates such as this Basic Report template for competitive scenarios, or this more in-depth template for private audits.

Conclusion

By following these ten steps, auditors can approach each new audit with confidence in where to begin the process. Large codebases can be intimidating and by applying a systematic and routine framework security researchers are better able to work with efficiency and attention to detail without getting lost in the weeds.

Remember:

Q. How does someone eat an elephant?

A. One bite at a time.

– If you want to dive deeper into smart contract security and auditing, make sure to check out Cyfrin Updraft - the ultimate learning platform for smart contract development and auditing. 

Secure your protocol today

Join some of the biggest protocols and companies in creating a better internet. Our security researchers will help you throughout the whole process.
Stay on the bleeding edge of security
Carefully crafted, short smart contract security tips and news freshly delivered every week.