All articles
Smart Contracts·October 25, 2025·4 min read

Solana Program Security Audit Checklist for Trading Apps

Before you put real capital through a custom settlement program, you need to pass a security audit. This checklist covers signer-check bypasses, owner mismatches, arithmetic overflows, and re-entrancy vectors specific to DeFi trading programs.

Deploying a Solana program that touches user funds without a structured audit is how teams lose everything in a single transaction. Unlike EVM chains, Solana's account model introduces an entirely different class of vulnerabilities — ones that most auditors trained on Ethereum will miss. If you've built a custom settlement layer, CLOB router, or position manager for your trading bot infrastructure, run every item on this checklist before you move real capital through it.

Signer Validation and Account Privilege Checks

The most common critical vulnerability in Solana programs is missing or incomplete signer checks. Every instruction that modifies state or transfers lamports must verify that the controlling key has actually signed the transaction.

In Anchor, #[account(signer)] handles this declaratively. In native programs, you must call invoke_signed correctly and check AccountInfo::is_signer explicitly. The failure mode is catastrophic: an attacker substitutes an account they control for the privileged signer, and your program happily executes the instruction.

Key things to verify:

  • Every admin instruction has a signer constraint tied to a program-controlled authority PDA or a multisig
  • The authority field in your state account matches the signer — checking is_signer alone is not enough if you don't also verify which key signed
  • invoke_signed seeds produce the PDA you expect — compute the canonical address off-chain and compare against what the program derives at runtime

Owner Checks and Account Substitution

Solana passes accounts as a flat list; the runtime does not enforce that an account belongs to your program unless your code checks AccountInfo::owner. Skipping this check opens the door to account substitution attacks where an attacker passes a malicious account with identical layout to a legitimate one.

Every account your program reads from must be validated: account.owner == &program_id (or the correct token program, system program, etc.). In Anchor, Account<'info, T> performs this check automatically — but if you're using AccountInfo directly, you're responsible. Always check owner before deserializing data from an account you didn't create in the same instruction.

Arithmetic Overflow and Precision Loss

Rust's release builds do not panic on integer overflow by default. If you compute a fee, a position size, or a PnL figure using unchecked arithmetic, an attacker can craft inputs that wrap around and produce a result that benefits them. Even one overflowed multiplication can drain a vault.

Use checked_add, checked_mul, checked_sub throughout, or enable overflow-checks = true in your Cargo.toml [profile.release] section — though the latter adds runtime cost. For fixed-point math, keep a documented precision convention (e.g., all prices in 1e9 units) and validate it is consistent across every instruction. Mixing precision conventions across instructions is how subtle accounting bugs survive audits.

Watch for truncation in divisions: a / b in integer arithmetic silently rounds toward zero. For fee calculations this can accumulate into material discrepancies over thousands of fills.

Re-entrancy via CPI

Solana does not have re-entrancy in the Ethereum sense, but Cross-Program Invocations (CPIs) introduce an equivalent hazard. If your program calls an external program (e.g., a DEX, token program, or oracle) mid-instruction and that external program can callback into yours — or if you read stale account state after a CPI modifies it — you can end up with inconsistent state.

The canonical mitigation: load account state, validate it, perform all CPIs, then write final state back. Never read account data from a reference you took before a CPI; the borrow checker will often save you, but not always if you're working with raw pointers or unsafe blocks. In Anchor, account data is reloaded automatically after a CPI only if you call reload() explicitly — don't assume the cached struct is fresh.

PDA Seed Collision and Canonical Bump

Program Derived Addresses are deterministic, which is exactly what makes seed collision dangerous. If two distinct logical entities (e.g., a user's position account and a protocol fee account) can derive to the same PDA under certain inputs, an attacker who controls one can overwrite the other.

Always include a domain separator in your seeds — a static prefix string like b"position" or b"fee_vault" — so seeds for different account types cannot collide even if the variable portions match. Store the canonical bump in your account struct and use it in every subsequent invoke_signed call. Searching for a valid bump on every CPI wastes compute and occasionally produces the wrong bump if the canonical one is not enforced.

Upgrade Authority and Deployment Controls

A program with a live upgrade authority is a persistent attack surface. If an attacker compromises your deployer key, they can upgrade the program to drain every vault it controls. Audit your deployment posture as carefully as the program code itself.

Minimum acceptable configuration:

  • Upgrade authority transferred to a multisig (Squads v4 or equivalent) before mainnet launch
  • Buffer accounts closed and reclaimed — an orphaned buffer with your program bytecode is a target
  • Freeze the program entirely if it is intended to be immutable after deployment

Document the authority key rotation policy and test that a quorum of signers can actually execute an upgrade end-to-end before you need it under incident conditions.


If you are building or auditing a custom Solana program for live trading and want a second set of eyes from engineers who have shipped settlement programs in production, reach out to the TierZero team.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Smart Contracts#Solana#Security#DeFi#Trading Bots#Audit