---
name: safe-solana-builder
description: >
Use this skill whenever the user wants to write, scaffold, or build a Solana smart contract
or program from scratch. Triggers on: "write a Solana program", "create a smart contract",
"build an anchor program", "write a native Rust Solana program", "scaffold a Solana program",
"help me write a program that does X on Solana", or any request to produce production-grade
on-chain Solana code. This skill enforces Frank Castle's security best practices and pitfall
avoidance guidelines automatically — giving every program a first layer of protection before
it ever reaches an auditor. Always use this skill — even for simple programs — whenever
Solana program code is the primary deliverable.
---
# Safe Solana Builder — by Frank Castle
You are writing production-grade Solana programs. Security is not an afterthought — it is baked into every line. Every program produced by this skill ships with a full project scaffold, a test file skeleton, and a security checklist.
### What This Skill Enforces
This skill systematically addresses the following vulnerability classes derived from real Solana protocol audits:
- **Protocol-specific vulnerabilities** — oracle manipulation, fee bypass, slippage attacks, LP preprocessing gaps
- **Logic flaws & edge cases** — dust DoS, time-unit mismatches, pre/post-fee inconsistencies, type narrowing
- **Access control & authorization bugs** — missing signer checks, frontrunnable initialization, inbound transfer auth, post-expiry flows
- **State management errors** — coupled-field resets, counter drift, vested/unvested balance separation, rollback safety
- **PDA-related issues** — zombie accounts, seed collisions, canonical bump enforcement, lifecycle closure
- **Reward accounting exploits** — rounding gaps in partial unstake, dual-path reward debt bypass, retroactive rate application, dead share price, inflation/first-depositor attack, fee-on-transfer delta errors, rewards sourced from principal
- **Vault & pool architecture** — missing withdrawal paths on PDA-controlled vaults
- **Token-2022 extension validation** — PermanentDelegate seizure, uncontrolled FreezeAuthority, TransferHook CPI forwarding, ConfidentialTransfer compatibility
- **Admin key security** — two-step rotation pattern, timelock recommendations for Critical programs
- **BPF runtime limits** — 4096-byte stack frame DoS, Box<> mitigation for large account types
---
## Step 1 — Ask the Framework Question
If the user has not already specified, ask exactly this (and nothing else):
> "Should I write this in **Native Rust**, **Anchor**, or **Pinocchio**?"
**Pinocchio** is Anza's zero-dependency, zero-copy framework — 88–95% CU reduction vs. Anchor. Best for high-throughput programs (DEXs, orderbooks, vaults). It is unaudited — flag this in the checklist for Critical programs.
Wait for the answer before proceeding.
---
## Step 1b — Ask the Testing Question
Immediately after the framework is chosen, ask:
> "Should I use **LiteSVM** for testing (fast, in-process, no validator required), or the default testing approach for your framework?"
Present the options clearly:
| Option | Best For |
|---|---|
| **LiteSVM** | Fast unit/integration tests, CI pipelines, time-lock testing, CU profiling, account injection from devnet |
| **Framework default** | Anchor: TypeScript with `@coral-xyz/anchor`; Native: `solana-program-test` async harness |
Wait for the answer before proceeding to Step 2.
---
## Step 2 — Load Your Reference Files
Once **both** the framework and testing approach are chosen, read the following files
**before writing a single line of code**:
1. **Always read first (both files):**
- `references/shared-base.md` — Core security rules, pitfall patterns, and best practices for ALL Solana programs. Sections 1–20 cover foundational security; sections 21–25 cover vulnerability-derived rules from real protocol audits (reward accounting, vault architecture, Token-2022 extension validation, admin key rotation, BPF stack frame limits).
2. **Then read the framework-specific file:**
- Native Rust → `references/native-rust.md`
- Anchor → `references/anchor.md`
- Pinocchio → `references/pinocchio.md`
→ Framework-specific patterns, constraints, additional pitfalls, and common build/tooling errors.
3. **If LiteSVM was chosen for testing, also read:**
- `references/litesvm.md`
→ Test structure patterns, sysvar control, token setup, account inspection, CU profiling, and the LiteSVM security test checklist.
4. **Check for a relevant example:**
See the Examples table at the bottom of this file. If a similar program exists in `examples/`, read it before writing — use it as a quality and structure benchmark.
Do not skip or skim these files. They are the source of truth for this skill.
---
## Step 3 — Assess Risk Level
Before gathering requirements, classify the program's sensitivity. This determines how thorough your security comments and "Known Limitations" section must be.
| Level | Criteria | Examples |
|---|---|---|
| 🟢 Low | No SOL/token custody, no CPI, single user, read-heavy | Counter, registry, simple config |
| 🟡 Medium | Token transfers, basic CPI, multi-user state, PDAs | Staking, voting, simple escrow |
| 🔴 Critical | Vaults, multi-CPI chains, admin keys, large TVL potential | AMM, lending, NFT launchpad, bridges |
State the risk level explicitly at the top of your security checklist. For 🔴 Critical programs: add a "High-Risk Decisions" section to the checklist and flag every admin key, upgrade authority, and irreversible state transition.
---
## Step 4 — Gather Program Requirements
Collect the following in one message (if not already provided):
- **Program name** — what is it called?
- **What it does** — brief description of functionality
- **Accounts** — what accounts does it need?
- **Instructions** — what instructions/functions?
- **Access control** — who can call what? Any admin roles?
- **Token standard** — SPL Token, Token-2022, or none?
- **Any external programs called** — Metaplex, another protocol, etc.?
If the user's description already covers most of these, proceed and note your assumptions clearly.
---
## Step 5 — Write the Program
### 5a. Security Pre-Check (internal, not shown to user)
Before writing, run through shared-base.md and the framework file. Flag which rules apply to this program's design. Note any inherent risks in the design itself.
### 5b. Project Scaffold
Deliver a complete, ready-to-build project structure. Not just `lib.rs` — the full scaffold:
**For Anchor:**
```
<program-name>/
├── Anchor.toml
├── Cargo.toml
├── programs/
│ └── <program-name>/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs
└── tests/
└── <program-name>.ts # if framework-default testing
└── <program-name>_tests.rs # if LiteSVM testing
```
**For Native Rust / Pinocchio:**
```
<program-name>/
├── Cargo.toml
└── src/
├── lib.rs
├── instruction.rs
├── processor.rs
├── state.rs
└── error.rs
tests/
└── <program-name>_tests.rs # if LiteSVM testing
```
### 5c. The Program Code
Requirements:
- Compilable without warnings
- Every account validated — ownership, type, signer, writable as applicable
- No unchecked math on any financial value
- PDAs derived with canonical bumps stored and reused
- No logic after CPI calls that relies on stale state
- Descriptive program-specific error types
- Inline security comments on every non-obvious decision
Header comment block at the top of `lib.rs`:
```rust
// ============================================================
// Program: <ProgramName>
// Framework: <Native Rust | Anchor | Pinocchio>
// Testing: <LiteSVM | solana-program-test | TypeScript/Anchor>
// Risk Level: 🟢 Low | 🟡 Medium | 🔴 Critical
// Author: Frank Castle Security Template
// Security: See accompanying security-checklist.md
// ============================================================
```
### 5d. Test File
Always produce a test file. The approach depends on what was chosen in Step 1b:
#### If LiteSVM was chosen:
Produce Rust tests following `references/litesvm.md`. The test file must include:
**Required structure:**
- A `setup()` function that loads the `.so`, airdrops SOL, and returns `(LiteSVM, Keypair)`
- A `send_tx()` helper that wraps message/transaction building and calls `expire_blockhash()` after each send
- PDA derivation helpers matching the on-chain seeds exactly
**Happy path tests (implement fully):**
- End-to-end success flow with full state assertion (lamports, token balances, account data fields)
- Account closure verification (lamports=0, data.len()=0, owner=system_program)
- CU consumption logged and recorded to a `CU_RESULTS` static for the `zz_cu_summary` test
**Security/edge case tests (implement or scaffold with `TODO` + explanation comment):**
- Wrong signer → `assert!(result.is_err())`
- Re-initialization attempt → `assert!(result.is_err())`
- Before-deadline action → `assert!(result.is_err())` (if time-locked)
- After-deadline action → succeeds (time travel via `svm.set_sysvar(&clock)`)
- Over-limit / zero-amount arithmetic → `assert!(result.is_err())`
- Any program-specific edge cases flagged in the checklist
**Mandatory closing test:**
```rust
#[test]
fn zz_cu_summary() { /* print CU table */ }
```
#### If framework default was chosen:
- Anchor: TypeScript using `@coral-xyz/anchor`
- Native Rust: Rust integration tests using `solana-program-test`
In both cases, cover the same happy path + security/edge case matrix as above.
Mark unimplemented security tests with `TODO` and an explanation comment.
## Examples
The `examples/` directory contains complete reference programs written to this skill's standard. Before writing, check if a similar example exists — use it to calibrate output quality, structure, and checklist depth. Do not copy-paste; treat it as a quality benchmark.
| Example | Framework | Testing | Risk Level | What it demonstrates |
|---|---|---|---|---|
| `examples/nft-whitelist-mint/` | Anchor | TypeScript/Anchor | 🔴 Critical | MintConfig PDA, per-user WhitelistEntry PDA, double-mint guard, Metaplex CPI with program ID verification, SOL balance check around CPI, Token-2022 compatible mint, safe account close |
Each example folder contains:
- `lib.rs` — the full program
- `security-checklist.md` — the applied rules checklist
---
## Notes for Edge Cases
- **Simple programs (counter, hello world):** Still apply all checks. Simplicity is not an excuse for insecure patterns.
- **Inherent design risks (admin key with no timelock, no upgrade authority check):** Flag explicitly in the checklist under "High-Risk Decisions" or "Known Limitations."
- **Token-2022 features (transfer hooks, confidential transfers):** Flag in the checklist as requiring extra manual review — expanded attack surface. Always validate extensions at `initialize` per shared-base §23.
- **Programs with `remaining_accounts`:** Apply the same ownership, signer, and type checks as named accounts. Flag in checklist.
- **Upgrade authority:** Always note whether the program is upgradeable and who holds the authority. Recommend a timelock or multisig for 🔴 Critical programs.
- **Staking / yield programs:** Pay special attention to shared-base §21 (reward accounting). Every reward payout path must update `reward_debt`. Retroactive rate application and partial-unstake rounding are the two most common Critical findings in this category.
- **Share-based pools (stX/totalStaked):** Apply §21.4 (dead share price) and §21.5 (inflation attack) checks at design time — these are architectural, not line-level, and cannot be patched easily after deployment.
- **Large account contexts:** After `anchor build`, check for stack frame warnings (§25). Apply `Box<>` to large account fields if the warning appears.
- **LiteSVM for RPC-dependent tests:** LiteSVM does not support all RPC methods. If the program requires wallet integration tests or real validator behaviour, note in the checklist that those tests must use `solana-test-validator` separately.