All articles
Comparisons·June 20, 2026·6 min read

Hiring a Solana Auditor vs Static Analysis Tools: Worth It?

Static analyzers like Soteria and X-Ray catch known Solana bug patterns in minutes; deciding whether to hire a Solana smart contract auditor is about what they can't see.

Run Soteria against a stock Anchor vault program and it flags the same five or six patterns every time: missing signer checks, unchecked account ownership, integer overflow on unguarded arithmetic. Ask it whether your fee-accrual math lets a large depositor drain the pool over a few hundred slots by timing withdrawals around a rounding edge case, and it says nothing — because it can't. That gap is the entire question when you're deciding whether to hire a Solana smart contract auditor or ship on the strength of a scanner report.

What the scanners are actually doing

Soteria was the original static analyzer built specifically for Solana/Anchor programs, running symbolic execution against known unsafe patterns. The team behind it rebranded to sec3 and folded the tool into X-Ray, which now ships as a SaaS scanner plus a CI-integrated linter. Under the hood, both are pattern-matchers: they walk your account structs and instruction handlers looking for shapes that match Neodyme's sealevel-attacks catalog — the canonical list of Solana-specific footguns like missing owner checks, account type confusion, PDA seed collisions, and unchecked AccountInfo where a typed Account<'info, T> should be.

That catalog is genuinely useful. A large share of real Solana incidents trace back to exactly these patterns because Anchor's macro system makes it easy to skip a constraint without noticing. A scanner that catches "you forgot #[account(owner = token_program)]" before you deploy is worth running on every commit, and it costs nothing meaningful to do so — X-Ray's baseline scans run in minutes and slot straight into a GitHub Actions pipeline.

Where the coverage stops

Static tools reason about syntax and account structure, not economics. They don't know what your protocol is supposed to do, so they can't tell when it does something technically valid but financially wrong. Concretely, they miss:

  • Share-price or exchange-rate math that rounds in the depositor's favor across many small transactions
  • Multi-instruction attack sequences where no single instruction is unsafe in isolation
  • Oracle staleness or manipulation windows specific to your price-feed integration
  • PDA seed design that looks correct but collides under an input space you didn't consider
  • Upgrade authority and admin-key centralization risk — a scanner won't tell you your program is one signature away from a rug
  • Cross-program invocation trust boundaries when you're calling into a partner protocol whose behavior you're assuming rather than verifying

Cashio's $48M exploit in 2022 is the textbook case: the program accepted a caller-supplied collateral token account without properly tracing it back to a legitimate, whitelisted banking mint, so an attacker forged a fake collateral chain and minted CASH against nothing. A well-tuned scanner can flag "unchecked account passed into a mint check" as a pattern, but confirming whether the validation logic itself is sound — whether the chain of derived accounts actually proves what the code assumes it proves — takes someone tracing the call graph by hand. Wormhole's $326M bridge hack the same year came from a deprecated signature-verification path that skipped confirming the guardian set was checked against the correct sysvar; again, something a human reviewing the trust model would ask about directly, and something a pattern-matcher has no real handle on.

A concrete example

#[derive(Accounts)]
pub struct Withdraw<'info> {
    #[account(mut)]
    pub vault: Account<'info, Vault>,
    #[account(mut)]
    pub vault_token_account: Account<'info, TokenAccount>,
    #[account(mut)]
    pub user_token_account: AccountInfo<'info>, // should be Account<'info, TokenAccount>
    pub authority: Signer<'info>,
    pub token_program: Program<'info, Token>,
}

A scanner will correctly flag user_token_account as an unchecked account and recommend the typed wrapper. Fix that, rerun the scan, get a clean report. Now suppose the handler computes withdraw_amount = user_shares * vault.total_assets / vault.total_shares and the deposit path rounds shares up while the withdrawal path rounds assets down. Individually both roundings look conservative. Combined, a depositor who cycles small deposit/withdraw pairs can extract slightly more than they put in, and at scale against a large TVL vault that's a real loss. No static tool flags that, because it requires understanding what "correct" means for your specific share-accounting model, not just whether the syntax is safe.

Cost and turnaround, honestly

X-Ray's scans are effectively free at low volume and cheap at scale — this is not where teams overspend. A manual audit of a mid-sized Anchor program (roughly 2,000–5,000 lines, a handful of CPIs into Token/Associated Token/a DEX or lending protocol) typically runs from the mid five figures up, over one to three weeks, depending on how much custom logic versus boilerplate is in scope. That's a real cost for an early-stage team, which is exactly why a lot of projects try to substitute a scanner report for it and hope nobody asks harder questions before mainnet.

The honest framing is that the two aren't substitutes, they're sequential. Run static analysis continuously during development because it's cheap and catches syntactic mistakes before they cost you review time. Bring in humans once for the things that require understanding intent — and if your program touches execution paths like Jito bundle landing, Yellowstone gRPC streaming, or Jupiter versus Raydium swap routing, those integrations each carry their own trust assumptions that no generic scanner rule set was written to check.

Side by side

Dimension Static analyzer (Soteria / X-Ray) Manual audit
Catches missing signer/owner checks Yes, reliably Yes
Catches account type confusion Yes, mostly Yes
Catches economic/logic bugs No Yes
Understands cross-instruction attack sequences No Yes
Evaluates admin key / upgrade authority risk No Yes, if scoped in
Cost Free–low hundreds/mo Mid five figures and up
Turnaround Minutes 1–3+ weeks
Fits CI/CD Yes No
Produces a report investors/exchanges accept Rarely sufficient alone Standard expectation

Which to pick when

If you're iterating on a testnet prototype, forking a well-audited template with no custom accounting, or you have no real user funds at risk yet, a static scanner wired into CI is genuinely enough for that stage — don't pay audit rates to review boilerplate. But the moment you're taking deposits, running custom vault or AMM math, holding an upgrade authority a real attacker would want, or integrating CPIs into protocols you don't control, a scanner report is not a security posture, it's a first pass. At that point you want a dedicated code review and audit engagement or a full smart contract audit that traces your specific logic against your specific threat model, not a generic rule list. Teams that are unsure where their program sits on that spectrum are usually better off starting with a strategy consultation to scope the risk before committing to either path.

If your program is going to hold other people's money on mainnet, get a human to audit it before you flip that switch.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Solana security#smart contract audit#static analysis#Soteria#X-Ray