S

Smart Contract Pro

Powerful agent for agent, developing, production, level. Includes structured workflows, validation checks, and reusable patterns for blockchain web3.

AgentClipticsblockchain web3v1.0.0MIT
0 views0 copies

Smart Contract Pro

An autonomous agent that audits, optimizes, and develops smart contracts β€” performing security analysis, gas optimization, upgrade pattern implementation, and formal verification preparation for Solidity contracts.

When to Use This Agent

Choose Smart Contract Pro when:

  • You need a security audit of existing smart contracts before deployment
  • You want gas optimization for contracts with high transaction volume
  • You need to implement upgradeable contract patterns (UUPS, Transparent Proxy)
  • You are preparing contracts for a formal security audit

Consider alternatives when:

  • You need to build a complete DApp frontend (use a Web3 frontend agent)
  • You need blockchain infrastructure or node management
  • You are writing contracts for non-EVM chains (Solana, Move)

Quick Start

# .claude/agents/smart-contract-pro.yml name: smart-contract-pro description: Audit, optimize, and develop secure smart contracts agent_prompt: | You are a Smart Contract Security Expert. When reviewing contracts: 1. Scan for common vulnerabilities (reentrancy, overflow, access control) 2. Check for gas optimization opportunities 3. Verify upgrade patterns are correctly implemented 4. Review business logic for edge cases 5. Check test coverage and suggest missing tests 6. Generate audit report with severity ratings Severity levels: CRITICAL (funds at risk), HIGH (logic break), MEDIUM (suboptimal), LOW (best practice), INFO (gas savings).

Example invocation:

claude "Audit the staking contract in contracts/Staking.sol for security issues and gas optimization"

Sample audit output:

Smart Contract Audit β€” Staking.sol
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Findings: 2 Critical, 1 High, 3 Medium, 2 Low

[CRITICAL] Reentrancy in withdraw() β€” Line 87
  The external call to transfer ETH happens before state update.
  Attack: Reentrant call re-enters withdraw() with stale balance.
  Fix: Move `balances[msg.sender] = 0` before the transfer call,
       or add ReentrancyGuard modifier.

[CRITICAL] Missing access control on setRewardRate() β€” Line 112
  Any address can call setRewardRate() and drain reward pool.
  Fix: Add `onlyOwner` modifier.

[HIGH] Unbounded loop in distributeRewards() β€” Line 145
  Iterates over all stakers array. At 10K stakers, exceeds gas limit.
  Fix: Use pull-based rewards (users claim individually) instead
       of push-based distribution.

Gas Optimization:
  - Use `uint128` for amounts (saves 1 storage slot per staker)
  - Pack struct fields: address + uint96 in one slot
  - Use `unchecked` for safe arithmetic (saves ~30 gas per operation)
  Estimated savings: 15-20% gas reduction per transaction

Core Concepts

Security Audit Checklist

CategoryVulnerabilitySeverity
ReentrancyExternal calls before state updatesCritical
Access ControlMissing modifiers on sensitive functionsCritical
IntegerOverflow/underflow (pre-0.8.0)High
LogicIncorrect reward calculationsHigh
DOSUnbounded loops, block gas limitMedium
Front-runningUnprotected price-sensitive operationsMedium
CentralizationOwner can drain funds, pause indefinitelyMedium
GasUnnecessary storage reads/writesLow

Gas Optimization Patterns

// Before: 45,000 gas per call function inefficientTransfer(address to, uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] = balances[msg.sender] - amount; balances[to] = balances[to] + amount; emit Transfer(msg.sender, to, amount); } // After: 28,000 gas per call (38% savings) function optimizedTransfer(address to, uint256 amount) public { uint256 senderBalance = balances[msg.sender]; require(senderBalance >= amount, "Insufficient balance"); unchecked { balances[msg.sender] = senderBalance - amount; balances[to] += amount; } emit Transfer(msg.sender, to, amount); } // Storage packing: 2 slots β†’ 1 slot // Before struct Stake { address staker; // slot 1 (20 bytes) uint256 amount; // slot 2 (32 bytes) uint256 timestamp; // slot 3 (32 bytes) } // After struct Stake { address staker; // slot 1 (20 bytes) uint96 amount; // slot 1 (12 bytes) β€” packed with address uint256 timestamp; // slot 2 (32 bytes) }

Configuration

OptionTypeDefaultDescription
auditDepthstring"comprehensive"Depth: quick, standard, comprehensive
gasOptimizebooleantrueInclude gas optimization recommendations
checkUpgradeablebooleantrueVerify upgrade pattern safety
solidityVersionstring"0.8.20"Target Solidity version
generateReportbooleantrueOutput formatted audit report
testCoverageTargetnumber95Minimum test coverage recommendation

Best Practices

  1. Use the checks-effects-interactions pattern universally β€” Every function that makes an external call should validate inputs first (checks), update all contract state second (effects), and make external calls last (interactions). This eliminates reentrancy vulnerabilities by design.

  2. Prefer pull over push for value distribution β€” Instead of looping through users to distribute rewards (push pattern, which hits gas limits), let each user call a claim() function to pull their rewards. Pull patterns are gas-efficient, cannot be DOS-attacked, and scale to unlimited users.

  3. Pack storage variables to save gas β€” Solidity stores each variable in 32-byte slots. An address (20 bytes) followed by a uint256 (32 bytes) uses 2 slots. But an address followed by a uint96 (12 bytes) fits in 1 slot, saving 20,000 gas per write. Reorder struct fields to maximize packing.

  4. Implement timelocks on admin functions β€” Any function that can change critical protocol parameters (fee rates, reward rates, whitelists) should have a timelock delay. This gives users time to react to malicious or accidental parameter changes before they take effect.

  5. Write negative tests β€” test what should NOT happen β€” Most test suites only verify happy paths. Write tests that verify: unauthorized users cannot call admin functions, transfers fail with insufficient balance, paused contracts reject transactions, and overflow inputs revert properly.

Common Issues

Contract upgrade breaks storage layout β€” Adding a new variable between existing ones shifts all subsequent storage slots, corrupting data. Always add new variables at the end of the contract, never between existing ones. Use OpenZeppelin's @openzeppelin/hardhat-upgrades plugin to automatically detect storage layout incompatibilities.

Gas estimation fails for transactions near block gas limit β€” Complex transactions that use 80-90% of the block gas limit may fail if gas prices spike or miners include other transactions first. Design contracts so that no single transaction requires more than 50% of the block gas limit. Break large operations into multiple smaller transactions.

Events not indexed, making off-chain querying expensive β€” Emitting events without indexed parameters forces indexers to scan every event to filter by value. Mark at least one parameter as indexed (e.g., event Transfer(address indexed from, address indexed to, uint256 amount)) to enable efficient filtering by address.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates