solana-anchor

Solid

Detect bug classes specific to Solana / Anchor (Rust) programs — missing signer checks, missing account owner checks, account-confusion / type-cosplay without discriminator validation, unchecked AccountInfo, non-canonical PDA seeds/bumps & seed collisions, missing has_one/constraint, CPI to unverified programs, close-account lamport-drain & revival, sysvar spoofing, and arbitrary-account substitution. Activate on any `.rs` file with `use anchor_lang`, `#[program]`, `#[derive(Accounts)]`, `#[account]`, `Signer<'info>`, or `AccountInfo`.

AI & Automation 38 stars 5 forks Updated 2 days ago MIT

Install

View on GitHub

Quality Score: 82/100

Stars 20%
53
Recency 20%
100
Frontmatter 20%
70
Documentation 15%
100
Issue Health 10%
50
License 10%
100
Description 5%
100

Skill Content

# Solana / Anchor (Rust) detection ## When this applies - Any `.rs` file importing `anchor_lang` (`use anchor_lang::prelude::*`) - Macros `#[program]`, `#[derive(Accounts)]`, `#[account]`, `#[instruction(...)]` - Account wrappers `Signer<'info>`, `Account<'info, T>`, `AccountInfo<'info>`, `UncheckedAccount`, `Program<'info, T>`, `Sysvar<'info, T>` - PDA derivation: `seeds = [...]`, `bump`, `find_program_address`, `create_program_address` - CPI: `CpiContext`, `invoke`, `invoke_signed`, `*_cpi` Solana has no implicit caller. Every authority, ownership, and identity invariant must be asserted explicitly in the account struct or handler. ## Detection patterns ### Missing signer check (CRITICAL) ```rust #[derive(Accounts)] pub struct Withdraw<'info> { pub authority: AccountInfo<'info>, // ← not Signer; nobody proves they're authority #[account(mut)] pub vault: Account<'info, Vault>, } ``` **Signal:** an "authority"/"owner"/"admin" account typed `AccountInfo`/`UncheckedAccount` instead of `Signer<'info>`, or a handler reading `ctx.accounts.x` without checking `x.is_signer`. Anyone passes the real authority's pubkey without their signature. ### Missing owner check / arbitrary account substitution (CRITICAL) ```rust let data = ctx.accounts.state.to_account_info(); let state = State::try_from_slice(&data.data.borrow())?; // ← no owner check ``` **Signal:** deserializing from a raw `AccountInfo`/`UncheckedAccount` without verifying `account.owner == program_id`, or...

Details

Author
iktok90-design
Repository
iktok90-design/ai-smart-contract-auditor
Created
1 weeks ago
Last Updated
2 days ago
Language
JavaScript
License
MIT

Bundled in these plugins

Similar Skills

Semantically similar based on skill content — not just same category