Learn-skills.dev solidity-audit

Security audit and code review checklist. Covers 30+ vulnerability types with real-world exploit cases (2021-2026) and EVMbench Code4rena patterns. Use when conducting security audits, code reviews, or pre-deployment security assessments.

install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/0xlayerghost/solidity-agent-kit/solidity-audit" ~/.claude/skills/neversight-learn-skills-dev-solidity-audit && rm -rf "$T"
manifest: data/skills-md/0xlayerghost/solidity-agent-kit/solidity-audit/SKILL.md
source content

Solidity Security Audit Checklist

Language Rule

  • Always respond in the same language the user is using. If the user asks in Chinese, respond in Chinese. If in English, respond in English.

Usage: This skill is for security audits and code reviews. It is NOT auto-invoked — call

/solidity-audit
when reviewing contracts for vulnerabilities.

Contract-Level Vulnerabilities

1. Reentrancy

VariantDescriptionCheck
Same-functionAttacker re-enters the same function via fallback/receiveAll external calls after state updates (CEI pattern)?
Cross-functionAttacker re-enters a different function sharing stateAll functions touching shared state protected by
nonReentrant
?
Cross-contractAttacker re-enters through a different contract that reads stale stateExternal contracts cannot read intermediate state?
Read-onlyView function returns stale data during mid-execution stateNo critical view functions used as oracle during state transitions?

Case: GMX v1 (Jul 2025, $42M) — reentrancy in GLP pool on Arbitrum, attacker looped withdrawals to drain liquidity.

2. Access Control

CheckDetail
Missing modifierEvery state-changing function has explicit access control?
Modifier logicModifier actually reverts on failure (not just empty check)?
State flagAccess-once patterns properly update storage after each user?
Admin privilege scopeOwner powers are minimal and time-limited?

Case: Bybit (Feb 2025, $1.4B) — Safe{Wallet} UI injected with malicious JS, hijacked signing process. Not a contract flaw, but access control at the infrastructure layer.

3. Input Validation

CheckDetail
Zero addressAll address params reject
address(0)
?
Zero amountFund transfers reject zero amounts?
Array boundsPaired arrays validated for matching length?
Arbitrary callNo unvalidated
address.call(data)
where attacker controls
data
?
Numeric boundsInputs bounded to prevent dust attacks or gas griefing?

4. Flash Loan Attacks

VariantMechanismDefense
Price manipulationFlash-borrow → swap to move price → exploit price-dependent logic → repayTWAP oracle with min-liquidity check
GovernanceFlash-borrow governance tokens → vote → repay in same blockSnapshot voting + minimum holding period + timelock ≥ 48h
LiquidationFlash-borrow → manipulate collateral value → trigger liquidationMulti-oracle price verification + circuit breaker
Combo (rounding)Flash-borrow → manipulate pool → micro-withdrawals exploit rounding → repayMinimum withdrawal amount + virtual shares

Cases:

5. Oracle & Price

CheckDetail
Single oracle dependencyUsing multiple independent price sources?
Stale priceChecking
updatedAt
timestamp and rejecting old data?
Spot price usageNever using raw AMM reserves for pricing?
Minimum liquidityOracle reverts if pool reserves below threshold?
Price deviationCircuit breaker if price moves beyond threshold vs last known?
Chainlink round completenessChecking
answeredInRound >= roundId
?

Case: Cream Finance (Oct 2021, $130M) — attacker manipulated yUSD vault price by reducing supply, then used inflated collateral to drain all lending pools.

6. Numerical Issues

TypeDescriptionDefense
Primitive overflow
uint256 a = uint8(b) + 1
— reverts if b=255 on Solidity ≥0.8
Use consistent types, avoid implicit narrowing
Truncation
int8(int256Value)
— silently overflows even on ≥0.8
Use
SafeCast
library for all type narrowing
Rounding / precision loss
usdcAmount / 1e12
always rounds to 0 for small amounts
Multiply before divide; check for zero result
Division before multiplication
(a / b) * c
loses precision
Always
(a * c) / b

Case: Bunni (Sep 2025, $8.4M) — rounding errors in micro-withdrawals exploited via flash loan.

7. Signature Issues

TypeDescriptionDefense
ecrecover returns address(0)Invalid sig returns
address(0)
, not revert
Always check
recovered != address(0)
Replay attackSame signature reused across txs/chainsInclude
chainId
+
nonce
+
deadline
in signed data
Signature malleabilityECDSA has two valid (s, v) pairs per signatureUse OpenZeppelin
ECDSA.recover
(enforces low-s)
Empty loop bypassSignature verification in for-loop, attacker sends empty arrayCheck
signatures.length >= requiredCount
before loop
Missing msg.sender bindingProof/signature not bound to callerAlways include
msg.sender
in signed/proven data

8. ERC20 Compatibility

IssueDescriptionDefense
Fee-on-transfer
transfer(100)
may deliver <100 tokens
Check balance before/after, use actual received amount
Rebase tokensToken balances change without transfersNever cache external balances; always read live
No bool returnSome tokens (USDT) don't return bool on transferUse
SafeERC20.safeTransfer
ERC777 hooksTransfer hooks can trigger reentrancyUse
ReentrancyGuard
on all token-receiving functions
Zero-amount transfer
transferFrom(A, B, 0)
— address poisoning
Reject zero-amount transfers
Approval raceChanging allowance from N to M allows spending N+MUse
safeIncreaseAllowance
/
safeDecreaseAllowance

9. MEV / Front-Running

TypeDescriptionDefense
Sandwich attackAttacker front-runs buy + back-runs sell around victimSlippage protection + deadline parameter
ERC4626 inflationFirst depositor donates to inflate share price, rounding out later depositorsMinimum first deposit or virtual shares (ERC4626 with offset)
Approval front-runAttacker spends old allowance before new allowance tx confirmsUse
increaseAllowance
not
approve
Unrestricted withdrawalAttacker monitors mempool for withdraw tx, front-runs with ownRequire commit-reveal or auth binding

10. Storage & Low-Level

IssueDescription
Storage pointer
Foo storage foo = arr[0]; foo = arr[1];
— does NOT update arr[0]
Nested delete
delete structWithMapping
— inner mapping data persists
Private variablesAll contract storage is publicly readable via
eth_getStorageAt
Unsafe delegatecallDelegatecall to untrusted contract can
selfdestruct
the caller
Proxy storage collisionUpgrade changes parent order → variables overwrite each other (use storage gaps)
msg.value in loopmsg.value doesn't decrease in loop — enables double-spend

11. Contract Detection Bypass

MethodHow it works
Constructor callAttack from constructor —
extcodesize == 0
during deployment
CREATE2 pre-computePre-calculate contract address, use as EOA before deploying

12. Proxy & Upgrade Vulnerabilities

Source: EVMbench Paper §4.2, Appendix H / Code4rena 2024-07-basin H-01

CheckDetail
_authorizeUpgrade
access control
UUPS
_authorizeUpgrade
must have
onlyOwner
modifier?
Permissionless factory/registryCan attacker use permissionless factory (e.g. Aquifer
boreWell
) to satisfy upgrade checks?
upgradeTo
modifier
Overridden
upgradeTo
/
upgradeToAndCall
retains
onlyProxy
modifier?
Initializer protection
initializer
modifier prevents re-initialization? Implementation calls
_disableInitializers()
?
Storage layout compatibilityUpgrade-safe storage layout (storage gaps or ERC-7201 namespace)?

Case: Code4rena 2024-07-basin H-01 (via EVMbench Paper Fig.12, p.19) —

_authorizeUpgrade
only checked delegatecall and Aquifer registration but lacked
onlyOwner
, allowing anyone to upgrade a Well proxy to a malicious implementation and drain funds. Oracle patch: add a single
onlyOwner
modifier.

13. Trust Boundary & Protocol Composability

Source: EVMbench Paper §4.2.1, Fig.6 / Code4rena 2024-04-noya H-08, 2024-07-benddao

CheckDetail
Cross-vault trust isolationRegistry/Router relay calls verify vault-level authorization?
Trusted sender abuseFunctions like
sendTokensToTrustedAddress
verify source vault, not just router identity?
Flash loan + routing comboCan attacker use flash loan callback to make router impersonate arbitrary vault?
Collateral ownership verificationLiquidation/staking operations verify actual NFT/collateral owner?
Cross-contract state dependencyMulti-contract interactions free from intermediate state dependencies?

Cases:

14. State Ordering & Counter Manipulation

Source: EVMbench Paper Appendix H.1, Fig.19-21 / Code4rena 2024-08-phi H-06

CheckDetail
Counter/ID increment order
credIdCounter++
or similar ID increments happen before external calls?
Auto-buy in create
create()
functions with auto
buy()
calls execute only after ID/state fully initialized?
Refund timingETH refund (excess) happens after all state updates complete?
Bonding curve metadata overwriteCan attacker reenter to modify bonding curve/pricing params — buy cheap, switch to expensive curve, sell high?

Case: Code4rena 2024-08-phi H-06 (via EVMbench Paper Appendix H.1, p.25-28) —

_createCredInternal
called
buyShareCred
before incrementing
credIdCounter
;
_handleTrade
refunded excess ETH before updating
lastTradeTimestamp
. Attacker reentered to accumulate shares on cheap curve, overwrote metadata to expensive curve, sold to drain all contract ETH. Fix: add
nonReentrant
to
buyShareCred
/
sellShareCred
.

Infrastructure-Level Vulnerabilities

15. Frontend / UI Injection

Attackers inject malicious code into the dApp frontend or signing interface.

Defense: Verify transaction calldata matches expected function selector and parameters before signing. Use hardware wallet with on-device transaction preview. Audit all frontend dependencies regularly.

Case: Bybit (Feb 2025, $1.4B) — malicious JavaScript injected into Safe{Wallet} UI, tampered with transaction data during signing.

16. Private Key & Social Engineering

Compromised keys remain the #1 loss source in 2025-2026.

Defense: Store keys in HSM or hardware wallet. Use multisig (≥ 3/5) for all treasury and admin operations. Never share seed phrases with any "support" contact. Conduct regular social engineering awareness training.

Case: Step Finance (Jan 2026, $30M) — treasury wallet private keys compromised via device breach.

17. Cross-Chain Bridge

CheckDetail
Inherited codeAudit all bridge logic inherited from third-party frameworks
Message verificationCross-chain messages validated with proper signatures and replay protection?
Liquidity isolationBridge funds separated from protocol treasury?

Case: SagaEVM (Jan 2026, $7M) — inherited vulnerable EVM precompile bridge logic from Ethermint.

18. Legacy / Deprecated Contracts

Old contracts with known bugs remain callable on-chain forever.

Defense: Permanently

pause
or migrate funds from deprecated contracts. Monitor old contract addresses for unexpected activity. Remove mint/admin functions before deprecation.

Case: Truebit (Jan 2026, $26.4M) — Solidity 0.6.10 contract lacked overflow protection, attacker minted tokens at near-zero cost.

Audit Execution Checklist

When conducting a security audit, check each item:

Reentrancy:

  • All functions with external calls use
    nonReentrant
  • CEI pattern followed — no state reads after external calls
  • View functions not used as oracle during state transitions

Access Control:

  • Every state-changing function has explicit access modifier
  • Modifiers actually revert (not silently pass)
  • Admin privileges are minimal and documented

Input & Logic:

  • No unvalidated arbitrary
    call
    /
    delegatecall
  • No
    tx.origin
    for authentication
  • Array lengths validated for paired inputs
  • No division-before-multiplication precision loss

Token Handling:

  • All ERC20 ops use
    SafeERC20
  • Fee-on-transfer tokens handled (balance diff check)
  • Rebase token balances not cached
  • Zero-amount transfers rejected

Price & Oracle:

  • No raw spot price usage
  • Stale price check (
    updatedAt
    /
    answeredInRound
    )
  • Minimum liquidity threshold enforced
  • Price deviation circuit breaker

Signature & Crypto:

  • ecrecover
    result checked against
    address(0)
  • Signed data includes
    chainId
    ,
    nonce
    ,
    msg.sender
    ,
    deadline
  • Using OZ
    ECDSA
    (low-s enforced)
  • MerkleProof leaves bound to
    msg.sender

Flash Loan Defense:

  • Governance: snapshot voting + holding period + timelock
  • Price: TWAP or multi-oracle, not single-block spot
  • Vault: minimum first deposit or virtual shares (ERC4626)

Proxy & Upgrade (EVMbench):

  • UUPS
    _authorizeUpgrade
    has
    onlyOwner
    — [EVMbench/basin H-01]
  • upgradeTo
    /
    upgradeToAndCall
    retains
    onlyProxy
    — [EVMbench/basin H-01]
  • Implementation constructor calls
    _disableInitializers()
    — [EVMbench/basin H-01]
  • Storage layout upgrade-compatible (storage gaps or ERC-7201) — [EVMbench/basin H-01]

Trust Boundary & Composability (EVMbench):

  • Router/Registry relay calls verify source vault/contract authorization — [EVMbench/noya H-08]
  • Liquidation operations verify actual collateral ownership — [EVMbench/benddao]
  • Flash loan callback paths cannot be abused to penetrate trust boundaries — [EVMbench/noya H-08]
  • No intermediate state dependencies in multi-contract interactions — [EVMbench/noya H-08]

State Ordering (EVMbench):

  • Counter/ID increments complete before external calls — [EVMbench/phi H-06]
  • ETH refunds execute after all state updates — [EVMbench/phi H-06]
  • Auto-operations in create functions (auto-buy etc.) execute after full initialization — [EVMbench/phi H-06]

Infrastructure:

  • Third-party dependencies audited (bridge code, inherited contracts)
  • No deprecated contracts still callable with admin/mint functions
  • Multisig on all treasury and admin wallets
  • Frontend transaction verification (calldata matches expected)

AI Agent Audit Methodology

Source: EVMbench (OpenAI/Paradigm, Feb 2026) — evaluated AI agents on 120 high-severity vulnerabilities from 40 Code4rena audit repositories across Detect/Patch/Exploit modes.

Audit Strategy

  1. Coverage over depth: scan ALL in-scope files; do not stop after finding the first vulnerability [EVMbench §5, p.10]
  2. Three-phase audit: Detect (identify vulnerabilities) -> Patch (write fix) -> Exploit (build PoC) [EVMbench §3.2, p.5]
  3. Incremental output: write findings continuously during audit to preserve progress [EVMbench Appendix G, Fig.18, p.24]
  4. Systematic category scan: check by vulnerability class (reentrancy, access control, numerical, oracle...) rather than intuition [EVMbench §3.1, p.4]
  5. Verify fixes: after patching, confirm original tests still pass AND exploit is no longer viable [EVMbench §3.2.2, p.5]

High-Frequency Vulnerability Patterns (Code4rena Data)

Source: EVMbench Table 4 (p.17) — 40 audit repositories

  • Missing access control (upgradeability, liquidation, admin functions) — basin H-01, munchables, benddao
  • Reentrancy + state ordering errors (refund before state update) — phi H-06, noya H-08
  • Flash loan trust boundary penetration (exploiting router/registry trust propagation) — noya H-08
  • Signature replay / front-running (checkpoint bypass, session signature replay) — sequence H-01, H-02
  • Numerical precision / rounding (bonding curve, micro-withdrawals) — abracadabra H-02, size H-02

Key Findings

Source: EVMbench Paper §4.1 (p.7), Fig.7 (p.10), Fig.10 (p.18), Fig.11 (p.19)

  • With mechanism hints, Patch success rate jumps from ~40% to ~94% [Fig.7] — agents know how to fix but struggle to find vulnerabilities
  • Most vulnerabilities require ≤5 lines of code to fix [Fig.10, p.18]
  • Most exploits require only 1-3 transactions [Fig.11, p.19]
  • Agents whose finding count is closest to actual vulnerability count score highest (quality > quantity) [Fig.5, p.8]

2021-2026 Incident Quick Reference

DateProjectLossAttack TypeRoot CauseSource
Oct 2021Cream Finance$130MFlash loan + oracleyUSD vault price manipulation via supply reductionrekt.news
Feb 2025Bybit$1.4BUI injection / supply chainSafe{Wallet} JS tampered via compromised dev machineNCC Group
Mar 2025Abracadabra$13MLogic flawState tracking error in cauldron liquidationHalborn
Jul 2025GMX v1$42MReentrancyGLP pool cross-contract reentrancy on ArbitrumHalborn
Sep 2025Bunni$8.4MFlash loan + roundingRounding direction error in withdraw, 44 micro-withdrawalsThe Block
Oct 2025Abracadabra #2$1.8MLogic flawcook() validation flag reset, uncollateralized MIM borrowHalborn
Jan 2026Step Finance$30MKey compromiseTreasury wallet private keys stolen via device breachHalborn
Jan 2026Truebit$26.4MLegacy contractSolidity 0.6.10 integer overflow in mint pricingCoinDesk
Jan 2026SagaEVM$7MSupply chain / bridgeInherited Ethermint precompile bridge vulnerabilityThe Block