openzeppelin
Develop Smart Contracts with OpenZeppelin
Adapted from OpenZeppelin's official skill for Scaffold-ETH 2 Solidity projects.
Prerequisites
Check if ./packages/nextjs/scaffold.config.ts exists directly in the current working directory (do not search subdirectories). If it doesn't exist, this is not a Scaffold-ETH 2 project. Follow the instructions at https://docs.scaffoldeth.io/SKILL.md to scaffold it first. If it exists, continue directly with building.
Detect the Solidity framework flavor:
- If
packages/hardhatexists → Hardhat flavor - If
packages/foundryexists → Foundry flavor
Core Principle: Prefer Library Components Over Custom Code
Before writing ANY contract logic, search the installed OpenZeppelin library for an existing component:
- Exact match exists? Import and use it directly — inherit, override only what's needed
- Close match exists? Import and extend — override only functions the library marks as
virtual - No match? Only then write custom logic. Confirm by browsing the library's directory first
Never hand-write what the library already provides:
- Don't write
require(totalSupply() + amount <= cap)whenERC20Cappedexists - Don't write
require(msg.sender == owner)whenOwnableexists - Don't implement token transfer hooks manually when the library's base contracts handle it
- Don't copy library source into your contract — always import from the dependency so the project gets security updates
Pattern Discovery: Read the Installed Source
APIs, override points, and import syntax change between major versions. Don't assume patterns from memory — always verify by reading the installed source.
Step 1: Identify the installed version and browse the library
Find the OpenZeppelin version and locate the installed source:
- Hardhat: check
packages/hardhat/package.jsonfor@openzeppelin/contractsversion, then browsepackages/hardhat/node_modules/@openzeppelin/contracts/ - Foundry: check
packages/foundry/lib/openzeppelin-contracts/and the remappings inpackages/foundry/foundry.toml
Browse the library's directory structure to discover available components. Key directories inside the OZ contracts root:
token/{ERC20,ERC721,ERC1155}/— token standards and their base implementationstoken/{ERC20,ERC721}/extensions/— Capped, Burnable, Pausable, Permit, Votes, Enumerable, etc.access/— Ownable, AccessControl, AccessManagerutils/— ReentrancyGuard, Pausable, math, structs
Step 2: Read the source file for the component you need
Look at:
- Import syntax: how the library's own files import each other — mirror that style. OZ v5+ uses named imports:
// ✅ import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; // ❌ import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; virtualfunctions: only these can be overridden. Functions that were virtual in one version may not be in another- Constructor parameters: what must be passed during deployment
- NatSpec comments:
NOTE: This function is not virtual, {X} should be overridden instead— follow these
Step 3: Extract the minimal integration pattern
From the source, identify only what's needed:
- Imports to add
- Inheritance chain
- Constructor parameters and chaining
- Required overrides (when inheriting multiple contracts that define the same virtual function, you must override it and call
super) - New functions to expose
Step 4: Apply to the user's contract
Integrate into existing code. Check for conflicts: duplicate access control, incompatible inheritance, missing overrides. The Solidity compiler will error if two parent contracts define the same function and you don't explicitly override it.
SE-2 Integration Notes
- OpenZeppelin is pre-installed in both flavors — no additional dependency installation needed
- Contracts:
packages/hardhat/contracts/(Hardhat) orpackages/foundry/contracts/(Foundry) - Deploy scripts:
packages/hardhat/deploy/(Hardhat) orpackages/foundry/script/(Foundry) - Frontend reads contract ABIs from
packages/nextjs/contracts/deployedContracts.ts(auto-generated byyarn deploy)
More from scaffold-eth/scaffold-eth-2
solidity-security
Master smart contract security best practices to prevent common vulnerabilities and implement secure Solidity patterns. Use when writing smart contracts, auditing existing contracts, or implementing security measures for blockchain applications.
10defi-protocol-templates
Implement DeFi protocols with production-ready templates for staking, AMMs, governance, and lending systems. Use when building decentralized finance applications or smart contract protocols.
10ponder
Integrate Ponder into a Scaffold-ETH 2 project for blockchain event indexing. Use when the user wants to: index contract events, add a blockchain backend, set up GraphQL for onchain data, use Ponder with SE-2, or build an indexer for their dApp.
7erc-20
Add an ERC-20 token contract to a Scaffold-ETH 2 project. Use when the user wants to: create a fungible token, deploy an ERC-20, add token minting, build a token transfer UI, or work with ERC-20 tokens in SE-2.
6erc-721
Add an ERC-721 NFT contract to a Scaffold-ETH 2 project. Use when the user wants to: create an NFT collection, deploy an ERC-721, add NFT minting, build an NFT gallery or transfer UI, or work with non-fungible tokens in SE-2.
5siwe
Add Sign-In with Ethereum (SIWE) authentication to a Scaffold-ETH 2 project. Use when the user wants to: add wallet-based login, implement SIWE, authenticate users with their Ethereum wallet, add session management with wallet signing, build sign-in with Ethereum, or add Web3 authentication.
5