Smart Contract Audit
forefy/.context
Comprehensive smart contract security audit framework with multi-expert analysis.
Scans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing.
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install trailofbits/skills solana-vulnerability-scanner --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .claude/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .claude/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scannerType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install trailofbits/skills solana-vulnerability-scanner --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .agents/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .agents/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install trailofbits/skills solana-vulnerability-scanner --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .cursor/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .cursor/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/trailofbits/skills.git --path plugins/building-secure-contracts/skills/solana-vulnerability-scanner--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install trailofbits/skills solana-vulnerability-scanner --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .gemini/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .gemini/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install trailofbits/skills solana-vulnerability-scannerInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .github/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .github/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install trailofbits/skills solana-vulnerability-scanner --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/trailofbits/skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/plugins/building-secure-contracts/skills/solana-vulnerability-scanner .opencode/skills/solana-vulnerability-scanner && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "solana-vulnerability-scanner" agent skill from https://github.com/trailofbits/skills/tree/main/plugins/building-secure-contracts/skills/solana-vulnerability-scanner into .opencode/skills/solana-vulnerability-scanner/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "solana-vulnerability-scanner", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
solana-vulnerability-scannerScans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing.
Solana Vulnerability Scanner is an agent skill from trailofbits/skills, published by the product's own GitHub organization. Scans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing. Use when auditing Solana/Anchor programs.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 6 other files, including assets (for example `agents/openai.yaml` and `resources/VULNERABILITY_PATTERNS.md`).
It sits in Security, covering Smart contract auditing and Smart contracts. It works with Solana and Rust. The repository describes itself as: Trail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows. The licence is CC-BY-SA-4.0.
12 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 82fe822. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
rgFrom the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
github.comanchor-lang.comsolanacookbook.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Solana Vulnerability Scanner loads about 3.6k tokens when it runs. Until then it costs about 57 tokens; SKILL.md has 1,129 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from trailofbits/skills at commit 82fe822, republished under its CC-BY-SA-4.0 licence (© trailofbits). 1,129 words, ~3,606 tokens.
.claude/skills/solana-vulnerability-scanner/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.Systematically scan Solana programs (native and Anchor framework) for platform-specific security vulnerabilities related to cross-program invocations, account validation, and program-derived addresses. This skill encodes 6 critical vulnerability patterns unique to Solana's account model.
.rs// Native Solana program indicators
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
pubkey::Pubkey,
program::invoke,
program::invoke_signed,
};
entrypoint!(process_instruction);
// Anchor framework indicators
use anchor_lang::prelude::*;
#[program]
pub mod my_program {
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// Program logic
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(mut)]
pub authority: Signer<'info>,
}
// Common patterns
AccountInfo, Pubkey
invoke(), invoke_signed()
Signer<'info>, Account<'info>
#[account(...)] with constraints
seeds, bumpprograms/*/src/lib.rs - Program implementationAnchor.toml - Anchor configurationCargo.toml with solana-program or anchor-langtests/ - Program testsWhen invoked, I will:
I check for 6 critical vulnerability patterns unique to Solana. For detailed detection patterns, code examples, mitigations, and testing strategies, see VULNERABILITY_PATTERNS.md.
For complete vulnerability patterns with code examples, see VULNERABILITY_PATTERNS.md.
programs/*/src/lib.rs)# Find all CPI calls
rg "invoke\(|invoke_signed\(" programs/
# Check for program ID validation before each
# Should see program ID checks immediately before invokeFor each CPI:
Program<'info, T> type# Find PDA usage
rg "find_program_address|create_program_address" programs/
rg "seeds.*bump" programs/
# Anchor: Check for seeds constraints
rg "#\[account.*seeds" programs/For each PDA:
find_program_address() or Anchor seeds constraint# Find account deserialization
rg "try_from_slice|try_deserialize" programs/
# Should see owner checks before deserialization
rg "\.owner\s*==|\.owner\s*!=" programs/For each account used:
Account<'info, T> and Signer<'info># Find instruction introspection usage
rg "load_instruction_at|load_current_index|get_instruction_relative" programs/
# Check for checked versions
rg "load_instruction_at_checked|load_current_index_checked" programs/# Add to Cargo.toml
[dependencies]
solana-program = "1.17" # Use latest version
[lints.clippy]
# Enable Solana-specific lints
# (Trail of Bits solana-lints if available)Report on every pattern in §6, whether or not it turned anything up. Emit this table above the findings, with all 6 rows present:
| # | Pattern | Verdict | Evidence |
|---|---|---|---|
| 1 | Arbitrary CPI | n/a | this program makes no cross-program invocations |
| 2 | Improper PDA Validation | ||
| 3 | Missing Ownership Check | ||
| 4 | Missing Signer Check | ||
| 5 | Sysvar Account Check | ||
| 6 | Improper Instruction Introspection |
Each verdict is one of:
found — cite file:line and write the finding up in full below.clear — the pattern applies to this program and the program handles it. Name the constraint, account
type, or check you searched for, so a reader can repeat the search.n/a — the pattern cannot apply here. Give the reason in one clause ("this program makes no CPI calls").
Not having looked is not n/a. Pattern 5 is version-scoped (pre-Solana 1.8.1): cite the solana-program
version the program targets rather than dropping the row, since "targets 1.17, fixed upstream" and "did not
look" are otherwise the same answer.A table with fewer than 6 rows is an incomplete scan and must be reported as one. A row whose Verdict cell is empty is incomplete in the same way: row 1 above is filled in to show the shape, and every row is filled in the same way before the report is done. Six clear verdicts is a
result a reader can act on. A report that covers two patterns and says nothing about the other four reads
exactly like a clean program, and that is the failure this table exists to prevent.
## [CRITICAL] Arbitrary CPI - Unchecked Program ID
**Location**: `programs/vault/src/lib.rs:145-160` (withdraw function)
**Description**:
The `withdraw` function performs a CPI to transfer SPL tokens without validating that the provided `token_program` account is actually the SPL Token program. An attacker can provide a malicious program that appears to perform a transfer but actually steals tokens or performs unauthorized actions.
**Vulnerable Code**:
```rust
// lib.rs, line 145
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
let token_program = &ctx.accounts.token_program;
// WRONG: No validation of token_program.key()!
invoke(
&spl_token::instruction::transfer(...),
&[
ctx.accounts.vault.to_account_info(),
ctx.accounts.destination.to_account_info(),
ctx.accounts.authority.to_account_info(),
token_program.to_account_info(), // UNVALIDATED
],
)?;
Ok(())
}
```
**Attack Scenario**:
1. Attacker deploys malicious "token program" that logs transfer instruction but doesn't execute it
2. Attacker calls withdraw() providing malicious program as token_program
3. Vault's authority signs the transaction
4. Malicious program receives CPI with vault's signature
5. Malicious program can now impersonate vault and drain real tokens
**Recommendation**:
Use Anchor's `Program<'info, Token>` type:
```rust
use anchor_spl::token::{Token, Transfer};
#[derive(Accounts)]
pub struct Withdraw<'info> {
#[account(mut)]
pub vault: Account<'info, TokenAccount>,
#[account(mut)]
pub destination: Account<'info, TokenAccount>,
pub authority: Signer<'info>,
pub token_program: Program<'info, Token>, // Validates program ID automatically
}
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
let cpi_accounts = Transfer {
from: ctx.accounts.vault.to_account_info(),
to: ctx.accounts.destination.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
};
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
cpi_accounts,
);
anchor_spl::token::transfer(cpi_ctx, amount)?;
Ok(())
}
```
**References**:
- building-secure-contracts/not-so-smart-contracts/solana/arbitrary_cpi
- Trail of Bits lint: `unchecked-cpi-program-id`#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn test_rejects_wrong_program_id() {
// Provide wrong program ID, should fail
}
#[test]
#[should_panic]
fn test_rejects_non_canonical_pda() {
// Provide non-canonical bump, should fail
}
#[test]
#[should_panic]
fn test_requires_signer() {
// Call without signature, should fail
}
}import * as anchor from "@coral-xyz/anchor";
describe("security tests", () => {
it("rejects arbitrary CPI", async () => {
const fakeTokenProgram = anchor.web3.Keypair.generate();
try {
await program.methods
.withdraw(amount)
.accounts({
tokenProgram: fakeTokenProgram.publicKey, // Wrong program
})
.rpc();
assert.fail("Should have rejected fake program");
} catch (err) {
// Expected to fail
}
});
});# Run local validator for testing
solana-test-validator
# Deploy and test program
anchor testbuilding-secure-contracts/not-so-smart-contracts/solana/Before completing Solana program audit:
CPI Security (CRITICAL):
invoke()Program<'info, T> typePDA Security (CRITICAL):
find_program_address() or Anchor seeds constraintAccount Validation (HIGH):
account.owner == expected_program_idAccount<'info, T> typeSigner Validation (CRITICAL):
is_signeraccount.is_signer == trueSigner<'info> typeSysvar Security (HIGH):
load_instruction_at_checked()Instruction Introspection (MEDIUM):
Testing:
found, clear or n/a with a reasonn/a costs one
clause and makes the judgment reviewable. Silence records nothing, and a reader cannot tell it apart from
not having checked.#[account(mut)] is not an ownership check, and UncheckedAccount opts out
entirely. Cite the attribute, not the framework.create_program_address without the
canonical bump admits multiple valid addresses, which is pattern 2 in full.© trailofbits, CC-BY-SA-4.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 3 other files (assets) in plugins/building-secure-contracts/skills/solana-vulnerability-scanner of trailofbits/skills.
Open the folder on GitHubat commit 82fe822
Solana Vulnerability Scanner next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Solana Vulnerability Scanner this skilltrailofbits/skills | 7.4k | — | ~3.6k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| Smart Contract Auditforefy/.context | 152 | 1 repos | ~5.1k | Automated safety check: Pass | MIT | |
| Smart Contract Auditelophanto/EloPhanto | 106 | — | ~2.7k | Automated safety check: Pass | Custom licence | |
| Stellar DevVelaPayments/vela-payments | 131 | — | ~1.8k | Automated safety check: Pass | MIT | |
| RadarAuditware/radar | 154 | — | ~2.1k | Automated safety check: Pass | GPL-3.0 | |
| Safe Solana BuilderFrankcastleauditor/safe-solana-builder | 145 | — | ~3.6k | Automated safety check: Pass | None |
forefy/.context
Comprehensive smart contract security audit framework with multi-expert analysis.
elophanto/EloPhanto
A skill your agent uses when reviewing a Solidity, Vyper, or Rust (Solana/Anchor) smart contract for paid audit work or pre-launch sanity check.
VelaPayments/vela-payments
End-to-end Stellar development playbook. An agent skill from VelaPayments/vela-payments.
Auditware/radar
Use radar for smart contract security analysis, AST generation, and detection template development.
Frankcastleauditor/safe-solana-builder
A skill your agent uses whenever the user wants to write, scaffold, or build a Solana smart contract or program from scratch.
OpenZeppelin/openzeppelin-relayer
Manage WireMock proxy for RPC testing. An agent skill from OpenZeppelin/openzeppelin-relayer.
trailofbits/skills
Generates Mermaid diagrams from Trailmark code graphs, including call graphs, class hierarchies, module dependency maps, complexity heatmaps and attack surface data flows.
trailofbits/skills
Scans a codebase for vulnerabilities with CodeQL's data flow and taint tracking in run-all or important-only modes, including data extensions for project-specific sources and sinks.
trailofbits/skills
Compares Trailmark code graphs at two snapshots, such as commits, tags or directories, to surface attack paths, blast radius and taint changes that text diffs miss.
trailofbits/skills
Draws a 12 Houses tarot spread to break ties when a request is vague or casually delegated, then reads the cards to pick the next step.
trailofbits/skills
Searches and extracts data from Burp Suite project files on the command line: regex searches over responses, audit findings, proxy history and site map data.
trailofbits/skills
Detects languages, proposes rulesets for approval, then runs the approved Semgrep scan across a codebase and merges the output into one SARIF file.
Categories
Scans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing. Solana Vulnerability Scanner is an agent skill from trailofbits/skills, published by the product's own GitHub organization. Scans Solana programs for 6 critical vulnerabilities including arbitrary CPI, improper PDA validation, missing signer/ownership checks, and sysvar spoofing.
Solana Vulnerability Scanner fits situations like: auditing Solana/Anchor programs; tasks that involve Smart contract auditing; tasks that involve Smart contracts.
Run `npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a claude-code`. Or copy the skill folder (plugins/building-secure-contracts/skills/solana-vulnerability-scanner in trailofbits/skills) into .claude/skills/solana-vulnerability-scanner in your project. Claude Code loads it when a task matches its description.
Run `npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a codex`. Or copy the skill folder (plugins/building-secure-contracts/skills/solana-vulnerability-scanner in trailofbits/skills) into .agents/skills/solana-vulnerability-scanner in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add trailofbits/skills --skill solana-vulnerability-scanner -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/solana-vulnerability-scanner, .gemini/skills/solana-vulnerability-scanner, .github/skills/solana-vulnerability-scanner and .opencode/skills/solana-vulnerability-scanner in your project.
Going by SKILL.md and its folder, Solana Vulnerability Scanner needs the command-line tools its instructions call (rg).
SKILL.md names 3 domains. As links in the text: github.com, anchor-lang.com and solanacookbook.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Solana Vulnerability Scanner is published under the CC-BY-SA-4.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.6k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Solana Vulnerability Scanner: Smart Contract Audit (forefy/.context, 152 stars), Smart Contract Audit (elophanto/EloPhanto, 106 stars), Stellar Dev (VelaPayments/vela-payments, 131 stars) and Radar (Auditware/radar, 154 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
trailofbits (a GitHub organization, an official publisher) maintains it in trailofbits/skills, which has 7,420 GitHub stars. The repository holds 79 skills in this directory. The repository was last updated on October 7, 2026.
Source: trailofbits/skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.