# 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.

- **Type:** Skill
- **Install:** `agentstack add skill-comeonoliver-skillshub-solidity-audit`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ComeOnOliver](https://agentstack.voostack.com/s/comeonoliver)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ComeOnOliver](https://github.com/ComeOnOliver)
- **Source:** https://github.com/ComeOnOliver/skillshub/tree/main/skills/0xlayerghost/solidity-agent-kit/solidity-audit
- **Website:** https://skillshub.wtf

## Install

```sh
agentstack add skill-comeonoliver-skillshub-solidity-audit
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 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

| 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)](https://www.halborn.com/blog/post/explained-the-gmx-hack-july-2025) — 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)](https://www.halborn.com/blog/post/explained-the-bybit-hack-february-2025) — 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)](https://rekt.news/cream-rekt-2/) — flash loan + yUSD oracle manipulation + missing reentrancy guard
- [Abracadabra (Mar 2025, $13M)](https://www.halborn.com/blog/post/explained-the-abracadabra-money-hack-march-2025) — state tracking error in cauldron, self-liquidation + bad loan
- [Bunni (Sep 2025, $8.4M)](https://www.theblock.co/post/369564/bunni-smart-contract-rounding-error) — 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)](https://rekt.news/cream-rekt-2/) — 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)](https://www.halborn.com/blog/post/explained-the-bunni-hack-september-2025) — 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  Source: [EVMbench Paper §4.2, Appendix H](https://cdn.openai.com/evmbench/evmbench.pdf) / [Code4rena 2024-07-basin H-01](https://code4rena.com/reports/2024-07-basin)

| 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](https://code4rena.com/reports/2024-07-basin) (via [EVMbench Paper Fig.12, p.19](https://cdn.openai.com/evmbench/evmbench.pdf)) — `_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](https://cdn.openai.com/evmbench/evmbench.pdf) / Code4rena [2024-04-noya H-08](https://code4rena.com/reports/2024-04-noya), [2024-07-benddao](https://code4rena.com/reports/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](https://code4rena.com/reports/2024-04-noya) (via [EVMbench Paper §4.2.1, Fig.6, p.8-9](https://cdn.openai.com/evmbench/evmbench.pdf)) — 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](https://code4rena.com/reports/2024-07-benddao) (via [EVMbench Paper Fig.13, p.19](https://cdn.openai.com/evmbench/evmbench.pdf)) — `isolateLiquidate` did 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](https://cdn.openai.com/evmbench/evmbench.pdf) / [Code4rena 2024-08-phi H-06](https://code4rena.com/reports/2024-08-phi)

| 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](https://code4rena.com/reports/2024-08-phi) (via [EVMbench Paper Appendix H.1, p.25-28](https://cdn.openai.com/evmbench/evmbench.pdf)) — `_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)](https://www.nccgroup.com/research-blog/in-depth-technical-analysis-of-the-bybit-hack/) — 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)](https://www.halborn.com/blog/post/explained-the-step-finance-hack-january-2026) — 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)](https://www.theblock.co/post/386638/sagaevm-suffers-exploit) — 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)](https://www.coindesk.com/markets/2026/01/09/truebit-token-tru-crashes-99-9-after-usd26-6m-exploit-drains-8-535-eth) — 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.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](https://cdn.openai.com/evmbench/evmbench.pdf)):**
- [ ] 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](https://cdn.openai.com/evmbench/evmbench.pdf)):**
- [ ] Router/Registry relay calls verify source vault/contract authorization — [EVMbench/noya H-08]
- [ ] Liquidat

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ComeOnOliver](https://github.com/ComeOnOliver)
- **Source:** [ComeOnOliver/skillshub](https://github.com/ComeOnOliver/skillshub)
- **License:** MIT
- **Homepage:** https://skillshub.wtf

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-comeonoliver-skillshub-solidity-audit
- Seller: https://agentstack.voostack.com/s/comeonoliver
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
