Slither Tutorial: Static Analysis for Solidity Teams
Quick answer. Install Slither with uv or pip, run slither . from your project root, and read each finding's impact and confidence. Record confirmed false positives in a comment or triage mode, then fail CI on Medium or High findings.
Video transcript
Slither scans Solidity in under a second per contract on average. The real work is triaging what it finds, and covering what it cannot see.
Slither is a free, open source analyzer from Trail of Bits. Its current release ships 101 detectors.
Install it with uv or pip, confirm your Foundry or Hardhat build compiles, then run Slither from the project root.
Read impact and confidence together. Reentrancy eth is High impact but Medium confidence, so confirm each hit by hand.
To triage, first filter out dependencies, tests and scripts. Then ask: can an attacker reach it, is the call trusted, and does a check elsewhere block it?
Record confirmed false positives next to the code with a disable comment, or use triage mode. Commit the decisions and pin the version.
Built-in detectors know Solidity. A custom detector can know your protocol. A short Python plugin can flag any unprotected write to your oracle or fee setting.
In CI, fail on Medium or High findings, export SARIF for code scanning, and add the pre-commit hook.
Slither cannot catch logic or economic bugs. Guardian's smart contract audit adds a design review, an invariant suite and senior researchers.
Read the full tutorial for the commands and detector code, or talk to Guardian about what static analysis cannot find.
Slither is a static analyzer for Solidity and Vyper from Trail of Bits. It reads your code without running it and flags known bad patterns.
Version 0.11.6, released July 28, 2026, ships 101 detectors. Its README cites an average run time under one second per contract.
It does not know your protocol's rules. Logic bugs need tests and review, as our guide to what free scanners miss shows.
Install and Run
Slither needs Python 3.10 or later. Its README recommends uv.
uv tool install slither-analyzer
# or: python3 -m pip install slither-analyzer
cd my-protocol # Foundry or Hardhat root
slither .
Run it from the project root. Slither compiles through your framework, so imports resolve.
Seeing "unknown file" errors? Check that forge build or npx hardhat compile works first. Slither cannot analyze what the framework cannot compile.
Three output flags are worth knowing:
--checklistwrites a Markdown report for a pull request.--json -prints results as JSON to stdout.--sarif results.sarifexports SARIF for code scanning.
Reading Detectors and Severities
Each finding describes the issue, points to the code and links to the detector's documentation. Every detector carries two ratings:
- Impact: how bad the issue would be, from High down to Optimization.
- Confidence: how sure the analysis is, from High to Low.
The 101 detectors in 0.11.6 split like this.
| Impact | Detectors | Examples |
|---|---|---|
| High | 30 | reentrancy-eth, arbitrary-send-erc20, unprotected-upgrade |
| Medium | 28 | divide-before-multiply, tx-origin, unchecked-lowlevel |
| Low | 17 | missing-zero-check, calls-loop, timestamp |
| Informational | 21 | naming-convention, solc-version, low-level-calls |
| Optimization | 5 | immutable-states, external-function |
Read the two ratings together. reentrancy-eth is High impact but Medium confidence, so confirm each hit by hand.
Slither runs every detector by default. Narrow it with --detect, --exclude, --exclude-informational or --exclude-low, and list them all with --list-detectors.
Triage and Suppressions
Start by cutting scope. Findings in dependencies, tests and scripts rarely belong in this review.
{
"filter_paths": "lib/,test/,script/",
"exclude_dependencies": true,
"exclude_informational": true,
"exclude_optimization": true
}
Save that as slither.config.json in the project root, and Slither loads it automatically. Command-line flags take priority over it.
Then take each finding in turn. Ask three questions:
- Can an attacker reach this code path?
- Does the external call go to a fixed, trusted contract, or to anyone?
- Does a modifier or check elsewhere already block it?
Fix real issues. For a confirmed false positive, record the decision next to the code.
// Calls our own immutable Oracle, which makes no external calls.
// slither-disable-next-line reentrancy-no-eth
oracle.update(price);
Other ways to suppress or review:
// slither-disable-start [detector]and-endwrap a whole section.@custom:security non-reentranton a variable marks calls through it as non-reentrant.--triage-modeasks, finding by finding, what to hide. Answers go inslither.db.json.--show-ignored-findingsbrings everything hidden back for a full review.
Commit the triage file so CI sees the same decisions. Add --warn-unused-ignores, new in 0.11.6, to flag disable comments that no longer suppress anything.
Pin the Slither version too. Release 0.11.6 alone added a detector and cut false positives in others, so an upgrade changes results.
Printers for Code Review
Printers summarize code rather than judge it. They are a fast way to map a codebase before a review.
slither . --print human-summary
slither . --print entry-points,vars-and-auth
slither . --print inheritance-graph # writes a .dot file
- human-summary: a readable overview of each contract.
- entry-points: every state-changing function an outsider can call.
- vars-and-auth: the state each function writes, and its checks on
msg.sender. - call-graph and cfg: call graphs and per-function control-flow graphs, as .dot files.
Read vars-and-auth against your access control design. A function that writes a fee, oracle or owner variable with no sender check deserves a second look.
Slither also ships standalone tools, such as slither-check-upgradeability for proxies and slither-check-erc for token standards.
Custom Detectors
Built-in detectors know Solidity. A custom detector can know your protocol.
Say every write to oracle or feeBps must sit behind access control. This detector, built on Slither's documented skeleton, checks that.
from slither.detectors.abstract_detector import (
AbstractDetector,
DetectorClassification,
)
SENSITIVE = {"oracle", "feeBps"}
class SensitiveWrite(AbstractDetector):
ARGUMENT = "sensitive-write"
HELP = "Unprotected write to a sensitive variable"
IMPACT = DetectorClassification.HIGH
CONFIDENCE = DetectorClassification.MEDIUM
WIKI = "docs/security/slither.md"
WIKI_TITLE = "Unprotected sensitive write"
WIKI_DESCRIPTION = "Anyone can change a sensitive setting."
WIKI_EXPLOIT_SCENARIO = "An attacker swaps in their own oracle."
WIKI_RECOMMENDATION = "Add the access control modifier."
def _detect(self):
results = []
for contract in self.compilation_unit.contracts_derived:
for f in contract.functions_entry_points:
written = {v.name for v in f.state_variables_written}
if written & SENSITIVE and not f.is_protected():
info = [f, " writes a sensitive variable\n"]
results.append(self.generate_result(info))
return results
Slither refuses to load a detector whose HELP, ARGUMENT or WIKI fields are empty, so fill them all.
Know what is_protected() checks: an onlyOwner modifier, or msg.sender used in a condition or passed as an argument. Role checks built another way can look unprotected, hence Medium confidence.
To run it, package it as a plugin. Slither's plugin_example registers a make_plugin() function under the slither_analyzer.plugin entry point.
Install the package in the same environment as Slither, then run slither . --detect sensitive-write.
Slither in CI
By default, Slither exits with an error on any finding at all. Choose a threshold instead.
slither . --fail-medium --sarif results.sarif
- Thresholds:
--fail-high,--fail-medium,--fail-low, or--fail-noneto report only. - Same inputs everywhere: commit
slither.config.jsonandslither.db.json, and pin the version. - Before commit: Slither's repository ships a pre-commit hook.
- Code scanning: crytic's slither-action can write SARIF for GitHub code scanning. Our CI/CD pipeline guide has the pinned job.
Slither is one gate of several. Our pre-mainnet security checklist lists the rest.
Pair Slither with Foundry invariant tests, which check your protocol's own rules. To choose a fuzzer, see Echidna vs Medusa vs Foundry.
How Guardian Helps
Static analysis clears the surface. Guardian's smart contract audit goes after the rest in three passes: a design review, an invariant suite, then senior researchers.
Vanguard, Guardian's enterprise audit, puts two independent teams on one scope. Team A pairs expert manual review with fuzzing; Team B runs Helix, Guardian's AI auditor.
Only human-verified findings become the final result.
Frequently Asked Questions
Is Slither free to use?
Yes. Slither is open source under the AGPLv3 license and maintained by Trail of Bits in its crytic GitHub organization. Install it with uv, pip or Homebrew.
Can Slither find every vulnerability in my contracts?
No. It matches known code patterns, such as reentrancy and unchecked calls. It does not know your protocol's rules, so logic and economic bugs need invariant tests and manual review.
How do I ignore a Slither false positive?
Put a slither-disable-next-line comment with the detector name above the line, plus a note on why. Or run --triage-mode, which saves hidden results in slither.db.json. Commit either so CI respects the decision.
Does forge lint replace Slither?
Not fully. Foundry v1.8.0 added many security lints and claims "nearly complete Slither/Aderyn parity." Slither still adds printers, a Python API for custom detectors, triage mode and tools such as slither-check-upgradeability.
Sources
- crytic: Slither README, detectors, printers and install (accessed November 6, 2026)
- crytic: Slither 0.11.6 release notes (July 28, 2026)
- crytic: Slither usage docs, detector selection, suppression, triage mode and configuration file
- crytic: Slither detector documentation
- crytic: Slither printer documentation
- crytic: Adding new detectors to Slither
- crytic: Slither plugin example
- crytic: AbstractDetector source, required fields (0.11.6)
- crytic: Function.is_protected source (0.11.6)
- crytic: Slither command-line flags, fail-on thresholds (0.11.6)
- crytic: slither-action README
- foundry-rs: Foundry v1.8.0 release notes, security lints (August 27, 2026)
- Guardian: Smart Contract Audit
- Guardian: Vanguard
Find what static analysis cannot
Slither clears known patterns; Guardian's audit adds a design review, an invariant suite and senior researchers for the logic bugs no detector knows.