A formal audit costs $30k to $200k and the auditors' clock is running. Every hour they spend on issues you could have caught yourself is money burned, and a noisy codebase gets a shallower audit because attention goes to the easy stuff. Before any code I review goes to a paid audit, I run it through a fixed checklist. Here is the core of it, the EVM side in full and the Solana side in summary.
Solidity / EVM, the high-signal items
Access control
- Every state-changing external function has an intentional access modifier, not an accidental
public. - No single EOA holds an irreversible power without a timelock or multisig.
- Initializers cannot be front-run or called twice on upgradeable contracts.
Reentrancy and external calls
- Checks-Effects-Interactions on every function that calls out, state written before the call.
- Cross-function and cross-contract reentrancy considered, not just single-function.
- Arbitrary-token callbacks (ERC-777, fee-on-transfer, rebasing) considered where tokens are not fixed.
Oracles and pricing
- Price feeds checked for staleness (
updatedAt) and sane bounds. - On L2s, the sequencer-uptime feed is checked.
- No raw DEX spot price used as a manipulable oracle without a TWAP or sanity bounds.
Accounting and rounding
- Rounding always favors the protocol, and there is no add-then-remove or deposit-then-withdraw loop that extracts value.
- ERC-4626 vaults: first-depositor / share-inflation handled,
totalAssetscannot be moved by a direct token transfer.
Tests and invariants
- 3 to 5 written invariants (for example, total supply <= backing, sum of balances == totalAssets) with a Foundry, Echidna or Medusa suite that tries to break them.
- Fork tests against the real oracles and vaults you integrate.
Solana / Anchor, the bug families EVM intuition misses
On Solana there is no trusted msg.sender, any account can be passed into any instruction, and the program only knows what it checks. The recurring classes:
- Signer and authority: the privileged instruction checks the right authority signed, not just that someone signed.
- Account ownership and type: every account is owned by the expected program, and the discriminator stops a different account type being substituted.
- PDA and bump: derive with the canonical bump, never trust a user-supplied bump, no seed collisions across users or types.
- CPI: the invoked program id is verified, no arbitrary CPI to an attacker-passed program, the token program is the real SPL Token or Token-2022.
-
Anchor constraints:
has_oneon every relationship,init_if_neededcannot reset critical state,closecannot be revived in the same tx. - Arithmetic: checked math everywhere on value (overflow-checks on in the deploy profile), u128 for products that can exceed u64.
- Oracles and tokens: Pyth or Switchboard staleness and confidence checked, Token-2022 extensions (transfer fee, transfer hook) cannot break accounting.
Each item is a yes or no. Every no is a fix or a one-line justification you hand the auditors.
I packaged the full version, 22 sections across Solidity and Solana with every item, as a PDF here: https://payhip.com/b/zgtoW. And if you would rather have someone run it on your code and hand you a report, that is what I do. Repo and contact in my profile.











