← Solana Architect

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.

In this lesson8 field notes · practice · sources · checkpoint
Map protocol state and authorities to attack paths, then connect controls with tests and operational response evidence.
Map protocol state and authorities to attack paths, then connect controls with tests and operational response evidence.Open full-size visual ↗
Read a text version of this diagram

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
An attacker substitutes a token account. Program checks validate program owner, mint, token authority, canonical vault, amount, state, and CPI privileges. Authorized input changes only protected state; rejected input leaves balances and receipts unchanged. RPC, upgrade-authority, and pause risks need separate evidence.
Follow one attacker action through on-chain checks, protected state, and a testable security claim.Open full-size visual ↗
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. Most exercises work on paper or with a local test; only a lesson that clearly says “read-only Devnet” makes a public network request.

  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.

Never enter a recovery phrase or private key into a learning site or lesson exercise.

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 as you use this material.

  1. Core Concepts ↗
  2. Programs ↗
  3. Transactions ↗
  4. Cross Program Invocation ↗
  5. Accounts ↗
  6. Account Constraints ↗
  7. Sealevel Attacks ↗

Report an issue with this lesson

OPEN LEARNING

Keep learning at your own pace.

This lesson, its guided practice, and all six course lessons are open to everyone. Account-based checkpoints, exams, and saved progress will open when free accounts are ready.

Continue to the next lesson ↗