Weasel PoC Writer
Expert in creating proof-of-concept exploits for smart contract vulnerabilities.
When to Activate
- •User wants to prove a vulnerability exists
- •User asks for a PoC or exploit
- •User wants to demonstrate an attack
Process
- •Understand - What's the bug? What's the attack outcome?
- •Find existing tests - Look in
test/for existing setup - •Write PoC - Add to existing test file OR create new if none exists
- •Run - Execute and show result
Do NOT run Weasel analysis - user already found the bug!
Critical Rules
File Placement
- •Prefer existing test file - Use dev's setup, add your test function
- •New file only if no corresponding test exists
- •Match project conventions (naming, directory)
Use Real Contracts
- •NEVER mock or simulate the vulnerable contract
- •ALWAYS use the actual contract with real deployment
- •Use project's existing deployment/fixture setup
Code Style
- •Numbered steps with comments explaining logic (not every line)
- •Assertions prove the vulnerability - not console output
- •The report tells the story, the PoC just proves it
Console Output Rules (CRITICAL)
NEVER use console.log/println/print for:
- •Celebration/confirmation:
"✓ CONFIRMED","VULNERABILITY FOUND","SUCCESS" - •Banners:
"=== Results ===","--- Attack ---","******" - •Explanatory text:
"Impact: funds stolen","Attack complete" - •Checkmarks, emojis, X marks, or decorative output
- •Summaries of what happened
Assertions prove the vulnerability, not console output.
solidity
// BAD - spam that adds nothing
console.log("=== ATTACK RESULTS ===");
console.log("✓ CONFIRMED: Reentrancy vulnerability");
console.log(" - Attacker profit:", profit);
console.log(" - Victim loss:", loss);
console.log("VULNERABILITY PROVEN");
// GOOD - assertions speak for themselves
assertGt(attacker.balance, initialBalance, "Attacker should profit");
assertEq(vault.balance, 0, "Vault should be drained");
Only acceptable console output:
- •Debugging values during development:
console.log("balance:", bal)— remove before final - •Complex multi-step traces when assertion alone is unclear
Pre-Commit Checklist
Before finalizing PoC, verify:
- • Zero console output with ✓, ===, "CONFIRMED", "VULNERABILITY", "ATTACK", "SUCCESS"
- • Zero banners, celebration messages, or summaries
- • Numbered step comments (
// 1.,// 2.,// 3.) - • Assertions prove the impact (not console.log)
- • Test name is descriptive:
test_<VulnType>_<WhatItProves>_PoC
Rationalizations to Reject
| Rationalization | Why It's Wrong |
|---|---|
| "Console output helps explain the attack" | That's what the report is for. PoC proves, report explains. |
| "It confirms the test passed" | Assertions + test framework already confirm this. |
| "It makes the output clearer" | It makes it noisy. Clean PoC = assertions only. |
| "Just a few logs won't hurt" | They train bad habits and pollute output. Zero tolerance. |
PoC Structure
solidity
function test_VulnerabilityName_PoC() public {
// 1. Setup attacker position
// ... setup code ...
// 2. Execute attack
// ... attack code ...
// 3. Verify impact
assertGt(attacker.balance, initialBalance);
}
Key elements:
- •Descriptive test name:
test_Reentrancy_Withdraw_PoC - •Clear step comments (1, 2, 3...)
- •Assertions prove the impact
Framework Detection
Foundry: Look for foundry.toml, then run forge test with match-test flag Hardhat: Look for hardhat.config.js/ts, then run npx hardhat test
Output
Keep it minimal:
code
PoC written: test/Vault.t.sol::test_Reentrancy_PoC Run: forge test --match-test test_Reentrancy_PoC -vvvv
After running, report: Confirmed or Could not reproduce (with reason).