Skip to content
Security
Command

/exploit

Generate a working Foundry PoC that exploits a specific finding. Compiles and passes.

From plugin
rugproof
945 skills23 agents45 commands4 hooks
Install
> /plugin marketplace add omermaksutii/RugProof
> /plugin install rugproof@rugproof

How it fires

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

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/exploit

Context preview

What this command does when you run it.

Generate a working Foundry PoC that exploits a specific finding. Compiles and passes.

Command definition

exploit.md
description: Generate a working Foundry PoC that exploits a specific finding. Compiles and passes.
argument-hint: "<finding-id>  [--framework foundry|hardhat] [--story]"
allowed-tools: Read, Write, Edit, Bash, Agent, Skill, mcp__forge-runner__*

/exploit — write a working PoC

This is the headline feature. For a given finding ID, produce a Foundry test that:

1. Sets up the vulnerable state. 2. Executes the exploit. 3. Asserts the attacker gained value or the protocol was broken. 4. **Compiles.** 5. **The test passes when run.**

If `--story` is set, also produce a narrative "attack walkthrough" — punchy prose suitable for a tweet thread or blog post.

Procedure

Step 1 — Read the finding and the target

  • Pull finding `$ARGUMENTS[0]` from the latest audit.
  • Read the affected file and all imports it needs.
  • Note the function signatures, state vars, and any setup needed (e.g. funded balances, deployed dependencies like a Uniswap V2 pair).

Step 2 — Dispatch `exploit-poc-writer` subagent

The subagent writes the Foundry test. Use Foundry's `Test` base + `vm.prank`, `vm.deal`, `vm.warp`, `vm.expectRevert`, `vm.startPrank`, etc.

Structure:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import {Vault} from "src/Vault.sol";
import {MaliciousReceiver} from "./MaliciousReceiver.sol";

contract ExploitREENT001 is Test {
    Vault vault;
    address attacker = makeAddr("attacker");
    address victim = makeAddr("victim");

    function setUp() public {
        vault = new Vault();
        vm.deal(victim, 10 ether);
        vm.deal(attacker, 1 ether);
        vm.prank(victim);
        vault.deposit{value: 10 ether}();
    }

    function test_Reentrancy_Drain() public {
        MaliciousReceiver bad = new MaliciousReceiver(vault);
        vm.deal(address(bad), 1 ether);
        vm.startPrank(attacker);

        bad.attack{value: 1 ether}();   // ← seed deposit + trigger reentrancy

        assertGt(address(bad).balance, 1 ether, "exploit failed to drain");
        assertLt(address(vault).balance, 1 ether, "vault not drained");
    }
}

Plus any auxiliary attacker contract.

Step 3 — Compile and run

Use the `forge-runner` MCP:

mcp__forge-runner__build()
mcp__forge-runner__test(test="test_Reentrancy_Drain")

If build fails: read the error, fix, retry. If test fails: read the trace, fix, retry.

**Hard requirement:** the test must pass before outputting. If after 3 attempts it doesn't pass, output a diagnosis and ask the user to verify the setup matches the deployed state.

Step 4 — Output

  • The full test file (path + content).
  • The forge-runner output showing the test passing.
  • If `--story` is set, also a 200-400 word "attack walkthrough":

> **How REENT-001 drains the Vault** > > The vulnerable function `Vault.withdraw()` sends ether before zeroing the balance. By depositing once and re-entering during the receive callback, an attacker can re-call `withdraw()` while their balance is still recorded as the full deposit. They withdraw the same balance repeatedly until the vault is empty. > > Step-by-step: … > > Cost: ~0.001 ETH gas. Profit: entire vault balance. Time: 1 block.

Step 5 — Save

Save the test to `test/exploits/Exploit<ID>.t.sol`. Mention this path in the output.

Notes

  • **The test MUST pass.** A PoC that doesn't run is worthless.
  • Don't over-mock — use the actual contract source where possible.
  • For exploits requiring mainnet state (oracle prices, deployed tokens), use `--fork-url` and a real block number. Note this in the test.
  • Be honest if the exploit needs an unrealistic precondition — say so.
Read more
Ships withrugproof

Rugproof your code before someone else does. 🌐 Live site: omermaksutii.github.io/RugProof 📦 Latest: v1.0.0 — 45 commands · 23 agents · 45 skills · 13 MCP servers · tested, offline-first, with rule packs, a benchmark, non-EVM coverage, and post-deploy

Get the whole plugin

Other commands on rugproof.