Skip to content

Latest commit

 

History

History
190 lines (146 loc) · 7.36 KB

File metadata and controls

190 lines (146 loc) · 7.36 KB

SolAST

npm CI License: Apache-2.0

AST-based vulnerability scanner for Solidity smart contracts. SolAST parses Solidity source into an Abstract Syntax Tree (AST) with @solidity-parser/parser, runs a library of 300+ detectors over that AST and a lightweight semantic model, and reports findings as human-readable text, NDJSON, or SARIF 2.1.0 — with no solc, compilation, or build configuration required.

Scan a contract in one line — no install, no config, no API keys:

npx @snovon/solast scan contracts/

⚠️ SolAST detects known vulnerability patterns through static AST analysis. Findings are best-effort and heuristic: they include false positives and will miss real vulnerabilities. SolAST is not a substitute for a professional security audit, formal verification, or testing, and should never be the sole basis for deciding whether a contract is safe to deploy. No warranty — see LICENSE.

What it detects

A non-exhaustive sample of the detector corpus:

  • Reentrancy — classic, cross-function, cross-contract, read-only, and ERC-777/ERC-1155 callback / flashloan-amplified variants
  • Access control — missing or incorrect authorization, unguarded initializers, ownership / privilege escalation
  • Unsafe delegatecall — attacker-controlled targets, storage collisions, proxy/init reentrancy
  • Oracle & price manipulation — spot-price / AMM oracle abuse, flashloan-driven price manipulation
  • Cross-chain & bridges — message replay, forged proofs, missing nonces, calldata truncation
  • Signatures & permits — EIP-712 domain separators, ERC-2612 permit, EIP-7702 delegation, ERC-1271
  • Arithmetic — integer overflow/underflow, division-before-multiplication
  • ERC-standard misuse — unchecked ERC-20 returns, ERC-721/1155, ERC-4626 vault, ERC-777 hooks
  • Insecure randomness, denial of service (unbounded loops), and more

Run solast scan --rule <id> to target a single detector, or --tier core for the higher-signal subset.

Install

# global CLI (installs the `solast` command)
npm install -g @snovon/solast

# or run without installing anything
npx @snovon/solast scan contracts/

# or as a project dependency / library
npm install @snovon/solast

Requires Node.js ≥ 18. SolAST parses any Solidity source accepted by the @solidity-parser/parser grammar (pragmas from 0.4.x through 0.8.x); it does not invoke solc, so no compiler install, remappings, or build setup are needed.

Quick start

solast scan contracts/MyToken.sol      # one file
solast scan contracts/                 # a whole directory of .sol files

Example output

$ solast scan examples/reentrancy.sol
Discovered 1 Solidity file(s).
▼ examples/reentrancy.sol (9)
  examples/reentrancy.sol:16:8 [high] classic-reentrancy (Vault.withdraw): Potential reentrancy: state modification after external call in function 'withdraw'
  16 |         balances[msg.sender] = 0; // state updated AFTER the external call
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^
  examples/reentrancy.sol:16:8 [medium] check-effects-interactions (Vault.withdraw): Check-effects-interactions violation in 'withdraw': state mutation occurs after an external interaction.
  16 |         balances[msg.sender] = 0; // state updated AFTER the external call
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^
  ...
9 finding(s) across 1 file(s)

See examples/ for the vulnerable contracts above (reentrancy, access control, unsafe delegatecall).

Usage

# machine-readable output for CI / tooling
solast scan --format sarif contracts/ > findings.sarif   # GitHub code scanning
solast scan --format json  contracts/                    # NDJSON, one object per finding

# focus the scan
solast scan --rule classic-reentrancy contracts/         # a single detector
solast scan --tier core contracts/                       # higher-signal subset
solast scan --dedup contracts/                           # collapse overlapping findings

# gate CI on severity
solast scan --ci --severity-threshold high contracts/

# only report net-new findings vs a checked-in baseline
solast scan --format json contracts/ > baseline.ndjson
solast scan --diff-baseline baseline.ndjson contracts/

Run solast scan --help for the full option list (workers, ignore patterns, opt-in detectors, FP tuning, and more).

Library API

import { scan, type ScanResult } from '@snovon/solast';

// scan() takes a path (or array of paths) and returns the findings array.
const findings: ScanResult[] = scan('contracts/');
for (const f of findings) {
  console.log(`${f.file}:${f.line} [${f.severity}] ${f.ruleId}: ${f.message}`);
}

Why SolAST?

SolAST is not trying to replace Slither — it makes a different trade-off:

  • Zero setup. SolAST analyzes raw Solidity source. There is no solc to install, no compilation step, and no remappings/build config — npx @snovon/solast scan contracts/ just works. (Slither compiles with solc and builds a richer IR, which buys precision at the cost of a working build.)
  • DeFi-heavy corpus. Beyond generic Solidity checks, the detector library leans into DeFi-specific failure classes: oracle/flashloan manipulation, bridge & cross-chain message safety, and modern signature standards (EIP-2612 / EIP-712 / EIP-7702 / ERC-1271).
  • CI-native output. First-class SARIF 2.1.0 (drop straight into GitHub code scanning) and NDJSON, severity gating (--ci --severity-threshold), and content-hashed stable finding IDs for suppression and run-to-run diffing (--diff-baseline).

Many teams run more than one tool; SolAST is cheap to add to that set.

False-positive philosophy

SolAST favors recall over precision: when a line looks suspicious, multiple detectors may flag it from different angles (the reentrancy example above produces 9 findings on a single function). That is by design — a finding is a signal to review, not a confirmed bug. To manage noise:

  • --dedup collapses overlapping findings from related detectors
  • --severity-threshold high (and --ci) filters low-signal findings
  • --rule / --tier core narrow the active detector set
  • --fp-threshold downgrades the severity of statistically noisy rules

If a detector is wrong for your codebase, exclude it with --ignore-pattern.

Exit codes

Code Meaning
0 No findings
1 One or more findings at or above the active severity threshold
2 User error (invalid arguments or unreadable input)
3 Internal error

Building from source

git clone https://github.com/Snovon/SolAST.git
cd SolAST
npm install
npm run build   # compiles src/ to dist/; entrypoint is dist/cli.js

Contributing

Contributions are welcome — see CONTRIBUTING.md. To report a security issue in SolAST itself, follow SECURITY.md (please do not open a public issue for that).

License

Apache-2.0 — see LICENSE.