I will lay down the most common, repeated things I do when starting a new audit. I'm not saying this is how things should be done, probably there are more efficient and better ways to approach a new audit, but that's how I've been doing it.
The first thing I do is read as much documentation as possible to give myself a good overview of the system I'm about to audit. This gives me an insight into how the project functions. How similar is it to other projects? The last point is important as it can give me a good starting point to investigate attack vectors present in other similar projects and see if it applies to this one.
After that step, I try to form some hierarchy of the contracts. Often I use Solidity Visual Developer add-on to VS Code. It helps me see the inheritance tree of the contract, call graphs, etc. It's convenient and helpful.
The third step will be to validate if contracts don't have anything obvious to point out, like re-entrency attack, lack checks-effects-interaction pattern, etc. I use Slither to help me find anything blatant in the codebase. I take notes of every issue.
Threat Modeling & Vulnerability Identification
Knowing how the project works and how contracts behave and interact with each other, I can start auditing the codebase.
Public and External functions are the ones that the attacker will have access to, so I start from these functions. I then check which internal functions are called and which state variables they change. I try to find a way to manipulate state variables so it would be holding an incorrect value, something the logic shouldn't allow.
I also cross-check the documentation or technical specification of contracts to verify if any of the behavior was supposed to be valid. Sometimes there is a mismatch between docs and the actual implementation.
Stuff like gas optimization, or other informational, not crucial issues, are the last on my list. It's too easy to get distracted by it, and most of the time, it's not that important. When I have one week for an audit, I have verified any critical and major vulnerabilities rather than some optimizations. They are not crucial to the overall security of the system.
What if code is a fork of another project?
This kind of audit is more streamlined.
I focus only on checking if new code or code changes made where they are used and validate if any changes break any of the previous mechanisms. For example, suppose they changed the fund transaction mechanism. In that case, you check all functions funds are transferred in, check what the expected "norms" for the variables are, and evaluate whether the new code "breaks" with those "norms".
That's a general overview of my audit process. I'm sure I'm doing many other things that I haven't listed, but I found these items to be most repeated with every audit.
Thanks for reading, and if you like my writing, you can subscribe to my blog to receive the daily newsletter as I'm currently in the middle of 100 days of blogging challenge. Subscription box below 👇
If the newsletter is not your thing, check out my Twitter @adrianhetman, where I post and share exciting news from the Blockchain world and security.
See you tomorrow!