Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions solidity-auditor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,21 @@ _Portrayed below: finding multiple high-confidence vulnerabilities in a codebase
/solidity-auditor --file-output
```

## Constraints (optional)

Drop a `.pashov-skills-constraints.yaml` in your repo root to tell the skill what your codebase does and doesn't use. Agents will skip irrelevant attack vectors during triage, reducing noise and scan time.

```yaml
tokens: [USDC, WETH] # skip exotic-token vectors
standards: [ERC20] # skip ERC721/ERC1155/ERC4626 vectors
cross_chain: false # skip LayerZero/bridge vectors
proxy_pattern: none # none | transparent | uups | diamond | beacon
oracle: chainlink # chainlink | twap | pyth | custom | none
account_abstraction: false # skip ERC-4337 vectors
```

All fields optional. Code overrides constraints.

## Known Limitations

**Codebase size.** Works best up to ~2,500 lines of Solidity. Past ~5,000 lines, triage accuracy and mid-bundle recall drop noticeably. For large codebases, run per module rather than everything at once.
Expand Down
23 changes: 19 additions & 4 deletions solidity-auditor/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ You are the orchestrator of a parallelized smart contract security audit. Your j

- `--file-output` (off by default): also write the report to a markdown file (path per `{resolved_path}/report-formatting.md`). Without this flag, output goes to the terminal only. Never write a report file unless the user explicitly passes `--file-output`.

## Constraints (optional)

If a `.pashov-skills-constraints.yaml` file exists in the repository root, the orchestrator reads it during discovery and includes it in every agent bundle. Agents use declared constraints to fast-track **Skip** classification during triage. Constraints describe factual codebase properties, not security assumptions. Code overrides constraints.

Supported fields (all optional, unknown fields ignored):

```yaml
tokens: [USDC, WETH] # accepted token list (skip exotic-token vectors if set)
standards: [ERC20] # implemented standards (skip unlisted standard vectors)
cross_chain: false # no bridge/LayerZero/cross-chain logic
proxy_pattern: none # none | transparent | uups | diamond | beacon
oracle: chainlink # chainlink | twap | pyth | custom | none
account_abstraction: false # no ERC-4337 / smart account logic
```

## Version Check

After printing the banner, run two parallel tool calls: (a) Read the local `VERSION` file from the same directory as this skill, (b) Bash `curl -sf https://raw.githubusercontent.com/pashov/skills/main/solidity-auditor/VERSION`. If the remote fetch succeeds and the versions differ, print:
Expand All @@ -29,16 +44,16 @@ Then continue normally. If the fetch fails (offline, timeout), skip silently.

## Orchestration

**Turn 1 — Discover.** Print the banner, then in the same message make parallel tool calls: (a) Bash `find` for in-scope `.sol` files per mode selection, (b) Glob for `**/references/attack-vectors/attack-vectors-1.md` and extract the `references/` directory path (two levels up). Use this resolved path as `{resolved_path}` for all subsequent references.
**Turn 1 — Discover.** Print the banner, then in the same message make parallel tool calls: (a) Bash `find` for in-scope `.sol` files per mode selection, (b) Glob for `**/references/attack-vectors/attack-vectors-1.md` and extract the `references/` directory path (two levels up), (c) Read `.pashov-skills-constraints.yaml` from the repository root (if not found, continue without constraints). Use this resolved path as `{resolved_path}` for all subsequent references.

**Turn 2 — Prepare.** In a single message, make three parallel tool calls: (a) Read `{resolved_path}/agents/vector-scan-agent.md`, (b) Read `{resolved_path}/report-formatting.md`, (c) Bash: create four per-agent bundle files (`/tmp/audit-agent-{1,2,3,4}-bundle.md`) in a **single command** — each concatenates **all** in-scope `.sol` files (with `### path` headers and fenced code blocks), then `{resolved_path}/judging.md`, then `{resolved_path}/report-formatting.md`, then `{resolved_path}/attack-vectors/attack-vectors-N.md`; print line counts. Every agent receives the full codebase — only the attack-vectors file differs per agent. Do NOT read or inline any file content into agent prompts — the bundle files replace that entirely.
**Turn 2 — Prepare.** In a single message, make three parallel tool calls: (a) Read `{resolved_path}/agents/vector-scan-agent.md`, (b) Read `{resolved_path}/report-formatting.md`, (c) Bash: create four per-agent bundle files (`/tmp/audit-agent-{1,2,3,4}-bundle.md`) in a **single command** — if constraints were found in Turn 1, each bundle starts with a `## Constraints` section containing the raw YAML content; then concatenate **all** in-scope `.sol` files (with `### path` headers and fenced code blocks), then `{resolved_path}/judging.md`, then `{resolved_path}/report-formatting.md`, then `{resolved_path}/attack-vectors/attack-vectors-N.md`; print line counts. Every agent receives the full codebase — only the attack-vectors file differs per agent. Do NOT read or inline any file content into agent prompts — the bundle files replace that entirely.

**Turn 3 — Spawn.** In a single message, spawn all agents as parallel foreground Agent tool calls (do NOT use `run_in_background`). Always spawn Agents 1–4. Only spawn Agent 5 when the mode is **DEEP**.

- **Agents 1–4** (vector scanning) — spawn with `model: "sonnet"`. Each agent prompt must contain the full text of `vector-scan-agent.md` (read in Turn 2, paste into every prompt). After the instructions, add: `Your bundle file is /tmp/audit-agent-N-bundle.md (XXXX lines).` (substitute the real line count).
- **Agent 5** (adversarial reasoning, DEEP only) — spawn with `model: "opus"`. Receives the in-scope `.sol` file paths and the instruction: your reference directory is `{resolved_path}`. Read `{resolved_path}/agents/adversarial-reasoning-agent.md` for your full instructions.
- **Agent 5** (adversarial reasoning, DEEP only) — spawn with `model: "opus"`. Receives the in-scope `.sol` file paths and the instruction: your reference directory is `{resolved_path}`. If constraints were found in Turn 1, also include: the constraints file is at `.pashov-skills-constraints.yaml` in the repository root. Read `{resolved_path}/agents/adversarial-reasoning-agent.md` for your full instructions.

**Turn 4 — Report.** Merge all agent results: deduplicate by root cause (keep the higher-confidence version), sort by confidence highest-first, re-number sequentially, and insert the **Below Confidence Threshold** separator row. Print findings directly — do not re-draft or re-describe them. Use report-formatting.md (read in Turn 2) for the scope table and output structure. If `--file-output` is set, write the report to a file (path per report-formatting.md) and print the path.
**Turn 4 — Report.** Merge all agent results: deduplicate by root cause (keep the higher-confidence version), sort by confidence highest-first, re-number sequentially, and insert the **Below Confidence Threshold** separator row. Print findings directly — do not re-draft or re-describe them. Use report-formatting.md (read in Turn 2) for the scope table and output structure. If constraints were loaded, add a **Constraints** row to the scope table showing the declared values. If `--file-output` is set, write the report to a file (path per report-formatting.md) and print the path.

## Banner

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ You communicate results back ONLY through your final text response. Do not outpu

## Workflow

1. Read all in-scope `.sol` files, plus `judging.md` and `report-formatting.md` from the reference directory provided in your prompt, in a single parallel batch. Do not use any attack vector reference files.
2. Reason freely about the code — look for logic errors, unsafe external interactions, access control gaps, economic exploits, and any other vulnerability you can construct a concrete attack path for. For each potential finding, apply the FP gate from `judging.md` immediately (three checks). If any check fails → drop and move on without elaborating. Only if all three pass → trace the full attack path, apply score deductions, and format the finding.
3. Your final response message MUST contain every finding **already formatted per `report-formatting.md`** — indicator + bold numbered title, location · confidence line, **Description** with one-sentence explanation, and **Fix** with diff block (omit fix for findings below 80 confidence). Use placeholder sequential numbers (the main agent will re-number).
4. Do not output findings during analysis — compile them all and return them together as your final response.
5. If you find NO findings, respond with "No findings."
1. Read all in-scope `.sol` files, plus `judging.md`, `report-formatting.md`, and `.pashov-skills-constraints.yaml` (if it exists) from the reference directory provided in your prompt, in a single parallel batch. Do not use any attack vector reference files.
2. If `.pashov-skills-constraints.yaml` was found, note the declared codebase properties and use them to focus your analysis on relevant attack surfaces. Constraints describe codebase properties, not security assumptions — code overrides constraints.
3. Reason freely about the code — look for logic errors, unsafe external interactions, access control gaps, economic exploits, and any other vulnerability you can construct a concrete attack path for. For each potential finding, apply the FP gate from `judging.md` immediately (three checks). If any check fails → drop and move on without elaborating. Only if all three pass → trace the full attack path, apply score deductions, and format the finding.
4. Your final response message MUST contain every finding **already formatted per `report-formatting.md`** — indicator + bold numbered title, location · confidence line, **Description** with one-sentence explanation, and **Fix** with diff block (omit fix for findings below 80 confidence). Use placeholder sequential numbers (the main agent will re-number).
5. Do not output findings during analysis — compile them all and return them together as your final response.
6. If you find NO findings, respond with "No findings."
4 changes: 3 additions & 1 deletion solidity-auditor/references/agents/vector-scan-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ You communicate results back ONLY through your final text response. Do not outpu
## Workflow

1. Read your bundle file in **parallel 1000-line chunks** on your first turn. The line count is in your prompt — compute the offsets and issue all Read calls at once (e.g., for a 5000-line file: `Read(file, limit=1000)`, `Read(file, offset=1000, limit=1000)`, `Read(file, offset=2000, limit=1000)`, `Read(file, offset=3000, limit=1000)`, `Read(file, offset=4000, limit=1000)`). Do NOT read without a limit. These are your ONLY file reads — do NOT read any other file after this step.
2. **Triage pass.** For each vector, classify into three tiers:
2. **Triage pass.** If a `## Constraints` section is present at the top of your bundle, use it to fast-track Skip classification. For example, if `cross_chain: false`, skip all cross-chain/bridge vectors without further analysis. If `standards: [ERC20]`, skip ERC721/ERC1155/ERC4626-specific vectors. Constraints describe codebase properties, not security assumptions. Code overrides constraints — classify based on what the code actually contains.

For each vector, classify into three tiers:
- **Skip** — the named construct AND underlying concept are both absent (e.g., ERC721 vectors when there are no NFTs at all).
- **Borderline** — the named construct is absent but the underlying vulnerability concept could manifest through a different mechanism in this codebase (e.g., "stale cached ERC20 balance" when the code caches cross-contract AMM reserves; "ERC777 reentrancy" when there are flash-swap callbacks).
- **Survive** — the construct or pattern is clearly present.
Expand Down
1 change: 1 addition & 0 deletions solidity-auditor/references/report-formatting.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Save the report to `assets/findings/{project-name}-pashov-ai-audit-report-{times
| **Mode** | ALL / default / filename |
| **Files reviewed** | `File1.sol` · `File2.sol`<br>`File3.sol` · `File4.sol` | <!-- list every file, 3 per line -->
| **Confidence threshold (1-100)** | N |
| **Constraints** | _if `.pashov-skills-constraints.yaml` found, list declared values; otherwise omit this row_ |

---

Expand Down