w3goaudit

module
v0.4.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 27, 2026 License: MIT

README ΒΆ

W3GoAudit

Go Reference

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.Selector stores canonical text such as transfer(address,uint256); Function.Signature stores its four-byte Keccak value such as a9059cbb
  • Call Graph - Recursive tracing with filtered built-ins and optimized styling
  • Exact Identity - Internal contracts use absPath#Contract; functions use absPath#Contract.selector(types). Exact C3 LinearizedBaseIDs and 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: unicodeCodePoints and never emits byte offsets as charOffset/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 regex matcher 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.md landing page, summary.md, overview.md (metrics + in-scope contract index), findings.md, always-on results.sarif + run.log, a machine-readable data/ (manifest.json, reusable database.json, findings/overview, always-on diagnostics.json, plus nav/explorer/xref data for the editor extension), and a contracts/ 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-templates release 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) + primaryAst in JSON, relatedLocations in SARIF, dotted-level trace block in Markdown / HTML, ↳ via … continuation line on the --verbose console. Multi-site findings also carry related[], 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.json pairs declarations[] jump targets with references[] occurrences that carry the declaration refId, so an editor gets exact go-to-definition and find-references (state vars, parameters, locals, resolved calls, library using, UDVT wrap/unwrap, type casts, revert/emit targets, 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 in data/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.json schemas 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
  1. Discover .sol files
  2. Parse with solast-go
  3. Build database (inheritance, call graph, selectors, per-function effects)
  4. Load WQL templates (home β†’ embedded fallback)
  5. Execute queries
  6. Generate findings
  7. Write the result folder (overview, findings, SARIF, run.log, data/, per-contract workflows + state-changes)
2. Build Workflow

Build phases:

  1. Parse files
  2. Build ASTs, data flow, and semantic type facts
  3. Calculate canonical Function.Selector text and four-byte Function.Signature values
  4. Build inheritance (C3)
  5. Build call graph
  6. Calculate entry points
  7. 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.


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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL