Skip to content
Development
Command

/audit-solana

Security audit for Solana programs (Anchor/native)

From plugin
solana-ai-kit
10130 skills15 agents30 commands7 MCP
Install
> /plugin marketplace add solanabr/solana-ai-kit
> /plugin install solana-ai-kit@stbr

How it fires

How this command gets triggered: by you, by Claude, or both.

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/audit-solana

Context preview

What this command does when you run it.

Security audit for Solana programs (Anchor/native)

Command definition

audit-solana.md
description: "Security audit for Solana programs (Anchor/native)"

You are conducting a security audit for Solana programs. This is CRITICAL - take your time.

Related Skills

  • [security.md](../skills/ext/solana-dev/skill/references/security.md) - Comprehensive security checklist
  • [programs/anchor.md](../skills/ext/solana-dev/skill/references/programs/anchor.md) - Anchor security patterns
  • [programs/pinocchio.md](../skills/ext/solana-dev/skill/references/programs/pinocchio.md) - Pinocchio security patterns
  • [testing.md](../skills/ext/solana-dev/skill/references/testing.md) - Fuzz testing with Trident

Pre-Audit Checklist

  • [ ] All tests passing
  • [ ] Code compiles without warnings
  • [ ] Documentation complete
  • [ ] No hardcoded keys or secrets

Step 1: Automated Analysis

echo "๐Ÿ” Running automated security analysis..."

# Dependency audit (check for known vulnerabilities)
echo "  ๐Ÿ“ฆ Checking dependencies..."
cargo audit

# Supply chain security (check for malicious dependencies)
if command -v cargo-geiger >/dev/null 2>&1; then
    echo "  โ˜ข๏ธ  Checking unsafe code usage..."
    cargo geiger
fi

# Clippy with strict security lints
echo "  ๐Ÿ”Ž Running clippy security lints..."
cargo clippy --all-targets -- \
    -W clippy::all \
    -W clippy::pedantic \
    -W clippy::unwrap_used \
    -W clippy::expect_used \
    -W clippy::panic \
    -W clippy::arithmetic_side_effects \
    -D warnings

# Format check
echo "  ๐Ÿ“ Checking format..."
cargo fmt --check

# Run full test suite
echo "  ๐Ÿงช Running tests..."
if [ -f "Anchor.toml" ]; then
    anchor build && anchor test
else
    cargo build-sbf && cargo test
fi

echo "โœ… Automated analysis complete"

Step 2: Account Validation Review

**CRITICAL**: Every account MUST be validated. Check each instruction:

Owner Checks

// โœ“ CORRECT: Validate account owner
if *account.owner != expected_program_id {
    return Err(ProgramError::IncorrectProgramId);
}

// โœ— WRONG: Assuming owner without check

Signer Checks

// โœ“ CORRECT: Verify signer
if !authority.is_signer {
    return Err(ProgramError::MissingRequiredSignature);
}

// โœ— WRONG: Privileged operation without signer check

PDA Validation

// โœ“ CORRECT: Use stored canonical bump
let seeds = &[
    b"vault",
    authority.key.as_ref(),
    &[vault.bump],  // stored bump
];

// โœ— WRONG: Recalculating bump or accepting user-provided bump
let (pda, _) = Pubkey::find_program_address(seeds, program_id);

Step 3: Arithmetic Safety Review

Check ALL arithmetic operations:

// โœ“ CORRECT: Checked arithmetic
let total = amount_a
    .checked_add(amount_b)
    .ok_or(ErrorCode::Overflow)?;

// โœ— WRONG: Unchecked arithmetic (can panic/overflow)
let total = amount_a + amount_b;

**Checklist**:

  • [ ] All additions use `checked_add`
  • [ ] All subtractions use `checked_sub`
  • [ ] All multiplications use `checked_mul`
  • [ ] All divisions use `checked_div`
  • [ ] No unwrap() in arithmetic operations

Step 4: Common Attack Vectors

Type Cosplay

// โœ“ CORRECT: Check discriminator
if account.data.borrow()[0..8] != User::DISCRIMINATOR {
    return Err(ProgramError::InvalidAccountData);
}

// In Anchor, Account<'info, T> does this automatically

Account Revival

// โœ“ CORRECT: Zero data AND set closed discriminator
let mut data = account.data.borrow_mut();
data.fill(0);
data[0..8].copy_from_slice(&CLOSED_ACCOUNT_DISCRIMINATOR);

// Anchor's `close` constraint handles this
#[account(mut, close = destination)]

Arbitrary CPI

// โœ“ CORRECT: Validate program ID
if cpi_program.key() != spl_token::ID {
    return Err(ErrorCode::InvalidProgram.into());
}

// โœ— WRONG: Accepting any program from user
invoke(&instruction, accounts)?;

Missing Reload After CPI

// โœ“ CORRECT: Reload account after CPI
transfer_checked(cpi_ctx, amount, mint.decimals)?;
ctx.accounts.token_account.reload()?;

// โœ— WRONG: Using stale data after CPI
transfer_checked(cpi_ctx, amount, mint.decimals)?;
// ... using token_account without reload

PDA Seed Collision

// โœ“ CORRECT: Unique prefixes per account type
let user_seeds = [b"user_vault", user.key().as_ref()];
let admin_seeds = [b"admin_config", admin.key().as_ref()];

// โœ— WRONG: Shared PDA space
let seeds = [b"vault", key.as_ref()];  // collision possible

Step 5: CPI Security

Check all cross-program invocations:

  • [ ] Target program ID is validated (hardcoded or checked)
  • [ ] Signer privileges not blindly forwarded
  • [ ] Accounts reloaded after CPI if modified
  • [ ] Return values checked
  • [ ] Error handling proper

Step 6: Economic Security

For financial operations:

  • [ ] Slippage protection implemented
  • [ ] Oracle data validated (staleness, confidence)
  • [ ] No price manipulation vectors
  • [ ] Proper fee accounting
  • [ ] Inflation attack prevention (for vaults)

Step 7: Error Handling

  • [ ] No `unwrap()` or `expect()` in program code
  • [ ] All error codes defined
  • [ ] Descriptive error messages
  • [ ] All errors propagated correctly

Step 8: CU (Compute Units) Optimization

Check for CU waste:

  • [ ] Minimal logging (use feature flags for debug logs)
  • [ ] PDA bumps stored and reused (not recalculated)
  • [ ] Efficient data access patterns
  • [ ] No unnecessary account loads

Step 9: Testing Requirements

Verify comprehensive test coverage:

  • [ ] All instructions tested (success paths)
  • [ ] All error conditions tested
  • [ ] Account validation failures tested
  • [ ] Arithmetic edge cases tested (max values, overflow)
  • [ ] PDA derivation tested
  • [ ] CPI success and failure paths tested
  • [ ] Fuzz testing with Trident (REQUIRED for mainnet)

Fuzz Testing with Trident

# Setup Trident (if not already)
if [ ! -d "trident-tests" ]; then
    echo "Setting up Trident fuzz testing..."
    trident init
fi

# Run fuzz tests for at least 10 minutes (Trident v0.7+)
echo "๐Ÿ” Running fuzz tests (10 minutes minimu
Read more
Ships withsolana-ai-kit

Production-ready Claude Code configuration for full-stack Solana development. Combines best practices from multiple sources into an agent-optimized, token-efficient config you can install and adapt to your specific project.

Get the whole plugin

Other commands on solana-ai-kit.