mcpField
S
solidity-checklist

solidity-checklist

github.com/0xlayerghost测试与质量462 次安装2 周前更新
代码仓库

关于 solidity-checklist

solidity-checklist 是面向 Solidity 开发者的链上操作预检技能,要求执行前按六层流程核查权限、依赖、参数、安全与本地测试,并在执行后验证和记录结果。

主要功能

  1. 01六层链上操作预检流程
  2. 02核查权限与合约依赖
  3. 03验证参数和安全风险
  4. 04本地测试、模拟与估算
  5. 05执行后检查并记录经验

适用场景

  1. 01发送交易前检查权限和参数
  2. 02部署或升级合约前进行安全预检
  3. 03排查交易模拟失败原因

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/0xlayerghost/solidity-agent-kit --skill solidity-checklist

安装后在 Claude Code 中输入/solidity-checklist确认已加载。

详细介绍

Solidity 检查清单

语言规则

  • 始终使用用户正在使用的语言进行回复。 如果用户用中文提问,就用中文回复。如果用户用英文提问,就用英文回复。

此技能的用途

大多数链上操作失败都是因为跳过了系统性验证。此技能不再采用被动的循环:

部署 -> 失败 -> 粘贴错误 -> 询问 AI -> 重试 -> 再次失败 -> 再次询问

而是强制执行主动验证流程:

检查权限 -> 检查依赖项 -> 检查参数 -> 检查安全性 -> 本地测试 -> 执行 -> 记录知识

6 层预检流程

每项链上操作在执行前都必须按顺序通过以下 6 层检查。

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.

第 1 层:权限检查

进行任何链上调用前,请确认调用者具有所需的访问权限。

检查项命令通过条件
合约所有者cast call <CONTRACT> "owner()" --rpc-url <RPC>返回预期的部署者/管理员地址
基于角色的访问控制cast call <CONTRACT> "hasRole(bytes32,address)" <ROLE_HASH> <CALLER> --rpc-url <RPC>返回 true
白名单状态cast call <CONTRACT> "isWhitelisted(address)" <CALLER> --rpc-url <RPC>返回 true(如适用)
代币授权额度cast call <TOKEN> "allowance(address,address)" <OWNER> <SPENDER> --rpc-url <RPC>返回值 >= 所需金额
暂停状态cast call <CONTRACT> "paused()" --rpc-url <RPC>返回 false
决策规则
结果操作
所有检查均通过继续第 2 层
缺少权限先修复权限(授予角色/批准/取消暂停),然后重新检查
不确定需要哪些权限阅读合约源码,在目标函数中查找所有 onlyOwner、onlyRole、require

第 2 层:依赖项检查

了解影响范围——此操作会涉及哪些合约和状态?

检查项方法
直接依赖项阅读目标函数源码,列出所有外部调用(如 IERC20(token).transfer(...) 等)
上游合约哪些合约持有对该合约地址的引用?
下游影响此状态变更是否会触发回调、事件或链下索引器?
初始化状态cast call <CONTRACT> "initialized()" --rpc-url <RPC> — 合约是否已完成全部设置?
关联地址验证合约状态中存储的所有地址均正确且非零
依赖关系图模板

对多合约系统进行操作前,请在脑海中(或书面)绘制关系图:

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
决策规则
结果操作
依赖项明确继续第 3 层
依赖项未知阅读合约源码或询问他人——切勿盲目继续
需要重新部署追踪完整的依赖关系图,找出所有需要更新地址的合约

第 3 层:参数验证

发送前验证每一项输入。

检查项常见问题
地址格式网络地址错误、零地址、校验和不匹配
代币精度对 6 位小数的代币(USDC/USDT)使用 18 位小数
金额精度1e18 与 1e6 相差 12 个数量级
函数选择器调用了错误的函数或错误的重载
枚举值传入了无效的枚举索引
数组长度批量操作中的数组长度不匹配
截止时间/时间戳截止时间已过、时区错误,或混淆了 block.timestamp 与 Unix 时间戳
验证命令
# Check token decimals before calculating amounts
cast call <TOKEN> "decimals()" --rpc-url <RPC>

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

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

# Estimate gas before sending (catches obvious reverts)
cast estimate <CONTRACT> "functionName(args)" --from <CALLER> --rpc-url <RPC>
决策规则
结果操作
所有参数均已验证继续第 4 层
发现精度不匹配使用正确的精度重新计算
地址是 EOA,但预期为合约地址错误——请核实部署信息

第 4 层:安全快速检查

执行前检查常见安全风险。

风险检查项风险信号
重入函数是否在更新状态前进行外部调用?状态更新前进行外部调用
抢跑交易这是否是对价格敏感的操作(交换、清算)?缺少滑点保护或截止时间
访问控制函数是否恰当地限制调用者?敏感函数缺少 onlyOwner / onlyRole
数值处理函数是否正确处理 msg.value?接受 ETH 却未使用,或反之
授权额度我授权的额度是否超过必要范围?对未知合约调用 approve(spender, type(uint256).max)
私钥泄露开发者是否选择了密钥库或被 gitignore 忽略的 .env?在命令、脚本、日志或已提交文件中出现明文私钥
私钥规则(强制)
# NEVER put a literal private key in the command
cast send ... --private-key 0xdead...

# Option A: Foundry Keystore (recommended)
cast send ... --account <KEYSTORE_NAME>

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

# Option B: load PRIVATE_KEY from a gitignored .env
source .env
cast send ... --private-key "$PRIVATE_KEY"

执行前让开发者选择选项 A 或选项 B。切勿读取、打印或提交 .env。

决策规则
结果操作
没有风险信号继续第 5 层
发现重入风险在继续前添加 ReentrancyGuard,或修复 CEI 模式
存在抢跑交易风险添加滑点/截止时间参数
私钥泄露停止 — 轮换密钥,然后使用密钥库或被 gitignore 忽略的 .env

第 5 层:本地测试

未经本地或分叉环境验证的交易,绝不发送。

方法命令适用场景
单元测试forge test --match-test <testName> -vvvv新增/修改合约函数
分叉测试forge test --fork-url <RPC> --match-test <testName> -vvvv针对实时状态进行测试
演练脚本forge script <Script> --rpc-url <RPC> -vvvv(不加 --broadcast)部署或复杂操作
Gas 估算cast estimate <CONTRACT> "func(args)" --from <CALLER> --rpc-url <RPC>执行任何 cast send 前
模拟cast call <CONTRACT> "func(args)" --from <CALLER> --rpc-url <RPC>快速测试函数调用
测试决策树
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
决策规则
结果操作
测试通过 / 估算成功继续第 6 层
测试失败修复问题 — 切勿部署有问题的代码
估算回滚很可能是第 1 层(权限)或第 3 层(参数)的问题 — 返回检查

第 6 层:执行并记录

执行操作、验证是否成功,并记录经验。

执行
# Option A: send transaction using Foundry Keystore (recommended)
cast send <CONTRACT> "functionName(type1,type2)" <arg1> <arg2> \
  --account <KEYSTORE_NAME> \
  --rpc-url <RPC>

# Option A: deploy using Foundry Keystore
forge script <Script> \
  --rpc-url <RPC> \
  --account <KEYSTORE_NAME> \
  --broadcast \
  --gas-limit <LIMIT> \
  -vvvv

# Option B: load PRIVATE_KEY from a gitignored .env, then send or deploy
source .env
cast send <CONTRACT> "functionName(type1,type2)" <arg1> <arg2> \
  --private-key "$PRIVATE_KEY" \
  --rpc-url <RPC>

forge script <Script> \
  --rpc-url <RPC> \
  --private-key "$PRIVATE_KEY" \
  --broadcast \
  --gas-limit <LIMIT> \
  -vvvv
执行后验证(强制)
检查项命令
TX 状态检查回执中的 status 字段:1 = 成功,0 = 失败
状态变更使用 cast call 验证预期状态是否已变更
事件发出检查回执中的 logs 是否包含预期事件
余额变更使用 cast balance 或 cast call balanceOf 验证代币流转
经验记录

每次操作成功或失败后,都要记录所得经验:

记录内容位置
含参数的成功命令个人命令手册(.md 文件)
遇到的新错误及解决方法调试笔记
合约地址及其作用项目架构文档
已发现的权限/角色要求合约依赖关系图
常见操作的 Gas 成本Gas 参考表
反模式:一次性消耗

最大的杠杆:把每次与 AI 的交互都转化为自己的知识,而不是一次性消耗。

如果你向 AI 询问了某条命令,并且它能正常运行:

  1. 理解每个参数为何如此设置
  2. 用自己的话记录下来
  3. 下次先自己写一遍 — 再用 AI 验证

按操作类型快速参考

操作关键层最常见的失败原因
approveL1(所有者)、L3(金额/小数位数)小数位数错误
transferL1(余额)、L3(金额/小数位数)余额不足
addLiquidityL1(批准两个代币)、L3(金额/比例)、L5(估算)缺少批准
removeLiquidityL1(LP 批准)、L3(minAmounts)、L4(滑点)滑点容忍度过低
stakeL1(批准 + 白名单)、L2(质押合约状态)、L3(金额)质押未激活 / 不在白名单中
unstakeL1(质押者状态)、L2(锁定期)、L3(金额)锁定期尚未结束
deployL3(构造函数参数)、L4(完整安全检查)、L5(必须进行分叉测试)构造函数参数不匹配
upgradeL1(代理管理员)、L2(存储布局)、L4(存储冲突)、L5(必须进行分叉测试)存储布局不兼容

预检摘要卡

每次进行链上操作前,都打印这份思维检查清单:

[ ] 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 个层级,2 分钟。节省数小时的调试时间和浪费的 Gas。

评论

支持 Markdown