How to Prepare for a Smart Contract Audit

Photo by Glenn Carstens-Peters

An audit is an investment in the security of your smart contract system. Besides selecting a high quality auditor for the work (contact us here), there are several things you can do to make sure you get the most out of your investment.

Following these steps to prepare for an audit will go a long way to helping you get the best results.

  1. Documentation
  2. Clean code
  3. Testing
  4. Automated Analysis
  5. Frozen code
  6. Use a checklist

1. Documentation

The less time we spend trying to understand your system, the faster we can get deep into your code, and the more time we can spend finding bugs. This is why the number one thing you can do to improve the quality of your audit is provide good documentation.

Good documentation starts with a plain English description of what you are building, and why you are building it. It should do this both for the overall system and for each unique contract within the system.

Another marker of good documentation is that it includes a specification of your system's intended functionality. For each contract, it should describe the most important properties or behaviors that should be maintained. It should also describe the actions and states that should not be possible.

One of the best examples we've seen is the protocol spec for the 0xProject. In particular, their use of flow charts nicely illustrates how the system fits together.

Don't let me scare you off. Good documentation requires a lot of effort. If you don't have the capacity to put it together, we can help. Writing our own documentation of the code's behavior is an excellent way to understand it. It can even lead us to discover vulnerabilities and unexpected edge cases.

What about a pseudocode spec? I placed an emphasis on “plain English” above (as opposed to rigid/formal English) because plain English more clearly expresses what you want the code to do. By contrast, the actual code is often so similar to the pseudocode specification that it can be hard to see when they both describe something you do not actually want.

Pseudocode does have its place and can be especially helpful for precisely describing complex mathematics, but it should always be accompanied by some English about what the math is meant to achieve.

2. Clean code

Polished, well-formatted code is easier to read, which reduces the cognitive overhead needed to review it. A little bit of cleanup will go a long way towards allowing us to focus our energy on finding bugs.

  1. Run a linter on your code. Fix any errors or warnings unless you have a good reason not to. For Solidity, we like EthLint.
  2. If the compiler outputs any warnings, address them.
  3. Remove any comments that indicate unfinished work (ie. TODO or FIXME).
    (This is assuming it's your final audit before deploying to mainnet. If not, exercise your judgement about what makes sense to leave in.)
  4. Remove any code that has been commented out.
  5. Remove any code you don't need.

3. Testing

Write tests! A good goal is a test suite with 100% code coverage.

Review the list of test cases for gaps. Are your tests mostly focused on making sure the the ‘happy path’ works? Write some tests to verify undesirable actions are properly protected against, and that the contract fails properly instead of landing in an undesired state.

Important: Your README should give clear instructions for running the test suite. If any dependencies are not packaged with your code (e.g. Truffle), list them and their exact versions.

4. Automated Analysis

Ethereum has many good security analysis tools to help find some of the most common issues. We use some of these during our audits, though you can also run them in advance, which will allow us to spend our time looking for trickier bugs.

Our MythX suite, which runs several kinds of analysis at once, is a great place to start. There are many ways to submit your contracts for analysis, including CLI tools for JavaScript and Python as well as plugins for Remix and Truffle. You can find more security tools listed in our Smart Contract Best Practices.

It's not essential to do this, but it helps. A caveat is that you will often get warnings about issues that don't actually exist. If you're unsure if something is an issue, just let us know and we'll assess it during the audit.

5. Frozen code

At the risk of stating the obvious, you should be done with development of your smart contracts before we audit them.

At the start of our audit, we'll confirm that you've “frozen the code” (i.e. halted development), and we'll ask for a specific git commit hash to be the target of our audit.

If a change comes in halfway through an audit, it means the auditors wasted time on old code. In addition, the auditors would have to stop and incorporate the change, which can have wide-ranging impacts on things like the threat model and other code that interacts with the changed code.

If your code won't be ready by the scheduled start date, let us know. It’s better to delay altogether than try to complete an audit while you continue development.

6. Use a checklist

I've summarized these steps in a markdown checklist that you can copy and paste for use in your own project.

Conclusion

A little bit of work to prepare for an audit will go a long way to getting you the most value out of the process.

If you're thinking about an audit for your smart contracts, or have other questions about smart contract security get in touch! Sooner is better as we're typically booking projects 6 to 8 weeks out.


Thinking about smart contract security? We can provide training, ongoing advice, and smart contract auditing. Contact us.

More posts chevronRight icon