I've spent time auditing DeFi protocols on Solana and Ethereum. Here are the patterns that keep showing up.
1. Oracle Manipulation
If your protocol uses a price oracle (Pyth, Chainlink, Switchboard), the #1 question is: can someone manipulate the price in the same transaction they exploit your contract?
The pattern:
- Attacker flash loans a large amount
- Manipulates a DEX pool price
- Your oracle reads the manipulated price
- Attacker borrows/withdraws at the wrong price
- Repays flash loan, keeps profit
The fix: Use TWAP (time-weighted average prices), require price staleness checks, and use multiple oracle sources.
2. Missing Signer Checks
Solana programs must explicitly verify that the right accounts signed the transaction. Unlike Ethereum where msg.sender is implicit, Solana requires manual checks.
// BAD - no signer check
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
// Anyone can call this!
transfer(ctx.accounts.vault, ctx.accounts.destination, amount)
}
// GOOD - verify authority
pub fn withdraw(ctx: Context<Withdraw>, amount: u64) -> Result<()> {
require!(ctx.accounts.authority.is_signer, ErrorCode::Unauthorized);
transfer(ctx.accounts.vault, ctx.accounts.destination, amount)
}
3. Integer Overflow in Token Math
DeFi math involves lots of multiplication and division. Without checked math, values can silently overflow.
Common scenario: Calculating LP token shares, reward distributions, or fee percentages with large numbers that exceed u64 bounds.
The fix: Use checked_mul, checked_div, checked_add everywhere. Or use the uint crate for arbitrary precision.
4. Reentrancy via CPI
Solana's Cross-Program Invocations (CPI) can create reentrancy-like vulnerabilities. If your program calls another program that calls back into yours before state is updated, you're vulnerable.
The fix: Update state BEFORE making CPI calls (checks-effects-interactions pattern). Use reentrancy guards for critical functions.
5. Account Substitution
Solana programs receive accounts as a list. If you don't validate that each account is what you expect, an attacker can substitute a fake account.
Example: Passing a fake token mint, a different PDA, or an attacker-controlled program where your program expects a specific one.
The fix: Always validate account addresses against expected PDAs, check account owners, verify mint addresses.
If you're building on Solana and want a security review, feel free to reach out: lymantate2@gmail.com
I've audited oracle contracts, vault patterns, and DeFi protocols. Happy to do a quick review of your code.
Top comments (2)
This is a top-tier breakdown of the most common "gotchas" that sink even the most hyped protocols on Solana and Ethereum. The emphasis on account substitution and signer checks is especially crucial since those manual requirements are where most EVM developers trip up when migrating to Solana's architecture.
Clean summary of the patterns I see most frequently in audits. The comparison to Ethereum's msg.sender for pattern #2 is especially helpful for devs making the cross-chain transition. Thanks for sharing.