SkillHub

solidity-audit-precheck

v1.0.1

Automated pre-audit checklist for Solidity smart contracts. Runs SWC registry scan, OpenZeppelin pattern validation, gas optimization suggestions, and common vulnerability detection before sending contracts to a paid manual audit. Reduces audit cost and scope by catching low-hanging fruit automatica...

Sourced from ClawHub, Authored by samledger67-dotcom

Installation

Please help me install the skill `solidity-audit-precheck` from SkillHub official store. npx skills add samledger67-dotcom/solidity-audit-precheck

Solidity Audit Pre-Check Skill

Automated security pre-flight for Solidity contracts. Catches common vulnerabilities, validates OpenZeppelin usage, and surfaces gas inefficiencies — before you pay $20k+ for a manual audit.

When to Use

  • Before submitting contracts to a paid auditor (Trail of Bits, Certik, Spearbit, etc.)
  • After writing a new contract feature or major refactor
  • During internal review of a PR that touches contract code
  • When onboarding a new contract codebase to understand risk surface
  • Pre-deployment to mainnet or any public testnet

When NOT to Use

  • As a replacement for a manual audit. This is a pre-filter, not a security guarantee.
  • For non-Solidity contracts (Rust/Anchor, Cairo, Stylus — use language-specific tools)
  • For already-deployed and immutable contracts (nothing actionable)
  • For frontend/UI code or off-chain scripts
  • As a compliance certification — automated tools have known false negative rates

Toolchain Setup

Install required CLI tools:

# Slither — most complete static analyzer
pip install slither-analyzer

# Mythril — symbolic execution / SMT-based analysis
pip install mythril

# Foundry (forge, cast, anvil) — for testing and gas snapshots
curl -L https://foundry.paradigm.xyz | bash && foundryup

# Solhint — linter for style and security rules
npm install -g solhint

# Aderyn — Rust-based Solidity AST analyzer (fast)
cargo install aderyn

Verify:

slither --version
myth version
forge --version
solhint --version
aderyn --version

Pre-Check Workflow

Step 1 — Inventory the Codebase

# Count contracts, identify external deps
find . -name "*.sol" | head -50
cat foundry.toml   # or hardhat.config.ts
cat remappings.txt

# Identify entry points (deployed contracts vs libraries/interfaces)
grep -r "contract " src/ --include="*.sol" | grep -v "interface|abstract|library"

Key questions: - How many contracts? How many are deployed vs inherited? - What OpenZeppelin version? (lib/openzeppelin-contracts/package.json) - External protocols used? (Uniswap, Aave, Chainlink, etc.) - Upgradeability pattern? (UUPS, Transparent Proxy, Beacon, none)


Step 2 — Slither Static Analysis

# Full scan with all detectors
slither . --checklist --markdown-root .

# JSON output for structured review
slither . --json slither-output.json

# Print human-readable summary
slither . --print human-summary

# Filter by severity
slither . --filter-paths "lib/,node_modules/" --exclude-low

Severity levels: | Level | Action | |-------|--------| | High | Block deployment — fix before audit | | Medium | Must address — provide justification if not fixed | | Low | Fix or document rationale | | Informational | Style/gas — address in optimization pass |

Common high-severity detectors to watch: - reentrancy-eth — reentrant Ether transfers - unchecked-transfer — ERC20 transfer without return value check - arbitrary-send-eth — unrestricted ETH send - controlled-delegatecall — attacker-controlled delegatecall - suicidal — selfdestruct reachable by anyone - tx-origin — tx.origin used for auth


Step 3 — Mythril Symbolic Execution

# Analyze single contract (slower, deeper)
myth analyze contracts/MyContract.sol --solc-json mythril-config.json

# With timeout for large contracts
myth analyze contracts/MyContract.sol --execution-timeout 120 --max-depth 12

# Output as JSON
myth analyze contracts/MyContract.sol -o json

Mythril catches: - Integer overflow/underflow (pre-0.8.x contracts) - Reentrancy via symbolic paths - Delegatecall to user-supplied addresses - Unprotected selfdestruct - Dependence on predictable values (block.timestamp, blockhash)


Step 4 — Aderyn AST Analysis

# Run from project root
aderyn .

# Output markdown report
aderyn . --output report.md

# Target specific directory
aderyn src/ --output aderyn-report.md

Aderyn is fast (sub-second on most codebases) and catches: - Centralization risk (single owner controls) - Missing events on state changes - Unsafe ERC20 operations - Weak access control patterns - Incorrect inheritance order


Step 5 — Solhint Linting

# Init config
solhint --init

# Lint all contracts
solhint 'contracts/**/*.sol'

# Use security ruleset
solhint --config .solhint.json 'contracts/**/*.sol'

Recommended .solhint.json:

{
  "extends": "solhint:recommended",
  "rules": {
    "avoid-call-value": "error",
    "avoid-low-level-calls": "warn",
    "avoid-tx-origin": "error",
    "check-send-result": "error",
    "compiler-version": ["error", "^0.8.20"],
    "func-visibility": ["warn", {"ignoreConstructors": true}],
    "mark-callable-contracts": "error",
    "multiple-sends": "error",
    "no-complex-fallback": "error",
    "no-inline-assembly": "warn",
    "not-rely-on-block-hash": "error",
    "not-rely-on-time": "warn",
    "reentrancy": "error",
    "state-visibility": "error"
  }
}

Step 6 — OpenZeppelin Pattern Validation

Manual checklist — verify each applies:

# Check OZ version
cat lib/openzeppelin-contracts/package.json | grep '"version"'

# Find all inherited OZ contracts
grep -r "import.*openzeppelin" contracts/ --include="*.sol"

Access Control: - [ ] Ownable2Step used instead of Ownable (prevents accidental ownership transfer) - [ ] AccessControl roles defined with keccak256 constants, not inline strings - [ ] DEFAULT_ADMIN_ROLE not held by an EOA in production (use multisig) - [ ] renounceRole and revokeRole tested for edge cases

Tokens (ERC20/ERC721): - [ ] SafeERC20.safeTransfer used for all external token transfers - [ ] _safeMint used in ERC721 (not _mint) - [ ] Callback hooks (onERC721Received) handled - [ ] Reentrancy guard on any function that calls external contracts after state change

Upgradeability: - [ ] Initializers called correctly (no constructor logic in upgradeable contracts) - [ ] _disableInitializers() called in implementation constructor - [ ] Storage gaps defined in all base contracts - [ ] ERC-7201 namespaced storage used (OZ v5+) - [ ] No storage collisions between proxy and implementation

Pausability: - [ ] Pausable integrated with whenNotPaused on critical functions - [ ] pause() protected by role (not public) - [ ] Emergency unpause path defined and tested


Step 7 — Gas Optimization Audit

# Forge gas snapshot baseline
forge snapshot

# Gas report per function
forge test --gas-report

# Compare before/after optimization
forge snapshot --diff .gas-snapshot

Common gas optimizations to flag:

Pattern Issue Fix
uint256 i = 0 in loop Wastes gas uint256 i (zero default)
storage variable read in loop SLOAD per iteration Cache in memory first
require(condition, "long string") String costs gas Use custom errors
Multiple mappings vs struct Extra SLOADs Pack into struct
public on internal functions Extra ABI overhead internal or private
Unbounded loops DoS risk + gas Add maxIterations param
transfer() / send() 2300 gas limit Use call{value: x}("")

Custom error pattern (saves ~50 gas per revert):

// Bad
require(balance >= amount, "Insufficient balance");

// Good
error InsufficientBalance(uint256 balance, uint256 required);
if (balance < amount) revert InsufficientBalance(balance, amount);

Step 8 — SWC Registry Cross-Reference

Cross-check findings against SWC Registry:

SWC Name Slither Detector Severity
SWC-100 Function Default Visibility suicidal, controlled-selfdestruct High
SWC-101 Integer Overflow/Underflow integer-overflow High (pre-0.8.x)
SWC-104 Unchecked Call Return Value unchecked-transfer High
SWC-105 Unprotected Ether Withdrawal arbitrary-send-eth High
SWC-106 Unprotected SELFDESTRUCT suicidal High
SWC-107 Reentrancy reentrancy-eth, reentrancy-no-eth High/Med
SWC-111 Use of Deprecated Functions deprecated-standards Med
SWC-112 Delegate Call to Untrusted Callee controlled-delegatecall High
SWC-115 Authorization via tx.origin tx-origin High
SWC-116 Block values as time proxy weak-prng, block-timestamp Low/Med
SWC-120 Weak Sources of Randomness weak-prng High
SWC-128 DoS With Block Gas Limit costly-loop Med

Step 9 — Manual Review Checklist

Items automated tools miss — must be done by human:

Business Logic: - [ ] Economic invariants hold (balances sum to total supply, etc.) - [ ] State machine transitions are complete and non-overlapping - [ ] Off-by-one errors in fee/slippage calculations - [ ] Rounding direction favors protocol, not attacker (round down for user, up for protocol) - [ ] Flash loan attack surface: any function callable within a single tx that can drain funds?

Access Control Logic: - [ ] Every privileged function has a role check - [ ] Role assignments tested for separation of duties - [ ] Time locks on critical parameter changes (fee changes, oracle updates)

Oracle / Price Feed: - [ ] Chainlink feeds: stale data check (updatedAt + heartbeat) - [ ] Chainlink feeds: min/max circuit breakers handled - [ ] TWAP used instead of spot price for large positions - [ ] No single-source price oracle

Proxy Patterns: - [ ] Proxy admin is a multisig, not an EOA - [ ] Implementation cannot be initialized by attacker - [ ] selfdestruct in implementation would brick proxy — is it present?


Step 10 — Pre-Audit Report Template

Generate a structured handoff document for the audit team:

# Pre-Audit Report: [Contract Name]
Date: YYYY-MM-DD
Audited by: [Team]
Commit: [git hash]

## Scope
- Contracts: [list]
- Out of scope: [list]
- Solidity version: [version]
- OZ version: [version]

## Automated Scan Results
### Slither
- High: [N] findings
- Medium: [N] findings
- [Link to slither-output.json]

### Mythril
- [N] issues found
- [Summary]

### Aderyn
- [N] issues found

## Known Issues (Won't Fix)
- [Issue]: [Rationale]

## Fixed Issues (Pre-Audit)
- [Issue]: [Fix applied, commit hash]

## Gas Baseline
- forge snapshot attached
- Estimated deployment cost: [N] ETH at [gwei] gwei

## Areas of Concern for Auditors
- [Specific complex logic to focus on]
- [External protocol integrations]
- [Novel patterns used]

## Test Coverage
forge coverage output:
[paste output]

Example: Full Pre-Check Run

#!/bin/bash
# precheck.sh — run from project root

echo "=== Solidity Audit Pre-Check ==="
echo "Date: $(date)"
echo "Commit: $(git rev-parse --short HEAD)"

mkdir -p audit-precheck

echo "n[1/5] Slither..."
slither . --filter-paths "lib/,node_modules/" 
  --json audit-precheck/slither.json 
  --markdown-root . 2>&1 | tee audit-precheck/slither.log

echo "n[2/5] Aderyn..."
aderyn . --output audit-precheck/aderyn.md

echo "n[3/5] Solhint..."
solhint 'contracts/**/*.sol' > audit-precheck/solhint.log 2>&1

echo "n[4/5] Forge gas snapshot..."
forge snapshot --snap audit-precheck/.gas-snapshot

echo "n[5/5] Forge coverage..."
forge coverage --report lcov > audit-precheck/coverage.log 2>&1

echo "nPre-check complete. Results in ./audit-precheck/"
echo "Run: cat audit-precheck/slither.log | grep 'Impact|Result'"

Integration with Other Skills

  • develop-secure-contracts — Use to integrate OpenZeppelin patterns that this skill validates
  • upgrade-solidity-contracts — Pre-check upgradeable proxies before upgrade
  • ethskills — General Ethereum dev context and deployment patterns
  • erc20-tokenomics-builder — Pre-check token contracts built with this skill

Severity Thresholds for Deployment Go/No-Go

Severity Count Decision
Critical/High Any Block — do not deploy
Medium > 3 Block — audit required
Medium 1-3 Mitigate or justify in writing
Low Any Document and accept or fix
Informational Any Fix in optimization pass

A clean pre-check (zero High/Critical, documented Mediums) typically reduces manual audit time by 30-50% and audit cost by 20-40%.