Install
$ agentstack add skill-0xlayerghost-solidity-agent-kit-solidity-audit ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →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) — 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 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.
15. Per-Address State Bypass
> Any restriction based on mapping(address => ...) can be circumvented by multi-address splitting or intermediate transfer.
| Restriction Type | Bypass Method | Defense | |---|---|---| | Cooldown (_lastTxTime[addr]) | A buys → transfers to B → B sells immediately | Inherit sender's cooldown on transfer: _lastTxTime[to] = _lastTxTime[from] | | Max tx amount (maxTxAmount) | Split across N addresses, each within limit | Also limit by tx.origin per block, or accept as known tradeoff | | Max wallet balance (maxWalletBalance) | Distribute tokens to multiple wallets controlled by same entity | Inherently hard to enforce on-chain; monitor off-chain | | Same-block protection (_lastTxBlock[addr]) | Use different addresses in same block | Inherit sender's block: _lastTxBlock[to] = _lastTxBlock[from] | | Trade count limit | Rotate addresses, each uses one trade | Same as cooldown — propagate state on transfer |
Audit Methodology (3 Steps):
- Identify all per-address state: Search
mapping(address =>— for each, ask: "Can this be bypassed by switching addresses?" - Trace all token flow paths: Map every path tokens can move (buy, sell, transfer, mint). Check if each path updates the restriction state. The wallet-to-wallet transfer path is the most commonly overlooked.
- Check state transitivity: If A has restriction state and transfers tokens to B, does B inherit that state? If not, it's a bypass vulnerability.
Defense Principle: Token flow carries restriction state — wherever tokens go, the relevant per-address state must follow.
Two Common Pitfalls:
- Griefing via
block.timestamp: Using_lastTxTime[to] = block.timestampallows anyone to grief a target by sending dust tokens, resetting cooldown. Use sender's state instead. - Overwrite via direct assignment: Using
_lastTxTime[to] = _lastTxTime[from]allows a near-expired sender to shorten receiver's existing cooldown. Usemax:if (_lastTxTime[from] > _lastTxTime[to]) _lastTxTime[to] = _lastTxTime[from]— only extends, never shortens.
Infrastructure-Level Vulnerabilities
16. 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.
17. 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.
18. 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.
19. 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
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: 0xlayerghost
- Source: 0xlayerghost/solidity-agent-kit
- License: MIT
- Homepage: https://skills.sh/0xlayerghost/solidity-agent-kit/solidity-coding
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.