You commissioned a smart contract audit. The engagement is wrapping up and a PDF lands in your inbox. Now what? If you have never received an audit report before, or if past reports felt like opaque documents you filed away and never read, this guide breaks down what a professional audit report contains, how findings are classified, what separates a useful report from a checkbox exercise, and how to act on it to ship secure code.
This is written for CTOs, engineering leads, and founders evaluating audit firms or about to receive their first deliverable. If you are comparing firms, our analysis of audit effectiveness provides the data-driven context behind what follows here.
| Section | What You'll Learn |
|---|---|
| What an Audit Report Is (and Isn't) | The boundaries of what an audit actually covers |
| Standard Report Structure | Every section you should expect in a professional deliverable |
| Severity Classification System | How findings are categorized from Critical to Informational |
| How to Read an Audit Report | Where to start, what to check, what to question |
| Good Reports vs Bad Reports | How to evaluate report quality from the deliverable itself |
| After the Report: The Re-Audit | What happens after you fix findings |
| Public vs Private Reports | When and how to publish your report |
What an Audit Report Is (and Isn't)
A smart contract audit report is a structured assessment of a specific codebase at a specific point in time. It documents the vulnerabilities, design concerns, and code quality issues identified during the engagement, and it serves as the primary deliverable when you engage an audit firm.
Here is what it is not:
It is not a guarantee of security. No audit eliminates all risk. Bugs can exist that the auditors did not find, whether because they fall outside scope, because the time allocation was insufficient, or because the vulnerability class is novel. The report documents what was found. Absence of findings does not mean absence of bugs.
It is not a certificate. Some teams treat audit reports as a compliance badge. That misses the point. The report is a working document that tells your engineering team what to fix and your stakeholders what risks remain. If you file it and forget it, you wasted the engagement.
It is scoped to a specific code version. Every professional report references a commit hash, the exact version reviewed. If you deploy a different version, the findings may not apply. This is what happened with Nomad Bridge, where only 18.6% of the critical contract matched what auditors had reviewed. The commit hash is the single most important metadata in the report.
It typically does not cover operational security. Unless explicitly scoped, an audit covers smart contract code, not key management, multisig configuration, deployment pipelines, or governance processes. Our analysis of $10.77 billion in protocol hacks found that 80.5% of 2024 losses came from off-chain attack vectors. The report addresses the 19.5% that lives on-chain.
A clean report means: "Within the defined scope, timeline, and methodology, the auditing team did not identify vulnerabilities beyond those documented." That is valuable. It is not the same as "this code is safe."
Standard Report Structure
Professional audit reports follow a consistent structure. Formatting varies between firms, but the sections below are industry standard. If a report you receive is missing any of these, ask why.
Executive Summary
A high-level overview written for non-technical stakeholders: your CEO, investors, legal counsel. It should state:
- What was audited (protocol name, contract names, functionality)
- When the audit was conducted (dates of engagement)
- The commit hash of the reviewed code
- A summary of findings by severity (e.g., "2 Critical, 1 High, 4 Medium, 6 Low, 3 Informational")
- The overall assessment, not a pass/fail grade, but a qualitative statement about the codebase's security posture
This is the section most people outside engineering will read. It should be clear enough that a non-developer can understand the risk profile.
Scope and Methodology
This section defines the boundaries of the engagement:
- Files in scope: Which contracts were reviewed, typically listed by file path
- Lines of code: The size of the codebase under review
- Commit hash: The exact version of code audited
- Methodology: Whether the review was manual, automated, or both, and which tools were used (static analyzers like Slither, fuzzers like Echidna, formal verification tools like Certora)
- Auditor team: Who performed the review, and their relevant expertise
- Time allocation: How many person-days or person-weeks were spent
- Out of scope: Explicitly listed items that were not reviewed
This section is where you assess thoroughness. A report that lists only automated tool output should raise questions. A report that does not disclose time spent leaves you unable to judge coverage adequacy.
Findings Table
A summary table listing every issue with its severity, status, and a one-line description. A typical findings table:
| ID | Title | Severity | Status |
|---|---|---|---|
| F-01 | Unrestricted external call in withdraw() enables reentrancy | Critical | Fixed |
| F-02 | Missing slippage check in swap() allows sandwich attacks | High | Fixed |
| F-03 | setFee() has no upper bound, allowing owner to set 100% fee | Medium | Acknowledged |
| F-04 | Event not emitted on ownership transfer | Low | Fixed |
| F-05 | Unused import in Router.sol | Informational | Acknowledged |
Each finding gets a unique identifier. The status column is updated during re-audit to reflect whether findings were fixed, acknowledged, or disputed.
Detailed Findings
The core of the report. Each finding gets its own section containing:
- Description: What the vulnerability is, explained precisely
- Impact: What happens if it is exploited: fund loss, denial of service, privilege escalation, etc.
- Affected code: File path, function name, and specific line numbers
- Proof of concept: A concrete exploit scenario or test case demonstrating the vulnerability. This is what separates a professional finding from a guess.
- Recommendation: A specific, actionable fix, not "consider adding access control" but "add an
onlyOwnermodifier tosetFee()and enforce a maximum fee of 500 basis points"
This section determines whether the report is useful. Vague findings with generic recommendations are worth less than a well-documented vulnerability with a clear remediation path.
Remediation Status
After the initial report, you fix the findings and submit the updated code for re-audit. The final report includes a remediation section tracking the status of every finding:
- Fixed: The auditor verified that the fix resolves the issue
- Acknowledged: The team is aware of the issue but chose not to fix it (with stated rationale)
- Disputed: The team disagrees that the issue is valid (the auditor's response is typically included)
- Partially fixed: The fix addresses part of the issue but introduces new concerns or does not fully resolve it
This section is what users and investors will scrutinize most closely. A report full of "acknowledged" Critical findings is a red flag regardless of how clean the rest looks.
Appendices
Supplementary material that does not warrant its own finding but adds value:
- Gas optimizations: Suggestions for reducing transaction costs that have no security impact
- Code quality observations: Style inconsistencies, documentation gaps, unused variables
- Best practice recommendations: Design pattern suggestions, upgrade path considerations
- Architecture notes: Observations about the overall system design
These are not security findings, but they signal whether the auditor engaged deeply with the codebase or skimmed it.
Severity Classification System
Every finding in an audit report is assigned a severity level. This classification drives prioritization: what must be fixed before deployment, what should be fixed, and what is optional. The system below is industry-standard, though exact definitions vary slightly between firms.
| Severity | Definition | Exploitability | Example |
|---|---|---|---|
| Critical | Direct loss of funds, protocol takeover, or unrecoverable state corruption | Exploitable by any external actor without special conditions | Reentrancy in a withdrawal function allowing an attacker to drain the entire contract balance |
| High | Significant fund loss under specific conditions, privilege escalation, or protocol malfunction | Requires specific conditions or privileged access, but impact is severe | Missing access control on a mint() function allowing any caller to mint unlimited tokens |
| Medium | Limited fund loss, griefing, denial of service, or degraded protocol functionality | Exploitable but with bounded impact or requiring unlikely conditions | Lack of slippage protection in a swap function, enabling sandwich attacks with per-transaction losses |
| Low | Best practice violations, minor inefficiencies, or issues with negligible security impact | Theoretical risk or minimal practical impact | Missing zero-address check on a constructor parameter, which could brick deployment but not affect existing users |
| Informational | Code quality, documentation, style, or design suggestions with no security impact | Not exploitable | Unused imports, inconsistent naming conventions, missing event emissions for non-critical state changes |
Severity in Practice
The distinction between Critical and High often comes down to exploitability conditions. A reentrancy bug in withdraw() that any external actor can trigger in a single transaction is Critical; it is the pattern that cost The DAO $60 million. A missing onlyOwner modifier on setOracle() is High: the impact (draining lending pools via manipulated prices) is equally catastrophic, but the attacker must identify the unprotected function and deploy a malicious oracle contract first.
Medium findings are bounded in impact but real in production. A swap() function with no minimum output parameter enables sandwich attacks on every transaction. Per-trade losses are limited, but the vulnerability affects all users. Low findings describe theoretical risks: a missing zero-address check on a constructor parameter could brick a deployment, but only through deployer error. Informational findings have no exploit path. A pause() function that does not emit an event degrades off-chain monitoring but creates no security risk.
The severity level determines what must be fixed before deployment (Critical, High), what should be fixed (Medium), and what is discretionary (Low, Informational).
How to Read an Audit Report
You received the PDF. Here is the order in which to read it, and what to verify at each step.
1. Start With the Executive Summary
Does it match the engagement you scoped? Verify the protocol name, the functionality described, and the engagement dates. If the summary describes a "lending protocol" but you hired the firm to audit a "DEX aggregator," something went wrong in scoping.
2. Verify the Commit Hash
Open your repository. Check that the commit hash in the report matches the version you intended to have audited. If you pushed changes after the audit started and the report references an older commit, the findings may not apply to your current code. This is the single most common source of audit-to-deployment drift.
3. Read Critical and High Findings First
These are the findings that can cause direct fund loss or protocol compromise. For each one:
- Does the description make sense? Can you follow the exploit logic?
- Is there a proof of concept? Can your team reproduce it?
- Is the recommendation specific enough to implement?
- What is the status: fixed, or merely acknowledged?
If a Critical finding is marked "acknowledged" rather than "fixed," understand exactly why. There are valid reasons (e.g., the finding describes a known design trade-off that is mitigated by off-chain controls), but the rationale should be documented.
4. Check the Methodology Section
Was this a manual review, automated scan, or both? The strongest audits combine manual review from experienced Solidity auditors with automated tools (static analysis, fuzzing, symbolic execution) and, where warranted, formal verification.
If the methodology section says only "we used Slither" and lists tool output, you received an automated scan, not an audit. Automated tools are necessary, including AI-assisted tools like Sentinel that are advancing rapidly, but they do not replace human review for business logic and cross-contract interaction analysis.
Check the time allocation. A 10,000-line DeFi protocol audited in three person-days did not receive adequate coverage. Typical ratios are one person-day per 200-500 lines of complex Solidity.
5. Review Medium and Low Findings
These are less urgent but still worth fixing. Medium findings often describe griefing or denial-of-service vectors that will be exploited once your protocol has meaningful TVL. Ignoring them because they are not "Critical" is how protocols end up on Rekt News for preventable issues.
6. Read the Appendices
Gas optimizations and code quality notes reveal engagement depth. A report with detailed architecture observations was produced by someone who read every line. A report with zero appendices may indicate a surface-level review.
What Separates a Good Report From a Bad One
You can evaluate audit quality directly from the deliverable. You do not need to be a Solidity engineer to distinguish a thorough report from a superficial one.
Signs of a Good Report
- Specific code references for every finding: exact file, function, and line numbers
- Proof of concept for Critical and High findings: a concrete exploit scenario or executable test, not a theoretical description
- Actionable remediation guidance: "add a reentrancy guard to
withdraw()" is actionable; "consider potential reentrancy issues" is not - Transparent methodology: manual review process, tools used, time spent, and named auditors
- Clear scope boundaries: explicit documentation of what was and was not reviewed
- Thorough remediation verification: each "Fixed" finding is confirmed resolved without introducing new issues
Signs of a Bad Report
- Vague findings: "potential reentrancy vulnerability" without citing specific functions or lines
- No proof of concept: claims of exploitability with no exploit path, transaction sequence, or test case
- Generic recommendations: "follow best practices" without explaining which practice or how it applies
- No methodology section: no disclosure of how the audit was conducted or how much time was spent
- Raw tool output as findings: unfiltered Slither or Mythril warnings with no triage or false positive filtering
- Inflated finding counts: dozens of Informational items padding a report that missed substantive issues
If you are currently evaluating firms and want to compare what different auditors deliver, reach out to our team for details on what a SigIntZero engagement includes.
After the Report: The Re-Audit
The initial audit report is not the final deliverable. The workflow is:
- Receive the initial report with all findings documented
- Fix the findings in your codebase, prioritizing Critical and High severity
- Submit the updated code for re-audit verification
- Receive the final report with updated remediation statuses
What a Re-Audit Covers
The re-audit scope is typically limited to verifying fixes for the findings in the initial report. Auditors check that:
- Each fix resolves the reported vulnerability
- The fix does not introduce new vulnerabilities
- The fix does not break related functionality
A re-audit is not a full second audit. Significant changes beyond the reported findings (new features, major refactors, new external integrations) fall outside the re-audit scope and require a separate engagement.
Timeline
Re-audits typically take one to three days depending on finding count and fix complexity. Simple fixes (adding a modifier, updating a check) verify quickly. Complex fixes (redesigning economic logic, changing state machines) take longer and carry higher risk of introducing new issues.
The Final Report
The final report, with remediation statuses for every finding, is the document you publish and reference in communications. The initial report with unresolved findings is a working document, not a public artifact.
Public vs Private Reports
Once the final report is complete, you decide whether to publish it. The short answer: publish it.
Why Public Reports Matter
Public reports serve four functions: they give users evidence that the code was professionally reviewed, they satisfy investor due diligence requirements, they create accountability (a "Fixed" status is now a public commitment), and they contribute to the ecosystem by helping other teams learn from documented vulnerabilities.
What to Publish and Where
Publish the full final report. Redaction undermines credibility. If users see redacted sections, they assume the worst. The only valid reason to redact is information about an unresolved vulnerability that could enable exploitation, which should not exist in a final report where Critical and High findings are resolved.
Where to publish:
- Your project's GitHub repository: a
/auditsdirectory is the convention - Your documentation site: linked from the security section
- Audit aggregators: Solodit, DeFi Safety, DefiLlama's security listings
- Your audit firm's portfolio: many firms publish client reports (with permission) on their website
Private reports invite skepticism. "We were audited by [firm]" without a published report is an unverifiable claim. In 2026, publishing the report is the minimum standard.
What This Means for Your Next Engagement
An audit report is not a compliance artifact. It is a technical document that tells you what is wrong with your code, what happens if you do not fix it, and how to fix it. The quality of that document (the specificity of its findings, the rigor of its methodology, the clarity of its recommendations) determines whether the audit was worth the investment.
When evaluating firms, ask to see a sample report. Check it against the criteria in this guide. Does it have proofs of concept? Are findings specific or vague? Is the methodology transparent?
If you are preparing for your first audit or evaluating whether your current partner delivers at the standard your protocol requires, reach out to our team. We will walk through a SigIntZero engagement end to end so you know exactly what to expect.



