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 (0)