1---2name: solidity-scanner3description: Use when the user wants to audit Solidity smart contracts for security vulnerabilities, scan EVM-compatible contracts for reentrancy, oracle manipulation, access-control, or flash-loan issues, review DeFi protocols on Ethereum, Arbitrum, Optimism, Base, Polygon, or BSC, or generate security audit reports for smart contract deployments.4---56# Solidity Scanner Skill78## Purpose910Analyze Solidity smart contracts for security vulnerabilities across all EVM-compatible chains. This is the primary scanner for the most widely-deployed smart contract language, covering DeFi, NFTs, governance, bridges, and all Ethereum-ecosystem protocols.1112## Supported Chains1314| Chain | EVM Compatibility | Key Differences |15|---|---|---|16| Ethereum | Full | Baseline — all patterns apply |17| Arbitrum | Full | L2 sequencer risk, `block.number` returns L1 block, gas pricing differs |18| Optimism / Base | Full | L2 sequencer risk, `TIMESTAMP` from L1, cross-domain messaging |19| Polygon | Full | Different gas token (MATIC), PoS consensus, reorg risk higher |20| BSC | Full | Lower gas costs enable different attack economics |21| Avalanche | Full | Subnet awareness, different finality model |22| Scroll | Full | zkEVM — some precompile differences |23| Linea | Full | zkEVM — some opcode cost differences |24| zkSync Era | Partial | Different address derivation, no `SELFDESTRUCT`, custom deployment model |25| Blast | Full | Native yield — `WETH.balance()` increases, rebasing assumptions |2627### Chain-Specific Audit Considerations2829When auditing for a specific chain, check these additional concerns:3031```32Arbitrum/Optimism:33 ├── Sequencer downtime → oracle stale price risk34 ├── L1-to-L2 message delay → bridge timing attacks35 └── block.number semantics differ from L13637zkSync Era:38 ├── msg.value behaves differently in system contracts39 ├── Contract deployment uses CREATE2-like hash, not CREATE40 ├── Some opcodes unavailable or priced differently41 └── Native account abstraction changes tx.origin semantics4243Blast:44 ├── ETH and USDB are rebasing tokens by default45 ├── Protocol must explicitly configure yield mode46 └── balanceOf(address) can change between transactions without transfers47```4849## Detection Capabilities5051### Critical / High Severity5253| Category | Specific Patterns | Detection Method |54|---|---|---|55| **Reentrancy** | Classic single-function, cross-function, cross-contract, read-only, ERC777 callback, ERC721 callback | State write after external call analysis |56| **Access control** | Missing modifiers, `tx.origin` auth, unprotected `initialize()`, unprotected `selfdestruct`, privilege escalation | Public/external function modifier scan |57| **Unsafe external calls** | Unchecked `transfer()` return, unchecked low-level call, unchecked `approve()`, USDT non-standard behavior | Return value tracking |58| **Oracle manipulation** | Uniswap V2/V3 spot price, missing Chainlink staleness check, reserve-based pricing, circular pricing | Oracle usage pattern matching |59| **Flash loan vectors** | Balance-based pricing, single-tx manipulation, donation attacks | Balance-as-input detection |60| **Proxy vulnerabilities** | Uninitialized impl, storage collision, missing `_disableInitializers()`, UUPS auth bypass | Proxy pattern recognition |6162### Medium Severity6364| Category | Specific Patterns | Detection Method |65|---|---|---|66| **Integer issues** | Unsafe downcast, truncation on assignment, rounding errors in share math, first depositor inflation | `SafeCast` absence, division analysis |67| **Token handling** | Fee-on-transfer incompatibility, rebasing token assumption, non-standard decimals, approve race condition | Token interaction pattern scan |68| **MEV exposure** | Missing deadline, missing slippage protection, sandwich vulnerability, permit front-running | Swap/router call analysis |69| **Centralization** | Untimelocked admin powers, excessive owner privileges, upgradeable without governance | Admin function audit |70| **Signature issues** | Missing nonce, missing chainId, missing deadline, ecrecover zero-address, malleable signatures | Signature verification scan |71| **DoS vectors** | Unbounded loops, external call revert in batch, force-sent ETH breaking balance checks | Loop and batch analysis |7273### Low / Informational7475| Category | Specific Patterns |76|---|---|77| **Gas optimization** | Storage vs memory, redundant SLOADs, unchecked math for bounded loops, calldata vs memory |78| **Code quality** | Missing events, missing NatSpec, unused variables, floating pragma, unlocked compiler |79| **Best practices** | `block.timestamp` dependency, missing zero-address checks, magic numbers, missing error messages |8081## Compiler Version Awareness8283| Solidity Version | Key Security Considerations |84|---|---|85| < 0.8.0 | No built-in overflow protection — check for SafeMath usage |86| 0.8.0–0.8.12 | Built-in overflow but `unchecked` blocks bypass it — audit all `unchecked` usage |87| 0.8.13–0.8.14 | ABI encoder bug with nested arrays (fixed in 0.8.15) |88| 0.8.15–0.8.19 | Optimizer bug with `Yul` code (fixed in 0.8.20) |89| 0.8.20+ | Default EVM target = Shanghai (`PUSH0`) — may not deploy on all L2s |90| 0.8.24+ | Transient storage (`TSTORE`/`TLOAD`) available — new reentrancy guard patterns |91| 0.8.26+ | Custom storage layouts, event errors in interfaces |9293## Workflows9495| Workflow | Duration | Best For | Link |96|---|---|---|---|97| Quick Scan | 15–20 min | Triage, contest warm-up, initial assessment | [quick-scan.md](workflows/quick-scan.md) |98| Comprehensive Audit | 3–5 days | Protocol launch, client engagement, major upgrade | [comprehensive-audit.md](workflows/comprehensive-audit.md) |99| Competitive Audit | 8–16 hours | Code4rena, Sherlock, CodeHawks contests | [competitive-audit.md](workflows/competitive-audit.md) |100101## Resources102103| Resource | Purpose | Link |104|---|---|---|105| Vulnerability Patterns | Complete pattern catalog with code examples | [vulnerability-patterns.md](resources/vulnerability-patterns.md) |106| Severity Guide | Classification criteria with decision tree | [severity-guide.md](resources/severity-guide.md) |107| Tool Configs | Slither, Aderyn, Mythril, Semgrep setup | [tool-configs.md](resources/tool-configs.md) |108| False Positives | Common FPs with reasoning for each | [false-positives.md](resources/false-positives.md) |109| Foundry Security | 10 vulnerability categories with Foundry PoC tests | [foundry-security.md](resources/foundry-security.md) |110| Foundry Testing | Fuzz, invariant, fork, differential testing guide | [foundry-testing.md](resources/foundry-testing.md) |111| Foundry Cheatcodes | 150+ cheatcodes reference for security auditors | [foundry-cheatcodes.md](resources/foundry-cheatcodes.md) |112| Gas & Security | Gas optimization patterns with security trade-offs | [gas-security.md](resources/gas-security.md) |113| Foundry CI/CD | GitHub Actions for automated security testing | [foundry-ci-cd.md](resources/foundry-ci-cd.md) |114115## Standard Audit Procedure116117```1181. Load Solidity contract(s) and note compiler version1192. Map inheritance tree and external dependencies1203. Identify protocol type (DeFi, NFT, governance, bridge, etc.)1214. Select workflow based on engagement type1225. Run static analysis tools (Slither → Aderyn → Mythril)1236. Execute manual review per methodology1247. Classify each finding with severity guide1258. Run variant analysis on confirmed findings1269. Generate structured report127```128129## Integration with Other Skills130131| Skill | How Solidity Scanner Uses It |132|---|---|133| `methodology/` | Provides the audit methodology framework (phases, timing, approach) |134| `severity/` | Classifies each finding into Critical/High/Medium/Low |135| `scoring/` | Scores overall protocol security posture |136| `checklists/` | Protocol-specific security checklists (ERC-20, vault, AMM, etc.) |137| `patterns/` | Vulnerability pattern database for cross-reference |138| `variant-analysis/` | When one bug is found, hunt for all variants |139| `static-analysis/` | Tool configuration and integration |140| `exploit-forensics/` | Real-world exploit case studies for pattern awareness |141| `fix-review/` | Verify proposed fixes after initial audit |142| `differential-review/` | Compare upgraded contract versions |143| `chain-guides/` | Chain-specific considerations when target != Ethereum mainnet |144145## Error Code Reference146147Common Solidity/EVM error selectors and revert reasons encountered during audits. Use a selector decoder like [openchain.xyz](https://openchain.xyz/signatures) or [4byte.directory](https://www.4byte.directory/) to identify unknown selectors.148149### OpenZeppelin Standard Errors150151| Error Selector | Error Signature | Meaning |152|----------------|----------------|----------|153| `0xe450d38c` | `ERC20InsufficientBalance(address,uint256,uint256)` | Token balance too low for transfer |154| `0xfb8f41b2` | `ERC20InsufficientAllowance(address,uint256,uint256)` | Allowance too low for transferFrom |155| `0x118cdaa7` | `OwnableUnauthorizedAccount(address)` | Caller is not the owner |156| `0x1e4fbdf7` | `OwnableInvalidOwner(address)` | Invalid owner address (e.g., zero address) |157| `0xe602df05` | `ERC20InvalidApprover(address)` | Invalid address for approve |158| `0x94280d62` | `ERC20InvalidReceiver(address)` | Invalid receiver (zero address) |159| `0xd93c0665` | `EnforcedPause()` | Contract is paused |160| `0x8dfc202b` | `ExpectedPause()` | Contract is NOT paused (expected to be) |161| `0xa9fbf51f` | `AccessControlUnauthorizedAccount(address,bytes32)` | Missing role for access control |162| `0xd92e233d` | `ZeroAddress()` | Zero address provided where not allowed |163164### ERC Standard Errors165166| Error Selector | Error Signature | Meaning |167|----------------|----------------|----------|168| `0x7e273289` | `ERC721NonexistentToken(uint256)` | Token ID does not exist |169| `0x177e802f` | `ERC721InsufficientApproval(address,uint256)` | Not approved for token operation |170| `0x64283d7b` | `ERC721IncorrectOwner(address,uint256,address)` | Token not owned by expected address |171| `0xf0dd15fd` | `ERC4626ExceededMaxDeposit(address,uint256,uint256)` | Deposit exceeds vault max |172| `0x936941fc` | `ERC4626ExceededMaxRedeem(address,uint256,uint256)` | Redeem exceeds vault max |173174### Common Revert Reasons (String)175176| Revert String | Typical Source | Audit Significance |177|--------------|---------------|--------------------|178| `"ReentrancyGuard: reentrant call"` | OpenZeppelin ReentrancyGuard | Guard is active — check if all entry points are protected |179| `"Initializable: contract is already initialized"` | OZ proxy initializer | Re-initialization attempt — check `_disableInitializers()` |180| `"Address: low-level call failed"` | OZ Address library | External call failure — check error handling |181| `"SafeERC20: low-level call failed"` | OZ SafeERC20 | Token transfer failure — may indicate non-standard token |182| `"Pausable: paused"` / `"Pausable: not paused"` | OZ Pausable | Pause state mismatch — check centralization risk |183| `"ECDSA: invalid signature"` | OZ ECDSA | Signature verification failed — check for malleable sigs |184| `"ERC20: transfer amount exceeds balance"` | OZ ERC20 (pre-custom-errors) | Insufficient balance — older OZ version indicator |185186### Proxy-Related Errors187188| Error Selector | Error Signature | Meaning |189|----------------|----------------|----------|190| `0xb398979f` | `ERC1967InvalidImplementation(address)` | Invalid implementation address for proxy |191| `0x4c9c8ce3` | `ERC1967InvalidAdmin(address)` | Invalid admin address for transparent proxy |192| `0x7e2732890` | `ERC1967NonPayable()` | Proxy received ETH when not expected |193| `0xf92ee8a9` | `InvalidInitialization()` | OZ v5 Initializable — already initialized |194| `0xd7e6bcf8` | `NotInitializing()` | OZ v5 Initializable — not in initializing state |195196## Troubleshooting197198| Issue | Likely Cause | Solution |199|-------|-------------|----------|200| Scanner loads generic patterns instead of Solidity-specific | Trigger phrases not matching the Solidity scanner | Verify `triggers` field in frontmatter matches user query; check TRIGGERS.md mapping |201| False positives on `unchecked` blocks | Scanner flags all unchecked math as unsafe | Check Solidity version — 0.8.x+ has built-in overflow; `unchecked` in bounded loops is safe |202| Missed reentrancy in cross-contract calls | Scanner only checks single-function reentrancy | Enable cross-contract analysis mode; load `patterns/` for read-only reentrancy patterns |203| Oracle manipulation not detected | Protocol uses custom oracle not matching known patterns | Manually check any `balanceOf()` or reserve-based pricing; add custom oracle pattern |204| L2-specific issues not flagged | Chain-specific guide not loaded | Load the appropriate `chain-guides/` file for the target L2 before scanning |205| Proxy storage collision missed | Scanner doesn't map storage layouts across proxy/impl | Use `differential-review/` skill to compare storage layouts; check for `_gap` variables |206| Too many low-severity findings | Scanning in paranoid mode | Switch to "Standard" scan profile; filter informational findings for final report |