README
ΒΆ
W3GoAudit
A Go-based CLI & SDK for auditing Solidity smart contracts using rule-based templates with WQL query language.
Quick Start
# Install (templates download on first run; embedded pack is the offline fallback)
go install github.com/th13vn/w3goaudit/cmd/w3goaudit@latest
# Scan contracts β writes a ./contracts-audit result folder
# (the "-audit" suffix is the collision guard: the output can't overwrite the scanned dir)
w3goaudit ./contracts/
# Scan one file into a named folder
w3goaudit Token.sol -o audit/
# Use a custom template directory
w3goaudit ./contracts/ -t ./my-templates/
# Only high + critical findings
w3goaudit ./contracts/ -s high,critical
# Print the summary only, write nothing
w3goaudit ./contracts/ -q
# Build database
w3goaudit build ./contracts/ -o database.json
# Extract contract info β every extract subcommand can build from a source
# path (like the scan) or load a pre-built database with --db
w3goaudit extract main ./contracts/
w3goaudit extract inheritance MyToken ./contracts/
w3goaudit extract entry MyToken --db database.json
Example console output:
βΆ Reading sources: ./contracts/
βΆ Building database: 74 files, 164 contracts, 1203 functions
βΆ Scanning: 25 templates (~/.w3goaudit/templates)
βΆ Writing report: ./contracts-audit
81 findings: 65 HIGH, 16 MEDIUM Β· scanned 74 contracts in 51ms
ββ Findings ββββββββββββββββββββββββββββββββββββββββββββββ
π HIGH (65 findings)
1. Arbitrary transferFrom Call
2. Unchecked ERC20 transfer / transferFrom Return Value
... (titles only on console; full detail in findings.md, or use --verbose)
π Results written to: ./contracts-audit
Results land in a folder β README.md (landing page), summary.md,
overview.md, findings.md, results.sarif, run.log, a machine-readable
data/ folder (JSON + DB + manifest index), and a contracts/ tree (one
sub-folder per main contract, mirroring source paths) with per-entry workflow
files and a state-change report. See Result folder layout.
overview.md is the report index and links to detailed artifacts.
Features
- AST Parsing - Parse Solidity using solast-go
- Contract Database - Comprehensive database with inheritance, entry points, call graphs
- Semantic Type Facts - Parameters, state variables, locals, casts, and call receivers carry lightweight type facts so WQL can stay simple while call classification becomes more precise
- C3 Linearization - Proper Solidity inheritance resolution
- Function Identity -
Function.Selectorstores canonical text such astransfer(address,uint256);Function.Signaturestores its four-byte Keccak value such asa9059cbb - Call Graph - Recursive tracing with filtered built-ins and optimized styling
- Exact Identity - Internal contracts use
absPath#Contract; functions useabsPath#Contract.selector(types). Exact C3LinearizedBaseIDsand resolved import provenance prevent duplicate names in different files from cross-wiring. - Precise Locations - One-based, half-open Unicode-code-point columns plus
zero-based, half-open UTF-8 byte offsets. SARIF declares
columnKind: unicodeCodePointsand never emits byte offsets ascharOffset/charLength. These are not LSP positions; LSP lines and characters are zero-based and commonly use UTF-16 code units. - WQL Templates - Powerful query language for security pattern matching, with load-time validation (regex, preset names, filter/match placement) so typos fail fast instead of producing silent zero-finding scans. Includes a source-scope
regexmatcher for rare raw-source predicates and contract-scope AST matching for same-contract local/inherited combination rules. - Result Folder - One opinionated folder per scan: a
README.mdlanding page,summary.md,overview.md(metrics + in-scope contract index),findings.md, always-onresults.sarif+run.log, a machine-readabledata/(manifest.json, reusabledatabase.json, findings/overview, always-ondiagnostics.json, plus nav/explorer/xref data for the editor extension), and acontracts/tree mirroring source paths. Opt-in fully offline HTML mirror with--html(graph library embedded β no CDN request). - Per-Entry Workflow Files - For every entry function, a self-contained context block (signature, auth / access control, guards & checks, branch conditions, transitive state effects, Mermaid call workflow) β built to be fed to a human or an AI auditor.
- State-Change Matrix - Per contract, each state variable mapped to the functions that write it and the entry points that reach a writer (reverse call-graph walk).
- Self-Provisioning Templates - Downloads the latest
w3goaudit-templatesrelease on first run (nuclei-style, no git clone), refreshable with--update-templates; embedded official pack is the always-available offline fallback. Extraction is size/file-count capped and installed with a rollback-safe staged directory swap. The GitHub zipball is TLS-authenticated but not checksum/signature verified. - Reachability-Aware Findings - Every finding can carry the full call chain from an externally-callable entry down to the function that hosts the dangerous statement: structured
reachability.steps[]+entryPoint(auditor's fix-here pointer) +primaryAstin JSON,relatedLocationsin SARIF, dotted-level trace block in Markdown / HTML,β³ via β¦continuation line on the--verboseconsole. Multi-site findings also carryrelated[], and Markdown renders all matched sites with full function context. - SARIF 2.1.0 - Always emitted (
results.sarif) for GitHub Code Scanning, with portable relative URIs +srcRoot; fail-closed template loading,NO_COLOR-aware console. - Editor Cross-Reference -
data/xref.jsonpairsdeclarations[]jump targets withreferences[]occurrences that carry the declarationrefId, so an editor gets exact go-to-definition and find-references (state vars, parameters, locals, resolved calls, libraryusing, UDVTwrap/unwrap, type casts,revert/emittargets, applied modifiers) with no regex fallback. See Extension Output. - Project Detection - Auto-detect Foundry, Hardhat, Truffle
- Import Resolution - Foundry remappings (profile- and context-aware, per
sub-project), then
node_modules//lib//root search, then last-resort conventional-layout and unique-suffix heuristics so block-explorer-fetched sources that ship no remappings file still link. Heuristics accept only an existing file inside the scan tree and abstain on ambiguity; anything still unresolved is recorded indata/diagnostics.json. - Git Integration - Auto-detect git repos and generate clickable file links to GitHub/GitLab
- Advanced Metrics - nSLOC, Access Control Analysis, Grouped Entry Points
- Source Extraction - Extract function source, context bundles, and full transitive workflow source
Documentation
Comprehensive guides available in docs/:
- Workflows - Detailed internal workflows with diagrams
- Usage Guide - Complete CLI and SDK reference
- SDK Documentation - Comprehensive SDK API reference and integration guide
- WQL Syntax - Template writing reference
- Extension Output -
data/nav.json+data/explorer.json+data/xref.jsonschemas for editor integrations - Project Overview - Architecture and design
- Internals - Technical deep-dive: functions, workflows, algorithms (C3, taint, access-control), and precision/edge-case decisions
Installation
From Source
# Clone the repository
git clone https://github.com/th13vn/w3goaudit
cd w3goaudit
# Build
go build -o w3goaudit ./cmd/w3goaudit
# Move to PATH (optional)
sudo mv w3goaudit /usr/local/bin/
Via Go Install
go install github.com/th13vn/w3goaudit/cmd/w3goaudit@latest
Self-Update
w3goaudit --update # re-runs `go install β¦@latest` (requires the Go toolchain)
Result Folder Layout
Every scan (unless --stdout/-q) writes a result folder, optimized to feed a
human or AI auditor:
<output>/
βββ README.md # landing page: counts + links to everything
βββ summary.md # metrics + findings-by-severity + rules-hit tables
βββ overview.md # metrics + in-scope contract index (table, links into contracts/)
βββ findings.md # human-readable findings
βββ results.sarif # SARIF 2.1.0 (always)
βββ run.log # full verbose detail (always; replaces --log)
βββ data/ # machine-readable output
β βββ manifest.json # index: tool, scope, counts, file list, per-contract refs
β βββ database.json # canonical DB β reuse via --db data/database.json
β βββ findings.json
β βββ overview.json
β βββ diagnostics.json # analysis-quality diagnostics; [] when complete
β βββ nav.json # flat symbol/caller/interface-impl index (extension)
β βββ explorer.json # per-main-contract model: constants, storage, entry/getter fns
β βββ xref.json # precise xref: declarations[] + references[] (go-to-def / find-refs)
βββ contracts/ # one sub-tree per main contract, mirroring source paths
βββ <relative-source-path-without-ext>/
βββ <ContractName>/
βββ README.md # per-contract landing: findings + architecture detail
βββ state-changes.md # state var β Written By (fns) β Reachable From (entries)
βββ workflows/
βββ <entryFn>.md # one file per entry function
βββ <entryFn>__<selector>.md # overloads disambiguated by 4-byte selector
The default folder name is the scanned project dir name (or .sol file stem);
-o/--output overrides it, and -audit is appended if the default would collide
with the scanned directory. Each workflows/<entryFn>.md records the signature
(selector, 4-byte, payable, version), auth / access control (modifiers,
msg.sender checks, β Unprotected, β tx.origin), guards/checks, branch
conditions, transitive state effects, and a Mermaid call-workflow diagram.
data/manifest.json distinguishes the detected projectRoot from the original
scanTarget (target is the compatibility alias), separates declaration
category counts, exposes analysisComplete/diagnostic counts, and indexes every
emitted artifact. Finding/content ordering is deterministic; generated
timestamps vary unless SDK callers inject a fixed report/bundle clock.
CLI Quick Reference
Commands
| Command | Description |
|---|---|
| (default) | Scan contracts β stats, overview, findings |
build |
Build contract database (JSON) |
extract main |
Main (deployable) contracts in a project |
extract entry |
Entry point functions for a contract |
extract inheritance |
C3 linearization (derived β base) β must be a main contract |
extract statevar |
State variables (including inherited, storage order) |
extract selector |
Function selectors (4-byte hashes) |
extract involve |
Every entry-point workflow that reaches a function, one Mermaid chart per entry |
extract workflow |
Full transitive source for an entry function (report-ready) |
extract bundle |
LLM-ready one-document context: source + callers + callees + state + inheritance + selectors |
extract context |
Combined context package for a function |
extract source |
Raw Solidity source for a function |
extract diff |
Compare two pre-built databases |
completion |
Generate shell completions |
version |
Show version information |
The root command is the scan (there is no scan subcommand). Every scan
flag has a long and short form: -o/--output, -t/--template, -d/--db,
-v/--verbose, -s/--severity (exact set), -m/--min-severity (threshold),
-i/--include, -e/--exclude, -l/--list-templates, -H/--html,
-q/--stdout, --strict-imports, -T/--update-templates, -u/--update.
--severity and --min-severity are mutually exclusive. Import resolution is
tolerant by default; use --strict-imports when unresolved imports must fail
the source scan or an equivalent --db cache scan. Import warnings are always
written to stderr.
extract subcommands are listed widest-scope first (project β contract β
function β utility). Like the scan, each one (except diff) can build from a
source path β extract <name> ./contracts/ β or load a pre-built database
with --db. Extract output defaults to markdown; pass --format=json (or
-o file.json) for the machine-readable shape.
Contract queries accept an exact file#Contract ID or a unique name. Function
queries accept an exact function ID, Contract.selector, a full selector, a
4-byte signature, or a unique bare name. Ambiguous queries fail with sorted
candidates instead of selecting by map order; --contract follows the same
exact-ID-or-unique-name rule.
Examples
# Default scan β writes a ./contracts-audit result folder (collision guard adds "-audit")
w3goaudit ./contracts/
# Scan one file into a named folder
w3goaudit Token.sol -o audit/
# Use a custom template directory
w3goaudit ./contracts/ -t ./templates/official/
# Only high + critical (exact set), or a threshold + exclude glob
w3goaudit ./contracts/ -s high,critical
w3goaudit ./contracts/ -m medium -e 'HIGH-WEAK-PRNG'
# Also emit the HTML mirror, or print the summary only (write nothing)
w3goaudit ./contracts/ -H
w3goaudit ./contracts/ -q
# List the active template set (no path needed)
w3goaudit -l
# Re-scan a pre-built database (e.g. the DB from a previous run)
w3goaudit -d ./contracts/data/database.json
# Fail closed when any persisted/source import is unresolved
w3goaudit ./contracts/ --strict-imports
w3goaudit -d ./contracts/data/database.json --strict-imports
# Refresh templates from the latest release; update the tool itself
w3goaudit --update-templates
w3goaudit --update
# Extract directly from source (builds the database on the fly)
w3goaudit extract main ./contracts/
w3goaudit extract statevar MyToken ./contracts/
# β¦or build once and reuse the database across many extracts
w3goaudit build ./contracts/ -o db.json
w3goaudit extract entry MyToken --db db.json
w3goaudit extract selector MyToken --db db.json
w3goaudit extract diff --db1 old.json --db2 new.json
# LLM-ready bundle: one markdown document with source + callers/callees + state + inheritance
w3goaudit extract bundle withdraw --db db.json --contract MyToken -o bundle.md
# Every workflow that reaches a function, as markdown for AI agents
w3goaudit extract involve withdraw --db db.json --format=md
# Shell completion
source <(w3goaudit completion bash)
For complete usage, see Usage Guide.
SDK Quick Reference
import (
"log"
"github.com/th13vn/w3goaudit/pkg/reader"
"github.com/th13vn/w3goaudit/pkg/builder"
"github.com/th13vn/w3goaudit/pkg/engine"
)
// Read sources
r := reader.New()
inputPath := "./contracts/"
projectRoot, err := reader.DetectProjectRoot(inputPath)
if err != nil {
log.Fatal(err)
}
sources, err := r.Read(inputPath)
if err != nil {
log.Fatal(err)
}
if err := r.ResolveImports(projectRoot); err != nil {
log.Fatal(err)
}
sources = r.GetAllSources()
// Build database
b := builder.New()
db, err := b.Build(sources)
if err != nil {
log.Fatal(err)
}
// Execute template
e := engine.New(db)
tmpl, err := engine.LoadTemplate("./template.yaml")
if err != nil {
log.Fatal(err)
}
findings := e.Execute(tmpl)
For complete SDK documentation, see Usage Guide.
WQL Template Example
meta:
id: SEC-REEN-001
title: Potential Reentrancy
severity: HIGH
confidence: MEDIUM
description: External call before state variable update
recommendation: Apply Check-Effects-Interactions pattern
query:
from: entry_function # public/external functions of main contracts
where:
- not: { preset: reentrancy_guarded }
- sequence:
- block: outgoing_call
- block: state_write
This is WQL (W3GoAudit Query Language). A WQL document is meta plus one query: block.
That block contains select/from/where, or a query-level
and:/or: composition. All 106 repository templates (25 official, 5
feature-test, and 76 benchmark) use it; see the
WQL Syntax Guide for the full language reference.
Project Structure
w3goaudit/
βββ cmd/w3goaudit/ # CLI entry point (root scan, build, extract, completion)
βββ pkg/
β βββ reader/ # File discovery and loading
β βββ logging/ # Immutable scan-local logger
β βββ builder/ # Database construction (7 phases incl. per-fn effects)
β βββ engine/ # WQL template execution
β βββ home/ # ~/.w3goaudit config + template home (release download)
β βββ types/ # Core data structures
β βββ report/ # Result-folder bundle, state matrix, console/MD/HTML/SARIF
βββ templates/ # WQL detection templates (official/ embedded via go:embed)
β βββ official/ # Curated official pack (embedded fallback; split by severity: critical/ high/ medium/)
β βββ test/ # Engine feature-exercise templates
βββ benchmarks/ # Stored dated benchmark reports + Git-ignored results/ scratch
# (the benchmark harness itself lives in the git-ignored, dev-only scripts/)
βββ test-data/ # Test contracts (core/, security/)
βββ docs/ # Comprehensive documentation
Key Workflows
1. Scan Workflow
Input β Reader β Builder β Database β Engine β Findings β Result-folder bundle
- Discover
.solfiles - Parse with solast-go
- Build database (inheritance, call graph, selectors, per-function effects)
- Load WQL templates (home β embedded fallback)
- Execute queries
- Generate findings
- Write the result folder (overview, findings, SARIF, run.log, data/, per-contract workflows + state-changes)
2. Build Workflow
Build phases:
- Parse files
- Build ASTs, data flow, and semantic type facts
- Calculate canonical
Function.Selectortext and four-byteFunction.Signaturevalues - Build inheritance (C3)
- Build call graph
- Calculate entry points
- Analyze per-function effects (state writes, guards, access control)
3. Default Scan (Combined) Workflow
The default scan combines stats, an overview index, and findings:
- Statistics (files, contracts, functions, nSLOC)
- A contract index linking each per-contract architecture report
- Security findings (when templates provided)
For detailed workflows, see Workflows Documentation.
Database Structure
The contract database contains:
- Contracts - All contracts with kind, inheritance, functions, state variables
- Functions - Visibility, modifiers, parameters, selectors, AST trees
- Inheritance - C3 linearization for proper method resolution
- Call Graph - Internal/external call edges with line numbers
- Entry Points - Public/external functions per main contract
- Main Contracts - Deployable contracts ranked by inheritance depth
Testing
Development uses the exact Go version declared by go.mod (currently
Go 1.26.5). This security-driven floor includes the standard-library fixes
required by govulncheck. Before release, run formatting, go mod tidy -diff,
vet, staticcheck, cyclomatic complexity, Markdown links,
normal/race/shuffled tests, host and Linux ARM64 builds, govulncheck, a full
official scan/artifact smoke test, and the Docker Compose competitive benchmark
locally or in user-owned external automation.
# Build database
w3goaudit build test-data/core/build-database/ -o test-db.json --verbose
# Security scan β writes a test-data/security result folder
w3goaudit test-data/security/ --template templates/official/ -o scan-report/
# Project overview (always part of the scan β see overview.md in the folder)
w3goaudit test-data/core/build-database/ -o overview-out/
# Competitive quality gate (maintainer-only): the benchmark harness under
# scripts/ is dev-only and git-ignored, so these commands run only where the
# harness is checked out; a fresh clone does not include it.
# Gate: precision >= 0.65, recall >= 0.95, failed cases = 0. Local CLI, no Docker.
go build -o /tmp/w3goaudit ./cmd/w3goaudit
python3 scripts/benchmark/run_benchmark.py --suite competitive --tools w3goaudit \
--w3goaudit-bin /tmp/w3goaudit --out benchmarks/results/latest
python3 scripts/benchmark/assert_thresholds.py benchmarks/results/latest/benchmark.json
# Docker Compose only for the multi-tool comparison (Slither/Semgrep/4naly3er).
docker compose -f scripts/benchmark/compose.yaml run --rm benchmark
Stored, tracked benchmark reports live under benchmarks/ as dated
yyyy-mm-dd-<commit-slug>.md files; the harness that produces them is dev-only.
Test contracts are documented in:
Roadmap
Current Features
- AST parsing and contract database
- C3 inheritance linearization
- Recursive call graph building
- Per-function effects analysis (state writes, guards, access control)
- WQL query language
- Result-folder output: Markdown + SARIF + JSON data/ + per-entry workflows + state-change matrix
- Self-provisioning template home (
~/.w3goaudit) with release download + embedded fallback - CLI and SDK
- Source/context/workflow extraction for report writing
Planned Features π
- Repository scanning (GitHub)
- On-chain contract fetching (Etherscan API)
- Enhanced data flow analysis
- Visualization exports (Mermaid, DOT)
- LSP integration for IDE support
- Template marketplace
For complete roadmap, see Project Overview.
Contributing
Contributions are welcome β especially new detectors, which you can write in YAML without touching Go. See CONTRIBUTING.md for a "write your first detector in 5 minutes" walkthrough, the dev setup, and the PR checklist.
To report a vulnerability in the tool itself, see SECURITY.md (please don't open a public issue).
License
MIT Β© th13vn. Third-party dependency and trademark notices are in NOTICE.
Links
- Documentation: docs/
- Templates: templates/
- Test Data: test-data/
- AST Parser: solast-go
Directories
ΒΆ
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
w3goaudit
command
W3GoAudit - Solidity Smart Contract Audit Engine
|
W3GoAudit - Solidity Smart Contract Audit Engine |
|
pkg
|
|
|
builder
Package builder constructs the contract database from parsed AST.
|
Package builder constructs the contract database from parsed AST. |
|
engine
Package engine provides the WQL (W3GoAudit Query Language) template engine.
|
Package engine provides the WQL (W3GoAudit Query Language) template engine. |
|
home
Package home manages the cross-platform ~/.w3goaudit directory: the user config file and the template home that mirrors the published template pack (nuclei-style β downloaded from GitHub Releases, never via git clone).
|
Package home manages the cross-platform ~/.w3goaudit directory: the user config file and the template home that mirrors the published template pack (nuclei-style β downloaded from GitHub Releases, never via git clone). |
|
logging
Package logging provides scan-local verbose logging for w3goaudit.
|
Package logging provides scan-local verbose logging for w3goaudit. |
|
reader
Package reader provides file and directory reading capabilities for Solidity projects.
|
Package reader provides file and directory reading capabilities for Solidity projects. |
|
report
Package report provides report generation functionality for Solidity projects.
|
Package report provides report generation functionality for Solidity projects. |
|
testing
Package testing provides test utilities for w3goaudit
|
Package testing provides test utilities for w3goaudit |
|
types
Package types defines core data structures for the w3goaudit engine.
|
Package types defines core data structures for the w3goaudit engine. |
|
Package templates embeds the official WQL template pack into the binary so `w3goaudit <path>` works out of the box β without requiring the caller to have the repository's templates/ directory on disk (e.g.
|
Package templates embeds the official WQL template pack into the binary so `w3goaudit <path>` works out of the box β without requiring the caller to have the repository's templates/ directory on disk (e.g. |