← Solana Architect

Expert · LESSON 01 OF 07

1. Threat-model a Solana protocol

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

Look up Solana terms in the glossary

In this lesson10 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 ↗
FREE EXPERT PRACTICE

Threat Model Evidence Studio

Work through six fictional incidents involving account substitution, signer checks, CPI boundaries, replay, upgrade authority, and conflicting RPC evidence. This formative tabletop runs without a wallet, network request, or saved answers.

Open the online tabletop Download the offline casebook

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

Threat-model the upgrade and release control plane

A program can be correctly tested and still change after deployment if an upgrade authority remains active. Treat the loader, ProgramData account, upgrade authority, build pipeline, release approval, and published source as part of the system boundary. Ask who can authorize an upgrade, how that key is protected, what review occurs before a release, and how the deployed executable is matched to reviewed source. On the exact intended cluster, record the program ID, loader, ProgramData address, deployed slot, and current upgrade authority. A revoked authority makes an upgradeable-loader program immutable; it also removes the ability to patch it. A local unit test or frontend program label cannot establish which executable is deployed or who can change it.

FIELD NOTE 08

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 09

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.

FIELD NOTE 10

Treat RPC observations as scoped evidence

An application may receive stale, incomplete, or delayed observations from an RPC provider or indexer. A `null` result from `getSignatureStatuses` is not proof that a transaction never reached the cluster: without `searchTransactionHistory`, the method checks only its recent status cache. `getTransaction` can also return `null` when a transaction is not found at the requested commitment. Reconcile the public signature against the intended cluster, requested commitment, execution error, transaction details, and resulting account state. Use an independent provider as a comparison when integrity matters, but do not treat provider agreement alone as proof of program safety. Keep “not observed yet,” “failed,” and “committed with verified state” as distinct outcomes.

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.
  6. Review an upgrade-authority or RPC-status incident and separate onchain observations, service evidence, test evidence, and unresolved facts.

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

Practice 1 of 3

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. Prioritize whichever issue was reported most recently.
  3. Compare impact, exposure, assets, existing controls, and realistic exploitation paths before assigning priority.
Reveal the answer and 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

Practice 2 of 3

A protocol trusts an RPC provider to supply account data. How should that dependency appear in a threat model?

  1. Treat provider data as untrusted input.
  2. RPC data cannot be stale, forged, or unavailable because it comes directly from validator infrastructure.
  3. An RPC response is part of the Solana runtime and cannot be stale or unavailable.
Reveal the answer and explanation

One best answer: Treat provider data as untrusted input.

An RPC client is outside the program’s consensus enforcement path. Model stale, missing, censored, and unavailable responses separately, and make the program enforce its own invariants.

Sources: Accounts · Transactions · Sealevel Attacks

Practice 3 of 3

A test rejects a malformed account. What additional evidence shows the security invariant was enforced at the intended boundary?

  1. A client error proves it.
  2. Test rejection at the program boundary and unchanged state.
  3. A screenshot before submission establishes that the on-chain program rejected the malformed account.
Reveal the answer and explanation

One best answer: Test rejection at the program boundary and unchanged state.

The evidence chain should connect the attacker-controlled input to the enforcement point and the resulting state. A client-side refusal or comment does not prove an on-chain check ran.

Sources: Account Constraints · Sealevel Attacks

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-10-02. 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 ↗
  8. Program Deployment ↗
  9. Production Readiness ↗
  10. Transaction Pipeline ↗
  11. getSignatureStatuses ↗
  12. getTransaction ↗

Report an issue with this lesson

YOUR PROGRESS, SAVED

Ready for the checkpoint?

Make a free account to save your progress and unlock the quizzes.

Create free account