§ 01 · OriginGetting started.
AuditHunt runs as a CLI, a long-lived daemon (audithunt watch), or a hosted REST API. The same scan pipeline backs all three. This page is the printed manual; you should be able to follow it without ever opening the product.
1.1Install
Three install paths. Pick one. They produce identical binaries.
# homebrew (mac, linux) brew install audithunt/tap/audithunt # cargo (any platform with rust) cargo install audithunt # container (CI-friendly) docker pull ghcr.io/audithunt/cli:0.14.2
Verify the install:
$ audithunt --version audithunt 0.14.2 (engine solc 0.8.26, 34 detectors)
1.2First scan
Point the binary at a Solidity file, a directory, or a verified contract address. Output is a findings.json by default; use --format md for the report deliverable.
# local file audithunt scan ./contracts/Vault.sol # whole project — picks up foundry.toml/hardhat.config audithunt scan . # mainnet contract by address audithunt scan 0xDEADBEEF... --network mainnet
1.3Exit codes
The CLI exits non-zero when findings exceed the configured severity gate. Default gate is medium; override with --fail-on critical or set in audithunt.toml.
| Code | Meaning | Typical CI behavior |
|---|---|---|
| 0 | Clean, or only findings below gate | Pipeline passes |
| 1 | Findings at or above severity gate | Block merge |
| 2 | Parse error, no scan performed | Surface to author |
| 3 | Engine crash (please --bug-report) | Retry once, then alert |
| 4 | Authentication / quota | Renew token |
§ 02 · SurfaceThe command line.
Four verbs. Everything else is a flag. The CLI is the canonical surface; the API and SDK shell out to the same binary.
2.1scan
Run a one-shot audit and exit. The default and the verb you'll use 99% of the time.
- --network
- mainnet · base · arbitrum · optimism · custom RPC
- --format
- json · md · sarif · html
- --fail-on
- info · low · medium · high · critical
- --detectors
- comma list, e.g.
reentrancy,access-control - --exclude
- glob list, applied to source paths
- --cache-dir
- ~/.audithunt/cache
- --timeout
- per-detector, default 180s
2.2watch
Long-lived daemon. Re-runs only the detectors whose inputs changed. Useful for active development; not a CI tool.
$ audithunt watch . [ 09:04:18 ] watching 14 files [ 09:04:18 ] initial scan: 1 medium · 2 low (1.8s) [ 09:06:42 ] Vault.sol changed [ 09:06:42 ] partial rerun: reentrancy, access-control (0.4s) [ 09:06:42 ] 1 critical · 1 medium · 2 low
2.3explain
Print the full reasoning behind a finding ID. Includes the SWC reference, the corpus links, and a synthesized PoC where one is available.
$ audithunt explain RE-001 RE-001 · Reentrancy on external call before state write SWC-107 · derived from 14 incidents in corpus pattern: call.value(...)(...) followed by write to msg.sender mapping PoC: synthesized · see ./.audithunt/poc/RE-001.t.sol fix: apply checks-effects-interactions; or use ReentrancyGuard
2.4config
Print the effective configuration after merging defaults, project file, and CLI flags. Use --explain to trace where each value came from.
$ audithunt config --explain fail_on = "medium" // audithunt.toml [scan] network = "mainnet" // flag --network detectors = "all" // default cache_dir = "~/.audithunt/cache" // default
§ 03 · PostureConfiguration.
Configuration is project-local, in TOML. Environment variables override the file; CLI flags override the environment. The file is committed to your repo so reviewers see the same gate the author saw.
3.1audithunt.toml
# Project root: audithunt.toml [scan] fail_on = "medium" network = "mainnet" include = ["src/**/*.sol"] exclude = ["src/test/**", "src/mocks/**"] timeout_per_detector = 180 [detectors] disabled = ["oracle-stale"] # project uses pull-based oracle weight.access-control = 2.0 # promote AC findings [suppressions] "src/lib/SafeMath.sol#L42" = "intentional unchecked block; gas-critical"
3.2Rules & suppressions
A suppression is a key — path#Lline or contract.function — paired with a one-sentence justification. Suppressions require the justification; an empty string fails the lint.
- Suppressions are scoped to a finding ID at a location, not blanket-disabled.
- The justification appears in the report so a reviewer can challenge it.
audithunt audit-suppressionslists every active one with its age.
3.3Environment variables
| Variable | Purpose | Default |
|---|---|---|
AUDITHUNT_TOKEN | API auth, hosted runs | — |
AUDITHUNT_RPC | Custom RPC override | built-in |
AUDITHUNT_CACHE | Cache dir | ~/.audithunt/cache |
AUDITHUNT_TELEMETRY | off to disable | on |
NO_COLOR | Plain TTY output | — |
§ 04 · CatalogDetector catalog.
Thirty-four detectors, organized into eight families. Each detector traces back to one or more SWC entries and to specific incidents in the corpus. The full table follows; the families below it expand a representative pick from each.
| ID | Family | Name | SWC | Default severity |
|---|---|---|---|---|
| RE-001 | Reentrancy | Cross-function reentrancy | SWC-107 | Critical |
| RE-002 | Reentrancy | Read-only reentrancy | SWC-107 | High |
| AC-001 | Access control | Missing modifier on privileged fn | SWC-105 | Critical |
| AC-002 | Access control | Renounceable owner without succession | SWC-105 | Medium |
| AR-001 | Arithmetic | Unchecked block over external value | SWC-101 | High |
| AR-002 | Arithmetic | Precision loss on division | SWC-101 | Low |
| OR-001 | Oracle | Single-source price feed | SWC-136 | High |
| OR-002 | Oracle | Stale price tolerance > 1h | SWC-136 | Medium |
| XC-001 | External call | Unbounded loop over external call | SWC-128 | Medium |
| SG-001 | Signature | Missing nonce on permit-style sig | SWC-117 | High |
| ST-001 | Storage | Layout collision after upgrade | SWC-119 | Critical |
| DS-001 | DoS | Griefable transfer in loop | SWC-113 | Medium |
audithunt detectors --list to dump them locally with version stamps and corpus edges.
4.1Reentrancy family
Six detectors in this family. They all derive from SWC-107, but they fan out across what an attacker actually does — cross-function reentry, read-only reentry through view shares, ERC-777 hooks, and three more.
RE-001 · Cross-function reentrancy. Triggers when a function performs an external call before writing to msg.sender's state. The classic. The corpus binds this detector to The DAO, bZx round one, and seven smaller incidents.
RE-002 · Read-only reentrancy. Newer. Fires when a view function exposes a balance that a stateful function later reads back, while in the middle of an external call. Not theoretical — there are 220M USD of incidents in the corpus that took this shape.
4.2Access control family
Five detectors. The Parity wallet incident lives in this family's history; so do most of the "ownership transferred to address(0)" griefing reports.
4.3Arithmetic family
Four detectors. Solidity 0.8 made overflow checked by default, which removed the original batchOverflow shape — but unchecked blocks brought the surface back, and arithmetic precision loss is a different family of bug entirely.
4.4Oracle family
Five detectors. Many of the largest incidents in the corpus — bZx round two, MakerDAO Black Thursday, Mango — bind to this family. Oracle issues account for roughly a third of the lifetime damage represented in the brain.
§ 05 · WireREST API.
JSON over HTTPS. Authenticated with a bearer token from your dashboard. Rate-limited per token; quotas reset hourly. Same scan pipeline as the CLI; identical result schemas.
5.1Auth
Authorization: Bearer ah_live_••••••••••••••••
Tokens are scoped — scan, read, admin. Use the narrowest scope your integration needs.
5.2/v1/scans
- target
- required · address, github URL, or uploaded source bundle ID
- network
- mainnet · base · arbitrum · optimism
- detectors
- array · default
["all"] - callback_url
- optional · webhook fired on completion
{
"id": "scan_01HX7K...",
"status": "running",
"target": "0xDEADBEEF...",
"queued_at": "2026-04-26T14:02:11Z"
}
Poll until status is complete. Or set callback_url on creation and don't poll at all.
5.3/v1/findings
Returns an array of finding objects. The shape mirrors what the CLI emits as findings.json.
[
{
"id": "RE-001",
"severity": "critical",
"location": { "file": "Vault.sol", "line": 184 },
"swc": "SWC-107",
"corpus_edges": ["the-dao", "bzx-1"],
"poc": "./poc/RE-001.t.sol",
"fix": "checks-effects-interactions"
}
]
5.4Webhooks
Sent as POST to your callback_url with an HMAC-SHA256 signature in X-AuditHunt-Signature. Verify before acting.
POST /your/endpoint
X-AuditHunt-Signature: t=1745689331,v1=8a32b7...
Content-Type: application/json
{ "event": "scan.complete", "scan_id": "scan_01HX7K..." }
§ 06 · BindingsSDK.
Two officially-supported language bindings. Both wrap the REST API; community ports for Go and Rust live in the GitHub org.
6.1TypeScript
import { AuditHunt } from "@audithunt/sdk"; const ah = new AuditHunt({ token: process.env.AUDITHUNT_TOKEN }); const scan = await ah.scans.create({ target: "0xDEADBEEF...", network: "mainnet", }); const findings = await ah.scans.waitForFindings(scan.id); findings.filter(f => f.severity === "critical");
6.2Python
from audithunt import AuditHunt ah = AuditHunt(token=os.environ["AUDITHUNT_TOKEN"]) scan = ah.scans.create(target="0xDEADBEEF...", network="mainnet") findings = ah.scans.wait_for_findings(scan.id) for f in findings: if f.severity == "critical": print(f.id, f.location.file, f.location.line)
§ 07 · HooksCI integrations.
The CLI is the integration. The recipes below are conveniences — wrappers that surface the right defaults for the most common runners.
7.1GitHub Actions
# .github/workflows/audithunt.yml name: audithunt on: [pull_request] jobs: scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: audithunt/action@v1 with: token: ${{ secrets.AUDITHUNT_TOKEN }} fail-on: "medium" comment-pr: true
The action posts a single PR comment with the finding summary; subsequent runs edit it in place rather than spamming.
7.2Foundry / Hardhat hooks
Both toolchains expose a pre-test hook. AuditHunt installs into either with a one-line addition; see audithunt init for project-aware scaffolding.
# foundry.toml [profile.default] ffi = true extra_output = ["audithunt"]
§ 08 · SedimentChangelog.
What this engine has learned, in reverse chronological order. Older entries get terser as their context fades; the corpus they reference is the durable record.
v0.142026-04-26
- RE-002 · read-only reentrancy detector promoted out of beta.
- Storage-collision detector (ST-001) now models OZ upgradeable's reserved gap.
- Corpus refresh: +14 incidents from disclosed Q1 reports.
v0.132026-02-08
- Oracle family rewrites: now models pull-based and push-based feeds separately.
- CLI
watchverb shipped with partial-rerun semantics.
v0.122025-11-22
- 34th detector (DS-001 · griefable transfer) shipped.
- SARIF output format for code-scanning integrations.
v0.102025-09-04
- Public beta. 32 detectors. Hosted API opens with a waitlist.
audithunt history to print the full log; the daemon mirrors it into ~/.audithunt/history.jsonl.