Author: gbaleeeee
Introduction
If you’re reading this, I assume you already have a basic understanding of Web3 security and have gone through resources like How to Become a Smart Contract Auditor. You’re familiar with languages like Solidity and Rust and have studied plenty of security fundamentals. However, once you start auditing, you might find it challenging to uncover sophisticated vulnerabilities or you may often miss subtle but critical issues. I believe this struggle is more about mindset than a lack of technical knowledge.
My audit journey:
I began my web3 security journey in 2022, starting with foundational knowledge and learning about common vulnerabilities and attack patterns from real-world exploits. Later, I joined a security firm as a full-time auditor, delivering high-quality audit services. From being a novice to now a senior auditor, I believe the most significant change for me has been the development of an audit mindset.
In this article, I’ll share my thoughts on how shifting audit mindset that make a significant difference. Auditing is deeply personal -everyone has their own approach and understanding. While my perspective is subjective, I hope it can provide some valuable insights.
Don’t fear missing something
In my early days of auditing, I felt pressure to find all the critical and high-severity issues. Part of it was due to working at a security firm, and part of it came from a fear that if I missed something crucial, I wasn’t good enough-leading to frustration and self-doubt. If you’ve ever felt the same way, it’s important to let go of that mindset. It we are focused on fearing missing something, we will miss out on the opportunity to learn and grow.
Finding a critical bug is great, but it shouldn’t be our main focus. Instead, we should aim to discover interesting and subtle bugs. This doesn’t mean critical bugs aren’t important-far from it. It simply means that by searching for the less obvious issues, we dig deeper into the code and gain a more comprehensive understanding of the project. The more we explore the code, the more familiar we become with it, and I believe that a deeper understanding will naturally make it easier to find critical bugs.
So, embrace the audit process and enjoy the challenge of breaking the code. Don’t be afraid of missing something. While many of the interesting and subtle bugs might not be critical, the process sharpens our critical thinking skills and builds confidence over time.
Refining auditing perspective
A senior auditor can often find more bugs in a single code review than a junior auditor might find after multiple reviews. This is because senior auditors have a more refined auditing perspective, allowing them to consider a wider range of cases and details. Based on my experience and what I’ve learned from others, I’ve summarized some key perspectives that contribute to this refined approach.
Extracting protocol invariants: One of the most common and effective approaches in auditing is identifying protocol invariants. After quickly reading through the code and understanding the core logic, we can begin to extract these invariants and verify their correctness. For example, when reviewing a modified MasterChef contract, we might identify invariants such as: the rewardIndex must always update before the user’s balance, or a user should not be able to earn rewards immediately after depositing. If an invariant is broken, it’s likely a critical bug. In a lending protocol, for instance, a user should never be able to manually create bad debt. In decentralized exchanges, the K value should always increase unless liquidity is removed. With more audit experience, this process of extracting invariants will become faster and more intuitive. Once we’re familiar with most DeFi protocol types, it will feel like pattern matching. As we search for ways to break these invariants, we will uncover subtle but crucial bugs.
Challenging Developer Assumptions: Developers often make assumptions when writing code, and during code review, it’s crucial to identify and challenge these assumptions. One common issue arises from the lack of input validation. For instance, a function might assume that a valid token address is passed by the user, but a malicious actor could input a fake token. Another example is when a function relies on being called in a specific sequence. For example, suppose function C is assumed to be called in a particular sequence: first function A, then function B, and finally function C. In this case, explore whether it’s possible to call function B before function A, or to bypass function B entirely, preventing function C from being called. When the specific flow assumption is found, consider what might happen if the functions are invoked in a different order. At a higher level, it’s important to examine how the protocol operates as a whole: what external protocols are integrated, how those integrations function, and how the protocol relies on administrative actions. The potential consequences of incorrect admin operations should be considered. All assumptions made by the developer regarding the protocol’s operation should be identified and evaluated for potential ways to break or challenge them.
Identifying Asymmetry: Symmetry is not only a concept in mathematics but should also apply to programming. When reviewing code, it’s important to look for any asymmetries in the logic. A common example can be found in lending protocols, which often provide two functions for users to borrow assets: one function allows users to input the amount of assets they wish to borrow, and the other allows them to input the debt shares they want to mint. It’s essential to verify if there are any discrepancies in the logic between these two functions.
This type of asymmetry is also an instance of the “Two Parser Bug.” I have written another article explaining this pattern in more detail.Attention to Detail: Senior auditors often catch subtle bugs in code details that others overlook, and even minor issues deserve careful consideration. My personal checklist for detail includes questions like: Is the rounding direction correct? Should I use > or >= when comparing two values? Should I add a check to ensure the variable is initialized? If a magic number is used, is it really safe and reasonable? When the protocol integrates with multiple tokens, does it correctly handle differences in token decimals? As our audit experience grows, our checklist for details should become increasingly comprehensive. Focusing on the finer points, not only being content with just the overall logic, will help us catch those elusive bugs.
Staying paranoid
Most of the time during code review, we might think, “This part of the code is simple; it looks well-written.” However, a good auditor should always maintain a paranoid mindset. We should constantly ask ourselves: Has the developer considered all possible edge cases? Is there any difference between how the code is expected to execute and how it might actually be invoked? Keep questioning the code like a hacker would. While code often turn out fine, maintaining this mindset will sharpen our critical thinking skills.
The trigger for me to dig deeper into the code is often a feeling like, “This function seems weird, I need to double-check” or “The implementation is more complicated than I expected” or even, “Wow, this function looks like it was written by a beginner-it’s so poorly done.” Whenever we feel dissatisfied with the code, we should explore ways to break it. Healthy paranoia and endless curiosity is key to becoming a good auditor/hacker. While it’s difficult to maintain this mindset constantly during the whole audit, whenever we get that feeling, we shouldn’t let it go.
Communication for Growth
“Two heads are better than one.” Communicating with elite auditors and learning from the web3sec community are great ways to improve your audit mindset. Understanding how they think and approach different problems can help you refine your own thought process. Even reading their reports or articles to learn new attack vectors, and drawing motivation from white hat success stories, can be highly beneficial.
Summary
I believe the audit mindset is more of an art than a science. It requires a blend of creativity and meticulous attention to detail. As we continue to explore and experiment, we will develop our own unique style and approach. The most important thing is to never lose your curiosity and joy in this journey. So, embrace the excitement and enjoy the thrill of hacking the code!
Seriously more people need to know your content