Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Expert usage of Hardhat for smart contract development, testing, and deployment. Includes TypeChain generation, plugin ecosystem, network forking, and deployment management.
.claude/skills/a5c-ai-hardhat-framework/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-12 | ✗→✓ | ▲ Improved | 206% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 167% | 0% |
| case-01 | ✗→✗ | = Same ✗ | 294% | 0% |
| case-02 | ✗→✗ | = Same ✗ | 216% | 0% |
| case-03 | ✗→✗ | = Same ✗ | 154% | 0% |
Expert-level usage of Hardhat, the most popular Ethereum development environment.
bash# Create project mkdir my-project && cd my-project npm init -y # Install Hardhat npm install --save-dev hardhat # Initialize project npx hardhat init # Install common dependencies npm install --save-dev @nomicfoundation/hardhat-toolbox
javascriptrequire("@nomicfoundation/hardhat-toolbox"); require("@openzeppelin/hardhat-upgrades"); require("hardhat-gas-reporter"); require("solidity-coverage"); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: { version: "0.8.20", settings: { optimizer: { enabled: true, runs: 200, }, viaIR: false, }, }, networks: { hardhat: { forking: { url: process.env.MAINNET_RPC_URL, blockNumber: 18000000, }, }, sepolia: { url: process.env.SEPOLIA_RPC_URL, accounts: [process.env.PRIVATE_KEY], }, mainnet: { url: process.env.MAINNET_RPC_URL, accounts: [process.env.PRIVATE_KEY], }, }, etherscan: { apiKey: process.env.ETHERSCAN_API_KEY, }, gasReporter: { enabled: true, currency: "USD", coinmarketcap: process.env.COINMARKETCAP_API_KEY, }, paths: { sources: "./contracts", tests: "./test", cache: "./cache", artifacts: "./artifacts", }, };
typescript// hardhat.config.ts import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import "@openzeppelin/hardhat-upgrades"; const config: HardhatUserConfig = { solidity: "0.8.20", networks: { sepolia: { url: process.env.SEPOLIA_RPC_URL || "", accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] : [], }, }, }; export default config;
javascript// test/Token.test.js const { expect } = require("chai"); const { ethers } = require("hardhat"); describe("Token", function () { let token; let owner; let addr1; beforeEach(async function () { [owner, addr1] = await ethers.getSigners(); const Token = await ethers.getContractFactory("Token"); token = await Token.deploy(); await token.waitForDeployment(); }); describe("Deployment", function () { it("Should set the right owner", async function () { expect(await token.owner()).to.equal(owner.address); }); it("Should assign total supply to owner", async function () { const ownerBalance = await token.balanceOf(owner.address); expect(await token.totalSupply()).to.equal(ownerBalance); }); }); describe("Transactions", function () { it("Should transfer tokens", async function () { await token.transfer(addr1.address, 50); expect(await token.balanceOf(addr1.address)).to.equal(50); }); it("Should emit Transfer event", async function () { await expect(token.transfer(addr1.address, 50)) .to.emit(token, "Transfer") .withArgs(owner.address, addr1.address, 50); }); it("Should fail if sender lacks funds", async function () { await expect( token.connect(addr1).transfer(owner.address, 1) ).to.be.revertedWith("Insufficient balance"); }); }); });
typescript// test/Token.test.ts import { expect } from "chai"; import { ethers } from "hardhat"; import { Token } from "../typechain-types"; describe("Token", function () { let token: Token; beforeEach(async function () { const Token = await ethers.getContractFactory("Token"); token = await Token.deploy(); }); it("Should deploy successfully", async function () { expect(await token.getAddress()).to.be.properAddress; }); });
javascriptconst { expect } = require("chai"); const { ethers, network } = require("hardhat"); describe("Fork Test", function () { const USDC_ADDRESS = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; const WHALE = "0x47ac0Fb4F2D84898e4D9E7b4DaB3C24507a6D503"; beforeEach(async function () { // Impersonate whale account await network.provider.request({ method: "hardhat_impersonateAccount", params: [WHALE], }); }); it("Should transfer USDC from whale", async function () { const whale = await ethers.getSigner(WHALE); const usdc = await ethers.getContractAt("IERC20", USDC_ADDRESS); const [, recipient] = await ethers.getSigners(); const amount = ethers.parseUnits("1000", 6); await usdc.connect(whale).transfer(recipient.address, amount); expect(await usdc.balanceOf(recipient.address)).to.equal(amount); }); });
javascript// scripts/deploy.js const hre = require("hardhat"); async function main() { const Token = await hre.ethers.getContractFactory("Token"); const token = await Token.deploy(); await token.waitForDeployment(); console.log("Token deployed to:", await token.getAddress()); // Verify on Etherscan if (hre.network.name !== "hardhat") { await hre.run("verify:verify", { address: await token.getAddress(), constructorArguments: [], }); } } main().catch((error) => { console.error(error); process.exitCode = 1; });
javascript// scripts/deploy-upgradeable.js const { ethers, upgrades } = require("hardhat"); async function main() { const Token = await ethers.getContractFactory("TokenV1"); // Deploy proxy const token = await upgrades.deployProxy(Token, [], { initializer: "initialize", }); await token.waitForDeployment(); console.log("Proxy deployed to:", await token.getAddress()); } main();
javascript// scripts/upgrade.js const { ethers, upgrades } = require("hardhat"); async function main() { const PROXY_ADDRESS = "0x..."; const TokenV2 = await ethers.getContractFactory("TokenV2"); const token = await upgrades.upgradeProxy(PROXY_ADDRESS, TokenV2); console.log("Token upgraded"); } main();
javascript// hardhat.config.js task("accounts", "Prints accounts", async (taskArgs, hre) => { const accounts = await hre.ethers.getSigners(); for (const account of accounts) { console.log(account.address); } }); task("balance", "Prints balance") .addParam("account", "The account address") .setAction(async (taskArgs, hre) => { const balance = await hre.ethers.provider.getBalance(taskArgs.account); console.log(hre.ethers.formatEther(balance), "ETH"); });
bash# Compile npx hardhat compile # Test npx hardhat test npx hardhat test --grep "transfer" # Coverage npx hardhat coverage # Run script npx hardhat run scripts/deploy.js --network sepolia # Console npx hardhat console --network localhost # Node npx hardhat node # Verify npx hardhat verify --network mainnet <address>
| Process | Purpose | |---------|---------| | smart-contract-development-lifecycle.js | Full development | | dapp-frontend-development.js | dApp integration | | All token processes | Token deployment | | All DeFi processes | Protocol deployment |
skills/foundry-framework/SKILL.md - Alternative frameworkskills/openzeppelin/SKILL.md - Contract libraries| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 4,054 | 2,946 | -27% | 1 | 1 | 0% | 749 | 2,952 | +294% | 0 | 0 | — |
case-02 | fail→fail | 4,935 | 4,546 | -8% | 1 | 1 | 0% | 989 | 3,125 | +216% | 0 | 0 | — |
case-03 | fail→fail | 5,769 | 4,081 | -29% | 1 | 1 | 0% | 1,279 | 3,253 | +154% | 0 | 0 | — |
case-04 | fail→fail | 5,372 | 5,661 | +5% | 1 | 1 | 0% | 1,180 | 3,500 | +197% | 0 | 0 | — |
case-05 | pass→pass | 5,990 | 5,502 | -8% | 1 | 1 | 0% | 1,278 | 3,409 | +167% | 0 | 0 | — |
case-06 | fail→fail | 4,127 | 4,951 | +20% | 1 | 1 | 0% | 922 | 3,351 | +263% | 0 | 0 | — |
case-07 | fail→fail | 4,738 | 3,321 | -30% | 1 | 1 | 0% | 899 | 2,843 | +216% | 0 | 0 | — |
case-08 | fail→fail | 2,914 | 2,622 | -10% | 1 | 1 | 0% | 506 | 2,812 | +456% | 0 | 0 | — |
case-09 | fail→fail | 2,189 | 2,311 | +6% | 1 | 1 | 0% | 411 | 2,784 | +577% | 0 | 0 | — |
case-10 | fail→fail | 4,184 | 3,097 | -26% | 1 | 1 | 0% | 722 | 2,897 | +301% | 0 | 0 | — |
case-11 | fail→fail | 3,397 | 3,356 | -1% | 1 | 1 | 0% | 617 | 2,957 | +379% | 0 | 0 | — |
case-12 | fail→pass | 4,574 | 2,338 | -49% | 1 | 1 | 0% | 873 | 2,671 | +206% | 0 | 0 | — |
case-13 | fail→fail | 5,930 | 1,684 | -72% | 1 | 1 | 0% | 994 | 2,561 | +158% | 0 | 0 | — |
case-14 | fail→fail | 3,032 | 1,898 | -37% | 1 | 1 | 0% | 519 | 2,638 | +408% | 0 | 0 | — |
case-15 | fail→fail | 5,130 | 2,983 | -42% | 1 | 1 | 0% | 1,034 | 2,909 | +181% | 0 | 0 | — |
case-16 | fail→fail | 6,072 | 4,645 | -24% | 1 | 1 | 0% | 1,393 | 3,333 | +139% | 0 | 0 | — |
case-17 | fail→fail | 7,455 | 5,362 | -28% | 1 | 1 | 0% | 1,477 | 3,321 | +125% | 0 | 0 | — |
case-18 | fail→fail | 3,073 | 1,519 | -51% | 1 | 1 | 0% | 466 | 2,528 | +442% | 0 | 0 | — |
case-19 | fail→fail | 3,188 | 2,847 | -11% | 1 | 1 | 0% | 528 | 2,833 | +437% | 0 | 0 | — |
case-20 | fail→fail | 6,971 | 6,758 | -3% | 1 | 1 | 0% | 1,420 | 3,951 | +178% | 0 | 0 | — |
case-21 | fail→fail | 4,526 | 4,524 | -0% | 1 | 1 | 0% | 924 | 3,366 | +264% | 0 | 0 | — |
case-22 | fail→fail | 8,345 | 9,062 | +9% | 1 | 1 | 0% | 1,792 | 4,285 | +139% | 0 | 0 | — |
case-23 | fail→fail | 3,320 | 2,691 | -19% | 1 | 1 | 0% | 598 | 2,838 | +375% | 0 | 0 | — |
case-24 | fail→fail | 5,869 | 1,664 | -72% | 1 | 1 | 0% | 1,094 | 2,563 | +134% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.