plugins/contract-security/skills/hardhat-v2-fork-testing/SKILL.md
当用户使用 Hardhat v2 测试智能合约, 需要测试已部署的主网/测试网合约, 模拟现有地址, 或在真实链状态上进行测试时应使用此技能
npx skillsauth add phpmac/skills hardhat-v2-fork-testingInstall 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.
使用 Hardhat v2 Network 的 fork 功能, 在本地环境中模拟主网/测试网状态.
注意: Hardhat v3 语法不同, 本技能仅适用于 Hardhat v2
| 工具 | 用途 | 检测命令 |
|------|------|----------|
| bun | 包管理/运行测试 | which bun |
不使用: 简单的单元测试 / 不依赖链状态的逻辑测试
| 操作 | 命令/代码 |
|------|----------|
| 启动 fork 测试 | FORK_ENABLED=true FORK_URL=<RPC_URL> bunx hardhat test --network hardhat |
| 模拟账户 | await ethers.provider.send("hardhat_impersonateAccount", [address]) |
| 设置账户余额 | await ethers.provider.send("hardhat_setBalance", [address, balance]) |
| 推进时间 | await ethers.provider.send("evm_increaseTime", [seconds]) |
| 挖出新块 | await ethers.provider.send("evm_mine", []) |
networks: {
hardhat: {
chainId: 1337,
accounts: {
mnemonic: "test test test test test test test test test test test junk",
count: 400,
},
forking: {
url: process.env.FORK_URL || "https://bsc-dataseed.binance.org/",
blockNumber: process.env.FORK_BLOCK_NUMBER ? parseInt(process.env.FORK_BLOCK_NUMBER) : undefined,
enabled: process.env.FORK_ENABLED === "true",
},
},
}
import { ethers } from "hardhat";
import { expect } from "chai";
import { parseEther } from "ethers";
describe("Fork Test", function () {
const CONTRACT_ADDRESS = "0x...";
const ADMIN_ADDRESS = "0x...";
let contract: any;
let admin: any;
before(async function () {
await ethers.provider.send("hardhat_impersonateAccount", [ADMIN_ADDRESS]);
admin = await ethers.getSigner(ADMIN_ADDRESS);
contract = await ethers.getContractAt("ContractName", CONTRACT_ADDRESS);
});
it("测试场景", async function () {
const tx = await contract.connect(admin).someMethod();
await tx.wait();
});
});
import { ethers } from "hardhat";
import { expect } from "chai";
import { parseEther } from "ethers";
describe("Fork test", function () {
const TARGET_ADDRESS = "0x1234...";
const CONTRACT_ADDRESS = "0xabcd...";
let contract: any;
let user: any;
this.beforeAll(async function () {
const network = await ethers.provider.getNetwork();
const isHardhat = network.chainId === BigInt(31337) || network.chainId === BigInt(1337);
const factory = await ethers.getContractFactory("ContractName");
contract = factory.attach(CONTRACT_ADDRESS);
if (isHardhat) {
await ethers.provider.send("hardhat_impersonateAccount", [TARGET_ADDRESS]);
user = await ethers.getSigner(TARGET_ADDRESS);
const [signer] = await ethers.getSigners();
await signer.sendTransaction({
to: TARGET_ADDRESS,
value: parseEther("1"),
});
} else {
const signers = await ethers.getSigners();
user = signers[0];
}
});
it("测试场景", async function () {
const tx = await contract.connect(user).someMethod();
await tx.wait();
});
});
# 使用 bunx (推荐)
FORK_ENABLED=true FORK_URL=https://your-rpc-url bunx hardhat test test/YourTest.ts --network hardhat
# 或在 hardhat.config.ts 中预设 URL
FORK_ENABLED=true bunx hardhat test test/YourTest.ts --network hardhat
| 错误 | 原因 | 解决方法 |
|------|------|----------|
| hardhat_impersonateAccount does not exist | 直接连接真实网络 | 使用 --network hardhat 并启用 fork |
| missing trie node | RPC 节点不是归档节点 | 使用 Alchemy/QuickNode 等归档节点 |
| insufficient funds for gas | 模拟账户没有 BNB | 用 hardhat_setBalance 或转账 |
| AccessControlUnauthorizedAccount | 签名者没有权限 | 模拟合约管理员/部署者地址 |
// 检查余额
const balance = await token.balanceOf(address);
console.log("Balance:", ethers.formatEther(balance));
// 推进时间
await ethers.provider.send("evm_increaseTime", [3600]);
await ethers.provider.send("evm_mine", []);
// 从事件获取数据
const event = receipt.logs.find((log: any) => {
try {
return contract.interface.parseLog(log)?.name === "EventName";
} catch {
return false;
}
});
const value = contract.interface.parseLog(event).args.paramName;
// 检查是否在 fork 环境
const network = await ethers.provider.getNetwork();
const isHardhat = network.chainId === BigInt(1337);
必须使用归档节点, 公共节点通常不支持 fork:
| 网络 | 推荐归档节点 | |------|------------| | Ethereum | Alchemy, Infura | | BSC 主网 | Alchemy, QuickNode | | BSC 测试网 | QuickNode | | Polygon | Alchemy, QuickNode |
data-ai
当用户提到 Linux 提权/本地提权/local privilege escalation/获取root权限/内核漏洞利用/LPE/SUID/sudo滥用/容器逃逸/权限提升检测; 或要求在Linux系统上从普通用户提升到root权限; 或查询CVE提权漏洞(如Dirty Pipe/CopyFail/Dirty Frag/PwnKit/Looney Tunables); 或需要安全加固建议时应使用此技能
tools
当用户要求 "计算仓位", "仓位管理", "止损比例", "凯利公式", "盈亏比", "资金管理", "半凯利", "反马丁格尔", "固定风险", "position sizing", "策略评估", "策略体检", "SQN", "夏普比率", "卡玛比率", "期望值", "获利因子", "MAE", "MFE", "R乘数", "索提诺", "蒙特卡洛", "样本外测试", "策略回测" 或需要计算合约交易的最优仓位/止损/资金分配/策略质量评估时应使用此技能. 覆盖仓位管理/策略评估/交易解剖/压力测试的完整框架. 即使用户只是提到 "这笔交易该下多少", "策略好不好", "复盘怎么算" 等模糊描述也应触发.
development
当用户要求 "提取API", "逆向APK", "分析APP接口", "提取业务端点", "React Native逆向", "Flutter逆向" 或需要从移动应用提取后端API信息时使用此技能. 覆盖APK解包/JS bundle分析/kernel_blob.bin分析/H5页面参数发现/Spring Boot API验证全流程. 支持React Native和Flutter两种框架.
research
当用户要求 "推荐VPS", "选服务器", "对比服务商", "建站VPS", "便宜VPS", "VPS推荐" 或需要研究/筛选/对比VPS服务商时应使用此技能. 从 hostloc/lowendtalk/lowendbox/测评站搜集真实评测数据, 交叉验证后给出可溯源排名.