Back to the engineering blog

Don't Audit Your Smart Contracts Before You Fix the Obvious Bugs

Sending smart contracts for audit too early is a common, expensive mistake that teams make, often due to overlooking basic development hygiene.

By

Don't Audit Your Smart Contracts Before You Fix the Obvious Bugs

Getting a smart contract audited is often one of the largest expenses for a new Web3 project. It's a critical step, but many teams rush into it, submitting code that isn't ready. This ends up wasting valuable audit time on issues that could have been caught much earlier in the development cycle.

I’ve seen firsthand how teams eager to launch push code to auditors before it's truly polished. The auditors then spend their precious, high-cost hours pointing out simple bugs, style guide violations, or even basic logical flaws that could have been identified with standard development practices.

What 'Ready for Audit' Really Means

Before even thinking about an audit, your smart contract codebase should meet a baseline of quality. Think of it like this: you wouldn't send a rough draft of a novel to a publisher and expect them to proofread it for typos, structural issues, and story inconsistencies all at once. An auditor's job is to find deep, subtle security vulnerabilities, not to be your QA team or Linter.

Here’s a practical checklist of what should be in place before you send your contracts off, based on standard industry advice [1]:

1. Comprehensive Unit and Integration Tests

This is non-negotiable. Every function, every edge case, every potential interaction should be covered by tests. If your tests aren't catching basic bugs, they aren't good enough. Focus on:

  • Positive paths: Does the contract behave as expected when valid inputs are given?
  • Negative paths: Does it correctly revert or handle invalid inputs, insufficient funds, or unauthorized calls?
  • Edge cases: What happens at the maximum or minimum values? What about zero values?
  • Re-entrancy: Have you specifically tested for re-entrancy vulnerabilities in functions that interact with external contracts?

Tools like Hardhat or Foundry offer excellent testing frameworks. Use them rigorously.

2. Clear Documentation and Specifications

Auditors need to understand what your contract is supposed to do. This isn't just about comments in the code. It includes:

  • High-level architecture: How do different contracts interact? What are their roles?
  • Function-level descriptions: What does each public function achieve? What are its pre-conditions and post-conditions?
  • Threat model: What are the known risks, and how are you mitigating them? What attack vectors have you considered?

Well-written NatSpec comments in Solidity are a great start, but a separate document outlining the system's design and intent is invaluable.

3. Static Analysis and Linting

Run automated tools like Slither, Mythril, or Solhint. These tools catch common vulnerabilities, style guide violations, and potential gas optimizations automatically. They're cheap to run and can save auditors significant time by flagging low-hanging fruit.

4. Gas Optimization Passes

While not strictly a security issue, inefficient code can sometimes lead to unexpected behaviors or make certain attacks more viable by making transactions prohibitively expensive. Optimizing for gas before the audit means auditors don't have to flag obvious inefficiencies, letting them focus on deeper security issues.

5. Dependency Review

If you're using libraries like OpenZeppelin, ensure you're using stable, audited versions. Don't pull in experimental code or unverified external dependencies without careful consideration.

The Cost of Rushing

When a team sends unfinished code to an auditor, several things happen:

  • Higher audit cost: Auditors charge by the hour or by the scope. If they're finding basic bugs, they're spending time on something you should have found, inflating the bill.
  • Delayed launch: Findings that require significant refactoring mean longer iteration cycles and push back your launch date.
  • Reputation risk: If auditors consistently find basic errors, it can impact their perception of your team's engineering rigor.

I always tell teams to aim for the audit to be the final verification layer, not the first line of defense. The goal is for auditors to confirm the security of a well-engineered system, not to debug a half-finished one.

Building secure contracts means prioritizing quality throughout the development process, not just at the audit stage. This approach leads to better outcomes, faster launches, and a stronger foundation for your project.

---

Sources:

[1] What to have ready before your first smart contract audit. (2023, November 28). DEV Community. https://dev.to/bloqarl/what-to-have-ready-before-your-first-smart-contract-audit-580b