Important config changes must be documented in the PR description
OpenZeppelin Library Selection Standards
When writing Solidity contracts, prioritize using battle-tested OpenZeppelin libraries over custom implementations. Select the appropriate library based on the scenario:
to user-facing functions; keep admin functions unpaused
ERC20 token interaction
SafeERC20
Use
safeTransfer
/
safeTransferFrom
/
safeApprove
instead of raw calls
Rule
Any contract that transfers tokens or ETH MUST use
ReentrancyGuard
+
SafeERC20
Token Standards
Scenario
Library
Notes
Fungible token
ERC20
Base standard
Token with burn mechanism
ERC20Burnable
Adds
burn()
and
burnFrom()
Token with max supply cap
ERC20Capped
Enforces
totalSupply <= cap
Gasless approval (EIP-2612)
ERC20Permit
Saves users approve tx gas
Governance voting token
ERC20Votes
Snapshot-based voting power
NFT
ERC721
Base NFT standard
NFT with enumeration
ERC721Enumerable
Supports
tokenOfOwnerByIndex
queries
Multi-token (FT + NFT mixed)
ERC1155
Game items, batch operations
Utility Libraries
Scenario
Library
Usage
Whitelist / airdrop verification
MerkleProof
Gas-efficient Merkle tree verification
Signature verification
ECDSA
+
EIP712
Off-chain sign + on-chain verify
Auto-increment IDs
Counters
Token ID, order ID generation
Batch function calls
Multicall
Multiple operations in one tx
Address set / uint set
EnumerableSet
Iterable sets with O(1) add/remove/contains
Revenue sharing
PaymentSplitter
Split ETH/token payments by shares
Standardized yield vault
ERC4626
DeFi vault standard
Contract Upgrade
Scenario
Library
Notes
Upgradeable contract (gas efficient)
UUPSUpgradeable
Upgrade logic in implementation contract
Upgradeable contract (admin separated)
TransparentUpgradeableProxy
Upgrade logic in proxy, higher gas
Initializer (replace constructor)
Initializable
Use
initializer
modifier instead of constructor
Rule
New projects prefer
UUPSUpgradeable
; always use
Initializable
for upgradeable contracts
Oracle and Off-Chain Services
Scenario
Library
Notes
Token price data
AggregatorV3Interface
Only for tokens with supported oracle data feeds
Verifiable randomness (lottery/NFT)
VRFConsumerBaseV2
On-chain provably fair random numbers
Automated execution (cron jobs)
AutomationCompatible
Replace centralized keepers
Cross-chain messaging
CCIP
Cross-chain token/message transfer
Library Selection Decision Flow
Does contract handle user funds/tokens?
├── YES → Add ReentrancyGuard + SafeERC20
│ Does it need emergency stop?
│ ├── YES → Add Pausable
│ └── NO → Skip
└── NO → Skip
How many admin roles needed?
├── 1 role → Ownable2Step
├── 2+ roles → AccessControl
└── DAO/governance → TimelockController
Does contract need price data?
├── Token has oracle feed → AggregatorV3Interface
├── No oracle feed → Custom TWAP with min-liquidity check
└── No price needed → Skip
Will contract need upgrades?
├── YES → UUPSUpgradeable + Initializable
└── NO → Standard deployment (immutable)
Anti-Patterns (Do NOT)
Do NOT
write custom
transfer
wrappers — use
SafeERC20
Do NOT
write custom access control modifiers — use
Ownable
/
AccessControl
Do NOT
write custom pause logic — use
Pausable
Do NOT
use
SafeMath
on Solidity >= 0.8.0 — overflow checks are built-in
Do NOT
use
require(token.transfer(...))
— use
token.safeTransfer(...)
via
SafeERC20
Do NOT
use
tx.origin
for auth — use
msg.sender
with
Ownable
/
AccessControl
MCP-Assisted Contract Generation (if available)
When
OpenZeppelinContracts
MCP is configured, prefer using it to generate base contracts instead of writing from scratch:
Contract Type
MCP Tool
When to Use
Fungible token
solidity-erc20
Any new ERC20 token contract
NFT
solidity-erc721
Any new NFT contract
Multi-token
solidity-erc1155
Game items, batch operations
Stablecoin
solidity-stablecoin
Stablecoin with ERC20 compliance
Real-world assets
solidity-rwa
Asset tokenization
Smart account
solidity-account
ERC-4337 account abstraction
Governance
solidity-governor
DAO voting and proposals
Custom
solidity-custom
Non-standard contracts with OZ patterns
Workflow
MCP generates base → apply this skill's naming/structure rules → customize business logic → apply /solidity-security rules
Why MCP over manual
MCP output is validated against the same rule-set as OZ Contracts Wizard — imports, modifiers, security checks are guaranteed correct. Manual coding risks missing imports or using wrong OZ versions.
When NOT to use MCP
Heavily custom contracts with non-standard patterns, contracts that don't fit any OZ template, or when you need fine-grained control from line 1.
Graceful degradation
If MCP is not configured, fall back to the Library Selection Standards above and write contracts manually following all rules in this skill.
Foundry Quick Reference
Operation
Command
Create new project
forge init
Install dependency
forge install openzeppelin-contracts
Build contracts
forge build
Format code
forge fmt
Update remappings
forge remappings