bb-methodology
The "3rd eye" for pentesting — reminds agent to understand before assuming, validate before…
Complete reference for all 10 DeFi smart contract bug classes. Use this when hunting for specific vulnerability types, need attack patterns for accounting desync, access control, incomplete path, off-by-one, oracle manipulation, ERC4626 vaults, reentrancy, flash loans, signature
$ npx -y skills add Gabson0x/bountyforge --skill web3-bug-classes --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web3-bug-classesContext preview
The summary Claude sees to decide when to auto-load this skill.
Complete reference for all 10 DeFi smart contract bug classes. Use this when hunting for specific vulnerability types, need attack patterns for accounting desync, access control, incomplete path, off-by-one, oracle manipulation, ERC4626 vaults, reentrancy, flash loans, signature
name: web3-bug-classes description: Complete reference for all 10 DeFi smart contract bug classes. Use this when hunting for specific vulnerability types, need attack patterns for accounting desync, access control, incomplete path, off-by-one, oracle manipulation, ERC4626 vaults, reentrancy, flash loans, signature replay, or proxy/upgrade bugs.
10 bug classes. Each one with root cause, vulnerable code, fix, grep patterns, and real paid examples.
See also: [[Vuln Classes]], [[Web3 Audit]], [[Trust Map]], [[A→B Chains]], [[Methodology]]
---
> #1 Critical bug class — 28% of all Criticals on Immunefi. > Real protocols: Yeet, Alchemix V3, Folks Finance, ResupplyFi, MetaPool
Two state variables are supposed to stay in sync. One code path updates variable A but forgets variable B. Later code reads both and makes decisions based on the stale B.
Real Value = A - B If A is updated but B isn't → Real Value appears larger than it is → phantom value
// BEFORE (correct state): // aToken.balanceOf(this) = 1000 (principal + yield) // totalSupply = 1000 (only principal) // yield = 1000 - 1000 = 0 ✓ correct // Attacker triggers startUnstake: totalSupply -= amount; // decremented BEFORE transfer // totalSupply = 900 now // aToken.balanceOf still = 1000 // yield appears = 1000 - 900 = 100 (PHANTOM) // Now harvest(): yieldAmount = aToken.balanceOf(this) - totalSupply; // = 1000 - 900 = 100 (phantom yield — no real yield was earned) // Protocol harvests 100 of principal and distributes as "yield"
**Variant 1: Phantom Yield** — totalSupply decremented before transfer
// Yeet protocol (35 duplicate reports):
function startUnstake(uint256 amount) external {
totalSupply -= amount; // decremented here, transfer happens later
// balanceOf(this) - totalSupply now shows phantom yield
}**Variant 2: Fast Path Skips State Update** — early return bypasses critical updates
// Alchemix V3 claimRedemption:
function claimRedemption(uint256 tokenId) external {
if (transmuter.balance >= amount) {
transmuter.transfer(user, amount);
_burn(tokenId);
return; // EARLY RETURN — cumulativeEarmarked, _redemptionWeight, totalDebt never updated
}
// SLOW PATH: updates all state vars correctly
alchemist.redeem(...);
}**Variant 3: Rewards Accrue to Wrong Accumulator**
// Folks Finance Liquid Staking:
function addRewards(uint256 amount) external {
algoBalance += amount; // rewards go here
// MISSING: TOTAL_ACTIVE_STAKE += amount
}
function withdraw(uint256 shares) external {
uint256 myAmount = (shares * TOTAL_ACTIVE_STAKE) / totalSupply;
// TOTAL_ACTIVE_STAKE never got rewards → underflow → freeze
}**Variant 4: Update Happens in Wrong Order**
// Alchemix:
function deposit(uint256 amount) external {
_shares = (amount * totalShares) / totalAssets; // calculated BEFORE deposit
totalAssets += amount; // assets added AFTER shares calculated
totalShares += _shares; // shares calculation used stale totalAssets → wrong rate
}# List all balance/supply variables grep -rn "totalSupply\|totalShares\|totalAssets\|totalDebt\|totalCollateral\|cumulativeReward\|rewardPerShare" contracts/ | grep -v "//\|test" # Find ALL writes to key variables grep -rn "totalSupply\s*[-+*]=[^=]\|totalSupply\s*=" contracts/ grep -rn "cumulativeRewardPerShare\s*[-+*]=" contracts/ # Find all early returns in claim/redeem functions grep -rn "\breturn\b" contracts/ -B3 | grep -B3 "if\b" # For each early return: which state updates are in the normal path but not this one?
| Protocol | Root Cause | |----------|-----------| | Yeet | `startUnstake` decrements totalSupply before transfer → phantom yield | | Alchemix V3 | `claimRedemption` fast path skips 3 state updates → phantom collateral | | Folks Finance | Rewards accrue to `algoBalance` not `TOTAL_ACTIVE_STAKE` → underflow | | ResupplyFi | ERC4626 near-empty vault exchange rate manipulation | | MetaPool | `mint()` skipped receipt check from `_deposit()` |
---
> #2 Critical bug class — 19% of all Criticals. $953M lost in 2024 alone. > Real protocols: Wormhole ($10M), ZeroLend, Flare FAssets, Parity ($150M frozen)
A function that should be restricted is callable by anyone. Or a function checks the wrong condition (existence vs. ownership). Or a modifier uses `if` instead of `require` and silently does nothing for non-admins.
**Variant 1: Missing Modifier on Sibling Function**
function vote(uint256 tokenId) external onlyNewEpoch(tokenId) { // guarded
function reset(uint256 tokenId) external onlyNewEpoch(tokenId) { // guarded
function poke(uint256 tokenId) external { // NO GUARD
// Anyone calls poke() unlimited times per epoch
// poke() distributes FLUX rewards → infinite inflation
}**Variant 2: Wrong Check — Existence vs. Ownership**
// ZeroLend split() — anyone can steal victim's tokens:
function split(uint256 tokenId, uint256 amount) external {
_requireOwned(tokenId); // checks if token EXISTS, not if caller OWNS it
_burn(tokenId);
_mint(msg.sender, amount); // attacker gets tokens they don't own
}**Variant 3: Tautology in Require**
// Flare FAssets — proof validation always passes:
require(
sourceAddressesRoot == sourceAddressesRoot, // always true! comparing to itself
"Invalid"All-round bug bounty skill for Claude Code — parallelized agents for smart contract audits (EVM, Move, Solana, TRON), web/API security, local tooling orchestration, and submission-ready reports for HackerOne, Bugcrowd, Intigriti & Immunefi.
Repo: Gabson0x/bountyforge
The "3rd eye" for pentesting — reminds agent to understand before assuming, validate before…
Complete bug bounty workflow — recon (subdomain enumeration, asset discovery, fingerprinting,…
Analyze EVM smart contracts for storage-safety vulnerabilities that can cause persistent…
Generate Echidna/Medusa-compatible Solidity fuzz suites from Foundry or Hardhat projects.…
Convert English-language properties in PROPERTIES.md (produced by the Fizz skill) into…