0
# Contract Presets
1
2
OpenZeppelin provides ready-to-deploy token contracts with common configurations for rapid development and deployment. These presets combine base token functionality with popular extensions like minting, pausing, and access control.
3
4
## Capabilities
5
6
### ERC20 Presets
7
8
Pre-configured ERC20 token contracts with common patterns and extensions.
9
10
```solidity { .api }
11
/**
12
* ERC20 token, including:
13
* - Preminted initial supply
14
* - No access control mechanism (for minting/pausing)
15
* - Fixed supply (no additional tokens can be minted)
16
*/
17
contract ERC20PresetFixedSupply is ERC20 {
18
/**
19
* Mints initialSupply amount of token and transfers them to owner
20
*/
21
constructor(
22
string memory name,
23
string memory symbol,
24
uint256 initialSupply,
25
address owner
26
) ERC20(name, symbol);
27
}
28
29
/**
30
* ERC20 token, including:
31
* - Ability for holders to burn (destroy) their tokens
32
* - A minter role that allows for token minting (creation)
33
* - A pauser role that allows to stop all token transfers
34
* - Token transfers are pausable
35
*/
36
contract ERC20PresetMinterPauser is ERC20, ERC20Burnable, ERC20Pausable, AccessControl {
37
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
38
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
39
40
/**
41
* Grants DEFAULT_ADMIN_ROLE, MINTER_ROLE and PAUSER_ROLE to the account that deploys the contract
42
*/
43
constructor(string memory name, string memory symbol) ERC20(name, symbol);
44
45
/**
46
* Creates amount new tokens for to
47
* Requirements: the caller must have the MINTER_ROLE
48
*/
49
function mint(address to, uint256 amount) public virtual;
50
51
/**
52
* Pauses all token transfers
53
* Requirements: the caller must have the PAUSER_ROLE
54
*/
55
function pause() public virtual;
56
57
/**
58
* Unpauses all token transfers
59
* Requirements: the caller must have the PAUSER_ROLE
60
*/
61
function unpause() public virtual;
62
}
63
```
64
65
**Usage Examples:**
66
67
```solidity
68
// Deploy a fixed supply token
69
ERC20PresetFixedSupply token = new ERC20PresetFixedSupply(
70
"MyToken",
71
"MTK",
72
1000000 * 10**18, // 1 million tokens
73
msg.sender // owner receives all tokens
74
);
75
76
// Deploy a mintable/pausable token
77
ERC20PresetMinterPauser mintableToken = new ERC20PresetMinterPauser(
78
"MintableToken",
79
"MINT"
80
);
81
82
// Grant minter role to another address
83
mintableToken.grantRole(mintableToken.MINTER_ROLE(), minterAddress);
84
85
// Mint new tokens
86
mintableToken.mint(recipient, 1000 * 10**18);
87
```
88
89
### ERC721 Presets
90
91
Pre-configured ERC721 non-fungible token contracts with common functionality.
92
93
```solidity { .api }
94
/**
95
* ERC721 token, including:
96
* - Ability for holders to burn (destroy) their tokens
97
* - A minter role that allows for token minting (creation)
98
* - A pauser role that allows to stop all token transfers
99
* - Token ID and URI autogeneration
100
*/
101
contract ERC721PresetMinterPauserAutoId is ERC721, ERC721Enumerable, ERC721Burnable, ERC721Pausable, AccessControl {
102
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
103
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
104
105
/**
106
* Grants DEFAULT_ADMIN_ROLE, MINTER_ROLE, and PAUSER_ROLE to the account that deploys the contract
107
*/
108
constructor(
109
string memory name,
110
string memory symbol,
111
string memory baseTokenURI
112
) ERC721(name, symbol);
113
114
/**
115
* Creates a new token for to. Its token ID will be automatically assigned (and available on the emitted Transfer event)
116
* Requirements: the caller must have the MINTER_ROLE
117
*/
118
function mint(address to) public virtual;
119
120
/**
121
* Pauses all token transfers
122
* Requirements: the caller must have the PAUSER_ROLE
123
*/
124
function pause() public virtual;
125
126
/**
127
* Unpauses all token transfers
128
* Requirements: the caller must have the PAUSER_ROLE
129
*/
130
function unpause() public virtual;
131
}
132
```
133
134
**Usage Example:**
135
136
```solidity
137
// Deploy an NFT collection
138
ERC721PresetMinterPauserAutoId nft = new ERC721PresetMinterPauserAutoId(
139
"MyNFTCollection",
140
"MYNFT",
141
"https://api.example.com/metadata/"
142
);
143
144
// Grant minter role
145
nft.grantRole(nft.MINTER_ROLE(), minterAddress);
146
147
// Mint NFTs with auto-incrementing IDs
148
nft.mint(recipient1); // Token ID 1
149
nft.mint(recipient2); // Token ID 2
150
```
151
152
### ERC777 Presets
153
154
Pre-configured ERC777 advanced token contracts.
155
156
```solidity { .api }
157
/**
158
* ERC777 token, including:
159
* - Preminted initial supply
160
* - No access control mechanism (for minting/pausing)
161
* - Fixed supply
162
*/
163
contract ERC777PresetFixedSupply is ERC777 {
164
/**
165
* Mints initialSupply amount of token and transfers them to owner
166
*/
167
constructor(
168
string memory name,
169
string memory symbol,
170
address[] memory defaultOperators,
171
uint256 initialSupply,
172
address owner
173
) ERC777(name, symbol, defaultOperators);
174
}
175
```
176
177
**Usage Example:**
178
179
```solidity
180
address[] memory defaultOperators = new address[](1);
181
defaultOperators[0] = operatorAddress;
182
183
ERC777PresetFixedSupply token777 = new ERC777PresetFixedSupply(
184
"MyAdvancedToken",
185
"MAT",
186
defaultOperators,
187
1000000 * 10**18,
188
msg.sender
189
);
190
```
191
192
### ERC1155 Presets
193
194
Pre-configured ERC1155 multi-token contracts.
195
196
```solidity { .api }
197
/**
198
* ERC1155 token, including:
199
* - Ability for holders to burn (destroy) their tokens
200
* - A minter role that allows for token minting (creation)
201
* - A pauser role that allows to stop all token transfers
202
*/
203
contract ERC1155PresetMinterPauser is ERC1155, ERC1155Burnable, ERC1155Pausable, AccessControl {
204
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
205
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
206
207
/**
208
* Grants DEFAULT_ADMIN_ROLE, MINTER_ROLE, and PAUSER_ROLE to the account that deploys the contract
209
*/
210
constructor(string memory uri) ERC1155(uri);
211
212
/**
213
* Creates amount tokens of token type id, and assigns them to to
214
* Requirements: the caller must have the MINTER_ROLE
215
*/
216
function mint(
217
address to,
218
uint256 id,
219
uint256 amount,
220
bytes memory data
221
) public virtual;
222
223
/**
224
* Batched version of mint
225
*/
226
function mintBatch(
227
address to,
228
uint256[] memory ids,
229
uint256[] memory amounts,
230
bytes memory data
231
) public virtual;
232
233
/**
234
* Pauses all token transfers
235
* Requirements: the caller must have the PAUSER_ROLE
236
*/
237
function pause() public virtual;
238
239
/**
240
* Unpauses all token transfers
241
* Requirements: the caller must have the PAUSER_ROLE
242
*/
243
function unpause() public virtual;
244
}
245
```
246
247
**Usage Example:**
248
249
```solidity
250
// Deploy multi-token contract
251
ERC1155PresetMinterPauser multiToken = new ERC1155PresetMinterPauser(
252
"https://api.example.com/metadata/{id}.json"
253
);
254
255
// Mint different token types
256
multiToken.mint(recipient, 1, 100, ""); // 100 tokens of type 1
257
multiToken.mint(recipient, 2, 1, ""); // 1 token of type 2 (NFT-like)
258
259
// Batch mint
260
uint256[] memory ids = new uint256[](2);
261
uint256[] memory amounts = new uint256[](2);
262
ids[0] = 3; amounts[0] = 50;
263
ids[1] = 4; amounts[1] = 25;
264
multiToken.mintBatch(recipient, ids, amounts, "");
265
```
266
267
## Custom Preset Pattern
268
269
Creating your own preset combining multiple OpenZeppelin components:
270
271
```solidity
272
pragma solidity ^0.8.0;
273
274
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
275
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
276
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Snapshot.sol";
277
import "@openzeppelin/contracts/access/AccessControl.sol";
278
import "@openzeppelin/contracts/security/Pausable.sol";
279
import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
280
281
/**
282
* Custom ERC20 preset with advanced features:
283
* - Burnable tokens
284
* - Snapshot functionality
285
* - Role-based access control
286
* - Pausable transfers
287
* - Gasless approvals with permit
288
*/
289
contract AdvancedERC20Preset is
290
ERC20,
291
ERC20Burnable,
292
ERC20Snapshot,
293
AccessControl,
294
Pausable,
295
ERC20Permit
296
{
297
bytes32 public constant SNAPSHOT_ROLE = keccak256("SNAPSHOT_ROLE");
298
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
299
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
300
301
constructor(
302
string memory name,
303
string memory symbol,
304
address admin,
305
uint256 initialSupply
306
) ERC20(name, symbol) ERC20Permit(name) {
307
_grantRole(DEFAULT_ADMIN_ROLE, admin);
308
_grantRole(SNAPSHOT_ROLE, admin);
309
_grantRole(PAUSER_ROLE, admin);
310
_grantRole(MINTER_ROLE, admin);
311
312
if (initialSupply > 0) {
313
_mint(admin, initialSupply);
314
}
315
}
316
317
function snapshot() public onlyRole(SNAPSHOT_ROLE) {
318
_snapshot();
319
}
320
321
function pause() public onlyRole(PAUSER_ROLE) {
322
_pause();
323
}
324
325
function unpause() public onlyRole(PAUSER_ROLE) {
326
_unpause();
327
}
328
329
function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
330
_mint(to, amount);
331
}
332
333
function _beforeTokenTransfer(
334
address from,
335
address to,
336
uint256 amount
337
) internal override(ERC20, ERC20Snapshot) {
338
super._beforeTokenTransfer(from, to, amount);
339
require(!paused(), "ERC20Pausable: token transfer while paused");
340
}
341
342
// Required override for multiple inheritance
343
function supportsInterface(bytes4 interfaceId)
344
public
345
view
346
override(AccessControl)
347
returns (bool)
348
{
349
return super.supportsInterface(interfaceId);
350
}
351
}
352
```
353
354
## Deployment Scripts
355
356
### Basic Deployment Pattern
357
358
```solidity
359
// SPDX-License-Identifier: MIT
360
pragma solidity ^0.8.0;
361
362
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
363
364
contract TokenDeployer {
365
event TokenDeployed(address indexed token, string name, string symbol);
366
367
function deployMintableToken(
368
string memory name,
369
string memory symbol
370
) external returns (address) {
371
ERC20PresetMinterPauser token = new ERC20PresetMinterPauser(name, symbol);
372
373
// Transfer admin rights to deployer
374
token.grantRole(token.DEFAULT_ADMIN_ROLE(), msg.sender);
375
token.renounceRole(token.DEFAULT_ADMIN_ROLE(), address(this));
376
377
emit TokenDeployed(address(token), name, symbol);
378
return address(token);
379
}
380
}
381
```
382
383
### Factory with Create2
384
385
```solidity
386
import "@openzeppelin/contracts/utils/Create2.sol";
387
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";
388
389
contract DeterministicTokenFactory {
390
using Create2 for bytes32;
391
392
event TokenCreated(address indexed token, bytes32 indexed salt);
393
394
function createToken(
395
string memory name,
396
string memory symbol,
397
uint256 supply,
398
address owner,
399
bytes32 salt
400
) external returns (address) {
401
bytes memory bytecode = abi.encodePacked(
402
type(ERC20PresetFixedSupply).creationCode,
403
abi.encode(name, symbol, supply, owner)
404
);
405
406
address token = Create2.deploy(0, salt, bytecode);
407
emit TokenCreated(token, salt);
408
return token;
409
}
410
411
function predictAddress(
412
string memory name,
413
string memory symbol,
414
uint256 supply,
415
address owner,
416
bytes32 salt
417
) external view returns (address) {
418
bytes memory bytecode = abi.encodePacked(
419
type(ERC20PresetFixedSupply).creationCode,
420
abi.encode(name, symbol, supply, owner)
421
);
422
423
return Create2.computeAddress(salt, keccak256(bytecode));
424
}
425
}
426
```