✳ SOLANA ACADEMYCourse overview

Expert · LESSON 01 OF 06

1. Threat-model a Solana protocol

By the end, you can map protocol assets, account trust boundaries, attacker capabilities, and observable security evidence.

Map protocol state and authorities to attack paths, then connect controls with tests and operational response evidence.
1. Threat-model a Solana protocol workflow. Map protocol state and authorities to attack paths, then connect controls with tests and operational response evidence.
A caller substitutes a token account or withdrawal destination. The program validates the token program, mint, authority PDA, canonical vault, amount, and state transition. Valid inputs change only the protected vault state; invalid inputs reject with balances and receipt state unchanged. Separate evidence is needed for RPC and indexer reliability, upgrade authority, and incident response.
Trace a Solana threat from attacker input to evidence. A caller substitutes a token account or withdrawal destination. The program validates the token program, mint, authority PDA, canonical vault, amount, and state transition. Valid inputs change only the protected vault state; invalid inputs reject with balances and receipt state unchanged. Separate evidence is needed for RPC and indexer reliability, upgrade authority, and incident response.

Read the workflow

Start from the protocol’s protected state and identify every authority able to change it. Trace plausible attack paths through caller-controlled accounts, signatures, program invocations, or operational keys. For each path, name an enforcement control and a negative test; separately identify monitoring, pause, and incident response evidence that runtime tests cannot provide.

  1. PROTOCOL STATE
  2. AUTHORITIES
  3. ATTACK PATHS
  4. CONTROLS
  5. TEST + RESPONSE

FIELD NOTE 01

Start with a system and its invariants

Choose one concrete system, such as a token vault, marketplace escrow, staking pool, or credential issuer. State what must always remain true: only the intended authority can move pooled assets, a receipt represents the correct deposit, and a failed instruction cannot leave a partial business result. Describe the normal user journey before listing attacks. A threat model is scoped to a version of a system and its dependencies; “Solana is secure” or “we use Anchor” does not establish that a particular program checks the right accounts.

FIELD NOTE 02

Map state and authorities

On Solana, programs contain executable code while mutable application state lives in separate accounts passed to instructions. Record each important account’s address derivation, owning program, data fields, lamports, and authority. Ask which program may modify its data and which signer may authorize a transition. For a vault, distinguish the token mint, vault token account, authority PDA, user token account, and executable program. A matching display name or token symbol is not enough: the mint address and owning token program must match the protocol’s expectation.

FIELD NOTE 03

Trace the transaction boundary

A transaction message names its instructions, accounts, and required signers. Treat account addresses, instruction bytes, and client-selected options as attacker-controlled until the program validates them. For every instruction, write down which accounts must be writable, which signer authorizes the action, and the relationships that must hold among them. A user may substitute a different token account or mint while keeping the interface looking plausible. The program should derive or verify canonical addresses and check account ownership, mint, authority, and state before changing balances or recording a receipt.

FIELD NOTE 04

Model program-specific attacks

Turn the intended action into an invariant table: precondition, state change, postcondition, and failure case. Check for missing signer checks, unchecked arithmetic, stale or duplicate state, account substitution, unsafe close or reinitialization paths, and assumptions about instruction order. For a deposit, test a wrong mint, wrong vault, unrelated authority, repeated receipt, and insufficient balance. For a withdrawal, test a substituted destination and a forged amount. Include the exact attacker capability and the protected asset in each scenario so the test demonstrates a real boundary.

FIELD NOTE 05

Follow cross-program calls

A cross-program invocation lets one program call another. The callee receives only the signer and writable privileges passed by its caller; it cannot escalate them. `invoke_signed` lets the calling program add signer privilege for a PDA derived from that program ID and the supplied seeds. This authority is narrow but powerful: validate the intended callee program ID, each forwarded account, and the exact PDA seeds before invoking it. Record every CPI edge and expected effect. Atomicity does not make an incorrect authorization safe: a malicious but valid instruction can still commit a harmful result.

FIELD NOTE 06

Follow one attack from input to proof

Suppose a vault accepts a deposit for mint M into vault account V, controlled by authority PDA A. A caller can submit arbitrary public account addresses and can sign for their own wallet, but cannot sign for A. The attack path is to substitute a token account with the same display symbol but a different mint, or to redirect a withdrawal to a different writable destination. The program must establish the relationships on chain: the account has the expected token-program owner, its mint is M, its token authority is the expected owner or PDA, the vault address is canonical for this vault, and the amount and state transition satisfy the instruction invariant. Reject untrusted CPI targets and unexpected forwarded privileges. Test each mutation with valid-looking accounts and assert both the expected rejection and unchanged protected balances and receipt state. These tests show the local program rejected the case; they do not establish which bytes or upgrade authority are live on Mainnet.

FIELD NOTE 07

Include runtime and operational dependencies

Threats include more than program code. Consider upgrade authority, frontend and wallet behavior, RPC providers, indexers, price oracles, token extensions, metadata storage, and release tooling. A compromised upgrade authority can change the code users interact with; an RPC provider can return stale or incomplete observations to an application. Record which facts are verified on chain and which depend on a service. Separate availability failures from integrity failures, and define a pause or fallback only when the actual architecture supports it.

FIELD NOTE 08

Rank risks and demand evidence

Rank each scenario by plausible likelihood, impact, affected users, and detectability. Then connect the mitigation to evidence: a negative program test, a property test, a local-validator run, an authority inspection, an alert rehearsal, or an independently verified transaction. State what the evidence does not establish. A unit test cannot prove deployed program identity; a written policy cannot prove that an operator can pause issuance. Keep open risks, owners, and release decisions visible instead of turning assumptions into security claims.

MAKE THE CONNECTION

A detail worth keeping

For a vault protocol, write invariants for deposit, withdrawal, token mint, vault authority, and receipt uniqueness. Then build an attack tree for a user who can submit arbitrary account addresses but cannot sign for the program’s PDA. Test whether the on-chain checks stop each path.

Work through an example

Review the same design under an upgrade-authority compromise and an RPC outage. These threats need different controls: account constraints cannot contain a malicious upgrade, and an RPC timeout is not proof that a submitted transaction failed. Record the authority or observation that resolves each uncertainty.

Threat-model a fictional token vault. Submit an account and authority map, attacker-capability table, five explicit invariants, one traced account-substitution attack, a CPI privilege map, negative tests that assert unchanged protected state, an external-dependency scenario, and a residual-risk register with owners and evidence. Use fictional addresses and no wallet keys or live funds.

GUIDED PRACTICE · EXPERT

Do the work, one step at a time

Use fictional addresses and disposable test data. Do not enter a recovery phrase or private key. Unless a lesson explicitly says “read-only Devnet,” use paper or a local test and do not connect to a public network.

  1. Choose a fictional vault, escrow, staking pool, or credential program and draw its accounts and authorities.
  2. Trace one valid instruction from wallet signature through program checks to changed account state.
  3. Create five account-substitution or authorization attacks and name the invariant each targets.
  4. Write a test and expected unchanged state for every rejected attack.
  5. Separate local-test evidence from deployment, RPC, upgrade-authority, and incident-response evidence.

Before you move on, check your reasoning

  • Choose a protocol and map its assets, accounts, signers, and program boundaries.
  • Write attacker paths as broken invariants, then pair each high-impact path with a negative test.
  • Record residual risks and the operational or deployment evidence still needed before release.

OPEN SELF-CHECK · UNGRADED

Pause and test your reasoning

Two findings have the same likelihood: one exposes a high-value authority used by many users; the other affects a rarely used cosmetic field. How should you prioritize?

  1. Rank the cosmetic issue first because it has fewer lines of code.
  2. Compare impact, exposure, assets, existing controls, and realistic exploitation paths before assigning priority.
  3. Prioritize whichever issue was reported most recently.
Reveal one best answer and its explanation

One best answer: Compare impact, exposure, assets, existing controls, and realistic exploitation paths before assigning priority.

Threat priority comes from a system-specific risk model, not line count, novelty, or finding frequency alone. Record the affected asset, attacker capability, reachable path, impact, controls, residual risk, and owner.

Sources: Sealevel Attacks ↗ · Account Constraints ↗

This practice is not scored, saved, or part of a certificate. Account-based lesson checkpoints and level exams remain separate.

Scored checkpoints and level exams are online and require a free account. They are not included in this pack.

READ THE SOURCE

Go deeper in the official docs

Reviewed on 2026-09-29. Protocol documentation can change; check the linked page’s current version when you reconnect.