A Rust smart contract audit is a time-boxed security review of an on-chain program written in Rust, such as a Solana program, a NEAR or CosmWasm contract, or an Arbitrum Stylus contract. Move contracts on Sui and Aptos get the same kind of review. The audit ends in a report that ranks each finding by severity, and it lowers risk without proving the code safe.

The steps that are the same in every language are in the general smart contract audit guide. Below are the checks specific to Rust and Move.
How a Rust or Move audit differs from a Solidity audit
Rust does not make a contract safe. The language prevents many memory errors, but most losses come from logic: a missing check, a wrong account or a bad calculation. Those bugs compile and run without errors, and where they hide depends on the chain.
- An EVM contract reads its own storage. A Solana program receives every account it touches as an input, so the caller chooses them. The program has to check each account's owner, type, signer status and address. Most lessons in Solana's own security course deal with checks of this kind.
- Reentrancy rules differ by chain. Solana's CPI rules allow a program to call itself (A to A) but reject A to B to A with a
ReentrancyNotAllowederror. NEAR calls are asynchronous, so another method can run before a callback. The Stylus docs say the Rust SDK flushes its storage cache before every external call, and they still recommend the checks-effects-interactions pattern. - Integer overflow depends on the build. The Rust Book says debug builds panic on overflow, while release builds with
--releasewrap around silently. Au8at 255 plus 1 becomes 0. Programs are deployed as release builds, so auditors check the Cargo profile and every calculation. - Move checks more by default. Its arithmetic aborts on overflow, and the type system stops code from copying or dropping an asset unless the type allows it. The Aptos guidelines note one exception: a left shift does not abort on overflow.
Common bug classes on Solana
The Solana Foundation's program security course has one lesson per common bug: signer authorization, owner checks, account data matching, reinitialization, PDA sharing, type cosplay, arbitrary CPI, duplicate mutable accounts, bump seed canonicalization and closing accounts. The sealevel-attacks repository shows each class as a small program with its Anchor fix.
Missing signer checks
An instruction that changes an authority or moves funds has to confirm that the authority signed the transaction. Without the check, anyone can pass the admin's public key and call the instruction. In native Rust the check reads the account's is_signer flag:
if !ctx.accounts.authority.is_signer {
return Err(ProgramError::MissingRequiredSignature.into());
}
In Anchor, declaring the account as Signer<'info> runs the same check.
Missing owner and type checks
Any program can create an account with bytes laid out like your account. If your program does not check that the account is owned by your program, an attacker can pass a fake one. Anchor's Account<'info, T> type checks the owner automatically, and the owner constraint covers accounts from other programs.
Type cosplay is the same problem between two account types of one program. A User account passed where an Admin account is expected can pass deserialization if the layouts match. Anchor writes an 8-byte discriminator to each account so the program can tell the types apart, and native programs need their own type field.
Account data matching: the Cashio case
Owner checks are not enough when an account's fields point to other accounts. Anchor's has_one constraint checks that a stored field matches the key of another account in the instruction. In March 2022 the Solana stablecoin Cashio lost over $52 million because of a missing check of this kind. According to Halborn's analysis, the program checked the saber_swap.arrow account but never validated the mint field inside it. The attacker built a chain of fake accounts, deposited worthless collateral and minted real CASH tokens.
Spoofed system accounts: the Wormhole case
In February 2022 an attacker minted 120,000 wrapped ETH on Solana through the Wormhole bridge, worth over $320 million at the time, according to Merkle Science. Ackee's analysis traces it to signature verification that called the deprecated load_instruction_at function. That function did not check that the account passed in was the real instructions sysvar, so the attacker supplied a fake account with forged signature data. The checked version, load_instruction_at_checked, verifies the address.
PDA seeds and bumps
A program derived address (PDA) comes from seeds plus a bump value. The security course explains that create_program_address accepts any valid bump, so one set of seeds can produce several addresses. find_program_address returns the highest valid bump, called the canonical bump. Anchor's seeds and bump constraints check that an account is the PDA derived from the given seeds and bump. Auditors also check that seeds include enough data, such as the user's key, so that two users cannot share one PDA.
Arbitrary CPI
To call another program, a Solana program receives that program as an account. If the code does not compare the program's address to the expected one, the caller can pass a malicious program in its place. Anchor's generated CPI modules check the address, and native code has to compare the public key itself.
Overflow in release builds
The Anchor CLI refuses to build when overflow-checks is missing from the release profile, according to its source code. Native programs have no such guard. The setting goes in the workspace root Cargo.toml:
[profile.release]
overflow-checks = true
With the flag on, an overflow aborts the transaction instead of wrapping. Auditors still look for explicit checked_add or checked_mul on balances, and for rounding errors in fee and share calculations, which the flag does not catch.
Bug classes on NEAR, CosmWasm and Stylus
- NEAR. The NEAR security checklist asks that callbacks be private, for example with
#[private], and that a contract stay safe if another public method runs before its callback. It also covers predecessor versus signer accounts, one-yoctoNEAR deposits on sensitive methods and debiting balances before transfers. - CosmWasm. Oak Security's CosmWasm security spotlight series covers storage changes that are never saved, missing access controls, address validation and rounding errors when assets have different decimals.
- Arbitrum Stylus. The Stylus security page says the old
reentrantfeature and its guard were deprecated in SDK 0.10.5. It tells developers to use checked or saturating math in production and to handle the result of every external call.
Bug classes in Move on Sui and Aptos
Move removes some Solana bugs, because objects carry their own types and arithmetic aborts on overflow. Access control and math still go wrong.
- The Sui security best practices recommend capability objects such as
AdminCapand say a function should check that a capability matches the object it governs, so a capability for one vault cannot operate on another. The page warns that a leaked capability stays valid for the life of the package unless the design includes a way to revoke it. - Anyone can reference a shared object on Sui in a transaction. Every privileged function that touches shared state needs a capability, a sender check or an ownership check.
- On Aptos, the guidelines say any
Object<T>can be passed to any function, so the code must check that the signer owns it. Generic type parameters need the same care, so that one asset type cannot stand in for another. The guidelines also cover abilities:copy,dropandstoreshould be granted only where needed.
Checked arithmetic does not cover overflow checks that a team writes by hand. In May 2025 the Sui exchange Cetus lost about $223 million. Halborn traced it to a flawed overflow check in a function called checked_shlw, which compared the input to the wrong limit. The attacker chose a liquidity value that passed the check and still overflowed, so the deposit cost one token. Sui validators froze $162 million of the stolen funds, The Defiant reported, and Dedaub notes that the bug went undetected through several earlier audits.
The audit process and deliverables
Audit firms publish similar steps. SigIntZero and Hackerbane list these:
- The team and the auditor agree the scope and threat model: they fix the commit, the crates in scope, the runtime and the privileged roles.
- On Solana the auditor maps every account, PDA derivation and CPI call before reading code line by line.
- Linters such as Clippy and the firm's own detectors run over the code.
- In the manual review, auditors check validation, authorization, CPI safety and state changes in every instruction.
- Auditors write invariant tests and fuzz harnesses and feed in malicious accounts. High and critical findings get a proof of concept.
- The report ranks findings as critical, high, medium, low or informational, with root cause and fix advice. A second pass checks the fixes.
Ask for these deliverables in writing: the report naming the audited commit, proofs of concept for serious findings, the results of the fix review, and any fuzz harnesses or property tests written during the review. Hackerbane lists the harnesses as a deliverable, and you can keep running them after launch.
Tools used in Rust and Move audits
- Clippy, the standard Rust linter, flags common mistakes and risky patterns.
- cargo-audit checks
Cargo.lockagainst the RustSec advisory database for crates with known vulnerabilities. cargo-deny runs the same check and also enforces rules on licenses, download sources and duplicate versions. - Trident is an open-source fuzzing framework for Solana programs from Ackee Blockchain Security, funded by a Solana Foundation grant. It runs sequences of transactions and compares account states before and after each one.
- cargo-fuzz feeds random inputs to plain Rust functions, outside the chain runtime.
- Move Prover checks properties written in the Move Specification Language against Move code.
Tools find known patterns. Missing account checks that depend on business rules, such as Cashio's mint field, still need a person who knows what each account should be.
How to prepare for a Rust smart contract audit
- Freeze one commit and stop adding features to it.
- Set
overflow-checks = truein the release profile and run Clippy and cargo-audit yourself first. - Write a table of every instruction with the accounts it takes, which must sign, which are writable, who owns each one and how each PDA is derived.
- List privileged roles and keys: upgrade authority, admin, pause, fee recipient. On Sui, include each capability object and who holds it.
- Write a short spec of the rules that must always hold, such as "total deposits equal the vault balance."
- Bring a test suite that already covers the normal paths, including failures when a wrong account is passed.
- Document every outside program you call and every oracle you read.
- Pin the toolchain and make the build reproducible, so anyone can match the deployed program to the audited code.
How to choose a Rust or Move auditor
- Solana, CosmWasm, NEAR and Move each need different knowledge. Ask for public reports on the same chain and framework, such as Anchor or native Solana.
- Read two of the firm's public reports. Good ones explain root cause and include a proof of concept for serious findings.
- Ask who will review your code and for how many weeks. Zealynx, for example, says it puts two senior auditors on a typical audit.
- Confirm that the quote includes a review of your fixes, and what happens if a fix creates new code.
- Cetus passed several audits before its loss. Protocols holding large sums often add a second firm, an audit contest or a bug bounty.
What a Rust smart contract audit costs
Cost follows auditor time, and these factors move it most:
- lines of logic in scope, and how dense that logic is
- custom math, such as AMM curves or interest models
- the number of programs and cross-program calls
- outside integrations such as oracles and bridges
- the chain and language, since fewer auditors work on Rust and Move
- urgency, and whether formal verification is in scope
Few firms publish prices. SigIntZero's pricing page starts human-led audits at $5,000 and says complex L1, bridge and ZK systems scale to $200,000 or more. SigIntZero says most of its Rust audits take one to three weeks, while Zealynx gives two to five weeks for a typical audit and sells a three-day pre-audit review for $1,500. Get quotes from several firms on the same frozen commit so that the numbers compare.
After the audit, the smart contract security article covers monitoring, bug bounties and why audited code still gets hacked. The smart contract development guide covers the build stages before the review.
Frequently asked questions
What does a Rust smart contract audit cover?
It reviews an on-chain Rust program, such as a Solana, NEAR, CosmWasm or Stylus contract, for security bugs. Auditors map the accounts and calls, run automated checks, review each instruction by hand, write tests and report findings by severity, then check the fixes.
How is a Solana audit different from a Solidity audit?
A Solana program receives every account it touches from the caller, so the audit focuses on missing signer, owner, type and address checks. Solana also rejects indirect reentrancy, and Rust release builds wrap on overflow unless overflow checks are turned on.
Does Rust prevent smart contract vulnerabilities?
No. Rust prevents many memory errors, but most losses come from logic bugs such as a missing account check, which compile and run normally. Cashio and Wormhole both lost funds on Solana because of missing account validation.
Are Move smart contracts safer than Rust ones?
Move aborts on arithmetic overflow and controls whether assets can be copied or dropped, which removes some bug classes. Access control and hand-written math can still fail, and the Cetus exchange on Sui lost about $223 million in May 2025 through a flawed overflow check.
How much does a Rust smart contract audit cost?
Few firms publish prices. SigIntZero starts human-led audits at $5,000 and says complex L1, bridge and ZK systems scale to $200,000 or more.
How long does a Rust smart contract audit take?
SigIntZero says most of its Rust audits take one to three weeks. Zealynx gives two to five weeks for a typical audit. A second pass to check the fixes comes after the report.