Solidity audit
Skill ComeOnOliver/skillshub/skills/0xlayerghost/solidity-agent-kit/solidity-audit
π§ The right skill, one API call. AI agent skills registry with token-efficient skill resolution. 5,000+ skills from 500+ top repos.
npx -y skills add ComeOnOliver/skillshub --skill solidity-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
22.9 KB, as published. Nobody here has run it
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-auditwhen reviewing contracts for vulnerabilities.
Contract-Level Vulnerabilities
1. Reentrancy
| Variant | Description | Check |
|---|---|---|
| Same-function | Attacker re-enters the same function via fallback/receive | All external calls after state updates (CEI pattern)? |
| Cross-function | Attacker re-enters a different function sharing state | All functions touching shared state protected by nonReentrant? |
| Cross-contract | Attacker re-enters through a different contract that reads stale state | External contracts cannot read intermediate state? |
| Read-only | View function returns stale data during mid-execution state | No 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
| Check | Detail |
|---|---|
| Missing modifier | Every state-changing function has explicit access control? |
| Modifier logic | Modifier actually reverts on failure (not just empty check)? |
| State flag | Access-once patterns properly update storage after each user? |
| Admin privilege scope | Owner 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
| Check | Detail |
|---|---|
| Zero address | All address params reject address(0)? |
| Zero amount | Fund transfers reject zero amounts? |
| Array bounds | Paired arrays validated for matching length? |
| Arbitrary call | No unvalidated address.call(data) where attacker controls data? |
| Numeric bounds | Inputs bounded to prevent dust attacks or gas griefing? |
4. Flash Loan Attacks
| Variant | Mechanism | Defense |
|---|---|---|
| Price manipulation | Flash-borrow β swap to move price β exploit price-dependent logic β repay | TWAP oracle with min-liquidity check |
| Governance | Flash-borrow governance tokens β vote β repay in same block | Snapshot voting + minimum holding period + timelock β₯ 48h |
| Liquidation | Flash-borrow β manipulate collateral value β trigger liquidation | Multi-oracle price verification + circuit breaker |
| Combo (rounding) | Flash-borrow β manipulate pool β micro-withdrawals exploit rounding β repay | Minimum withdrawal amount + virtual shares |
Cases:
- Cream Finance (Oct 2021, $130M) β flash loan + yUSD oracle manipulation + missing reentrancy guard
- Abracadabra (Mar 2025, $13M) β state tracking error in cauldron, self-liquidation + bad loan
- Bunni (Sep 2025, $8.4M) β flash loan + pool price manipulation + rounding error micro-withdrawals
5. Oracle & Price
| Check | Detail |
|---|---|
| Single oracle dependency | Using multiple independent price sources? |
| Stale price | Checking updatedAt timestamp and rejecting old data? |
| Spot price usage | Never using raw AMM reserves for pricing? |
| Minimum liquidity | Oracle reverts if pool reserves below threshold? |
| Price deviation | Circuit breaker if price moves beyond threshold vs last known? |
| Chainlink round completeness | Checking 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
| Type | Description | Defense |
|---|---|---|
| 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
| Type | Description | Defense |
|---|---|---|
| ecrecover returns address(0) | Invalid sig returns address(0), not revert | Always check recovered != address(0) |
| Replay attack | Same signature reused across txs/chains | Include chainId + nonce + deadline in signed data |
| Signature malleability | ECDSA has two valid (s, v) pairs per signature | Use OpenZeppelin ECDSA.recover (enforces low-s) |
| Empty loop bypass | Signature verification in for-loop, attacker sends empty array | Check signatures.length >= requiredCount before loop |
| Missing msg.sender binding | Proof/signature not bound to caller | Always include msg.sender in signed/proven data |
8. ERC20 Compatibility
| Issue | Description | Defense |
|---|---|---|
| Fee-on-transfer | transfer(100) may deliver <100 tokens | Check balance before/after, use actual received amount |
| Rebase tokens | Token balances change without transfers | Never cache external balances; always read live |
| No bool return | Some tokens (USDT) don't return bool on transfer | Use SafeERC20.safeTransfer |
| ERC777 hooks | Transfer hooks can trigger reentrancy | Use ReentrancyGuard on all token-receiving functions |
| Zero-amount transfer | transferFrom(A, B, 0) β address poisoning | Reject zero-amount transfers |
| Approval race | Changing allowance from N to M allows spending N+M | Use safeIncreaseAllowance / safeDecreaseAllowance |
9. MEV / Front-Running
| Type | Description | Defense |
|---|---|---|
| Sandwich attack | Attacker front-runs buy + back-runs sell around victim | Slippage protection + deadline parameter |
| ERC4626 inflation | First depositor donates to inflate share price, rounding out later depositors | Minimum first deposit or virtual shares (ERC4626 with offset) |
| Approval front-run | Attacker spends old allowance before new allowance tx confirms | Use increaseAllowance not approve |
| Unrestricted withdrawal | Attacker monitors mempool for withdraw tx, front-runs with own | Require commit-reveal or auth binding |
10. Storage & Low-Level
| Issue | Description |
|---|---|
| Storage pointer | Foo storage foo = arr[0]; foo = arr[1]; β does NOT update arr[0] |
| Nested delete | delete structWithMapping β inner mapping data persists |
| Private variables | All contract storage is publicly readable via eth_getStorageAt |
| Unsafe delegatecall | Delegatecall to untrusted contract can selfdestruct the caller |
| Proxy storage collision | Upgrade changes parent order β variables overwrite each other (use storage gaps) |
| msg.value in loop | msg.value doesn't decrease in loop β enables double-spend |
11. Contract Detection Bypass
| Method | How it works |
|---|---|
| Constructor call | Attack from constructor β extcodesize == 0 during deployment |
| CREATE2 pre-compute | Pre-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
| Check | Detail |
|---|---|
_authorizeUpgrade access control | UUPS _authorizeUpgrade must have onlyOwner modifier? |
| Permissionless factory/registry | Can 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 compatibility | Upgrade-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
| Check | Detail |
|---|---|
| Cross-vault trust isolation | Registry/Router relay calls verify vault-level authorization? |
| Trusted sender abuse | Functions like sendTokensToTrustedAddress verify source vault, not just router identity? |
| Flash loan + routing combo | Can attacker use flash loan callback to make router impersonate arbitrary vault? |
| Collateral ownership verification | Liquidation/staking operations verify actual NFT/collateral owner? |
| Cross-contract state dependency | Multi-contract interactions free from intermediate state dependencies? |
Cases:
- Code4rena 2024-04-noya H-08 (via EVMbench Paper Β§4.2.1, Fig.6, p.8-9) β PositionRegistry + BalancerFlashLoan pipeline lacked vault-level auth; keeper used flash loan to make router impersonate any vault, draining cross-vault funds via
sendTokensToTrustedAddress - Code4rena 2024-07-benddao (via EVMbench Paper Fig.13, p.19) β
isolateLiquidatedid not verify NFT ownership, allowing attacker to pass others' tokenIds for liquidation
14. State Ordering & Counter Manipulation
Source: EVMbench Paper Appendix H.1, Fig.19-21 / Code4rena 2024-08-phi H-06
| Check | Detail |
|---|---|
| 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 timing | ETH refund (excess) happens after all state updates complete? |
| Bonding curve metadata overwrite | Can 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
| Check | Detail |
|---|---|
| Inherited code | Audit all bridge logic inherited from third-party frameworks |
| Message verification | Cross-chain messages validated with proper signatures and replay protection? |
| Liquidity isolation | Bridge 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.
Automated Analysis with Slither MCP (if available)
When slither MCP is configured, run automated analysis BEFORE the manual checklist below:
Recommended Audit Flow
Step 1: slither MCP automated scan
β get_detector_results(path, impact="High")
β get_detector_results(path, impact="Medium")
Step 2: Review Slither findings β triage true positives vs false positives
Step 3: Manual checklist below β catch what Slither misses (business logic, economic attacks)
Step 4: Cross-reference β Slither + manual findings combined into final report
Slither MCP Tools
| Tool | Usage | Complements |
|---|---|---|
get_contract_metadata | Extract functions, inheritance, flags | Manual access control review |
get_function_source | Get exact source code with line numbers | Faster than grep for locating code |
find_implementations | Find all implementations of a function signature | Cross-contract reentrancy analysis |
get_detector_results | Run 90+ security detectors, filter by impact/confidence | Automated version of manual checklist |
get_detector_metadata | List available detectors with descriptions | Understanding what's being checked |
What Slither Catches vs What It Misses
| Slither Catches Well | Manual Review Still Needed |
|---|---|
| Reentrancy patterns | Business logic flaws |
| Unprotected functions | Economic attack vectors (flash loan combos) |
| Unused state variables | Cross-protocol composability risks |
| Shadowing issues | Oracle manipulation scenarios |
| Incorrect ERC20 interface | Trust boundary architecture issues |
| Dead code | MEV/front-running specific to business logic |
Key Principle: Slither provides ground truth via static analysis β reduces false negatives on known vulnerability patterns. But it cannot reason about protocol-level economic attacks β that's where the manual checklist below is essential.
Graceful degradation: If slither MCP is not configured, skip this section and proceed directly to the manual checklist. All checklist items remain valid and self-contained.
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.originfor 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:
-
ecrecoverresult checked againstaddress(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
_authorizeUpgradehasonlyOwnerβ [EVMbench/basin H-01] -
upgradeTo/upgradeToAndCallretainsonlyProxyβ [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
- Coverage over depth: scan ALL in-scope files; do not stop after finding the first vulnerability [EVMbench Β§5, p.10]
- Three-phase audit: Detect (identify vulnerabilities) -> Patch (write fix) -> Exploit (build PoC) [EVMbench Β§3.2, p.5]
- Incremental output: write findings continuously during audit to preserve progress [EVMbench Appendix G, Fig.18, p.24]
- Systematic category scan: check by vulnerability class (reentrancy, access control, numerical, oracle...) rather than intuition [EVMbench Β§3.1, p.4]
- 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
| Date | Project | Loss | Attack Type | Root Cause | Source |
|---|---|---|---|---|---|
| Oct 2021 | Cream Finance | $130M | Flash loan + oracle | yUSD vault price manipulation via supply reduction | rekt.news |
| Feb 2025 | Bybit | $1.4B | UI injection / supply chain | Safe{Wallet} JS tampered via compromised dev machine | NCC Group |
| Mar 2025 | Abracadabra | $13M | Logic flaw | State tracking error in cauldron liquidation | Halborn |
| Jul 2025 | GMX v1 | $42M | Reentrancy | GLP pool cross-contract reentrancy on Arbitrum | Halborn |
| Sep 2025 | Bunni | $8.4M | Flash loan + rounding | Rounding direction error in withdraw, 44 micro-withdrawals | The Block |
| Oct 2025 | Abracadabra #2 | $1.8M | Logic flaw | cook() validation flag reset, uncollateralized MIM borrow | Halborn |
| Jan 2026 | Step Finance | $30M | Key compromise | Treasury wallet private keys stolen via device breach | Halborn |
| Jan 2026 | Truebit | $26.4M | Legacy contract | Solidity 0.6.10 integer overflow in mint pricing | CoinDesk |
| Jan 2026 | SagaEVM | $7M | Supply chain / bridge | Inherited Ethermint precompile bridge vulnerability | The Block |