skills/solidity-security/SKILL.md
[AUTO-INVOKE] MUST be invoked BEFORE writing or modifying any Solidity contract (.sol files). Covers private key handling, access control, reentrancy prevention, gas safety, and pre-audit checklists. Trigger: any task involving creating, editing, or reviewing .sol source files.
npx skillsauth add 0xlayerghost/solidity-agent-kit solidity-securityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
.env, load via source .env — never pass keys as CLI arguments.env.example with placeholder values for team reference.env to .gitignore — verify with git status before every commitWhen writing or reviewing Solidity code, apply these rules:
| Situation | Required Action |
|-----------|----------------|
| External ETH/token transfer | Use ReentrancyGuard + Checks-Effects-Interactions (CEI) pattern |
| ERC20 token interaction | Use SafeERC20 — call safeTransfer / safeTransferFrom, never raw transfer / transferFrom |
| Owner-only function | Inherit Ownable2Step (preferred) or Ownable from OZ 4.9.x — Ownable2Step prevents accidental owner loss |
| Multi-role access | Use AccessControl from @openzeppelin/contracts/access/AccessControl.sol |
| Token approval | Use safeIncreaseAllowance / safeDecreaseAllowance from SafeERC20 — never raw approve |
| Price data needed | Use Chainlink AggregatorV3Interface if feed exists; otherwise TWAP with min-liquidity check — never use spot pool price directly |
| Upgradeable contract | Prefer UUPS (UUPSUpgradeable) over TransparentProxy; always use Initializable |
| Solidity version < 0.8.0 | Must use SafeMath — but strongly prefer upgrading to 0.8.20+ |
| Emergency scenario | Inherit Pausable, add whenNotPaused to user-facing functions; keep admin/emergency functions unpaused |
| Whitelist / airdrop | Use MerkleProof for gas-efficient verification — never store full address lists on-chain |
| Signature-based auth | Use ECDSA + EIP712 — never roll custom signature verification |
| Signature content | Signature must bind chainId + nonce + msg.sender + deadline — prevent replay and cross-chain reuse |
| Cross-chain bridge / third-party dependency | Audit all inherited third-party contract code — never assume dependencies are safe |
| Deprecated / legacy contracts | Permanently pause or selfdestruct deprecated contracts — never leave unused contracts callable on-chain |
| UUPS upgrade pattern | _authorizeUpgrade must have onlyOwner; implementation constructor calls _disableInitializers(); retain onlyProxy on upgradeTo — EVMbench/basin H-01 |
| Multi-contract trust boundary | Router/Registry relay calls must verify source contract authorization; never trust caller identity inside flash loan callbacks — EVMbench/noya H-08 |
| Counter/ID + external call | All counter increments and ID assignments must complete before external calls; ETH refunds must be last — EVMbench/phi H-06 |
ReentrancyGuard, add nonReentrant modifier
@openzeppelin/contracts/security/ReentrancyGuard.sol (OZ 4.9.x)ReentrancyGuard:
require)address(0) for all address parameters--gas-limit (recommended >= 3,000,000)forge test --gas-report — review before every PRfoundry.toml: optimizer = true, optimizer_runs = 200Before submitting code for review or audit, verify:
Access & Control:
nonReentrant where applicabletx.origin used for authentication (use msg.sender)delegatecall to untrusted addressesOwnable2Step (not Ownable) to prevent accidental lossPausable with pause() / unpause()_authorizeUpgrade has onlyOwner modifier — EVMbench/basin H-01_disableInitializers() — EVMbench/basin H-01Token & Fund Safety:
SafeERC20 (safeTransfer / safeTransferFrom)token.transfer() or require(token.transfer()) patternssafeIncreaseAllowance, not raw approveexternal call return values checkedCode Quality:
.env is in .gitignoreOracle & Price (if applicable):
Testing:
forge test passes with zero failuresforge coverage shows adequate coverage on security-critical paths# Run all tests with gas report
forge test --gas-report
# Fuzz testing with higher runs for critical functions
forge test --fuzz-runs 10000
# Check test coverage
forge coverage
# Dry-run deployment to verify no runtime errors
forge script script/Deploy.s.sol --fork-url $RPC_URL -vvvv
# Static analysis (if slither installed locally)
slither src/
When slither MCP is configured, prefer it over the CLI for structured analysis:
| Approach | When to Use |
|---|---|
| slither src/ (CLI) | Quick local scan, raw terminal output |
| slither MCP get_detector_results | Structured results with impact/confidence filtering, AI can parse and reason about findings |
| slither MCP get_contract_metadata | Understanding contract structure before reviewing code |
| slither MCP get_function_source | Locating exact function implementations faster than grep |
Recommended: Use slither MCP when working with AI agents (results are structured and actionable). Use CLI for quick local checks during development.
Graceful degradation: If neither slither MCP nor slither CLI is available, rely on the Pre-Audit Checklist above and forge test --fuzz-runs 10000 for coverage.
testing
[AUTO-INVOKE] MUST be invoked when designing or reviewing ERC20 token contracts that need flash loan protection. Covers token-level defense design patterns: cost tracking, same-block cooldown, progressive sell tax, minimum balance retention, EIP-7702 aware address checks, front-run protection, and referral binding. Trigger: any ERC20 token with anti-flash-loan, anti-bot, or tokenomics security design requirements.
development
[AUTO-INVOKE] MUST be invoked BEFORE writing or modifying any Solidity contract (.sol files). Covers pragma version, naming conventions, project layout, OpenZeppelin library selection standards, oracle integration, and anti-patterns. Trigger: any task involving creating, editing, or reviewing .sol source files.
testing
[AUTO-INVOKE] MUST be invoked BEFORE any on-chain operation (cast send, forge script --broadcast). Systematic 6-layer verification checklist: permissions, dependencies, parameters, security, testing, and knowledge capture. Trigger: any task involving sending transactions, deploying contracts, or interacting with on-chain state.
development
[AUTO-INVOKE] MUST be invoked BEFORE writing or modifying any test files (*.t.sol). Covers test structure, naming conventions, coverage requirements, fuzz testing, and Foundry cheatcodes. Trigger: any task involving creating, editing, or running Solidity tests.