or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

access-control.mdcontract-presets.mdcryptography-math.mdgsn-support.mdindex.mdintrospection.mdpayment-mechanisms.mdproxy-patterns.mdsecurity-utilities.mdtoken-standards.md

contract-presets.mddocs/

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

```