A collection of resources to study Solana smart contract security, auditing, and exploits.
- Armani Sealevel Attacks and How to avoid them in Anchor
- Summary Thread by pencilflip - use Anchor attributes, constraints and types, it will make your life easier!
- Armani Tips on Developing Secure Solana Programs
- Be wary of
UncheckedAccount
andAccountInfo
- check them properly!
- Be wary of
- CMichel How to become a smart contract auditor
- Targeted at ETH folks but contains general advice
- DeFi MOOC samczsun Practical Smart Contract Security
- Great intro to smart contract security that provides an overview of a large surface area of attacks. Mostly ETH-based but also covers a cross-chain BTC/ETH exploit, and contains lots of concepts that carry over to Solana
- Kudelski Solana Program Security
- A high-level overview of ownership and data validation
- Neodyme Common Pitfalls
- Check owner, check signer, check account data, be careful of integer over/underflow, verify invoke_signed(), and use Anchor (unless you have a good reason not to), e.g. account confusions are prevented in Anchor by implicitly assigning each
#[account]
a type with an 8-byte identifier
- Check owner, check signer, check account data, be careful of integer over/underflow, verify invoke_signed(), and use Anchor (unless you have a good reason not to), e.g. account confusions are prevented in Anchor by implicitly assigning each
- Neodyme Solana Security Workshop Exercises and Solutions
- Corresponding exercises to the common pitfalls mentioned in the blog post
- Neodyme Thinking Like An Attacker Workshop Recording
- A quick rundown of the PoC framework and an explanation of Level 0 of the challenge
- OtterSec Solana from an Auditor’s perspective
- A bottoms-up introduction to Solana's Execution and Programming Model from a security perspective
- Sec3 Arithmetic Overflow and Underflow
- Don't use
+, - , /, *
operations, check arithmetic operations for overflow and underflow!
- Don't use
- Sec3 How to Audit Part 1: A Systematic Approach
- A high-level overview of common attack surfaces and questions to ask as an auditor
- Sec3 How to Audit Part 2: using automated tools to find vulnerabilities
- An outline of tools that can automatically scan your code for vulnerabilities, unsafe Rust, and spelling. More security tools are needed!
- Sec3 How to Audit Part 3: Penetration Testing
- How to execute a proof of concept for an attack with Neodyme's PoC framework
- Sec3 How to Audit Part 4: Anchor
- How Anchor's
#[program]
,#[derive(Accounts)]
and#[account]
work under-the-hood
- How Anchor's
- Sec3 Owner and Signer Check
- Check the owner and check the signer! Use
#[account]
andSigner<'info>
to prevent this
- Check the owner and check the signer! Use
- Solend Auditing Workshop
- Known attacks from ETH and how they carry over to Solana + auditing methodology
- Trail of Bits DeFi Security Success Stories
- ETH-focused but broadly applicable advice on securing systems in DeFi
- Zellic The Vulnerabilities You’ll Write With Anchor
- A subset of common vulnerabilities you'll come across in Anchor programs
- CASH Hack Summary Thread (samczsun)
- Establish a root of trust!
- CASH Hack — What’s the Vulnerability (Sec3)
- Check input accounts!
- Cope Roulette (Arrowana)
- Neat way to exploit reverting transactions
- Detecting Simulation in a Solana Program (Opcodes)
- Goes into how transaction simulation works and the purpose of the bank - Sec3 also has a great overview of the bank module
- How to freely borrow all the TVL from the Jet Protocol (Jayne)
- A fairly uncommon vulerability due to an unintended use of
break
- A fairly uncommon vulerability due to an unintended use of
- How to Become a Millionaire, 0.000001 BTC at a Time (Neodyme)
- An innocent-looking rounding error that put $2.6bn at risk. If in doubt, use
floor
(orceil
depending on direction) instead ofround
- Context on Neodyme Exploit by Solend
- An innocent-looking rounding error that put $2.6bn at risk. If in doubt, use
- New Integer Overflow Bug Discovered in Solana rBPF (BlockSec)
- Use
checked_add(), checked_div(), checked_mul(), checked_pow, checked_sub
orsaturating_add(), saturating_mul(), saturating_pow(), saturating_sub()
! → read relevant Sec3 blog post
- Use
- Schrodinger’s NFT, An Incinerator SPL Token program, and The Royal Flush Attack (Solens) (similar to samczsun explanation of combining attacks)
- Chaining small exploits to create a significant exploit. Watch samczsun's explanation of exploit chaining
- Smashing the Candy Machine for fun and profit! (Solens)
- Check unchecked accounts properly! There is a reason why Anchor requires
UncheckedAccount
to have/// CHECK
documentation. The fix came down to 1 line of Anchor code:#[account(zero)]
vs#[account(zero)]
- Check unchecked accounts properly! There is a reason why Anchor requires
- Solana Stake Pool: A Semantic Inconsistency Vulnerability (Sec3)
- Shows how to build a proof of concept with Neodyme’s Poc Framework. Also highlights how previously audited code (Stake Pool audits linked in audits section below) can contain vulnerabilities
- Solend Malicious Lending Market Incident Report (Rooter)
- Read Kudelski's blog post on Solana Program Security to understand the exploit
- SPL Token Program Approve Instruction (Hana)
- Sneaky way to revoke Solana token approvals
- The $200m Bluff: Cheating Oracles on Solana (OtterSec)
- How to move an AMM price to manipulate an oracle and exploit a lending protocol. Use fair pricing for LP tokens and TWAPs where possible! Drift has examples of oracle guardrails that aim to prevent these types of attacks
- Wormhole Hack Summary Thread (samczsun)
- Check/validate your input accounts anon!
- Wormhole Hack TLDR (Halborn)
- When chaining delegations of signature verifications, make sure it leads to proper verifications!
- Wormhole Hack Quick Analysis (Kudelski)
- Validate unmodified, reference-only accounts!
- Wormhole Post-Mortem Analysis (Entropy)
- Analyzing the input accounts to fake the
SignatureSet
- Analyzing the input accounts to fake the
- Cashio Exploit (PNM)
- Jet Governance (OtterSec)
- Port Max Withdraw Bug (nojob)
- SPL Token-Lending (Neodyme)
- Aldrin (Kudelski)
- Audius (Kudelski)
- Cashmere (OtterSec)
- Cega (OtterSec)
- Crema (Bramah)
- Cropper (Halborn)
- Debridge (Neodyme)
- Drift (Zellic)
- Francium (Certik)
- Friktion (Kudelski)
- Genopets (MadShield)
- GooseFx (Halborn)
- Hedge (Kudelski, OtterSec + Sec3)
- Hubble (Kudelski)
- Invariant (Sec3)
- Jet Governance (OtterSec)
- Juiced (OtterSec)
- Larix (SlowMist)
- Light (HashCloak)
- Mango (Neodyme)
- Maple (Bramah)
- Marinade (Kudelski + Ackee) and Code Review (Neodyme)
- Marinade v2 (Neodyme + Sec3)
- Mean (Sec3)
- Orca Whirlpools (Kudelski + Neodyme)
- Parrot (Halborn)
- Phantasia (Halborn)
- Phoenix (MadShield + OtterSec)
- Port Lending (Kudelski + SlowMist)
- Port Sundial (OtterSec)
- Pyth (Zellic)
- Quarry (Quantstamp)
- Saber (Bramah)
- Shared Memory and Token Swap Code Review (Kudelski)
- Soda (Certik)
- Solana (Kudelski, 2019)
- Solana Stake Pool (Kudelski)
- Solana Stake Pool (Neodyme)
- Solana Stake Pool (Quantstamp)
- Solend (Kudelski)
- Solido (Bramah + Neodyme)
- Solvent (OtterSec)
- Squads (OtterSec)
- Streamflow (Opcodes)
- Swim (Kudelski)
- Synthetify (Kudelski)
- UXD Audit (Sec3)
- Wormhole (Neodyme)
- Ackee Trdelnik (Anchor testing framework)
- Anchor Test UI (Visual Anchor testing framework)
- APR (Anchor Program Registry)
- Blockworks Checked Math (Macro to check math operations)
- cargo-audit (checks Cargo.lock files for vulnerable crates)
- cargo-geiger (checks usage of unsafe Rust code)
- Kudelski Semgrep (static analysis)
- Neodyme Solana PoC Framework (penetration testing)
- OtterSec Solana CTF Framework
- Saber Vipers (checks and validations)
- Sec3 Auto Auditor (vulnerability scanner)
- Drift (up to 500k)
- Friktion (up to 100k)
- Hubble (up to 500k)
- Jet (up to 75k)
- Larix (up to 150k)
- Lido (up to 2m)
- Mango (up to 1m)
- Marinade (up to 250k)
- Metaplex (up to 200k)
- Orca (up to 500k)
- Port (up to 500k)
- Phoenix (up to 100k)
- Saber (up to 1m)
- Serum (up to 1m)
- Solana Labs (up to 2m)
- Solend (up to 1m)
- Solvent (up to 250k)
- Swim (up to 100k)
- Synthetify (up to 100k)
- UXD (up to 2.5m)
- Wormhole (up to 2.5m)
- When is it appropriate to reward a bounty?
- When to audit a protocol?, thread on deploying to mainnet without an audit
- Who would pay for an Anchor exploit?
Pull requests are welcome! For major changes, please open an issue first to discuss what you would like to change.
Feel free to do whatever you want with this material (but pls be a whitehacker)!