---
name: openzeppelin
description: "Develop smart contracts using OpenZeppelin Contracts library. Use when the user wants to create or modify Solidity contracts that use OpenZeppelin โ including token standards (ERC20, ERC721, ERC1155), access control (Ownable, AccessControl), security primitives (Pausable, ReentrancyGuard), or any OZ extension. Covers library-first integration, pattern discovery from installed source, and version-safe development."
---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
- 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)