Learn-skills.dev solidity-security
[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.
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/0xlayerghost/solidity-agent-kit/solidity-security" ~/.claude/skills/neversight-learn-skills-dev-solidity-security && rm -rf "$T"
manifest:
data/skills-md/0xlayerghost/solidity-agent-kit/solidity-security/SKILL.mdsource content
Solidity Security Standards
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.
Private Key Protection
- Store private keys in
, load via.env
— never pass keys as CLI argumentssource .env - Never expose private keys in logs, screenshots, conversations, or commits
- Provide
with placeholder values for team reference.env.example - Add
to.env
— verify with.gitignore
before every commitgit status
Security Decision Rules
When writing or reviewing Solidity code, apply these rules:
| Situation | Required Action |
|---|---|
| External ETH/token transfer | Use + Checks-Effects-Interactions (CEI) pattern |
| ERC20 token interaction | Use — call / , never raw / |
| Owner-only function | Inherit (preferred) or from OZ 4.9.x — prevents accidental owner loss |
| Multi-role access | Use from |
| Token approval | Use / from — never raw |
| Price data needed | Use Chainlink if feed exists; otherwise TWAP with min-liquidity check — never use spot pool price directly |
| Upgradeable contract | Prefer UUPS () over TransparentProxy; always use |
| Solidity version < 0.8.0 | Must use — but strongly prefer upgrading to 0.8.20+ |
| Emergency scenario | Inherit , add to user-facing functions; keep admin/emergency functions unpaused |
| Whitelist / airdrop | Use for gas-efficient verification — never store full address lists on-chain |
| Signature-based auth | Use + — never roll custom signature verification |
| Signature content | Signature must bind + + + — 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 or deprecated contracts — never leave unused contracts callable on-chain |
Reentrancy Protection
- All contracts with external calls: inherit
, addReentrancyGuard
modifiernonReentrant- Import:
(OZ 4.9.x)@openzeppelin/contracts/security/ReentrancyGuard.sol
- Import:
- Always apply CEI pattern even with
:ReentrancyGuard- Checks — validate all conditions (
)require - Effects — update state variables
- Interactions — external calls last
- Checks — validate all conditions (
Input Validation
- Reject
for all address parametersaddress(0) - Reject zero amounts for fund transfers
- Validate array lengths match when processing paired arrays
- Bound numeric inputs to reasonable ranges (prevent dust attacks, gas griefing)
Gas Control
- Deployment commands must include
(recommended >= 3,000,000)--gas-limit - Monitor gas with
— review before every PRforge test --gas-report - Configure optimizer in
:foundry.toml
,optimizer = trueoptimizer_runs = 200 - Avoid unbounded loops over dynamic arrays — use pagination or pull patterns
Pre-Audit Checklist
Before submitting code for review or audit, verify:
Access & Control:
- All external/public functions have
where applicablenonReentrant - No
used for authentication (usetx.origin
)msg.sender - No
to untrusted addressesdelegatecall - Owner transfer uses
(notOwnable2Step
) to prevent accidental lossOwnable - Contracts with user-facing functions inherit
withPausable
/pause()unpause()
Token & Fund Safety:
- All ERC20 interactions use
(SafeERC20
/safeTransfer
)safeTransferFrom - No raw
ortoken.transfer()
patternsrequire(token.transfer()) - Token approvals use
, not rawsafeIncreaseAllowanceapprove - All
return values checkedexternal call
Code Quality:
- Events emitted for every state change
- No hardcoded addresses — use config or constructor params
-
is in.env.gitignore
Oracle & Price (if applicable):
- Price data sourced from Chainlink feed or TWAP — never raw spot price
- Oracle has minimum liquidity check — revert if pool reserves too low
- Price deviation circuit breaker in place
Testing:
-
passes with zero failuresforge test -
shows adequate coverage on security-critical pathsforge coverage - Fuzz tests cover arithmetic edge cases (zero, max uint, boundary values)
Security Verification Commands
# 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) slither src/