Skip to content

dusy4/pi3

Repository files navigation

guml — contract vulnerability triage pipeline (ETH + BSC)

image

📖 ARCHITECTURE.md — how the whole system works (pipeline, agent & contract lifecycle, providers/models, dashboard API). 🚀 DEPLOYMENT.md — set it up on a fresh host. 🔒 SECURITY.md — authorized use only; responsible disclosure; the dashboard is an unauthenticated control plane — keep it private.

(Internal docs deliberately live here, not in CLAUDE.md/AGENTS.md, because those are auto-read by the audit agent and would confuse it.)

License: add a LICENSE file before publishing — pick one that fits your intent (e.g. MIT/Apache-2.0). This is research tooling; see SECURITY.md for the use policy.

Continuously find funded smart contracts on ETH/BSC and queue them for an AI agent (pi.dev) to deep-audit one at a time in isolation. A secondary one-shot mode runs static analysis (Slither / bytecode) + a Foundry fork-fuzz over an address list.

Architecture

guml architecture — crawlers discover and score funded contracts into an ROI-ranked SQLite queue; an audit worker builds an isolated env folder (artifacts, AGENTS.md brief, Foundry scaffold, chain fork) and hands it to the pi.dev agent, which writes an Attack.sol exploit and proves it on a local anvil fork; proven drains are staged to confirmed/ and alerted, everything else is marked audited; a rescan heartbeat keeps the queue fresh; a Flask dashboard controls it all.

Why "funded" is the only pre-filter that matters: contracts with obvious high-severity bugs that hold money are almost always already drained by sweeper bots. The edge is a deeper auditor finding non-obvious bugs — so we just surface funded contracts and let the agent do the real work.

discover → liveness/value filter → source resolve → static analysis → score → report → fork-fuzz

This is a research / triage tool. Its output is a candidate list, not confirmed exploits, and the legitimate destination for any finding is responsible disclosure or a bug-bounty / audit program — never on-chain draining.

Continuous mode: crawl → queue → AI audit (primary)

cd /path/to/guml
PY=~/.venvs/guml/bin/python

# 1) Crawl funded contracts into the SQLite queue (guml.db).
#    --source rpc = recent/new contracts (no account); --source bigquery = old/bulk (needs GCP auth).
$PY -m guml.crawl --chain eth --source rpc --min-balance-eth 0.05 --loop

# 2) Audit workers: each claims one contract (row-locked) and runs pi.dev on it,
#    isolated in audits/<chain>/<address>/. Run up to ~5 in parallel.
$PY -m guml.audit --worker w1 --loop &
$PY -m guml.audit --worker w2 --loop &

Each audit folder gets AGENTS.md (the brief pi reads automatically), bytecode.txt, contract.json, verified source.sol when available, best-effort decompiled.sol for unverified contracts when Heimdall succeeds, and a Foundry PoC scaffold at foundry/test/Exploit.t.sol. The agent writes findings.json and completes the PoC. The worker then runs the PoC on a local fork: if it passes (provably extracts value), the contract is marked vulnerable and its exploit + proof are staged to confirmed/<chain>/<address>/. PoCs run on a local anvil fork only — never broadcast.

The pi.dev agent is installed by setup/install.sh (standalone Node 22 + @earendil-works/pi-coding-agent under ~/.guml-pi — kept off the repo mount to avoid WSL DrvFs corruption; resolved automatically by guml/tools.py). It uses the provider in ~/.pi/agent/models.json with OPENROUTER_API_KEY from .env. Swap the model via the PI_MODEL env var or that file. Without pi, the worker still prepares each workspace and writes a placeholder.

Model note: the configured free model nvidia/nemotron-3-ultra-550b-a55b:free works but is very slow (~74s for 20 tokens) — fine for validating wiring, impractical for real agentic audits. Point PI_MODEL at a faster model for real runs. Set PI_MODEL_FALLBACKS (comma-separated) or the pi_model_fallbacks setting to continue the same audit with another model after quota/auth/provider failures.

Live dashboard / control plane

$PY -m guml.dashboard          # http://127.0.0.1:8000

A control panel, not just a viewer:

  • Queue stats + which worker is on which contract, refreshed live.
  • Click any contract to watch the pi agent's live output (pi_live.log) and its findings.json.
  • Controls: pause/resume all workers, pause/stop a single worker, and kill a stuck pi (requeues the contract).
  • Switch the audit model at runtime from the model box — takes effect on the next contract each worker claims.
  • Confirmed vulnerabilities with links to proof + exploit code.

The audit agent is provider-agnostic: pi supports OpenAI-compatible and Anthropic-compatible endpoints plus OpenRouter — configure providers in pi/models.json and keys in .env (OPENROUTER_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY), then pick the model in the UI.

  • BigQuery source (--source bigquery, ETH only): gcloud auth application-default login once.
  • Queue (guml.db), workspaces (audits/), and confirmed exploits (confirmed/) are gitignored.

What it does, stage by stage

Stage Module What it does
Discover discover.py candidate addresses from a CSV export (BigQuery/Dune) or an RPC block-scan
Liveness liveness.py drop EOAs / self-destructed; record native balance (value-at-risk)
Source explorer.py Etherscan V2 (one key, chainid 1 or 56) → verified source or "unverified"
Static analyze/slither_runner.py Slither detectors on verified source (high confidence)
Static analyze/bytecode_runner.py opcode scan + heimdall decompile on unverified bytecode (low confidence)
Score score.py combine finding severity × confidence, weighted by value-at-risk → 0–100
Report report.py ranked.csv + per-contract markdown
Dynamic dynamic/foundry_harness.py anvil fork + invariant fuzz: can an unprivileged caller drain it?

Environment

Runs on Linux or WSL (the security tools are Unix-first). See DEPLOYMENT.md for the full setup.

Installed by the setup step:

  • Python venv at ~/.venvs/guml with web3, slither-analyzer, solc-select, …
  • solc (via solc-select), heimdall (via bifrost), forge/anvil/cast (Foundry), Rust

Setup

  1. Toolchain — already installed into WSL (~/.venvs/guml, Foundry, heimdall, solc). To reproduce on another machine, re-run setup/install_wsl.sh (see that file).

  2. Secrets — copy and fill in:

    cp .env.example .env
    • ETHERSCAN_API_KEYrequired for verified-source analysis. One free key from https://etherscan.io/apis works for both ETH and BSC (Etherscan V2). Without it, the pipeline still runs in bytecode-only mode.
    • ETH_RPC_URL, BSC_RPC_URL — public defaults are pre-filled; a paid node is faster.
  3. Discovery data (optional, for bulk runs):

    • ETH: run old_contracts.sql in BigQuery, export the address column to a CSV.
    • BSC: a Dune query on BNB-chain contracts, exported the same way.
    • Or skip both and use --scan START END to discover over RPC.

Usage

From WSL, via the wrapper (sets the venv + path for you):

# Analyze an exported address list on BSC, keep contracts holding >= 0.1 BNB
bash run.sh --chain bsc --in addresses.csv --min-balance-eth 0.1

# Discover by scanning a recent block range on ETH, then fork-fuzz the top hits
bash run.sh --chain eth --scan 19000000 19000200 --dynamic --dynamic-top 5

# Quick smoke of the analyzers (no RPC/key needed)
PYTHONPATH=. ~/.venvs/guml/bin/python setup/smoke.py

Output lands in out/<chain>/: ranked.csv, ranked.json, per-contract *.md, and (with --dynamic) a Foundry project + probe_result.txt per top candidate.

Performance note: the static pipeline is fast, but --dynamic fork-fuzzing is network-bound — on a public RPC it can take ~5 min per contract (lazy fork-state fetches). Use a paid/low-latency RPC and a small --dynamic-top for real runs, or tune [invariant] runs/depth in the generated foundry.toml.

Tests

~/.venvs/guml/bin/python -m pytest

Caveats

  • Output is a ranked candidate list; confirm by hand + simulation before believing it.
  • BSC contracts are mostly unverified → the noisier bytecode path dominates there.
  • The fork-fuzz invariants are heuristics: expect false positives (legit permissionless flows) and false negatives (multi-step / token-based exploits).
  • Funded + verified + known-vuln contracts on ETH are heavily swept already.

About

pi3/guml Crawl ETH and BSC blockchains for funded smart contracts and point LLM agents at them to find an exploit.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors