Skip to content
Security
Skill

/web3-poc-foundry

Complete Foundry PoC writing guide + all cheatcodes + DeFiHackLabs reproduction patterns. Use this when building a proof of concept exploit, setting up a fork test, using Foundry cheatcodes, or reproducing a known DeFi hack for learning.

BOOST
From plugin
tradecatlabs-vibe-coding-cn
17k18 skills
Install
$ npx -y skills add tradecatlabs/vibe-coding-cn --skill web3-poc-foundry --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/web3-poc-foundry

Context preview

The summary Claude sees to decide when to auto-load this skill.

Complete Foundry PoC writing guide + all cheatcodes + DeFiHackLabs reproduction patterns. Use this when building a proof of concept exploit, setting up a fork test, using Foundry cheatcodes, or reproducing a known DeFi hack for learning.

SKILL.md

web3-poc-foundry.SKILL.md
name: web3-poc-foundry
description: Complete Foundry PoC writing guide + all cheatcodes + DeFiHackLabs reproduction patterns. Use this when building a proof of concept exploit, setting up a fork test, using Foundry cheatcodes, or reproducing a known DeFi hack for learning.

PoC WRITING + FOUNDRY COMPLETE REFERENCE

Immunefi requires RUNNABLE code. Not pseudocode. Not steps. Running Foundry tests with before/after logs and a passing assert.

---

QUICK START

# Immunefi official templates (preferred for submissions)
forge init my-poc --template immunefi-team/forge-poc-templates --branch default
forge init my-poc --template immunefi-team/forge-poc-templates --branch reentrancy
forge init my-poc --template immunefi-team/forge-poc-templates --branch flash_loan
forge init my-poc --template immunefi-team/forge-poc-templates --branch price_manipulation

# Or blank Foundry project
forge init my-poc
cd my-poc

# Setup .env
echo "MAINNET_RPC_URL=https://eth.llamarpc.com" > .env
echo "BASE_RPC_URL=https://base.llamarpc.com" >> .env
echo "ARB_RPC_URL=https://arb1.arbitrum.io/rpc" >> .env

# Run exploit
source .env
forge test --match-test testExploit -vvvv --fork-url $MAINNET_RPC_URL

---

STANDARD PoC TEMPLATE (Production Quality for Immunefi)

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.10;

import "forge-std/Test.sol";
import "forge-std/console.sol";

/**
 * @title [Protocol Name] - [Bug Description]
 * @notice PoC for Immunefi submission
 * @dev Demonstrates [impact] by exploiting [root cause]
 *
 * Vulnerable contract: [address] ([name])
 * Vulnerable function: [functionName]
 * Immunefi program: [URL]
 * Severity: [Critical/High/Medium/Low]
 */

// Minimal interfaces — only what you need
interface IVulnProtocol {
    function deposit(uint256 amount) external;
    function withdraw(uint256 amount) external;
    function balanceOf(address) external view returns (uint256);
}

interface IERC20 {
    function approve(address, uint256) external returns (bool);
    function balanceOf(address) external view returns (uint256);
    function transfer(address, uint256) external returns (bool);
    function transferFrom(address, address, uint256) external returns (bool);
}

contract ExploitPoC is Test {
    // ============================================================
    // CONFIGURATION
    // ============================================================
    uint256 constant ATTACK_BLOCK = 18_000_000;  // pin block for reproducibility

    address constant VULN_CONTRACT = 0x...;
    address constant TOKEN = 0x0000000000000000000000000000000000000000; // example token placeholder

    IVulnProtocol vuln = IVulnProtocol(VULN_CONTRACT);
    IERC20 token = IERC20(TOKEN);

    // ============================================================
    // SETUP
    // ============================================================
    function setUp() public {
        vm.createSelectFork(vm.envString("MAINNET_RPC_URL"), ATTACK_BLOCK);
        vm.label(VULN_CONTRACT, "VulnerableProtocol");
        vm.label(TOKEN, "USDC");
        vm.label(address(this), "Attacker");
    }

    // ============================================================
    // EXPLOIT
    // ============================================================
    function testExploit() public {
        uint256 attackerBefore = token.balanceOf(address(this));
        uint256 protocolBefore = token.balanceOf(VULN_CONTRACT);

        console.log("=== INITIAL STATE ===");
        console.log("Attacker USDC:  ", attackerBefore);
        console.log("Protocol USDC:  ", protocolBefore);
        console.log("--------------------");

        // Step 1: [description]
        deal(TOKEN, address(this), 1e6);  // 1 USDC starting capital

        // Step 2: [description]
        token.approve(VULN_CONTRACT, type(uint256).max);
        vuln.deposit(1e6);

        // Step 3: [the exploit]
        // ... exploit logic ...

        uint256 attackerAfter = token.balanceOf(address(this));
        uint256 protocolAfter = token.balanceOf(VULN_CONTRACT);

        console.log("=== FINAL STATE ===");
        console.log("Attacker USDC:  ", attackerAfter);
        console.log("Protocol USDC:  ", protocolAfter);
        console.log("Profit:         ", attackerAfter - attackerBefore);
        console.log("Protocol loss:  ", protocolBefore - protocolAfter);

        assertGt(attackerAfter, attackerBefore, "Exploit failed: no profit");
    }
}

What a Passing PoC Output Looks Like

Running 1 test for test/Exploit.t.sol:ExploitPoC
[PASS] testExploit() (gas: 1234567)
Logs:
  === INITIAL STATE ===
  Attacker USDC:   100000
  Protocol USDC:   5000000
  --------------------
  === FINAL STATE ===
  Attacker USDC:   600000
  Protocol USDC:   4500000
  Profit:          500000
  Protocol loss:   500000

Test result: ok. 1 passed; 0 failed

The before/after numbers ARE your proof. Paste this output directly into the Immunefi report.

---

ESSENTIAL CHEATCODES — FULL REFERENCE

Identity / Caller Control

vm.prank(address who);
// Next single call is from `who`
// vm.prank(owner); target.setAdmin(attacker);

vm.startPrank(address who);
vm.stopPrank();
// ALL calls between start/stop are from `who`

vm.startPrank(address msgSender, address txOrigin);
// Set both msg.sender AND tx.origin simultaneously

vm.assume(bool condition);
// Skip fuzz test case if condition is false

State Manipulation

vm.deal(address who, uint256 ethAmount);
// Give ETH to any address
// vm.deal(attacker, 10 ether);

deal(address token, address to, uint256 amount);
// Give ERC20 tokens — works with any verified contract
// deal(USDC, attacker, 1_000_000e6); — gives 1M USDC without a source

vm.store(address target, bytes32 slot, bytes32 value);
// Write directly to any storage slot

vm.load(address target, bytes32 slot) returns (bytes32);
// Read any storage slot directly

vm.warp(uint256 timestamp);
// Set block.tim
Read more
Ships withtradecatlabs-vibe-coding-cn

从想法到产品的 AI 结对编程工作流标准:Prompt + Skill + Context + Quality Gate + 工程闭环 <!-- 徽章区域 (BADGES) --> 本仓库的 AI 解读链接:zread.ai/tukuaiai/vibe-coding-cn 🧠 六条核心命题

Get the whole plugin