一键导入
weasel-simplify
Solidity code simplification and refactoring for clarity and maintainability. Triggers on weasel simplify, weasel refactor, or weasel clean up.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Solidity code simplification and refactoring for clarity and maintainability. Triggers on weasel simplify, weasel refactor, or weasel clean up.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Static analysis and security review for Solidity smart contracts. Triggers on weasel analyze, weasel audit, weasel scan, weasel review, or weasel check.
Code explanation and understanding for Solidity smart contracts. Triggers on weasel explain, weasel what does, or weasel walkthrough.
False positive filtering for Weasel static analysis results. Triggers on weasel filter, weasel triage, or weasel clean report.
Project overview and audit preparation for smart contract security. Triggers on weasel overview, weasel scope, or weasel onboard.
Attack hypothesis validation for smart contracts. Triggers on weasel validate, weasel check attack, or weasel verify.
Proof of Concept exploit writing for Solidity vulnerabilities. Triggers on weasel poc, weasel prove, weasel exploit, or weasel demonstrate.
| name | weasel-simplify |
| description | Solidity code simplification and refactoring for clarity and maintainability. Triggers on weasel simplify, weasel refactor, or weasel clean up. |
Expert Solidity code simplification specialist focused on enhancing code clarity, consistency, and maintainability while preserving exact functionality.
User wants to modify their codebase for maintainability.
User wants to understand complex code during audit.
Detection: If in audit context (weasel-analyzer was used, or user mentions "audit"), default to Auditor Mode.
Never change what the code does - only how it's written. All features, outputs, and behaviors must remain identical.
Never simplify in a way that introduces vulnerabilities:
Readable code > compact code:
Don't "simplify" into more expensive code. Preserve:
// Before: Deep nesting hides logic
function withdraw(uint256 amount) external {
if (amount > 0) {
if (balances[msg.sender] >= amount) {
if (!paused) {
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
}
}
}
// After: Guards at top, happy path clear
function withdraw(uint256 amount) external {
if (amount == 0) revert ZeroAmount();
if (balances[msg.sender] < amount) revert InsufficientBalance();
if (paused) revert ContractPaused();
balances[msg.sender] -= amount;
payable(msg.sender).transfer(amount);
}
// Before: Same checks in multiple functions
function deposit() external payable {
require(msg.value > 0, "Zero");
require(!paused, "Paused");
// ...
}
function withdraw(uint256 amt) external {
require(amt > 0, "Zero");
require(!paused, "Paused");
// ...
}
// After: DRY with modifiers
modifier whenNotPaused() {
if (paused) revert ContractPaused();
_;
}
modifier nonZero(uint256 value) {
if (value == 0) revert ZeroValue();
_;
}
function deposit() external payable whenNotPaused nonZero(msg.value) { ... }
function withdraw(uint256 amt) external whenNotPaused nonZero(amt) { ... }
// Before: Hard to read
if (amount > 0 && amount <= max && !blocked[msg.sender] && block.timestamp >= start) { ... }
// After: Self-documenting
bool isValidAmount = amount > 0 && amount <= max;
bool isAllowedUser = !blocked[msg.sender];
bool hasStarted = block.timestamp >= start;
if (isValidAmount && isAllowedUser && hasStarted) { ... }
uint256 x = 0 → uint256 x)Security patterns - preserve even if "verbose":
// KEEP: Reentrancy guard
function withdraw() external nonReentrant { ... }
// KEEP: CEI order (Checks-Effects-Interactions)
uint256 amount = balances[msg.sender];
balances[msg.sender] = 0; // Effect BEFORE
(bool ok,) = msg.sender.call{value: amount}(""); // Interaction
require(ok);
// KEEP: Explicit type casts
uint128 small = uint128(bigNumber); // Don't hide conversions
// KEEP: Unchecked blocks
unchecked { ++i; } // Don't "simplify" to i++
Simplified: Vault.sol
Changes:
- withdraw(): 3 nested ifs → early reverts
- Created modifier: whenNotPaused (applied to 4 functions)
- Replaced 8 require strings with custom errors
- Removed 12 lines dead code
Preserved: nonReentrant, CEI pattern, onlyOwner checks
Next: Run tests → forge test
## Simplified View: withdraw()
*For analysis only - original code unchanged*
Core logic (ignoring guards):
1. Get user balance
2. Send ETH to user
3. Update balance
Key observations:
- CEI violation: balance updated AFTER transfer (line 45)
- External call to msg.sender (potential reentrancy target)
- No reentrancy guard visible
This reveals: Potential reentrancy in withdraw()
| Rationalization | Why It's Wrong |
|---|---|
| "This guard looks redundant, I'll remove it" | Guards exist for reasons. Understand before removing. |
| "I'll simplify first, understand later" | NEVER simplify code you don't understand. |
| "The tests pass, so my changes are safe" | Tests can have gaps. Review changes carefully. |
| "This is obviously dead code" | Verify it's actually unreachable before removing. |
| "Fewer lines = better code" | Clarity > brevity. Don't compress for line count. |
| "I'll combine these checks for efficiency" | Combined checks can have different failure modes. Be careful. |
| "This explicit cast is unnecessary" | Explicit casts document intent. Keep them. |