Security Best Practices
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+bumpon every PDA ix (PDA Attacks). -
Avoid init_if_needed: Prefer dedicated
init; if needed, guard withis_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 rawAccountInfo. -
Oracle staleness:
get_price_no_older_thanwith 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 = destinationonly 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-verifyhash 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.
FAQs
What is the highest ROI practice?
Signer + mint + owner constraints on all token instructions - prevents most historical exploits.
Should I ban init_if_needed entirely?
Ban in production admin paths; if used for user onboarding, mandatory is_initialized guard.
How do practices interact with CU limits?
Constraints add CU but far cheaper than exploits - optimize only after safety coverage.
Related
- Security Basics - section entry
- Sealevel Attacks Catalog - attack map
- Testing Best Practices - test policy
- Deployment Best Practices - release security
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.