Start with scope, not findings
The first thing to read in any audit report is the scope section, and most readers skip it entirely. It tells you what was actually examined — and everything outside it was not looked at, regardless of how thorough the rest of the document appears.
Three things to extract before you read a single finding:
- The commit hash. An audit describes one specific version of the code. If the report names a commit and the deployed contract does not match it, the report is describing something else. This is the single most common way an audit is misleading without anyone lying.
- The file list. A protocol of fifteen contracts with four in scope is a partial audit. That can be perfectly reasonable — but "audited" on the front page and four files in the scope section are two different claims.
- The explicit exclusions. Good reports list them: off-chain components, admin key management, oracle assumptions, economic modelling. A report with no exclusions section has not thought about its own limits, or does not want you to.
What severity actually means
Severity is not a single measurement. It is impact and likelihood combined, and different auditors combine them differently — which is why the same bug can be a high in one report and a medium in another without either being dishonest.
| Severity | Roughly means | What to do |
|---|---|---|
| Critical | Funds can be taken or frozen, by anyone, now | Do not deploy. If deployed, pause and fix immediately |
| High | Serious loss, but needs a condition — a role, a state, a specific ordering | Fix before launch, no exceptions |
| Medium | Real impact under realistic but narrower conditions | Fix, or document why you accept it |
| Low | Limited impact, or needs an unlikely precondition | Fix when convenient |
| Informational | Style, hygiene, gas, or a note about intended behaviour | Read them — centralization findings often hide here |
Two things this table cannot tell you. First, severity is contextual: unbounded gas growth is informational in a contract with ten users and critical in one with a hundred thousand. An auditor who does not know your usage patterns cannot always rank correctly, and you can.
Second, mediums compound. Three medium findings that individually need an unlikely condition can chain into one attack where the first creates the condition for the second. Human reports sometimes catch this and say so; generated reports rank findings individually and leave the synthesis to you, which is worth remembering when reading any automated report, ours included.
The status column is the whole document
Every finding should have a resolution: fixed, acknowledged, or disputed. This column is where most of the real information lives, and it is the one people skim past fastest.
Fixed should be followed by a commit hash. "Fixed" with no reference, in a report that was never re-reviewed, means the team said they fixed it. That may be true. It has not been verified.
Acknowledged means the team read it and chose not to change anything. Sometimes that is correct and well reasoned. Sometimes it is a critical marked acknowledged with no explanation, which tells you a great deal about the team.
Disputed means the team disagrees the finding is real. Read both arguments. A well-argued dispute is a good sign about a team; a dismissive one is not.
A report where every finding is "fixed" and none carries a commit hash is a report about intentions.
Centralization findings deserve your attention
These get filed as informational or low almost universally, because they are not exploitable by an attacker. They are, however, usually the findings that matter most to anyone deciding whether to put money in — because they describe what the team can do to you, deliberately, without any bug at all.
Read every one and turn it into a plain question:
- Can the owner mint more tokens? Then supply is a promise, not a property.
- Can the owner pause transfers? Then your exit is at their discretion.
- Can the owner upgrade the implementation? Then the audited code is the current code, not the final code.
- Can the owner change fees without a limit? Then the fee is whatever they later decide.
- Is the owner a single key or a multisig with a timelock? This one difference changes everything above.
None of these makes a project bad. Upgradeability and pausability exist for good reasons. But they are trust assumptions, and a report that lists them is telling you what you are trusting.
What a clean report does and does not mean
A report with no critical or high findings means the auditor did not find any within their scope, in their timebox, with their methods. It does not mean there are none.
Read a clean report with two questions. Was the scope wide enough for the absence of findings to be meaningful — a clean report on four files of a fifteen-file protocol says little about the protocol. And does the report show its work: does it list what was checked and passed, or only what failed? Coverage that only reports failures cannot distinguish "we checked and it was fine" from "we did not check". That is why our reports include a standards coverage grid showing the SWC and OWASP items that were tested and passed, not only the ones that fired.
Six questions to ask of any audit report
- Does the commit hash match what is deployed? If not, the report describes different code.
- What is in scope, and what is explicitly excluded?
- Was there a fix-review round? If not, every "fixed" is unverified.
- What do the centralization findings say the owner can do?
- Does the report show what passed, not just what failed?
- What did the team say about findings they did not fix?
If you are choosing an auditor rather than reading a finished report, the same scepticism applies earlier in the process — the questions that expose a weak auditor are on the audit companies page. And if you want to see how a generated report is structured before commissioning anything, the free testnet scan produces the real document.