Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
Free 30-min Web3 Consultation
Book Now
Smart Contract Security Audits
Learn More
Custom DeFi Protocol Development
Explore
Full-Stack Web3 dApp Development
View Services
LABS
Guides

How to Prepare for Re-Audits

A technical guide for developers on preparing smart contract code for a security re-audit. Covers triage, remediation, documentation, and submission.
Chainscore © 2026
introduction
INTRODUCTION

How to Prepare for Re-Audits

A proactive guide for developers and project leads on structuring and executing a successful security re-audit.

A smart contract re-audit is a focused security review conducted after initial audits and deployment, typically triggered by major upgrades, critical bug fixes, or significant changes in the threat landscape. Unlike the initial audit, a re-audit is not about establishing a baseline of security but about verifying that the system's security posture has been maintained or improved. It is a critical risk management practice for any protocol handling substantial value, as it addresses the reality that codebases are living entities. Projects like Compound and Aave undergo regular re-audits for every major governance proposal and version upgrade, setting a standard for the industry.

Effective preparation is the single biggest factor in a re-audit's cost, efficiency, and outcome. The goal is to provide auditors with a comprehensive, well-organized audit package that minimizes back-and-forth clarification and maximizes deep technical review time. This package should clearly delineate what has changed since the last review. Start by creating a precise diff between the previously audited commit hash and the new state of the codebase. Tools like git diff or dedicated platforms are essential. This diff, accompanied by a changelog, forms the core of your scope definition, telling auditors exactly which lines, functions, and files to scrutinize.

Beyond the raw code changes, your preparation must provide context. For each modification, document the reason for the change (e.g., "Optimization of fee calculation," "Fix for reentrancy vulnerability CVE-2023-..."), the potential security implications considered by the development team, and any mitigations already implemented. Include updated technical specifications, architecture diagrams, and a list of assumptions and invariants. This context transforms the auditor's task from forensic archaeology to targeted analysis. Furthermore, ensure all existing tests pass and consider writing new, specific unit and integration tests for the changed logic to demonstrate its intended behavior and robustness before the audit begins.

prerequisites
HOW TO PREPARE

Prerequisites

A successful re-audit requires meticulous preparation. This guide outlines the essential steps to organize your codebase, documentation, and team before engaging an audit firm.

Before initiating a re-audit, you must have a clear scope of work. This is not just a list of changed files. Define the specific modules, functions, and security properties to be reviewed. For a smart contract upgrade, this includes the new logic, any modified dependencies, and the integration points with the existing system. A precise scope prevents scope creep, ensures the auditor focuses on critical changes, and provides a basis for the final report. Tools like git diff against the previously audited commit hash are essential for generating an initial change list.

Your code must be in a production-ready state. The repository should be stable, with all tests passing and no known critical bugs. Auditors will not review moving targets. Ensure your development environment is documented (e.g., using a README.md with specific Node.js or Rust versions) and that the code compiles without errors. This also means having a comprehensive test suite with high coverage for the scoped components, including unit tests, integration tests, and, ideally, formal verification or fuzzing tests for critical invariants.

Complete and organized documentation is non-negotiable. This includes: a technical specification detailing the system's architecture and security assumptions, NatSpec comments for all public and external functions, and a document listing all known issues and their mitigation status. Provide the auditor with access to previous audit reports, the team's internal review notes, and any relevant threat models. This context allows auditors to understand the system's evolution and focus their efforts on new or unresolved risks.

Finally, designate a technical point of contact from your team. This person will manage the audit timeline, coordinate communication, and be prepared to answer detailed technical questions about the code's intent and design decisions. They should have the authority to schedule meetings, provide clarifications, and review preliminary findings. Establishing a clear communication channel (e.g., a dedicated Discord channel or email thread) and agreeing on a schedule for daily or weekly syncs will streamline the entire process.

key-concepts
SECURITY

Key Concepts for Re-Audits

A re-audit is a focused security review of a smart contract after initial deployment and changes. These concepts help developers prepare effectively.

01

The Change Log

A detailed, version-controlled record of all modifications since the last audit is the single most important artifact. It should include:

  • Code changes: Specific files, functions, and lines modified.
  • Reason for change: Bug fix, feature addition, or optimization.
  • Impact analysis: How the change affects existing logic and dependencies.

Without a precise change log, auditors must perform a full diff, wasting time and increasing the risk of missing subtle, high-impact issues.

02

Scope Definition

Clearly define what is and is not in scope for the re-audit. A vague scope leads to inefficiency.

  • In-Scope: Newly added contracts, modified functions, and any code paths directly touched by the changes.
  • Out-of-Scope: Unchanged, previously audited code (unless integration points are affected).
  • Integration Points: Critical areas where new code interacts with the existing system, such as state variable access or cross-contract calls.

Providing a mapped scope document allows auditors to focus their effort where risk is highest.

03

Test Coverage Analysis

Updated and comprehensive tests are a strong signal of code quality. Prepare:

  • Coverage Reports: Show line and branch coverage for the modified code, aiming for >95%.
  • Test Scenarios: Document new unit and integration tests written for the changes, especially for edge cases and failure states.
  • Fork Test Results: Evidence of tests run on a forked mainnet (e.g., using Foundry's forge test --fork-url) to simulate real environment behavior.

This demonstrates due diligence and helps auditors verify logic independently.

04

Documentation & Specifications

Updated technical documentation prevents misinterpretation of the system's intended behavior.

  • NatSpec/Comments: Ensure all new and modified functions have clear @dev and @param annotations.
  • Architecture Diagrams: Visualize how new components integrate with the existing system.
  • Formal Specification: For critical protocols, consider a written specification in a framework like Certora Prover or Halmos. This allows for formal verification of specific properties.

Clear specs act as a source of truth, reducing back-and-forth clarification during the audit.

05

Deployment & Admin Controls

Re-audits must review any changes to the system's operational security and upgradeability.

  • New Admin Functions: Any added onlyOwner or privileged functions, with a clear rationale for their necessity.
  • Timelock & Multisig: If changes affect governance, detail the timelock duration and multisig signer configuration.
  • Emergency Procedures: Document updated pause mechanisms, upgrade paths, and incident response plans.

Auditors will scrutinize these controls as they represent centralization risks and single points of failure.

06

Known Issues & Mitigations

Proactively disclosing known limitations builds trust and guides the audit.

  • Acknowledged Vulnerabilities: List any minor issues found internally or by the community, along with the decision to accept or mitigate them.
  • Gas Optimization Trade-offs: Note any code changes made for efficiency that may have slight security trade-offs.
  • Third-Party Dependencies: Declare any new external contracts or oracles used, and the due diligence performed on them (e.g., audit reports for used libraries).

This transparency allows auditors to validate your risk assessment rather than discover it.

triage-process
PREPARATION

Step 1: Triage the Initial Audit Report

Effectively processing the initial findings is the critical first step in preparing for a re-audit. This triage process transforms a raw list of issues into a structured, actionable plan.

Begin by categorizing every finding from the initial audit report. Standard classifications include Critical, High, Medium, Low, and Informational. This severity is based on the exploit's impact and likelihood. For example, a bug allowing unauthorized fund withdrawal is Critical, while a missing event emission is typically Low. This initial sort provides a clear priority order for your remediation efforts, ensuring the most dangerous vulnerabilities are addressed first.

Next, analyze each finding's root cause, not just its symptom. A report might list "Incorrect Access Control" in multiple functions. Your job is to determine if these are isolated logic errors or symptoms of a flawed permission architecture. Understanding the underlying pattern is essential for an effective fix. Use tools like Slither or manual code review to trace the vulnerability through the codebase, identifying shared libraries or inherited contracts that may need refactoring.

For each finding, create a detailed remediation plan. This goes beyond a simple "fix". Document the specific code changes required, any associated test updates, and the expected gas or security impact. For instance, fixing a reentrancy issue might involve applying the Checks-Effects-Interactions pattern and adding a reentrancy guard from OpenZeppelin. This plan becomes your engineering ticket and is vital for demonstrating to the re-auditor that the issue was understood and properly resolved.

Finally, compile a Master Findings Log. This is a single source of truth (like a spreadsheet or project management ticket) that tracks each finding's ID, description, severity, assigned developer, fix status, and link to the remediation plan. This log is indispensable for internal coordination and will be a key document you submit to the auditing firm at the start of the re-audit, proving your team's thoroughness and organization.

remediation-coding
ACTION PLAN

Step 2: Implement Remediations

After receiving your audit report, the critical next phase is to methodically address the identified vulnerabilities. This guide details the process of implementing fixes, verifying their correctness, and preparing your code for a successful re-audit.

Begin by categorizing the findings from your audit report. Prioritize critical and high-severity issues, such as reentrancy, access control flaws, or incorrect math that could lead to fund loss. Create a dedicated branch in your version control system (e.g., git checkout -b audit-fixes) to isolate all remediation work. For each finding, carefully review the auditor's description, the vulnerable code location, and the recommended fix. Do not make changes based solely on the title of the finding; understand the root cause.

When implementing fixes, follow the auditor's recommendations closely, but also understand the underlying principle. For a reentrancy vulnerability, simply adding a nonReentrant modifier from OpenZeppelin might be the fix, but you must ensure it's applied to all relevant functions. For logic errors, rewrite the flawed logic and add comprehensive unit tests that reproduce the exact bug scenario to prove it's resolved. Never implement "quick fixes" that only address the symptom; always solve the core vulnerability. Document each change with a commit message that references the specific finding ID from the report.

After applying all fixes, you must conduct rigorous internal verification before submitting for re-audit. This involves: 1) Running your full test suite to ensure no regressions, 2) Writing new, targeted tests for each remediated vulnerability, 3) Performing a manual code review of all changes, ideally by a developer who didn't write the original code. Tools like Slither or Mythril can be run again for a preliminary automated check. This step is crucial to avoid submitting code with incomplete or incorrect fixes, which wastes time and audit credits.

Prepare your submission for the re-audit. This typically involves creating a clear summary document for the auditors. List each original finding, its status (Fixed, Acknowledged, Contested), and the commit hash or code diff that implemented the fix. For findings you are contesting or believe are invalid, provide a detailed technical justification. Consolidate all fixed code into a single branch or pull request. The goal is to make the auditor's job as efficient as possible, allowing them to verify your fixes without searching through the entire codebase again.

Finally, consider the scope of the re-audit. Most firms offer a focused re-audit that only examines the remediated issues and their immediate context, which is faster and less expensive. Ensure your deployment and testing scripts are up-to-date so the auditor can easily verify the contract's behavior. A well-prepared re-audit package demonstrates professionalism, reduces back-and-forth communication, and significantly increases the likelihood of a clean final report, moving your project securely toward mainnet launch.

REMEDIATION PATTERNS

Common Fix Examples

Examples of common vulnerability fixes and their implementation approaches.

Vulnerability TypeInadequate FixRecommended FixAuditor Notes

Reentrancy Guard

Using nonReentrant modifier on only one function

Apply nonReentrant to all state-changing functions in the contract

Partial protection leaves attack vectors open.

Access Control

Hardcoded owner address in constructor

Implement a role-based system (e.g., OpenZeppelin AccessControl)

Hardcoded addresses prevent future upgrades and are error-prone.

Integer Overflow

Using unchecked blocks to silence compiler warnings

Use SafeMath library or Solidity 0.8+ built-in checks; validate inputs

Unchecked math is dangerous and should be explicitly justified.

Oracle Price Manipulation

Using a single spot price from one DEX

Use a time-weighted average price (TWAP) from a reputable oracle (e.g., Chainlink)

Spot prices are highly manipulable in low-liquidity pools.

Front-Running

No mitigation for public mint or claim functions

Implement commit-reveal schemes or use a private mempool service

Public transactions are transparent and vulnerable to MEV bots.

Centralization Risk

Single EOA holds upgradeability proxy admin keys

Use a multi-sig wallet or a decentralized governance timelock

A single point of failure compromises the entire protocol's security.

Gas Limit Issues

Unbounded loops in functions that iterate over user arrays

Implement pagination, limit array sizes, or use mappings with withdrawal patterns

Unbounded operations can cause transactions to fail as the protocol grows.

testing-verification
STEP 3

Test and Verify Fixes

After addressing the audit findings, you must rigorously test the implemented fixes to ensure they are correct, complete, and do not introduce new vulnerabilities.

The first step is to re-run the original audit tooling that discovered the issues. This includes both automated static analysis tools like Slither or Mythril and any custom scripts the auditors used. The goal is to confirm that the specific vulnerability reports are now closed. However, a clean scan is not sufficient. You must also perform regression testing to ensure the fixes didn't break existing functionality. Update your unit and integration test suites to cover the patched code paths, verifying both the security fix and the intended contract behavior.

For complex or critical fixes, especially those involving state changes or access control, create dedicated proof-of-concept (PoC) tests. These are small, standalone scripts that attempt to exploit the original vulnerability. The fix is only valid if these PoC tests now fail. For example, if you patched a reentrancy bug, write a test where a malicious contract attempts to re-enter; it should revert. Tools like Foundry's forge test are ideal for this, allowing you to write exploit simulations in Solidity directly.

Next, conduct manual code review of the changes. This review should focus on the context of the fix: is the patch applied in all required locations? Does it correctly handle edge cases? A common mistake is fixing one instance of a pattern while missing another similar vulnerability elsewhere in the codebase. Compare the diff side-by-side with the auditor's report to ensure the remediation fully addresses the root cause, not just a symptom.

Finally, consider the system-level impact. Some fixes, like adjusting fee calculations or pausing mechanisms, require broader integration testing. Use a forked mainnet environment (with tools like Foundry's cheatcodes or Tenderly forks) to simulate the fix under realistic market conditions and high load. Verify that interactions with other contracts, such as oracles or treasury managers, still function correctly. Only after all tests pass and the code review is complete should you proceed to the re-audit.

pre-submission-checklist
RE-AUDIT PREPARATION

Step 4: Pre-Submission Checklist

A thorough pre-submission review is critical for a successful re-audit. This checklist helps you address common issues and streamline the process.

01

Review Initial Audit Report

Before submitting for a re-audit, conduct a line-by-line review of the original audit report. Ensure every finding is addressed, not just marked as fixed. For each finding:

  • Categorize fixes: Distinguish between direct code patches, configuration changes, and architectural redesigns.
  • Document rationale: For any findings marked as "Acknowledged" or "Won't Fix," provide a detailed technical justification.
  • Update tests: Add or modify unit and integration tests to cover the patched vulnerabilities, ensuring they fail before the fix and pass after.
02

Conduct Internal Security Review

Perform a focused internal review targeting the areas of previous vulnerabilities. This is more efficient than a full new audit.

  • Static Analysis: Run tools like Slither or Mythril on the updated codebase to catch new issues introduced by fixes.
  • Differential Review: Use git diff against the audited commit to review every change made. Look for side effects and regressions in related functions.
  • Peer Review: Have at least one developer who did not write the original code review all security-related changes.
03

Update Documentation & Comments

Clear documentation is essential for auditors to verify fixes quickly. Inadequate documentation is a common cause of re-audit delays.

  • Code Comments: Add NatSpec comments for all modified functions, explicitly referencing the audit finding ID (e.g., // Fix for SC-AUDIT-2024-001).
  • Technical Report: Prepare a separate summary document mapping each finding to the specific commit hash, code diff, and test case.
  • Deployment Notes: Document any changes to constructor arguments, initialization parameters, or privileged roles that resulted from the audit.
04

Verify Test Coverage & Simulations

Auditors will scrutinize your test suite. Prove your fixes are robust under edge cases.

  • Coverage Metrics: Aim for >95% branch coverage for modified contracts. Use tools like solidity-coverage.
  • Fork Tests: Run integration tests on a forked mainnet (using Foundry or Hardhat) to simulate real-world state and price conditions.
  • Invariant Testing: For complex protocols, use fuzzing (Foundry's forge fuzz) or invariant tests (Foundry's forge invariant) to test system properties hold after changes.
05

Prepare the Submission Package

Organize all materials to expedite the auditor's onboarding. A messy submission increases review time and cost.

  • Repository: Create a clean, tagged release (e.g., v1.0.1-audit-ready) with the final code for review.
  • Audit Scope: Explicitly list the files and contracts in scope. If the scope changed from the first audit, justify why.
  • Setup Scripts: Include a README.md with one-command setup (e.g., make test), ensuring all dependencies are pinned.
  • Contact: Designate a primary technical contact available to answer auditor questions within 24 hours.
06

Assess Scope & Budget for New Issues

Re-audits often uncover new, unrelated issues. Plan for this possibility to avoid project delays.

  • Buffer Time: Allocate a 15-20% time/budget buffer in your project timeline for addressing new critical or high-severity findings.
  • Triage Protocol: Define a decision framework for new findings: Will you fix them immediately, postpone, or accept the risk?
  • Contingency Commits: Have pre-approved, minor code improvements ready that can be swapped in if auditors find low-severity issues in adjacent code, maximizing the engagement's value.
submission-package
RE-AUDIT PREPARATION

Step 5: Prepare the Submission Package

A well-organized submission package is critical for an efficient and effective re-audit. This step details the essential components and structure to provide to the auditing firm.

The primary goal of your submission package is to provide the auditors with a complete and unambiguous view of the changes made since the initial audit. This package should include the final, production-ready code, not a work-in-progress branch. Start by creating a comprehensive changelog that documents every modification. For each change, specify the file, line numbers, the reason for the change (e.g., "Fix for finding H-01: Unchecked return value"), and a brief technical explanation. This document is the auditor's roadmap and drastically reduces the time spent on triage.

Your package must contain the exact codebase to be reviewed. This includes all smart contracts, libraries, interfaces, and deployment scripts. Use a version-controlled diff (like a Git patch file or a link to a pull request comparing the old and new commit hashes) to highlight the precise modifications. Alongside the code, include the original audit report with your annotations, clearly marking which findings were addressed, partially addressed, or contested. For any contested findings, prepare a separate technical rationale explaining why you believe the issue is invalid or out of scope.

Beyond the code diff, provide the auditors with the necessary context to verify your fixes. This includes updated test suites that demonstrate the corrections work as intended. For complex fixes, consider adding specific unit or integration tests that target the patched vulnerability. Also, include any updated documentation, such as NatSpec comments, security considerations in your README, and details of any new dependencies or compiler version changes. A clear Makefile or set of scripts to build, test, and deploy the project will help the auditors replicate your environment quickly.

Finally, structure your submission as a single, well-organized archive (like a .zip file) or a dedicated repository tag. A suggested folder structure includes /contracts (final source), /diffs (patch files), /test (updated tests), and /docs (changelog, annotated report, rationale). Proactively address common questions by including a DISCLAIMERS.md file noting any known limitations or areas intentionally out of scope for the re-audit. A complete package demonstrates professionalism and directly contributes to a faster, more focused review cycle.

RE-AUDIT PREPARATION

Frequently Asked Questions

Common questions from developers preparing for a smart contract security re-audit. These answers cover process, cost, and technical best practices.

A re-audit is required after significant modifications to already-audited code. The primary triggers are:

  • Major Feature Additions: Introducing new core logic, such as a novel tokenomics model or complex governance mechanism.
  • Critical Vulnerability Fixes: Patching a high or medium-severity issue found in a previous audit requires verifying the fix and checking for new side-effects.
  • Protocol Upgrades: Migrating to a new compiler version (e.g., Solidity 0.8.x to 0.9.x) or integrating with a new external dependency (like a different oracle or bridge).
  • Formal Verification: If your audit scope expands to include formal verification, a re-audit is necessary to model and prove the new properties.
conclusion
SECURITY BEST PRACTICES

How to Prepare for Re-Audits

A proactive approach to re-audits ensures your smart contract remains secure through its lifecycle and can significantly reduce costs and time.

Treating a smart contract audit as a one-time event is a critical security mistake. The codebase is a living system; new features, integrations, and dependency updates introduce new risks. A re-audit is a focused security review of changes made since the last audit. To prepare effectively, maintain a detailed changelog from day one. This log should catalog every modification, library upgrade, and configuration change, linking each entry to a specific pull request or commit hash. This creates an immutable, auditable trail for security engineers.

Before engaging an auditor, conduct a rigorous internal review. This involves running your updated test suite, performing a diff analysis between the previously audited and current code versions using tools like git diff, and re-executing static analysis tools such as Slither or Foundry's forge inspect. The goal is to identify and fix obvious vulnerabilities and logical inconsistencies internally, ensuring the auditor's time is spent on complex, novel risks rather than basic issues. This step directly reduces audit scope and cost.

Compile a comprehensive re-audit package for the security firm. This should include: the finalized changelog, the specific commit hash of the audited version, the full diff output, updated technical documentation, and a list of known issues or trade-offs you've already identified. Clearly define the scope of work: specify which new contracts, functions, or modified lines are in scope and, just as importantly, which legacy, unchanged code is out of scope. This clarity prevents scope creep and misaligned expectations.

Integrate audit readiness into your development workflow. Adopt a security-focused branching strategy where all changes destined for a re-audit are merged into a dedicated audit branch. Use inline NatSpec comments to explain complex logic and security assumptions for the auditor. Furthermore, ensure your team understands common vulnerability patterns from the previous audit report to avoid reintroducing similar flaws. This cultural shift turns security from a checkpoint into a continuous process.

Finally, budget and plan for re-audits proactively. Factor them into your project roadmap alongside feature releases. Building a relationship with a reputable audit firm allows for streamlined subsequent reviews, as they are already familiar with your codebase and architecture. The process is not just about finding bugs; it's a quality assurance ritual that validates your development practices and provides ongoing assurance to your users and stakeholders in a high-stakes environment.

How to Prepare for Re-Audits: A Developer's Guide | ChainScore Guides