Write the security checklist you wish you'd had
You've found the bugs. Now build the checklist that stops them reaching production.
Write the security checklist you wish you'd had
For the last several days you have been thinking like an attacker. You wrote tests whose only job was to make your program fail, you generated thousands of fuzzed inputs to find the lamport value nobody chose by hand, and you rebuilt the missing owner check that drained Wormhole and Cashio. All of that knowledge currently lives in your head and in a scattered pile of test files. Today you turn it into something durable: a written security checklist, published with your name on it, that you and other builders can run down before any program touches mainnet.
A checklist is the format every serious safety-critical field eventually lands on. Surgeons use them, pilots use them, and security auditors use them because expertise fails in a predictable way: under pressure, the expert forgets the one routine step they have done a thousand times. Writing your own checklist is how you convert hard-won lessons into a habit that survives a tired Friday deploy. Publishing it is how you make those lessons useful to the next developer who is exactly where you were a month ago.
The scenario
You just finished a contract gig hardening a small Anchor program. The team lead, who came from a backend web2 shop, asks a fair question: “Great, but how do I know the next person will check the same things you did?” In a web2 code review you might point to a linter config or a pull request template. On Solana the failure modes are different enough that generic advice will not catch them, and the team needs something specific to the runtime: an account model where any account can be passed into any instruction, arithmetic that wraps silently, and cross-program calls that trust whatever program ID you hand them.
So you write the artifact you wish you had on day one of that gig. You publish it as a dev.to article, both so your team can bookmark it and so the wider community can borrow, argue with, and improve it. This is a Document day: the deliverable is clear writing that teaches, not new code.
The challenge
What you’ll need
- A free dev.to account (the same platform you have used on previous Document days)
- Your notes and test files from the Arc 12 days on adversarial tests, fuzzing, and the owner-check exploit
- A text editor for drafting in Markdown (dev.to renders Markdown natively)
- The reference links in the Resources section below, to check your claims and credit your sources
Steps
- Start from what you have already broken. Reread the three previous Arc 12 days. Every bug you reproduced or fuzzed into existence is a checklist item waiting to be written. The owner-check exploit becomes “verify the owner of every deserialized account.” Your overflow fuzz test becomes “use checked arithmetic on every balance change.” Lived experience makes for a far better checklist than a generic list copied from elsewhere.
- Group your items into categories. A flat list of forty checks is hard to use. Auditors organize by vulnerability class. A solid structure for your article is: account validation, authority and signer checks, arithmetic safety, cross-program invocation (CPI) safety, account lifecycle, and pre-deploy hygiene. These map directly onto what you covered across Arcs 9 through 12.
-
Write each item as a verifiable check, not a vague warning. “Be careful with accounts” is not actionable. “Confirm every
AccountInfois constrained with an owner check, or replaced by a typedAccount<'info, T>so Anchor checks the owner and discriminator for you” is something a reviewer can actually verify line by line. Aim for items a reader can answer yes or no. - Note where Anchor helps and where it does not. A big part of the value is explaining that Anchor’s typed accounts automatically check the program owner, the 8-byte discriminator, signer flags, and reinitialization, but that it still cannot reason about your business logic, your arithmetic, or whether a CPI target program is the one you intended. Drawing that line clearly is what makes your checklist trustworthy.
- Tie at least one item to a real exploit. Readers remember “$326M left Wormhole because a forged account was trusted without anyone verifying it was the real one” far longer than they remember an abstract rule. Use the post-mortem you already studied as the anchoring story for your account-validation section.
- Add a short intro and a closing note. Open by saying who the checklist is for and how to use it (run it before every mainnet deploy, top to bottom). Close by inviting corrections, since a security checklist is a living document and the community will spot gaps you missed.
- Format with proper Markdown. Use headings for each category and real checkbox or numbered lists for the items so the article is skimmable. Credit every source you drew from with a link.
-
Publish and tag. Add the
#100DaysOfSolanahashtag along with relevant tags likesolana,security, andrustso the article is discoverable.
Here is a starter skeleton you can paste into the dev.to editor and fill in with your own findings. The checks below are a representative core, not the whole list; expand each section from your own notes.
# My Solana Program Security Checklist
A pre-deploy checklist I run top to bottom before any Anchor program
goes to mainnet. Built from the bugs I reproduced myself.
## 1. Account validation
- [ ] Every deserialized account has its owner verified
(typed `Account<'info, T>` does this; raw `AccountInfo` does not).
- [ ] Account types are distinguished by their 8-byte discriminator,
so one account type cannot be passed where another is expected.
- [ ] Any `remaining_accounts` passed in are validated before use.
## 2. Authority and signer checks
- [ ] Every privileged instruction confirms the expected signer
with `Signer<'info>` or `has_one` / `constraint` checks.
- [ ] No instruction trusts a pubkey without also checking its
signer flag.
## 3. Arithmetic safety
- [ ] Every balance or supply change uses checked_add / checked_sub
/ checked_mul, never raw +, -, * on untrusted values.
- [ ] No silent cast that could truncate (e.g. u64 to u32).
## 4. CPI safety
- [ ] Every CPI verifies the target program ID is the one expected,
not whatever account the caller supplied.
- [ ] Accounts are reloaded after a CPI if their data is read again.
## 5. Account lifecycle
- [ ] Closed accounts are emptied and marked so they cannot be
revived or reused within the same transaction.
- [ ] No instruction allows reinitializing an already-initialized
account.
## 6. Pre-deploy hygiene
- [ ] Dependencies are current and free of known advisories.
- [ ] Adversarial and fuzz tests pass, not just the happy path.
Run it
There is no command to run today. Your “build” is the published article. Before you hit publish, do one pass reading each checklist item out loud and asking, “Could a reader actually verify this on a real program?” If the answer is no, rewrite it until it is yes.
What just happened
Anyone can fix a bug once; the people who protect users at scale are the ones who turn each incident into a check that prevents the entire class of bug from recurring. By writing items as yes-or-no verifications grouped by vulnerability class, you built something that works the way professional audit checklists work, which is exactly the format firms like Neodyme and the Solana Foundation use when they peer-review programs that hold real money.
Publishing it changes the nature of the work too. A private note in your repo helps only you. A public article invites scrutiny, which is the same force that makes open-source security strong: more eyes find more gaps. The team lead from the scenario now has a link to share, the next junior developer has a starting point, and you have a document you will quietly reach for every time you are about to deploy. You also practiced the habit that separates builders who last from builders who get exploited: writing down the lesson instead of trusting yourself to remember it under pressure.
Resources
- Program Security course on the official Solana developer site, a structured walk through the core checks
- coral-xyz/sealevel-attacks, paired insecure and secure example programs for each major Solana vulnerability class
- A Hitchhiker’s Guide to Solana Program Security by Helius, a thorough overview of what Anchor checks for you and what it does not
- Solana Smart Contracts: Common Pitfalls and How to Avoid Them by Neodyme, plus their hands-on Solana Security Workshop
- SlowMist’s Solana security best practices and the community-curated awesome-solana-security list for going deeper
Submission
Publish your checklist as an article on DEV using the #100DaysOfSolana hashtag so the community can find it, borrow from it, and suggest improvements. And don’t forget to submit it below!