anchor-audit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,28 +1,708 @@
1
- # anchor-audit CLI
1
+ # anchor-audit
2
2
 
3
- AI-driven security audit CLI for Anchor programs on Solana. Sends your program source plus the [rule catalog](../rules) to the Claude API and renders a structured audit report.
3
+ [![npm version](https://img.shields.io/npm/v/anchor-audit)](https://www.npmjs.com/package/anchor-audit)
4
4
 
5
- > **Status:** scaffolding only implementation lands in Phase 4 (see [IMPLEMENTATION_PLAN.md](../IMPLEMENTATION_PLAN.md)).
5
+ A security audit toolkit for [Anchor](https://www.anchor-lang.com/) smart contracts on Solana.
6
+
7
+ Anchor programs handle real money on-chain. A single missing signer check or unchecked arithmetic operation can drain a protocol entirely. `anchor-audit` gives developers a fast, structured first pass over their code before it ships.
8
+
9
+ > **Disclaimer:** `anchor-audit` is a triage aid, not a substitute for a professional human audit. See [Limitations](#limitations).
10
+
11
+ ---
12
+
13
+ ## What is anchor-audit?
14
+
15
+ `anchor-audit` checks your Rust/Anchor source files against a catalog of **50 known Solana security rules** - things like missing signer checks, arbitrary CPI targets, arithmetic overflows, and reinitialization attacks. It sends your code to an AI model that reads each rule and flags any matching patterns, then formats the results into a structured report.
16
+
17
+ It ships as two tools that share the same 50-rule catalog:
18
+
19
+ | Tool | What it is | When to use it |
20
+ |------|-----------|----------------|
21
+ | **Claude Code Skill** | A prompt skill for Claude Code | When you're already in a Claude Code session and want a quick review |
22
+ | **CLI (`anchor-audit`)** | A command-line tool | When you want a full automated report you can save, diff, and share |
23
+
24
+ Both tools stay in sync: when a rule is improved in `/rules/`, both the skill and the CLI benefit automatically.
25
+
26
+ ---
27
+
28
+ ## Table of Contents
29
+
30
+ - [Quick Start](#quick-start)
31
+ - [Claude Code Skill](#claude-code-skill)
32
+ - [CLI Setup](#cli-setup)
33
+ - [Cloud Providers](#cloud-providers)
34
+ - [Local Models](#local-models-no-api-key-no-cost)
35
+ - [Running an Audit](#running-an-audit)
36
+ - [Understanding the Flags](#understanding-the-flags)
37
+ - [Reading the Report](#reading-the-report)
38
+ - [Performance Guide](#performance-guide)
39
+ - [Rule Catalog](#rule-catalog)
40
+ - [Limitations](#limitations)
41
+ - [Contributing](#contributing)
42
+
43
+ ---
44
+
45
+ ## Quick Start
46
+
47
+ **Option A - Claude Code Skill (fastest):**
48
+ ```bash
49
+ git clone https://github.com/guptaaayush432/anchor-audit
50
+ cp anchor-audit/SKILL.md ~/.claude/skills/anchor-audit.md
51
+ # Then in any Claude Code session: "audit my program in ./programs/my-vault"
52
+ ```
53
+
54
+ **Option B - CLI with a cloud provider:**
55
+ ```bash
56
+ npm install -g anchor-audit
57
+
58
+ # Copy the example env file and add your key
59
+ cp .env.example .env
60
+ # Edit .env and fill in the key for your chosen provider
61
+
62
+ # Basic run - uses Anthropic claude-sonnet-4-6 by default
63
+ anchor-audit ./programs/my-vault
64
+
65
+ # Show progress as each rule batch is processed
66
+ anchor-audit ./programs/my-vault --verbose
67
+
68
+ # Use a different provider or model
69
+ anchor-audit ./programs/my-vault --provider openai --model gpt-4o
70
+ anchor-audit ./programs/my-vault --provider groq
71
+
72
+ # Only check critical and high severity rules (faster)
73
+ anchor-audit ./programs/my-vault --severity high
74
+
75
+ # Deeper analysis with more output per finding
76
+ anchor-audit ./programs/my-vault --effort high
77
+
78
+ # Fast triage - high severity rules only, low token budget
79
+ anchor-audit ./programs/my-vault --severity high --effort low
80
+
81
+ # Save report to a file
82
+ anchor-audit ./programs/my-vault --output AUDIT.md
83
+ ```
84
+
85
+ **Option C - CLI with Ollama (free, runs locally):**
86
+ ```bash
87
+ npm install -g anchor-audit
88
+ ollama pull llama3.1:8b
89
+ anchor-audit ./programs/my-vault --provider ollama --effort low
90
+ # Change the model and reasoning effort accordingly
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Claude Code Skill
96
+
97
+ The Claude Code Skill lets you audit Anchor programs directly inside a Claude Code session - no API key needed beyond your existing Claude/Codex subscription, no extra installation beyond copying one file.
98
+
99
+ ### Install
100
+
101
+ ```bash
102
+ git clone https://github.com/guptaaayush432/anchor-audit
103
+ cp anchor-audit/SKILL.md ~/.claude/skills/anchor-audit.md
104
+ ```
105
+
106
+ ### How to use it
107
+
108
+ Once installed, Claude/Codex picks up the skill automatically whenever you ask it to review Anchor code. Just describe what you want in plain English:
109
+
110
+ ```
111
+ > audit my anchor program in ./programs/my-vault
112
+ > review the withdraw instruction for authorization issues
113
+ > check this code for unchecked arithmetic
114
+ > does my vault have any CPI safety issues?
115
+ > look for missing signer checks in programs/staking/src/lib.rs
116
+ ```
117
+
118
+ Claude/Codex will read your source files, apply the 50-rule catalog, and respond with a structured list of findings.
119
+
120
+ ### When to use the Skill vs the CLI
121
+
122
+ | | Skill | CLI |
123
+ |--|-------|-----|
124
+ | Requires separate API key | No | Yes (or local model) |
125
+ | Interactive follow-up questions | Yes | No |
126
+ | Saves a report file automatically | No | Yes |
127
+ | Full 50-rule batch scan | Depends on context | Always |
128
+ | Good for | Quick reviews while coding | Full audits before shipping |
129
+
130
+ ---
131
+
132
+ ## CLI Setup
133
+
134
+ ### Requirements
135
+
136
+ - Node.js 20 or later (`node --version` to check)
137
+ - An AI provider - cloud (needs API key) or local (needs Ollama/LM Studio/vLLM running)
138
+
139
+ ### Install
140
+
141
+ ```bash
142
+ npm install -g anchor-audit
143
+ ```
144
+
145
+ Verify it works:
146
+
147
+ ```bash
148
+ anchor-audit --help
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Cloud Providers
154
+
155
+ Cloud providers are the easiest to start with and produce the most accurate results.
156
+
157
+ ### Setting up your API key
158
+
159
+ All API keys are loaded from a `.env` file in your project root. Copy the example file and fill in the key for the provider you want to use:
160
+
161
+ ```bash
162
+ cp .env.example .env
163
+ ```
164
+
165
+ Then open `.env` and add your key:
166
+
167
+ ```env
168
+ # Only fill in the provider you plan to use
169
+ ANTHROPIC_API_KEY=sk-ant-...
170
+ OPENAI_API_KEY=sk-...
171
+ GEMINI_API_KEY=...
172
+ GROQ_API_KEY=gsk_...
173
+ OPENROUTER_API_KEY=sk-or-...
174
+ ```
175
+
176
+ Never use `export KEY=...` in your terminal - that sets the key globally for all tools and sessions, which can accidentally bill API credits when you did not intend to.
177
+
178
+ ### Anthropic (default, recommended)
179
+
180
+ Best overall accuracy for security auditing. Uses `claude-sonnet-4-6` by default.
181
+
182
+ ```bash
183
+ # In .env: ANTHROPIC_API_KEY=sk-ant-...
184
+ anchor-audit ./programs/my-vault
185
+ ```
186
+
187
+ **Where to get a key:** [console.anthropic.com](https://console.anthropic.com)
188
+
189
+ For the deepest analysis, use a more powerful model:
190
+
191
+ ```bash
192
+ anchor-audit ./programs/my-vault --model claude-opus-4-8
193
+ ```
194
+
195
+ ### OpenAI (ChatGPT)
196
+
197
+ ```bash
198
+ # In .env: OPENAI_API_KEY=sk-...
199
+ anchor-audit ./programs/my-vault --provider openai
200
+ anchor-audit ./programs/my-vault --provider openai --model gpt-4o
201
+ ```
202
+
203
+ **Where to get a key:** [platform.openai.com](https://platform.openai.com)
204
+
205
+ ### Google Gemini
206
+
207
+ ```bash
208
+ # In .env: GEMINI_API_KEY=...
209
+ anchor-audit ./programs/my-vault --provider google
210
+ anchor-audit ./programs/my-vault --provider google --model gemini-2.0-flash
211
+ ```
212
+
213
+ **Where to get a key:** [aistudio.google.com](https://aistudio.google.com)
214
+
215
+ ### Groq
216
+
217
+ Groq offers a generous free tier - a good way to try the tool at no cost with a cloud model.
218
+
219
+ ```bash
220
+ # In .env: GROQ_API_KEY=gsk_...
221
+ anchor-audit ./programs/my-vault --provider groq
222
+ ```
223
+
224
+ **Where to get a key:** [console.groq.com](https://console.groq.com)
225
+
226
+ ### OpenRouter (access 100+ models with one key)
227
+
228
+ OpenRouter routes to Anthropic, OpenAI, Meta, Mistral, and many others. Useful if you want to compare results across models.
229
+
230
+ ```bash
231
+ # In .env: OPENROUTER_API_KEY=sk-or-...
232
+ anchor-audit ./programs/my-vault --provider openrouter
233
+ anchor-audit ./programs/my-vault --provider openrouter --model meta-llama/llama-3.3-70b-instruct
234
+ anchor-audit ./programs/my-vault --provider openrouter --model google/gemini-2.0-flash
235
+ ```
236
+
237
+ **Where to get a key:** [openrouter.ai](https://openrouter.ai)
238
+
239
+ ---
240
+
241
+ ## Local Models (no API key, no cost)
242
+
243
+ > **Warning:** Local models produce significantly worse results than cloud models. In testing, an 8B local model (qwen3 via Ollama) returned zero findings on a real-world program that a cloud model flagged multiple issues in. Use local models only for quick exploratory checks during development - never for a final audit before shipping.
244
+
245
+ Local models run entirely on your machine. No data leaves your computer, there are no API costs, and you can audit private code without sending it to a third party.
246
+
247
+ The trade-off is speed and accuracy - local models are slower and miss many real issues that a cloud model would catch. See [Performance Guide](#performance-guide) for tips.
248
+
249
+ ### Ollama
250
+
251
+ [Ollama](https://ollama.com) is the easiest way to run local models on macOS, Linux, or Windows.
252
+
253
+ **Step 1 - Install Ollama:**
254
+ ```bash
255
+ # macOS
256
+ brew install ollama
257
+
258
+ # Or download from https://ollama.com
259
+ ```
260
+
261
+ **Step 2 - Pull a model:**
262
+ ```bash
263
+ # Small and fast (good for quick checks)
264
+ ollama pull llama3.1:8b
265
+
266
+ # Larger and more accurate (slower)
267
+ ollama pull qwen2.5-coder:32b
268
+ ollama pull llama3.3:70b
269
+ ```
270
+
271
+ **Step 3 - Start the Ollama server** (it may already be running):
272
+ ```bash
273
+ ollama serve
274
+ ```
275
+
276
+ **Step 4 - Run the audit:**
277
+ ```bash
278
+ # No API key needed
279
+ anchor-audit ./programs/my-vault --provider ollama --model llama3.1:8b
280
+ ```
281
+
282
+ To use a non-default port:
283
+ ```bash
284
+ anchor-audit ./programs/my-vault --provider ollama \
285
+ --base-url http://localhost:5000/v1 \
286
+ --model llama3.1:8b
287
+ ```
288
+
289
+ ### LM Studio
290
+
291
+ [LM Studio](https://lmstudio.ai) provides a desktop GUI for downloading and running local models.
292
+
293
+ **Step 1** - Download and open LM Studio
294
+ **Step 2** - Download a model from the Discover tab (e.g. Mistral 7B, Qwen 2.5)
295
+ **Step 3** - Go to the Local Server tab and click **Start Server**
296
+ **Step 4** - Run the audit:
297
+
298
+ ```bash
299
+ # LM Studio's server runs on port 1234 by default
300
+ anchor-audit ./programs/my-vault --provider lmstudio --model local-model
301
+ ```
302
+
303
+ The `--model local-model` value is a placeholder - LM Studio uses whichever model is currently loaded in its UI.
304
+
305
+ ### vLLM
306
+
307
+ [vLLM](https://vllm.ai) is a high-throughput inference engine for production-grade local deployments.
308
+
309
+ ```bash
310
+ # Start vLLM server first (example)
311
+ python -m vllm.entrypoints.openai.api_server \
312
+ --model mistralai/Mistral-7B-Instruct-v0.3 \
313
+ --port 8000
314
+
315
+ # Then run the audit
316
+ anchor-audit ./programs/my-vault --provider vllm --model mistralai/Mistral-7B-Instruct-v0.3
317
+ ```
318
+
319
+ ### Custom endpoint
320
+
321
+ Any server that speaks the OpenAI chat completions API format works with `--provider custom`:
322
+
323
+ ```bash
324
+ anchor-audit ./programs/my-vault \
325
+ --provider custom \
326
+ --base-url http://192.168.1.10:8080/v1 \
327
+ --model my-model-name
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Running an Audit
333
+
334
+ ### Basic usage
6
335
 
7
336
  ```bash
8
- anchor-audit <path-to-anchor-program> [options]
337
+ # Print findings to the terminal
338
+ anchor-audit ./programs/my-vault
339
+
340
+ # Save to a file
341
+ anchor-audit ./programs/my-vault --output AUDIT.md
342
+
343
+ # Show progress as each rule batch is sent to the model
344
+ anchor-audit ./programs/my-vault --verbose
345
+ ```
346
+
347
+ ### Filter by severity
348
+
349
+ `--severity` controls **which rules are checked**. Rules below the chosen level are skipped entirely - fewer rules means fewer batches, which means a faster run.
350
+
351
+ ```
352
+ --severity critical → 4 rules → 1 batch (fastest)
353
+ --severity high → 25 rules → 5 batches
354
+ --severity medium → 42 rules → 9 batches
355
+ --severity low → 50 rules → 10 batches (default, slowest)
356
+ ```
357
+
358
+ ```bash
359
+ # Only check the 4 most critical rules (missing signer, owner, auth, arbitrary CPI)
360
+ anchor-audit ./programs/my-vault --severity critical
361
+
362
+ # Check critical + high rules (covers the most dangerous 25 rules)
363
+ anchor-audit ./programs/my-vault --severity high
364
+
365
+ # Check everything (default)
366
+ anchor-audit ./programs/my-vault
367
+ ```
368
+
369
+ ### Control analysis depth
370
+
371
+ `--effort` controls **how many output tokens the model is allowed to generate per batch**. More tokens means the model can write longer, more detailed findings - but each batch takes longer.
372
+
373
+ | Effort | Max tokens | Best for |
374
+ |--------|-----------|----------|
375
+ | `low` | 2,048 | Local models, fast triage |
376
+ | `medium` | 4,096 | Default, balanced |
377
+ | `high` | 8,192 | Cloud models, thorough reports |
378
+
379
+ ```bash
380
+ # Fast triage - good for local models or quick CI checks
381
+ anchor-audit ./programs/my-vault --effort low --severity high
382
+
383
+ # Deep analysis - good for pre-release audits with a cloud model
384
+ anchor-audit ./programs/my-vault --effort high
385
+ ```
386
+
387
+ ### Run only specific rules
388
+
389
+ If you already know which issues to look for, skip the rest:
390
+
391
+ ```bash
392
+ # Check only for missing signer (001), arbitrary CPI (017), and missing auth (030)
393
+ anchor-audit ./programs/my-vault --rules 001,017,030
394
+ ```
395
+
396
+ ### JSON output
397
+
398
+ ```bash
399
+ # Print JSON to stdout
400
+ anchor-audit ./programs/my-vault --format json
401
+
402
+ # Save JSON to file
403
+ anchor-audit ./programs/my-vault --format json --output audit.json
404
+ ```
405
+
406
+ ### Combining flags
407
+
408
+ ```bash
409
+ # Recommended for local models: fast, focused on high-severity issues
410
+ anchor-audit ./programs/my-vault \
411
+ --provider ollama --model llama3.1:8b \
412
+ --severity high --effort low \
413
+ --verbose
414
+
415
+ # Recommended for pre-release audit with Anthropic
416
+ anchor-audit ./programs/my-vault \
417
+ --provider anthropic --model claude-opus-4-8 \
418
+ --effort high \
419
+ --output AUDIT_$(date +%Y-%m-%d).md
420
+ ```
421
+
422
+ ---
423
+
424
+ ## Understanding the Flags
425
+
426
+ | Flag | Default | Description |
427
+ |------|---------|-------------|
428
+ | `--provider <name>` | `anthropic` | Which AI provider to use. See [Providers](#cloud-providers) |
429
+ | `--model <id>` | per-provider | Override the default model for the chosen provider |
430
+ | `--api-key <key>` | env var | Pass your API key inline instead of via environment variable |
431
+ | `--base-url <url>` | per-provider | Override the server URL (useful for local models on non-default ports) |
432
+ | `--severity <level>` | `low` | Only check rules at this level or above. Does not filter the *output* - it skips rules entirely |
433
+ | `--effort <level>` | `medium` | How many tokens the model can use per batch. Higher = more detail, slower |
434
+ | `--rules <ids>` | all 50 | Comma-separated list of rule IDs to run, e.g. `001,017,030` |
435
+ | `--format <fmt>` | `markdown` | Output format: `markdown` or `json` |
436
+ | `--output <path>` | - | Write the report to this file in addition to the auto-saved copy |
437
+ | `--verbose` | off | Print each batch as it's sent to the model - useful for tracking progress |
438
+
439
+ **Provider defaults:**
440
+
441
+ | Provider | Type | Default model | API key env var |
442
+ |----------|------|--------------|-----------------|
443
+ | `anthropic` | Cloud | `claude-sonnet-4-6` | `ANTHROPIC_API_KEY` |
444
+ | `openai` | Cloud | `gpt-4o` | `OPENAI_API_KEY` |
445
+ | `google` | Cloud | `gemini-2.0-flash` | `GEMINI_API_KEY` |
446
+ | `groq` | Cloud | `llama-3.3-70b-versatile` | `GROQ_API_KEY` |
447
+ | `openrouter` | Cloud | `anthropic/claude-sonnet-4-6` | `OPENROUTER_API_KEY` |
448
+ | `ollama` | Local | `llama3.1:8b` | none required |
449
+ | `lmstudio` | Local | `local-model` | none required |
450
+ | `vllm` | Local | `local-model` | none required |
451
+ | `custom` | Either | `gpt-4o` | `OPENAI_API_KEY` |
452
+
453
+ **Exit codes:**
454
+
455
+ | Code | Meaning |
456
+ |------|---------|
457
+ | `0` | Audit complete - no critical or high findings |
458
+ | `1` | Audit complete - at least one critical or high finding was found |
459
+ | `2` | Error - bad path, missing API key, connection refused, etc. |
460
+
461
+ Exit code `1` is useful in CI: add `anchor-audit` as a pipeline step and it will block the build if critical issues are found.
462
+
463
+ ---
464
+
465
+ ## Reading the Report
466
+
467
+ Every audit produces a markdown report with three sections:
468
+
469
+ ### Audit Metadata
470
+
471
+ At the top of every report, you'll see exactly how and when it was generated:
9
472
 
10
- Options:
11
- --output <path> output file (default: stdout)
12
- --rules <ids> comma-separated rule IDs (default: all)
13
- --severity <min> minimum severity to report (critical | high | medium | low)
14
- --format <fmt> markdown (default) | json
15
- --verbose print per-rule progress
16
- --api-key <key> override ANTHROPIC_API_KEY env var
17
- --model <id> override default model (claude-sonnet-4-6)
18
473
  ```
474
+ | Field | Value |
475
+ |----------------|--------------------------------|
476
+ | Date | 2026-06-19 |
477
+ | Time | 14:30:15 UTC |
478
+ | Model | claude-sonnet-4-6 |
479
+ | Provider | anthropic |
480
+ | Effort | medium |
481
+ | CLI Version | v0.1.0 |
482
+ | Project | my-vault |
483
+ | Git Branch | main |
484
+ | Git Commit | a1b2c3d |
485
+ | OS | Darwin 25.0.0 (arm64) |
486
+ | Duration | 42.3s |
487
+ | Files Analyzed | 3 |
488
+ | Total Findings | 7 |
489
+ ```
490
+
491
+ ### Summary table
492
+
493
+ A quick count of findings by severity so you know at a glance how serious the results are:
494
+
495
+ ```
496
+ | Severity | Count |
497
+ |----------|-------|
498
+ | Critical | 2 |
499
+ | High | 3 |
500
+ | Medium | 1 |
501
+ | Low | 1 |
502
+ | Total | 7 |
503
+ ```
504
+
505
+ ### Findings
506
+
507
+ Each finding looks like this:
508
+
509
+ ```
510
+ ### [CRITICAL] Rule 001: Missing signer check in set_admin
511
+
512
+ **File:** `src/lib.rs:42`
513
+
514
+ **Description:** The `authority` account is passed as `AccountInfo` but is
515
+ never verified as a signer. Any account can be passed here, letting an
516
+ attacker call set_admin with a fake authority.
517
+
518
+ **Vulnerable code:**
519
+ pub authority: AccountInfo<'info>,
520
+
521
+ **Recommendation:** Change `AccountInfo<'info>` to `Signer<'info>`. Anchor
522
+ will then automatically verify the account signed the transaction.
523
+
524
+ **Reference:** rules/001-missing-signer-check.md
525
+ ```
526
+
527
+ ### Auto-saved reports
528
+
529
+ Every run automatically saves a timestamped copy to a `reports/` folder so you never lose a result:
530
+
531
+ ```
532
+ reports/
533
+ my-vault-2026-06-19T14-30-15Z.md
534
+ my-vault-2026-06-20T09-12-44Z.md
535
+ ```
536
+
537
+ The `reports/` directory is gitignored by default. Use `--output` to save a named copy in a specific location as well.
538
+
539
+ ---
540
+
541
+ ## Performance Guide
542
+
543
+ ### Cloud models
544
+
545
+ Cloud models are fast and accurate. The full 50-rule audit typically finishes in **1–3 minutes**. No special configuration needed beyond an API key.
546
+
547
+ ### Local models
548
+
549
+ Local models run on your hardware. Speed depends on your machine's CPU, RAM, and whether you have a GPU:
550
+
551
+ | Hardware | 8B model speed | 50-rule audit time |
552
+ |----------|---------------|-------------------|
553
+ | MacBook (Apple Silicon) | 30–60 tok/s | ~5–10 min |
554
+ | Gaming GPU (RTX 4090) | 100–150 tok/s | ~2–4 min |
555
+ | CPU only | 5–15 tok/s | 20–40 min |
556
+
557
+ **Tips for faster local audits:**
558
+
559
+ ```bash
560
+ # 1. Use --effort low to halve the output token budget
561
+ anchor-audit ./programs/my-vault --provider ollama --effort low
562
+
563
+ # 2. Use --severity high to cut from 10 batches to 5 batches
564
+ anchor-audit ./programs/my-vault --provider ollama --effort low --severity high
565
+
566
+ # 3. Use --severity critical for a 1-batch quick check (4 rules only)
567
+ anchor-audit ./programs/my-vault --provider ollama --severity critical
568
+
569
+ # 4. Use a smaller model - 3B or 4B models are 2–3x faster than 8B
570
+ ollama pull llama3.2:3b
571
+ anchor-audit ./programs/my-vault --provider ollama --model llama3.2:3b --effort low
572
+ ```
573
+
574
+ **Recommended combinations:**
575
+
576
+ | Goal | Command |
577
+ |------|---------|
578
+ | Fastest possible check (local) | `--provider ollama --severity critical --effort low` |
579
+ | Balanced local scan | `--provider ollama --severity high --effort low` |
580
+ | Full local scan (patient) | `--provider ollama --effort low` |
581
+ | Best accuracy (cloud) | `--provider anthropic --model claude-opus-4-8 --effort high` |
582
+ | Free cloud option | `--provider groq --severity high` |
583
+
584
+ > **Note on accuracy:** The same rules are sent to every model. A stronger model (Claude Opus, GPT-4o) will find more real issues and produce fewer false positives than a smaller local model. Use local models for quick iterative checks during development, and a strong cloud model for pre-release audits.
585
+
586
+ ---
587
+
588
+ ## Rule Catalog
589
+
590
+ 50 rules across 8 categories. Click any rule ID to read the full description, vulnerable pattern, fix pattern, and references.
591
+
592
+ | ID | Rule | Severity | Category |
593
+ |----|------|----------|----------|
594
+ | [001](rules/001-missing-signer-check.md) | Missing signer check | Critical | Account validation |
595
+ | [002](rules/002-missing-owner-check.md) | Missing owner check | Critical | Account validation |
596
+ | [003](rules/003-missing-discriminator-check.md) | Missing discriminator check (type cosplay) | High | Account validation |
597
+ | [004](rules/004-account-substitution.md) | Account substitution | High | Account validation |
598
+ | [005](rules/005-sysvar-spoofing.md) | Sysvar spoofing | High | Account validation |
599
+ | [006](rules/006-missing-rent-exemption-check.md) | Missing rent-exemption check | Low | Account validation |
600
+ | [007](rules/007-account-aliasing.md) | Account aliasing (duplicate mutable accounts) | High | Account validation |
601
+ | [008](rules/008-uninitialized-account-use.md) | Uninitialized account use | High | Account validation |
602
+ | [009](rules/009-missing-mut-constraint.md) | Missing `mut` constraint | Medium | Account validation |
603
+ | [010](rules/010-missing-close-constraint.md) | Missing or improper close constraint | Medium | Account validation |
604
+ | [011](rules/011-pda-seed-collision.md) | PDA seed collision | High | PDA |
605
+ | [012](rules/012-missing-bump-validation.md) | Missing bump validation | Medium | PDA |
606
+ | [013](rules/013-non-canonical-bump-accepted.md) | Non-canonical bump accepted | High | PDA |
607
+ | [014](rules/014-predictable-pda.md) | Predictable / attacker-controlled PDA seeds | High | PDA |
608
+ | [015](rules/015-insecure-pda-across-upgrades.md) | Insecure PDA layout across upgrades | Medium | PDA |
609
+ | [016](rules/016-bump-mismatch.md) | Stored bump mismatch | Medium | PDA |
610
+ | [017](rules/017-arbitrary-cpi.md) | Arbitrary CPI (unvalidated target) | Critical | CPI |
611
+ | [018](rules/018-cpi-confused-deputy.md) | CPI confused deputy | High | CPI |
612
+ | [019](rules/019-missing-program-id-check-spl.md) | Missing program ID check on SPL CPIs | High | CPI |
613
+ | [020](rules/020-reentrancy-via-cpi.md) | Reentrancy via CPI | High | CPI |
614
+ | [021](rules/021-untrusted-callback.md) | Untrusted callback execution | High | CPI |
615
+ | [022](rules/022-cpi-with-attacker-accounts.md) | CPI invoked with attacker-controlled accounts | High | CPI |
616
+ | [023](rules/023-lamport-overflow.md) | Lamport arithmetic overflow / underflow | High | Math |
617
+ | [024](rules/024-token-amount-overflow.md) | Token amount arithmetic overflow | High | Math |
618
+ | [025](rules/025-precision-loss.md) | Precision loss (division before multiplication) | Medium | Math |
619
+ | [026](rules/026-rounding-direction.md) | Incorrect rounding direction | Medium | Math |
620
+ | [027](rules/027-token-decimal-mismatch.md) | Token decimal mismatch | Medium | Math |
621
+ | [028](rules/028-integer-cast-truncation.md) | Integer cast truncation | Medium | Math |
622
+ | [029](rules/029-off-by-one.md) | Off-by-one errors | Low | Math |
623
+ | [030](rules/030-missing-authorization.md) | Missing authorization on privileged instruction | Critical | Auth |
624
+ | [031](rules/031-reinitialization-attack.md) | Reinitialization attack | High | Auth |
625
+ | [032](rules/032-closed-account-revival.md) | Closed account revival | High | Auth |
626
+ | [033](rules/033-init-if-needed-misuse.md) | `init_if_needed` misuse | High | Auth |
627
+ | [034](rules/034-missing-has-one.md) | Missing `has_one` relationship enforcement | High | Auth |
628
+ | [035](rules/035-insecure-admin-transfer.md) | Insecure admin transfer (no acceptance handshake) | Medium | Auth |
629
+ | [036](rules/036-missing-pause-guards.md) | Missing pause / freeze guards | Low | Auth |
630
+ | [037](rules/037-clock-manipulation.md) | Clock / time-based logic without bounds | Medium | Auth |
631
+ | [038](rules/038-missing-address-validation.md) | Missing `address` validation on fixed-identity accounts | Medium | Constraints |
632
+ | [039](rules/039-constraint-evaluation-stage.md) | Constraint evaluation stage (pre- vs post-state) | Medium | Constraints |
633
+ | [040](rules/040-realloc-zero-init.md) | `realloc` without zero-init | Medium | Constraints |
634
+ | [041](rules/041-missing-payer-on-init.md) | `init` without `payer` (or wrong payer) | Low | Constraints |
635
+ | [042](rules/042-incorrect-space-allocation.md) | Incorrect `space` allocation | Medium | Constraints |
636
+ | [043](rules/043-account-vs-account-info.md) | `Account` vs `AccountInfo` misuse | High | Constraints |
637
+ | [044](rules/044-token-account-owner-unverified.md) | Token account owner unverified | High | SPL Token |
638
+ | [045](rules/045-token-mint-unverified.md) | Token mint unverified | High | SPL Token |
639
+ | [046](rules/046-ata-assumption-errors.md) | Associated token account assumption errors | Medium | SPL Token |
640
+ | [047](rules/047-token-program-id-hardcoded.md) | Token program ID hardcoded vs. validated | Medium | SPL Token |
641
+ | [048](rules/048-compute-budget-abuse.md) | Compute budget abuse (unbounded work) | Medium | Runtime |
642
+ | [049](rules/049-log-spam-dos.md) | Log spam / excessive logging DoS | Low | Runtime |
643
+ | [050](rules/050-stack-overflow-deep-cpi.md) | Stack / CPI depth exhaustion | Low | Runtime |
644
+
645
+ **Severity breakdown:** 4 Critical · 21 High · 17 Medium · 8 Low
646
+
647
+ ---
648
+
649
+ ## Limitations
650
+
651
+ `anchor-audit` is a **static, pattern-based triage tool**. It is useful for catching known vulnerability classes quickly, but it has real limits you need to understand before relying on it.
652
+
653
+ **What it may miss:**
654
+ - Business-logic vulnerabilities specific to your protocol's design
655
+ - Economic attacks (price manipulation, oracle exploits, flash loan vectors)
656
+ - Bugs that only appear when multiple instructions are called in sequence
657
+ - Issues in client-side TypeScript/JavaScript code
658
+
659
+ **What it may get wrong:**
660
+ - False positives - patterns that look like a rule but are safe in context (e.g. an `AccountInfo` that is verified elsewhere)
661
+ - False negatives - real issues the model fails to recognize because the code pattern is unusual
662
+
663
+ **What it does not cover:**
664
+ - Dynamic analysis or fuzzing
665
+ - Runtime behavior
666
+ - Cross-program interaction analysis beyond CPI rule patterns
667
+
668
+ **Model accuracy varies:**
669
+
670
+ The same 50 rules are sent to every model. A larger, more capable model produces more accurate findings. Expect:
671
+ - Strong cloud models (Claude Opus, GPT-4o): high precision, few false positives
672
+ - Smaller local models (7B–8B): more false positives, may miss subtle issues
673
+ - Free cloud tiers: varies; Groq's Llama models perform well for their cost
674
+
675
+ **Never deploy to mainnet based solely on a clean `anchor-audit` report.** Always review findings manually, and get an independent professional audit before any program that holds real funds goes live.
676
+
677
+ ---
678
+
679
+ ## Contributing
680
+
681
+ ### Adding or improving a rule
682
+
683
+ Each rule is a single markdown file in `/rules/` following a fixed template with seven required sections: description, vulnerable pattern, why it's dangerous, fix pattern, detection heuristic, references, and real-world exploits.
684
+
685
+ 1. Copy the template from [rules/README.md](rules/README.md) into a new file: `rules/NNN-kebab-name.md`
686
+ 2. Fill in all seven sections - no section may be left blank
687
+ 3. Cite your sources in the References section (Neodyme, Sec3, Helius, Anchor book, Cyfrin Updraft, public audit reports)
688
+ 4. Add a row to [rules/INDEX.md](rules/INDEX.md)
689
+ 5. Run the test suite - it validates every rule file automatically
690
+
691
+ ### Running tests locally
692
+
693
+ ```bash
694
+ npm install
695
+ npm test # 272 unit tests - all rules, scanner, reporter
696
+ npm run typecheck # TypeScript strict check
697
+ npm run lint # ESLint
698
+ ```
699
+
700
+ ### Reporting issues
701
+
702
+ Open an issue at [github.com/guptaaayush432/anchor-audit/issues](https://github.com/guptaaayush432/anchor-audit/issues).
19
703
 
20
- Requires Node 20+ and an `ANTHROPIC_API_KEY`. Exit code is `0` when no critical/high findings, `1` otherwise, `2` on execution error.
704
+ ---
21
705
 
22
- ## Module layout
706
+ ## License
23
707
 
24
- - `src/index.ts` entry point and flag parsing
25
- - `src/scanner.ts` — file collection + filtering
26
- - `src/rules-loader.ts` — loads `/rules/*.md` at runtime
27
- - `src/auditor.ts` — Claude API orchestration (rules batched 4–6 per call)
28
- - `src/reporter.ts` — markdown/JSON report generation
708
+ [MIT](./LICENSE) - Aayush Gupta, 2026
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ program
42
42
  .option("--base-url <url>", "base URL for OpenAI-compatible endpoint (required for --provider custom; " +
43
43
  "optional override for ollama/lmstudio/vllm defaults)")
44
44
  .option("--effort <level>", "analysis depth — low (2 k tokens) | medium (4 k) | high (8 k)", "medium")
45
- .version("0.1.0")
45
+ .version("0.1.1")
46
46
  .action(async (targetPath, opts) => {
47
47
  const startTime = new Date();
48
48
  const provider = (opts.provider ?? "anthropic");
package/dist/reporter.js CHANGED
@@ -20,7 +20,7 @@ import { writeFileSync, mkdirSync } from "node:fs";
20
20
  import { join } from "node:path";
21
21
  import chalk from "chalk";
22
22
  import { SEVERITY_ORDER } from "./auditor.js";
23
- const VERSION = "0.1.0";
23
+ const VERSION = "0.1.1";
24
24
  export function countBySeverity(findings) {
25
25
  const c = { critical: 0, high: 0, medium: 0, low: 0 };
26
26
  for (const f of findings)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anchor-audit",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "AI-driven security audit CLI for Anchor programs on Solana",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  ],
17
17
  "scripts": {
18
18
  "build": "tsc -p tsconfig.json",
19
- "prepublishOnly": "rm -rf ./rules && cp -r ../rules ./rules && npm run build",
20
- "postpublish": "rm -rf ./rules"
19
+ "prepublishOnly": "rm -rf ./rules && cp -r ../rules ./rules && cp ../README.md ./README.md && npm run build",
20
+ "postpublish": "rm -rf ./rules && git checkout README.md"
21
21
  },
22
22
  "keywords": [
23
23
  "solana",