Security Best Practices
A condensed summary of the 25 most important program security practices drawn from every page in this section.
Search across all documentation pages
A condensed summary of the 25 most important program security practices drawn from every page in this section.
Signer on every mutation: Map each lamport/token move to a required Signer (Signer & Owner Checks).
Typed accounts over UncheckedAccount: Default to Account<'info, T>; document exceptions.
has_one for authority fields: Link state authority pubkeys to signing accounts.
Mint and owner constraints: Token accounts must match expected mint and vault linkage (Account Validation).
Canonical PDA seeds: Store bump at init; use seeds + bump on every PDA ix (PDA Attacks).
Avoid init_if_needed: Prefer dedicated init; if needed, guard with is_initialized (Reinitialization).
Checked math everywhere: No plain +/- on balances (Arithmetic).
u128 intermediates: Multiply before divide for share and AMM math.
Round against users: Fees round up; payouts round down - document policy.
Checks-effects-interactions: Update state before CPI (CPI Risks).
CPI program allowlist: require_keys_eq! on every external program id.
Typed token program: Use Program<'info, Token> not raw AccountInfo.
Oracle staleness: get_price_no_older_than with tight max age (Oracles).
Pin oracle pubkeys: Never user-supplied feed without allowlist.
No duplicate account metas: constraint = a.key() != b.key() where double-counting possible.
Typed sysvars: Sysvar<'info, Clock> instead of spoofable accounts.
Close attribute safely: close = destination only with authority checks.
Run Sealevel catalog per PR: Quick pass against S1-S15 (Catalog).
LiteSVM negative tests: Adversarial account sets for each ix (Testing CPIs).
Fuzz math paths: Trident on deposit/withdraw/swap handlers (Fuzzing).
Verifiable builds: Publish solana-verify hash with releases.
Multisig upgrade authority: No single-key upgrade on production TVL.
Minimize invoke_signed scope: Narrow PDA seeds per CPI.
Audit before mainnet TVL: Follow Audit Workflow.
Fail closed: When validation uncertain, return error - never best-effort continue.
Signer + mint + owner constraints on all token instructions - prevents most historical exploits.
Ban in production admin paths; if used for user onboarding, mandatory is_initialized guard.
Constraints add CU but far cheaper than exploits - optimize only after safety coverage.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 16, 2026