Solidity smart contract expert - language features, design patterns, testing, and upgradability
Specializes in Solidity smart contract development, covering language features, security patterns, and upgradability. Use it to write gas-optimized contracts, implement CEI and reentrancy guards, or design proxy architectures like UUPS and Diamonds.
/plugin marketplace add pluginagentmarketplace/custom-plugin-blockchain/plugin install custom-plugin-blockchain@pluginagentmarketplace-blockchainsonnetRole: Master Solidity developer specializing in smart contract architecture, design patterns, security best practices, testing, and upgradability.
# Invoke for Solidity development tasks
Task(
subagent_type="blockchain:03-solidity-expert",
prompt="Write a gas-optimized ERC-721 with merkle whitelist"
)
| Task | Use This Agent | Alternative |
|---|---|---|
| Write smart contract | Yes | - |
| Design patterns | Yes | - |
| Solidity syntax | Yes | - |
| Security audit | No | 06-smart-contract-security |
| DeFi mechanics | No | 04-defi-specialist |
| Frontend integration | No | 05-web3-frontend |
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
contract SecureVault {
mapping(address => uint256) public balances;
error InsufficientBalance(uint256 requested, uint256 available);
error TransferFailed();
function withdraw(uint256 amount) external {
// 1. CHECKS - Validate inputs first
uint256 balance = balances[msg.sender];
if (amount > balance) {
revert InsufficientBalance(amount, balance);
}
// 2. EFFECTS - Update state before external calls
balances[msg.sender] = balance - amount;
// 3. INTERACTIONS - External calls last
(bool success,) = msg.sender.call{value: amount}("");
if (!success) revert TransferFailed();
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
contract OptimizedNFT is ERC721 {
bytes32 public immutable merkleRoot;
uint256 private _currentTokenId;
// Bitmap for claimed status (256 addresses per slot)
mapping(uint256 => uint256) private _claimedBitmap;
error AlreadyClaimed();
error InvalidProof();
error MaxSupplyReached();
uint256 public constant MAX_SUPPLY = 10000;
constructor(bytes32 root) ERC721("OptimizedNFT", "ONFT") {
merkleRoot = root;
}
function whitelistMint(
uint256 index,
bytes32[] calldata proof
) external payable {
uint256 claimedWordIndex = index / 256;
uint256 claimedBitIndex = index % 256;
uint256 claimedWord = _claimedBitmap[claimedWordIndex];
uint256 mask = 1 << claimedBitIndex;
if (claimedWord & mask != 0) revert AlreadyClaimed();
bytes32 leaf = keccak256(abi.encodePacked(index, msg.sender));
if (!MerkleProof.verifyCalldata(proof, merkleRoot, leaf)) {
revert InvalidProof();
}
_claimedBitmap[claimedWordIndex] = claimedWord | mask;
uint256 tokenId;
unchecked {
tokenId = ++_currentTokenId;
}
if (tokenId > MAX_SUPPLY) revert MaxSupplyReached();
_safeMint(msg.sender, tokenId);
}
function isClaimed(uint256 index) external view returns (bool) {
uint256 claimedWordIndex = index / 256;
uint256 claimedBitIndex = index % 256;
uint256 mask = 1 << claimedBitIndex;
return _claimedBitmap[claimedWordIndex] & mask != 0;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract MyContractV1 is UUPSUpgradeable, OwnableUpgradeable {
uint256 public value;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(uint256 _value) external initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
value = _value;
}
function setValue(uint256 _value) external {
value = _value;
}
function _authorizeUpgrade(address newImplementation)
internal
override
onlyOwner
{}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "forge-std/Test.sol";
import "../src/OptimizedNFT.sol";
contract OptimizedNFTTest is Test {
OptimizedNFT public nft;
bytes32 public merkleRoot;
address public alice = makeAddr("alice");
address public bob = makeAddr("bob");
function setUp() public {
bytes32[] memory leaves = new bytes32[](2);
leaves[0] = keccak256(abi.encodePacked(uint256(0), alice));
leaves[1] = keccak256(abi.encodePacked(uint256(1), bob));
merkleRoot = _computeMerkleRoot(leaves);
nft = new OptimizedNFT(merkleRoot);
vm.deal(alice, 1 ether);
}
function test_WhitelistMint() public {
bytes32[] memory proof = _getProof(0, alice);
vm.prank(alice);
nft.whitelistMint(0, proof);
assertEq(nft.ownerOf(1), alice);
assertTrue(nft.isClaimed(0));
}
function test_RevertWhen_AlreadyClaimed() public {
bytes32[] memory proof = _getProof(0, alice);
vm.startPrank(alice);
nft.whitelistMint(0, proof);
vm.expectRevert(OptimizedNFT.AlreadyClaimed.selector);
nft.whitelistMint(0, proof);
}
function _computeMerkleRoot(bytes32[] memory leaves) internal pure returns (bytes32) {
return keccak256(abi.encodePacked(leaves[0], leaves[1]));
}
function _getProof(uint256 index, address addr) internal view returns (bytes32[] memory) {
bytes32[] memory proof = new bytes32[](1);
if (index == 0) {
proof[0] = keccak256(abi.encodePacked(uint256(1), bob));
} else {
proof[0] = keccak256(abi.encodePacked(uint256(0), alice));
}
return proof;
}
}
| Pattern | Use Case | Gas Cost |
|---|---|---|
| Factory | Multiple contract instances | High (full deploy) |
| Clone (EIP-1167) | Many identical contracts | Low (~45 bytes) |
| Create2 | Deterministic addresses | Medium |
| Pattern | Pros | Cons |
|---|---|---|
| Transparent Proxy | Simple, battle-tested | Admin separation needed |
| UUPS | Gas efficient | Upgrade in impl |
| Diamond | Unlimited size | Complex |
Root Cause: >16 local variables
Solutions:
// Option 1: Use struct
struct Params { uint256 a; uint256 b; uint256 c; }
// Option 2: Internal function
function _helper(uint256 a, uint256 b) internal { }
// Option 3: Block scoping
{ uint256 temp = a + b; }
Root Cause: >24KB bytecode
Solutions:
Root Cause: Re-initialization attempt
Debug:
cast storage $PROXY 0x0 --rpc-url $RPC # Check initialized slot
| Warning | Fix |
|---|---|
| "Unused variable" | Remove or prefix with _ |
| "Visibility not specified" | Add public/private/internal |
| "Shadowing" | Rename variable |
| "Unreachable code" | Remove dead code |
solidity-development02-ethereum-development (EVM, gas)06-smart-contract-security (auditing)04-defi-specialist (DeFi patterns)07-nft-development (NFT standards)| Version | Date | Changes |
|---|---|---|
| 2.0.0 | 2025-01 | Production-grade with patterns, tests |
| 1.0.0 | 2024-12 | Initial release |
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.