- Operating System: Linux, macOS, or Windows Subsystem for Linux (WSL) is preferred for compatibility.
- Python 3.7+: Slither requires Python; I usually recommend setting up a virtual environment to avoid package conflicts.
- Solidity compiler (solc): Installed globally or via Hardhat. Slither relies on ABI and AST info, which Hardhat already generates.
- Node.js and Hardhat setup: This example assumes your Hardhat project is set up and compiles successfully.
To verify:
python3 --version
node --version
npx hardhat --version
If any tool is missing, install it accordingly (e.g., apt-get install python3 python3-venv on Ubuntu).
Installing Slither
The recommended way to install Slither is via pip:
python3 -m venv slither-env
source slither-env/bin/activate
pip install slither-analyzer
This ensures Slither and its dependencies won't clash with your global Python environment.
After installation, verify it by running:
slither --version
You should see the installed Slither version printed. As of this writing, the latest stable release is [check current version]. Note: Some issues have appeared in recent versions; if you encounter installation hiccups, check the GitHub repo issues, as this project is under active development.
Running Slither on a Hardhat Project
Now, let's run Slither against your Hardhat Solidity contracts. Since Hardhat outputs compiled artifacts in artifacts/ and generates centralized metadata, Slither can easily analyze your code.
Navigate to your project root and run:
slither .
The . tells Slither to look for Solidity contracts in the current directory recursively.
Pro tip: If you want to analyze a specific contract, provide its path explicitly:
slither contracts/MyToken.sol
Case in point: when I wired up Slither to my latest DeAI protocol, I caught an unguarded reentrancy vulnerability in a custom withdraw function — Slither flagged it immediately without firing up tests.
Configuring solc version: If your Hardhat config pins a specific Solidity compiler version, Slither automatically picks it up from your hardhat.config.js. If not, you might want to explicitly specify it via CLI for accuracy:
slither . --solc-remaps @openzeppelin=node_modules/@openzeppelin
Run Slither in JSON mode for CI integration:
slither . --json results.json
This outputs structured data you can parse to gate PR merges.
Understanding Slither’s Static Analysis Output
Slither outputs a categorized list of issues—each with:
- Type: Security, gas optimization, code quality
- Severity: Informational, low, medium, high
- Description: What the issue is and why it matters
- Location: Contract name, file, and line number
Example snippet:
[/contracts/MyToken.sol:45-65] High: Reentrancy vulnerability in function withdraw()
at MyToken.withdraw()
Description: Function allows external calls before updating state.
From experience, not every warning is critical. Slither can produce false positives (especially on complex proxy or assembly-heavy contracts). My advice: scan results to distinguish actionable findings from noise.
You can silence false positives with inline comments:
// slither-disable-next-line reentrancy-events
function riskyCall() {...}
But only do this after careful review—don’t hide potential exploits.
Writing Custom Detectors with Python
One standout Slither feature is its extensible detector framework. You can write your own static analysis rules in Python to track project-specific patterns.
For example, say you want to detect any use of tx.origin (which often opens phishing attack vectors). Here's a minimal custom detector:
from slither.slither import Slither
from slither.detectors.detector_extension import DetectorExtension
class TxOriginDetector(DetectorExtension):
ARGUMENT = 'txorigin'
HELP = 'Detect usage of tx.origin in contracts'
IMPACT = 'High'
def detect(self):
results = []
for contract in self.slither.contracts:
for function in contract.functions:
for node in function.nodes:
if 'tx.origin' in node.source_mapping['code']:
results.append(self.generate_result(contract, function, node))
return results
if __name__ == '__main__':
slither = Slither('contracts/MyToken.sol')
detector = TxOriginDetector(slither)
findings = detector.detect()
for find in findings:
print(find)
Running this script yields all tx.origin occurrences. That’s a quick way to enforce security policies beyond Slither's built-ins.
Writing custom detectors requires understanding Slither’s AST and intermediate representations, but it’s very rewarding once automated security checks run on your CI.
Common Use Cases and Best Practices
In my experience auditing Solidity projects, Slither is invaluable for:
- Finding reentrancy bugs: It flags risky external call patterns.
- Detecting uninitialized storage pointers: A common pitfall.
- Spotting gas inefficiencies: Identifies unnecessary state variable writes.
- Auto-checking for obsolete Solidity constructs: Deprecated syntax or unsafe low-level calls.
Best practice checklist:
- Integrate Slither as a pre-commit hook or in CI pipelines for continuous audits.
- Use JSON output to track trends over time.
- Combine with dynamic testing frameworks (e.g., Hardhat tests + fuzzers like ItyFuzz) for layered security.
- Always corroborate Slither reports with manual review or formal verification if possible.
Comparison with Other Solidity Static Analysis Tools
Slither is widely used, but it’s not your only choice. Here’s a brief feature comparison using key dimensions:
| Tool |
Language |
Chains Supported |
License |
Maturity |
Custom Detectors |
Notes |
| Slither |
Python |
EVM chains (Mainnet, L2s) |
MIT |
Actively maintained |
Yes |
Fast, modular, but can false alarm |
| Aderyn |
Rust |
EVM + Substrate (experimental) |
MIT |
Early |
Limited |
More formal; runtime checks coming |
| MythX |
SaaS/API |
EVM networks |
Commercial (has free tier) |
Mature |
No (but plugin support) |
Deep analysis, costs apply |
| Certora |
Custom spec |
EVM + Layer 2 |
Commercial |
Mature |
Yes (formal verification) |
Formal methods; complex setup |
For a deeper dive, see our solidity static analysis tools comparison.
Troubleshooting Slither
Common errors devs encounter:
SlitherException: solc version mismatch: Ensure your solc matches Hardhat's compiler setting.
Missing artifacts or ABI: Run npx hardhat compile before Slither.
ModuleNotFoundError during install: Use a clean Python venv and pip-update.
- False positives on proxy contracts: Slither struggles with delegatecall resolution. Cross-reference with manual tracing.
If Slither crashes or hangs on very large projects, consider disabling expensive detectors with --disable-detector <name> flags.
Further Reading and Integration Tips
- Automate Slither in your smart-contract-ci-cd-pipeline to fail builds on high-severity issues.
- For integrated fuzz testing, pair Slither with tools like ItyFuzz or
ai-agent-smart-contract-exploit-generation for proactive vulnerability discovery.
- If you’re expanding into AI-assisted audits, investigate integrating Slither JSON outputs with AI models via RPC or MCP data feeds.
More advanced verification options and tutorials can be found under Certora Formal Verification Tutorial.
Conclusion
Setting up Slither in your Hardhat project is straightforward and provides immediate security insights with minimal overhead. While it’s not a silver bullet, Slither's static analysis reduces the attack surface by flagging common Solidity pitfalls early on.
I believe every Solidity dev targeting DeFi or DeAI agents should have Slither in their toolbox—not just for audits but as part of day-to-day development. Try writing a custom detector once you get comfortable; that’s where Slither really shines.
The next step? Hook Slither into your CI pipeline and combine it with fuzzers or formal tools to cover all your bases.
Happy auditing!
For more context on integrating Slither into continuous audit systems, see our smart-contract-ci-cd-pipeline page, or compare Slither to other analyzers in the aderyn-vs-slither-comparison article.