AgentStack
SKILL verified MIT Self-run

Solidity Checklist

skill-0xlayerghost-solidity-agent-kit-solidity-checklist · by 0xlayerghost

[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.

No reviews yet
0 installs
9 views
0.0% view→install

Install

$ agentstack add skill-0xlayerghost-solidity-agent-kit-solidity-checklist

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Solidity Checklist? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Solidity 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.

Why This Skill Exists

Most on-chain operation failures come from skipping systematic verification. Instead of the reactive loop:

> deploy -> fail -> paste error -> ask AI -> retry -> fail again -> ask again

This skill enforces a proactive verification flow:

> check permissions -> check dependencies -> check params -> check security -> test locally -> execute -> capture knowledge

The 6-Layer Preflight Flow

Every on-chain operation MUST pass through these 6 layers in order before execution.

Layer 1: PERMISSIONS  — Do I have the right to do this?
Layer 2: DEPENDENCIES — Do I understand what this affects?
Layer 3: PARAMETERS   — Are my inputs correct?
Layer 4: SECURITY     — Is this safe to execute?
Layer 5: TESTING      — Have I verified locally first?
Layer 6: EXECUTE & CAPTURE — Do it, then record what I learned.

Layer 1: Permissions Check

Before any on-chain call, verify the caller has the required access.

| Check | Command | Pass Condition | |-------|---------|----------------| | Contract owner | cast call "owner()" --rpc-url | Returns expected deployer/admin address | | Role-based access | cast call "hasRole(bytes32,address)" --rpc-url | Returns true | | Whitelist status | cast call "isWhitelisted(address)" --rpc-url | Returns true (if applicable) | | Token allowance | cast call "allowance(address,address)" --rpc-url | Returns >= required amount | | Paused state | cast call "paused()" --rpc-url | Returns false |

Decision Rule

| Result | Action | |--------|--------| | All checks pass | Proceed to Layer 2 | | Missing permission | Fix permission first (grant role / approve / unpause), then re-check | | Unsure which permissions are needed | Read contract source — find all onlyOwner, onlyRole, require in target function |


Layer 2: Dependency Check

Understand the blast radius — what contracts and state does this operation touch?

| Check | How | |-------|-----| | Direct dependencies | Read target function source — list all external calls (IERC20(token).transfer(...), etc.) | | Upstream contracts | Which contracts hold a reference to this contract's address? | | Downstream effects | Will this state change trigger callbacks, events, or off-chain indexers? | | Initialization state | cast call "initialized()" --rpc-url — is the contract fully set up? | | Linked addresses | Verify all addresses stored in contract state are correct and not zero |

Dependency Map Template

Before operating on a multi-contract system, build a mental (or written) map:

ContractA (owner: deployer)
  ├── references: TokenB (ERC20), RouterC
  ├── authorized callers: deployer, ContractD
  └── state deps: must be initialized, TokenB must be approved

ContractD (owner: deployer)
  ├── references: ContractA, OracleE
  └── state deps: OracleE must have price feed set

Decision Rule

| Result | Action | |--------|--------| | Dependencies clear | Proceed to Layer 3 | | Unknown dependency | Read contract source or ask — do NOT proceed blindly | | Redeployment needed | Trace the full dependency graph to identify ALL contracts needing address updates |


Layer 3: Parameter Validation

Verify every input before sending.

| Check | Common Pitfall | |-------|---------------| | Address format | Wrong network address, zero address, checksum mismatch | | Token decimals | Using 18 decimals for a 6-decimal token (USDC/USDT) | | Amount precision | 1e18 vs 1e6 — off by 12 orders of magnitude | | Function selector | Calling wrong function or wrong overload | | Enum values | Passing invalid enum index | | Array length | Mismatched array lengths in batch operations | | Deadline/timestamp | Expired deadline, wrong timezone, block.timestamp vs unix |

Validation Commands

# Check token decimals before calculating amounts
cast call  "decimals()" --rpc-url 

# Verify address is a contract (not EOA)
cast code  --rpc-url 
# Empty (0x) = EOA, non-empty = contract

# Decode your own calldata to double-check
cast calldata-decode "functionName(type1,type2)" 

# Estimate gas before sending (catches obvious reverts)
cast estimate  "functionName(args)" --from  --rpc-url 

Decision Rule

| Result | Action | |--------|--------| | All params verified | Proceed to Layer 4 | | Decimal mismatch found | Recalculate with correct decimals | | Address is EOA, expected contract | Wrong address — verify deployment |


Layer 4: Security Quick Check

Scan for common security risks before execution.

| Risk | Check | Red Flag | |------|-------|----------| | Reentrancy | Does the function make external calls before updating state? | External call before state update | | Front-running | Is this a price-sensitive operation (swap, liquidation)? | No slippage protection or deadline | | Access control | Does the function restrict callers appropriately? | Missing onlyOwner / onlyRole on sensitive function | | Value handling | Does the function handle msg.value correctly? | Accepts ETH but doesn't use it, or vice versa | | Approval amount | Am I approving more than necessary? | approve(spender, type(uint256).max) on unknown contract | | Private key exposure | Am I using keystore, not raw private key? | --private-key flag in command |

Private Key Rule (MANDATORY)

# NEVER do this
cast send ... --private-key 0xdead...

# ALWAYS do this
cast send ... --account 

# Set up keystore if not done
cast wallet import  --interactive

Decision Rule

| Result | Action | |--------|--------| | No red flags | Proceed to Layer 5 | | Reentrancy risk found | Add ReentrancyGuard or fix CEI pattern before proceeding | | Front-running risk | Add slippage/deadline params | | Private key exposed | STOP — rotate the key, use keystore |


Layer 5: Local Testing

Never send a transaction that hasn't been verified locally or on a fork.

| Method | Command | When to Use | |--------|---------|-------------| | Unit test | forge test --match-test -vvvv | New/modified contract functions | | Fork test | forge test --fork-url --match-test -vvvv | Testing against live state | | Dry-run script | forge script --rpc-url -vvvv (no --broadcast) | Deployment or complex operations | | Gas estimation | cast estimate "func(args)" --from --rpc-url | Before any cast send | | Simulation | cast call "func(args)" --from --rpc-url | Quick function call test |

Testing Decision Tree

Is this a new or modified contract?
├── YES → Write forge test → Run test → Pass? → Proceed
│                                      → Fail? → Fix and re-test
└── NO (calling existing deployed contract)
    ├── Simple read? → cast call (Layer 3 already covers this)
    └── State-changing? → cast estimate first
        ├── Estimate succeeds → Proceed to Layer 6
        └── Estimate reverts → Debug with cast call + revert reason → Fix → Re-estimate

Decision Rule

| Result | Action | |--------|--------| | Test passes / estimate succeeds | Proceed to Layer 6 | | Test fails | Fix the issue — do NOT deploy broken code | | Estimate reverts | Likely a Layer 1 (permissions) or Layer 3 (params) issue — go back |


Layer 6: Execute & Capture

Execute the operation, verify success, and capture knowledge.

Execute

# Send transaction using keystore
cast send  "functionName(type1,type2)"   \
  --account  \
  --rpc-url 

# Deploy using forge script
forge script  \
  --rpc-url  \
  --account  \
  --broadcast \
  --gas-limit  \
  -vvvv

Post-Execution Verification (MANDATORY)

| Check | Command | |-------|---------| | TX status | Check status field in receipt: 1 = success, 0 = fail | | State change | cast call to verify the expected state change happened | | Events emitted | Check logs in receipt for expected events | | Balance change | cast balance or cast call balanceOf to verify token movements |

Knowledge Capture

After every successful (or failed) operation, capture what you learned:

| What to Record | Where | |----------------|-------| | Successful command with parameters | Personal command handbook (.md file) | | New error encountered + solution | Debug notes | | Contract address and its role | Project architecture doc | | Permission/role requirements discovered | Contract dependency map | | Gas cost of common operations | Gas reference table |

Anti-Pattern: One-Time Consumption

> The biggest leverage: turn every AI interaction into your own knowledge, not a one-time consumption.

If you asked AI for a command and it worked:

  1. Understand WHY each parameter is what it is
  2. Record it in your own words
  3. Next time, write it yourself first — then verify with AI

Quick Reference: Preflight by Operation Type

| Operation | Critical Layers | Most Common Failure | |-----------|----------------|---------------------| | approve | L1 (owner), L3 (amount/decimals) | Wrong decimals | | transfer | L1 (balance), L3 (amount/decimals) | Insufficient balance | | addLiquidity | L1 (approve both tokens), L3 (amounts/ratio), L5 (estimate) | Missing approval | | removeLiquidity | L1 (LP approve), L3 (minAmounts), L4 (slippage) | Slippage too tight | | stake | L1 (approve + whitelist), L2 (staking contract state), L3 (amount) | Staking not active / not whitelisted | | unstake | L1 (staker status), L2 (lock period), L3 (amount) | Lock period not expired | | deploy | L3 (constructor args), L4 (full security check), L5 (fork test mandatory) | Constructor arg mismatch | | upgrade | L1 (proxy admin), L2 (storage layout), L4 (storage collision), L5 (fork test mandatory) | Storage layout incompatible |


Preflight Summary Card

Print this mental checklist before EVERY on-chain operation:

[ ] L1 PERMISSIONS  — Can I call this? (owner/role/approve/whitelist/paused)
[ ] L2 DEPENDENCIES — What does this touch? (contracts/state/events)
[ ] L3 PARAMETERS   — Are inputs correct? (address/decimals/amount/selector)
[ ] L4 SECURITY     — Is this safe? (reentrancy/frontrun/key exposure)
[ ] L5 TESTING      — Did I test locally? (forge test/estimate/dry-run)
[ ] L6 EXECUTE      — Send it, verify it, record what I learned.

> 6 layers, 2 minutes. Saves hours of debugging and wasted gas.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.