DeFi Security AllianceRequest an audit
Menu

Tooling

Solidity Static Analysis: Triage Findings by Impact and Confidence

Treat scanner output as a set of claims to investigate. Solidity static analysis triage should preserve the reported impact and confidence, then establish reachable behavior before a finding is fixed, suppressed or sent to an auditor.

Conveyor sieve sorting small cubes into three trays, representing static analysis triage of Solidity scanner findings.

Key facts

Original measurement
100 documented detectors in the fetched Slither catalog
High-impact subset
14 of 29 High-impact detectors had Medium confidence
Confidence counts
59 High and 41 Medium labels across the catalog
Benchmark limit
Documentation census; no measured false-positive rate

Tools and what each detects

A scanner result has at least two independent dimensions: the consequence of a real issue and the confidence that the reported pattern represents that issue. Our census of Slither's published detector table found both dimensions explicitly labeled. Triage becomes less reliable when an export flattens them into a single severity column.

Solidity static analysis examines source or intermediate representations without executing the full application behavior under every possible state. It can identify patterns worth investigating and help reviewers understand the code. It cannot replace a specification of the economic properties the protocol is meant to preserve.

Slither provides vulnerability detectors as well as program-analysis facilities and visual information about contracts. Its README explains that project analysis relies on the underlying compilation framework when dependencies are present. A tool that failed to compile the relevant targets has not produced a clean assessment of those targets, even if the remaining output contains no high-severity findings.

Aderyn describes an architecture based on Solidity abstract syntax trees and custom detectors. The existence of another analyzer gives a team another inspection mechanism; it does not make the union of the tools a complete vulnerability inventory. Establish which source paths each run actually processed before comparing their findings.

Compare supported inputs and limits in the static analysis tool comparison before choosing which analyzers to run.

Interpret tool outputs according to their purpose
OutputUseful evidenceConclusion it cannot establish
Detector findingA named rule matched a location under the recorded configurationThe reported impact is reachable in this application
Compiler failureA target or dependency was not analyzed successfullyThe failed target has no vulnerabilities
Program structure outputA call or inheritance relationship was extractedEvery economic assumption was checked
Suppressed resultA finding was intentionally excluded from the visible listThe underlying behavior has been fixed

Semgrep-style rules can supplement this process when a team maintains rules for its own code conventions. Treat the selected rule set and its language support as part of the evidence. A generic pattern that recognizes an unsafe-looking call still needs an application-specific explanation of reachability and authority.

For an incomplete scan, record the analysis stage that failed. A missing compiler, unresolved import or unsupported construct should remain an execution problem until it is resolved. It should not become a false-positive classification, because no supported candidate was evaluated. The auditor needs both the successfully analyzed targets and the targets that the tool could not inspect under the recorded configuration.

Impact and confidence in the detector catalog

Method

Source and selection
All numbered detector rows in the fetched Slither README detector table; classify the documented impact and confidence columns.
Retrieved
Observation
All numbered rows of the Slither README detector table were parsed; the unit is a documented detector, not a finding in deployed code.

Results

Recorded observations on
Documented impactDetectorsPopulation
High29100 detector rows
Medium28100 detector rows
Low17100 detector rows
Informational21100 detector rows
Optimization5100 detector rows

The catalog contained 100 detectors. Confidence was labeled High for 59 rows and Medium for 41. Within the High-impact group, 14 of 29 detectors carried Medium confidence.

These counts explain why impact alone is a poor work-ordering rule. A High-impact, Medium-confidence result deserves prompt investigation, but its consequence is conditional on confirming the pattern in context. It is not automatically a demonstrated exploit. Conversely, a lower-impact finding can still reveal an assumption that matters to the application's asset flow.

Limits

  • This is a documentation census taken on the retrieval date. No scanner was executed against a project.
  • Confidence labels are the tool authors' classifications. They are not measured precision percentages.
  • The result cannot estimate how many vulnerabilities another analyzer would detect or how frequently developers make each mistake.

The reproducible record is kept in the repository: seo/research/articles-32-41-2026-09-05/surveys.py and seo/research/articles-32-41-2026-09-05/survey-34.json. These file paths are not public downloads.

Detector-by-detector triage

Triage starts with the reported rule and location, then asks whether the application satisfies the conditions required for the impact. Keep the reasoning with the finding. A reviewer should be able to understand why a result was accepted, rejected or escalated without reconstructing an undocumented conversation.

For an arbitrary token-transfer finding, inspect how the source account is bound to the caller's authority. A function accepting an address parameter is not enough evidence on its own: the surrounding authentication and authorization logic determines whether another user's allowance can be exercised. The documented detector gives a starting condition, not the final application verdict.

A controlled delegatecall target requires a different question. Identify who selects the target and which storage context the call uses. An administrative restriction changes the attacker model; it does not make arbitrary delegate execution harmless. The review must assess whether that authority is intended and protected.

Example triage questions for documented Slither detectors
DetectorQuestion to resolveEvidence to retain
arbitrary-send-erc20Can the caller choose a source account without the required authority?Authorization path and affected allowance flow
controlled-delegatecallWho can select the target and alter execution in the caller's context?Target-setting authority and reachable call path
reentrancy-ethDoes an external interaction expose state needed by a reachable callback?State sequence and relevant entry points
unprotected-upgradeCan an unauthorized actor affect initialization or implementation control?Deployment configuration and access-control proof

Do not merge separate findings merely because they share a rule identifier. Two locations can have different guards and different consequences. Equally, several detector outputs can describe one root cause. Link related outputs to the same investigation while retaining the locations so a fix is checked across the affected paths.

Use the reentrancy mechanism guide to distinguish a callback opportunity from a demonstrated harmful transition. The analysis should name the state that becomes inconsistent and the operation that consumes it. A call graph alone cannot supply that missing property.

Escalate a finding when the team cannot resolve an assumption with the available evidence. That status should identify the unanswered question, such as a dependency's callback behavior or an undocumented privileged workflow. Handing an auditor an explicit uncertainty is more useful than labeling the issue false positive to keep the release dashboard green.

Close the condition, not just the warning

Suppose a scanner reports a dangerous external call in a contract that restricts its caller. The restriction is relevant evidence, but it does not end the investigation. Trace who can obtain that role, whether a public entry point reaches the restricted function and whether an upgrade or delegate call changes the assumed boundary. This is an illustrative triage exercise, not a finding against a sampled project.

The disposition should state the condition under which the warning would matter. If the condition is unreachable in the reviewed artifact, explain why and identify the source that enforces it. If the condition depends on a deployment setting, record that dependency. A later release can then reopen the result when the setting changes instead of inheriting an unexplained suppression.

Distinguish a scanner limitation from an application exception. A parser that cannot analyze a construct has produced incomplete analysis. A correctly parsed pattern that is harmless under a documented invariant has produced a candidate that needs application context. Both may leave no confirmed vulnerability, but they require different follow-up work.

For a confirmed issue, retain the failing condition in the regression evidence. The repaired code should prevent the unwanted behavior while preserving the intended path. A scanner no longer emitting a warning is useful feedback, yet the stronger acceptance question is whether the original failure can still occur under the supported inputs and roles.

A reviewer should be able to challenge the disposition without rerunning the entire investigation. Include the target revision, detector identifier, affected location and the decisive code or configuration reference. Attach the unresolved assumption when evidence is missing. This keeps the triage artifact useful when responsibility moves from the developer to an outside assessor.

Finally, avoid merging separate warnings merely because they share a detector name. Similar output can arise from different authority boundaries or state transitions. Group results only when the same root cause and repair explain them, and retain the mapping from each original location to that grouped decision.

Suppression conventions

A suppression changes what the tool displays. It should therefore be reviewed as part of the security record. Preserve the original finding, the reason for suppression and the revision to which the decision applies. If the affected code changes, the prior disposition may no longer be valid.

Keep suppression scope as narrow as the supported reasoning. A global exclusion can remove unrelated findings that happen to share the same detector. A local exception is easier to review, provided the scanner supports it and the exact syntax has been checked for the pinned tool version. Avoid copying a comment convention from another analyzer and assuming it has the same effect.

Separate false positive, accepted risk and fixed issue. A false positive means the claimed condition does not apply. Accepted risk means the condition applies but an authorized owner accepts its consequence. Fixed means a change addresses the issue and the result has been checked. Those categories answer different questions and should not collapse into one closed status.

A finding changes status only with evidenceTriage preserves the finding while adding a reasoned disposition and a condition for reopening it.Raw findingContext reviewDispositionRecheck trigger
A finding changes status only with evidence. Triage preserves the finding while adding a reasoned disposition and a condition for reopening it.
  1. Retain the detector, location, revision and original output.
  2. Test the reported condition against reachable behavior and authority.
  3. Record fixed, false positive, accepted risk or unresolved with an owner.
  4. Revisit the decision when the code, dependency or relevant configuration changes.

A suppression record also needs a recheck trigger. Suppose a finding was dismissed because a dependency could not call back. If the dependency later becomes upgradeable, that reasoning may expire even when the application's own source remains unchanged. Link the disposition to the assumption, not merely the line number.

Require a second review for broad exclusions or decisions that accept meaningful asset risk. The purpose is to check the reasoning rather than add a ceremonial approval. The reviewer should be able to identify the evidence, the actor model and the remaining consequence from the record alone.

False-positive rates

A detector catalog cannot tell you its false-positive rate on your codebase. That requires labeled findings and a defined denominator. Tool documentation describing confidence is not a measured probability that an individual result is correct, and our catalog census does not convert it into one.

If the team wants a precision measure for triage planning, retain every finding in the selected run before filtering. Classify each as confirmed issue, confirmed false positive or unresolved. Record the rules used to classify ambiguous cases. Report unresolved findings separately rather than counting them as either correct or incorrect.

There is another denominator problem. A scanner may emit many duplicate locations for one root cause. A finding-level measure and a root-cause-level measure can produce different results from the same run. Choose the unit before calculating a percentage and state whether duplicates were collapsed.

Metrics require different evidence
MetricRequired denominatorKey limitation
Finding precisionAdjudicated outputs under a stated classification ruleUnresolved outputs and duplicate policy affect the result
Review effortRecorded analyst time for the selected outputsTime spent understanding the code may serve multiple findings
False negativesAn independently established set of relevant issuesA clean scanner run does not supply the missing ground truth
Change in outputComparable runs at named revisions and configurationsRule updates or scope changes can alter counts without a code repair

An illustrative triage ledger can help without inventing a benchmark. Give each output a stable identifier, raw severity, confidence, application impact and disposition. Include the evidence link and the reason a finding remains unresolved. When the team later calculates a metric, the reader can reconstruct the included rows.

Comparison between Slither and Aderyn needs the same discipline. Run each against the intended source scope with its recorded configuration, then compare actual findings by root cause. Merely comparing detector counts rewards documentation size and says little about the application's risks. We did not run that benchmark here, so no accuracy winner is claimed.

The smart contract fuzzing guide describes a complementary way to investigate behavior. A failed property test can help confirm an issue, while a passing campaign remains bounded by its handlers, assertions and explored states. It should not be used to erase a static finding without addressing the finding's actual condition.

Preparing scanner output for an auditor

Send the raw output and the triage ledger together. The auditor needs to see what the tool reported before exclusions, which results the team investigated and which assumptions still require independent review. A shortened spreadsheet containing only accepted findings hides useful evidence about how the team reached its conclusions.

Include the source revision, compiler configuration, analyzer version and commands used. List targets that failed compilation or were excluded from the run. Preserve dependency resolution so a reviewer can reproduce the source graph. If the output came from a hosted service, record the available run identifier and configuration rather than inventing a local version number.

  1. Freeze the source and dependency inputs used by the scan, then identify the intended analysis scope.
  2. Attach the unfiltered output with compilation failures and excluded targets clearly listed.
  3. Provide a disposition record for each reviewed result, including the evidence and unresolved assumptions.
  4. Map confirmed root causes to fixes and recheck results. Keep accepted risk distinct from remediation.
  5. Ask the auditor to validate the remaining trust boundaries and economic properties that the scanner output does not settle.

When a team needs manual validation after scanner triage, Pharos Production's smart contract code review and remediation verification page describes automated analysis alongside manual review and re-verification. That scope is relevant to turning a reported pattern into a supported finding and checking a repair. The page's description is a vendor statement; agree the precise target revision and deliverables in the engagement.

Use the member profile to find the provider and the tools hub to explore the surrounding workflow. Neither a provider listing nor the presence of several scanners establishes coverage of a specific contract.

Before handoff, let someone unfamiliar with the code read one closed finding and one unresolved finding. They should be able to identify the condition, the evidence and the remaining decision in each. If they cannot, improve the triage record before adding another scanner. The bottleneck may be the explanation of the application rather than the number of rules available to inspect it.

Frequently asked questions

Should a clean scan block an auditor from reporting a finding?

No. The auditor may establish a harmful behavior that the selected rules do not detect. Ask for the affected revision, conditions and supporting evidence rather than treating tool silence as a contradiction.

Can a suppression be carried into a fork automatically?

Only after checking that the original reasoning still applies to the fork's code and configuration. An inherited comment does not establish the fork's caller model or dependency behavior.

What should happen when scanner output changes after a tool upgrade?

Preserve both runs and compare rule versions, scope and configuration before attributing the difference to the source code. Re-triage new or changed findings under the current conditions.