analyzing-ethereum-sma…
Perform static and symbolic analysis of Solidity smart contracts using
Case study - role misconfiguration bug class applied to a yield aggregator protocol. Use as a template for applying all 10 bug classes to a single target.
$ npx -y skills add tradecatlabs/vibe-coding-cn --skill web3-case-study-role-misconfig --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/web3-case-study-role-misconfigContext preview
The summary Claude sees to decide when to auto-load this skill.
Case study - role misconfiguration bug class applied to a yield aggregator protocol. Use as a template for applying all 10 bug classes to a single target.
name: web3-case-study-role-misconfig description: Case study - role misconfiguration bug class applied to a yield aggregator protocol. Use as a template for applying all 10 bug classes to a single target. Contains: architecture walkthrough, all bug class verdicts, 2 findings (DISTRIBUTOR_ROLE never granted, dust harvest DoS), complete PoC templates, report drafts, validation steps.
> Bug Class: Access Control | Severity: Critical/Medium | Payout Range: $10K–$50K > This file shows how to apply the full 10-class methodology to a real yield aggregator target.
---
| Field | Value | |-------|-------| | Protocol Type | Yield aggregator — stablecoin → lending protocol → harvest → DEX → reward token | | Max Bounty | $50K (Critical) | | TVL | Low (fresh program, under $100K) | | Core Contracts | Vault.sol, RewardsDistributor.sol | | Program Age | ~5 days when hunted (fresh = low competition) | | Prior Audits | Firm A (16 findings, all Risk Accepted) + Firm B (18 findings, all Risk Accepted) |
**Scorecard:** Max bounty (+2) + custom math (+1) + recent code (+1) + known prior audits (+1) + public source (+1) + program new (+2) = **8/10 → HUNT**
**Why this scores high:** Fresh program on a live bounty platform + prior audits that accepted all risk = team is aware of issues but hasn't patched them. Hunt for what auditors missed or flagged but accepted.
---
User deposits Stablecoin
↓ deposit(uint256 amount)
Vault.sol stores:
- deposits[user] += amount
- totalDeposited += amount
- depositTimestamp[user] = block.timestamp
↓ safeTransferFrom(user, address(this), amount)
↓ lendingProtocol.supply(stablecoin, amount, address(this), 0)
Interest-bearing token accrues in Vault.sol balance
↓ (periodic) _performHarvest()
aToken balance > totalDeposited + DUST_THRESHOLD
↓ lendingProtocol.withdraw(stablecoin, harvestAmount - 1, address(this))
↓ dex.exactInputSingle(stablecoin → rewardToken)
↓ RewardsDistributor.distribute(rewardToken, amount)
RewardsDistributor tracks:
- cumulativeRewardPerShare updates
- users can call claimFor(user) to collect rewardToken
User withdraws:
↓ withdraw(uint256 amount)
if block.timestamp < depositTimestamp[user] + LOCK_PERIOD:
withdrawFee applies (e.g. 0.5%)
lendingProtocol.withdraw(stablecoin, amount, user)**Key state variables:**
---
All standard: missing events, gas optimizations, reentrancy guards present (CEI followed), centralization risks (owner can pause), single oracle (DEX swap is operational, not security-critical).
Including:
**Pattern:** Firm B flagged "missing check" but didn't verify the role was actually ungranted. This is the gap to exploit.
---
**Finding 1: The `-1` Stranding Pattern**
// In _performHarvest(): harvestAmount = aToken.balanceOf(address(this)) - totalDeposited - 1; // strands 1 wei
The hardcoded `-1` strands 1 wei of stablecoin per harvest permanently. Over thousands of harvests, this accumulates. Severity: LOW/INFORMATIONAL (no user loss, just protocol dust accumulation).
**Finding 2: Dust Harvest DoS** ← VALID MEDIUM
Scenario: Accumulated harvest amount is very tiny (< DEX minimum swap) 1. harvest() calls dex.exactInputSingle(stablecoin → rewardToken) 2. DEX returns 0 (amount too small to produce any output) 3. RewardsDistributor.distribute(0) is called 4. If distribute() reverts on 0 amount → harvest is permanently frozen 5. Users can still withdraw principal but all future yield is lost Verification: Check if distribute(0) reverts. Check DEX minimum swap threshold.
**Finding: DISTRIBUTOR_ROLE Never Granted** ← MAIN FINDING
// RewardsDistributor.sol
bytes32 public constant DISTRIBUTOR_ROLE = keccak256("DISTRIBUTOR_ROLE");
function claimFor(address user) external {
require(hasRole(DISTRIBUTOR_ROLE, msg.sender), "Not distributor");
// ... distribute rewardToken to user
}**Problem:** `DISTRIBUTOR_ROLE` is defined but NEVER granted in the constructor or any initialization function. No address holds this role. `claimFor()` can never succeed — all reward tokens are permanently locked.
**How Firm B missed it:** They flagged "missing check for whether role is set" — but their fix recommendation was "add a require that checks the role exists." They didn't verify that `getRoleMemberCount(DISTRIBUTOR_ROLE) == 0` on the live deployment.
**Severity Assessment:**
**Verification commands:**
# Check if any address has DISTRIBUTOR_ROLE (replace with actual address) cast call <REWARDS_DISTRIBUTOR_ADDR> \ "getRoleMemberCount(bytes32)(uint256)" \ "$(cast keccak 'DISTRIBUTOR_ROLE')" # Expected: 0 = confirmed bug # Alternative: Etherscan → Events → filter "RoleGranted" # If no RoleGranted events with DISTRIBUTOR_ROLE hash = confirmed
#
从想法到产品的 AI 结对编程工作流标准:Prompt + Skill + Context + Quality Gate + 工程闭环 <!-- 徽章区域 (BADGES) --> 本仓库的 AI 解读链接:zread.ai/tukuaiai/vibe-coding-cn 🧠 六条核心命题
Repo: tradecatlabs/vibe-coding-cn
Perform static and symbolic analysis of Solidity smart contracts using
Pre-deployment security audit of Solidity smart contracts in a Foundry project. Combines…
AI-powered tools for Web3 bug bounty automation. Use when you want to automate recon, run…
Complete reference for all 10 DeFi smart contract bug classes. Use this when hunting for…
Master grep command arsenal for Web3 smart contract auditing. Use when starting a new…
Hunter mindset, recon setup, and target scoring for Web3 bug bounty. Use at the START of any…