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

token-standards.mddocs/

0

# Token Standards

1

2

OpenZeppelin provides comprehensive implementations of Ethereum token standards including ERC20 (fungible tokens), ERC721 (non-fungible tokens), ERC777 (advanced fungible tokens), and ERC1155 (multi-token standard). Each implementation includes core functionality and optional extensions.

3

4

## Capabilities

5

6

### ERC20 - Fungible Token Standard

7

8

Standard fungible token implementation with optional extensions for burning, capping, pausing, and snapshots.

9

10

```solidity { .api }

11

/**

12

* Interface of the ERC20 standard as defined in the EIP

13

*/

14

interface IERC20 {

15

/**

16

* Returns the amount of tokens in existence

17

*/

18

function totalSupply() external view returns (uint256);

19

20

/**

21

* Returns the amount of tokens owned by account

22

*/

23

function balanceOf(address account) external view returns (uint256);

24

25

/**

26

* Moves amount tokens from the caller's account to recipient

27

* Returns a boolean value indicating whether the operation succeeded

28

* Emits a Transfer event

29

*/

30

function transfer(address recipient, uint256 amount) external returns (bool);

31

32

/**

33

* Returns the remaining number of tokens that spender will be allowed to spend on behalf of owner

34

*/

35

function allowance(address owner, address spender) external view returns (uint256);

36

37

/**

38

* Sets amount as the allowance of spender over the caller's tokens

39

* Returns a boolean value indicating whether the operation succeeded

40

* Emits an Approval event

41

*/

42

function approve(address spender, uint256 amount) external returns (bool);

43

44

/**

45

* Moves amount tokens from sender to recipient using the allowance mechanism

46

* amount is then deducted from the caller's allowance

47

* Returns a boolean value indicating whether the operation succeeded

48

* Emits a Transfer event

49

*/

50

function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

51

52

/**

53

* Emitted when value tokens are moved from one account (from) to another (to)

54

* Note that value may be zero

55

*/

56

event Transfer(address indexed from, address indexed to, uint256 value);

57

58

/**

59

* Emitted when the allowance of a spender for an owner is set by a call to approve

60

* value is the new allowance

61

*/

62

event Approval(address indexed owner, address indexed spender, uint256 value);

63

}

64

65

/**

66

* Implementation of the IERC20 interface with additional metadata extension

67

*/

68

contract ERC20 is Context, IERC20, IERC20Metadata {

69

/**

70

* Returns the name of the token

71

*/

72

function name() public view virtual override returns (string memory);

73

74

/**

75

* Returns the symbol of the token

76

*/

77

function symbol() public view virtual override returns (string memory);

78

79

/**

80

* Returns the number of decimals used to get its user representation

81

* For example, if decimals equals 2, a balance of 505 tokens should be displayed as 5.05

82

*/

83

function decimals() public view virtual override returns (uint8);

84

}

85

```

86

87

**Usage Example:**

88

89

```solidity

90

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

91

92

contract MyToken is ERC20 {

93

constructor() ERC20("MyToken", "MTK") {

94

_mint(msg.sender, 1000000 * 10**decimals());

95

}

96

}

97

```

98

99

### ERC20 Extensions

100

101

Extensions that add functionality to the base ERC20 implementation.

102

103

```solidity { .api }

104

/**

105

* Extension of ERC20 that allows token holders to destroy both their own tokens and those that they have been approved to use

106

*/

107

abstract contract ERC20Burnable is Context, ERC20 {

108

/**

109

* Destroys amount tokens from the caller

110

*/

111

function burn(uint256 amount) public virtual;

112

113

/**

114

* Destroys amount tokens from account, deducting from the caller's allowance

115

*/

116

function burnFrom(address account, uint256 amount) public virtual;

117

}

118

119

/**

120

* Extension of ERC20 that adds a cap to the supply of tokens

121

*/

122

abstract contract ERC20Capped is ERC20 {

123

/**

124

* Returns the cap on the token's total supply

125

*/

126

function cap() public view virtual returns (uint256);

127

}

128

129

/**

130

* ERC20 token with pausable token transfers, minting and burning

131

*/

132

abstract contract ERC20Pausable is ERC20, Pausable {

133

// All transfers, mints, and burns are paused when contract is paused

134

}

135

136

/**

137

* ERC20 token with snapshots

138

*/

139

abstract contract ERC20Snapshot is ERC20 {

140

/**

141

* Retrieves the balance of account at the time snapshotId was created

142

*/

143

function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256);

144

145

/**

146

* Retrieves the total supply at the time snapshotId was created

147

*/

148

function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256);

149

}

150

```

151

152

### SafeERC20

153

154

Wrapper around ERC20 operations that throw on failure for tokens that return false on failure.

155

156

```solidity { .api }

157

/**

158

* Wrappers around ERC20 operations that throw on failure

159

*/

160

library SafeERC20 {

161

using Address for address;

162

163

function safeTransfer(IERC20 token, address to, uint256 value) internal;

164

function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal;

165

function safeApprove(IERC20 token, address spender, uint256 value) internal;

166

function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal;

167

function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal;

168

}

169

```

170

171

### ERC721 - Non-Fungible Token Standard

172

173

Standard non-fungible token implementation with metadata and enumerable extensions.

174

175

```solidity { .api }

176

/**

177

* Required interface of an ERC721 compliant contract

178

*/

179

interface IERC721 {

180

/**

181

* Returns the number of tokens in owner's account

182

*/

183

function balanceOf(address owner) external view returns (uint256 balance);

184

185

/**

186

* Returns the owner of the tokenId token

187

*/

188

function ownerOf(uint256 tokenId) external view returns (address owner);

189

190

/**

191

* Safely transfers tokenId token from from to to

192

*/

193

function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;

194

function safeTransferFrom(address from, address to, uint256 tokenId) external;

195

196

/**

197

* Transfers tokenId token from from to to

198

*/

199

function transferFrom(address from, address to, uint256 tokenId) external;

200

201

/**

202

* Gives permission to to to transfer tokenId token to another account

203

*/

204

function approve(address to, uint256 tokenId) external;

205

206

/**

207

* Returns the account approved for tokenId token

208

*/

209

function getApproved(uint256 tokenId) external view returns (address operator);

210

211

/**

212

* Approve or remove operator as an operator for the caller

213

*/

214

function setApprovalForAll(address operator, bool _approved) external;

215

216

/**

217

* Returns if the operator is allowed to manage all of the assets of owner

218

*/

219

function isApprovedForAll(address owner, address operator) external view returns (bool);

220

221

event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

222

event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

223

event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

224

}

225

226

/**

227

* Implementation of ERC721 Non-Fungible Token Standard, including the Metadata extension

228

*/

229

contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {

230

/**

231

* Returns the token collection name

232

*/

233

function name() public view virtual override returns (string memory);

234

235

/**

236

* Returns the token collection symbol

237

*/

238

function symbol() public view virtual override returns (string memory);

239

240

/**

241

* Returns the Uniform Resource Identifier (URI) for tokenId token

242

*/

243

function tokenURI(uint256 tokenId) public view virtual override returns (string memory);

244

}

245

```

246

247

### ERC777 - Advanced Token Standard

248

249

Advanced fungible token standard with operator permissions and hooks.

250

251

```solidity { .api }

252

/**

253

* Interface of the ERC777Token standard as defined in the EIP

254

*/

255

interface IERC777 {

256

/**

257

* Returns the name of the token

258

*/

259

function name() external view returns (string memory);

260

261

/**

262

* Returns the symbol of the token

263

*/

264

function symbol() external view returns (string memory);

265

266

/**

267

* Returns the smallest part of the token that is not divisible

268

*/

269

function granularity() external view returns (uint256);

270

271

/**

272

* Returns the amount of tokens in existence

273

*/

274

function totalSupply() external view returns (uint256);

275

276

/**

277

* Returns the amount of tokens owned by an account

278

*/

279

function balanceOf(address owner) external view returns (uint256);

280

281

/**

282

* Moves amount of tokens from the caller's account to recipient

283

*/

284

function send(address recipient, uint256 amount, bytes calldata data) external;

285

286

/**

287

* Destroys amount tokens from the caller's account

288

*/

289

function burn(uint256 amount, bytes calldata data) external;

290

291

/**

292

* Returns true if an account is an operator of tokenHolder

293

*/

294

function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

295

296

/**

297

* Make an account an operator of the caller

298

*/

299

function authorizeOperator(address operator) external;

300

301

/**

302

* Revoke an account's operator status for the caller

303

*/

304

function revokeOperator(address operator) external;

305

306

/**

307

* Returns the list of default operators

308

*/

309

function defaultOperators() external view returns (address[] memory);

310

311

/**

312

* Moves amount tokens from holder to recipient

313

*/

314

function operatorSend(address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData) external;

315

316

/**

317

* Destroys amount tokens from account

318

*/

319

function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external;

320

321

event Sent(address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData);

322

event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

323

event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

324

event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

325

event RevokedOperator(address indexed operator, address indexed tokenHolder);

326

}

327

```

328

329

### ERC1155 - Multi Token Standard

330

331

Standard for contracts that manage multiple token types including both fungible and non-fungible tokens.

332

333

```solidity { .api }

334

/**

335

* Required interface of an ERC1155 compliant contract

336

*/

337

interface IERC1155 {

338

/**

339

* Transfers amount tokens of token type id from from to to

340

*/

341

function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;

342

343

/**

344

* Batched version of safeTransferFrom

345

*/

346

function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data) external;

347

348

/**

349

* Returns the amount of tokens of token type id owned by account

350

*/

351

function balanceOf(address account, uint256 id) external view returns (uint256);

352

353

/**

354

* Batched version of balanceOf

355

*/

356

function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);

357

358

/**

359

* Grants or revokes permission to operator to transfer the caller's tokens

360

*/

361

function setApprovalForAll(address operator, bool approved) external;

362

363

/**

364

* Returns true if operator is approved to transfer account's tokens

365

*/

366

function isApprovedForAll(address account, address operator) external view returns (bool);

367

368

event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

369

event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);

370

event ApprovalForAll(address indexed account, address indexed operator, bool approved);

371

event URI(string value, uint256 indexed id);

372

}

373

```

374

375

## Usage Patterns

376

377

### Creating a Basic ERC20 Token

378

379

```solidity

380

pragma solidity ^0.8.0;

381

382

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

383

import "@openzeppelin/contracts/access/Ownable.sol";

384

385

contract MyToken is ERC20, Ownable {

386

constructor() ERC20("MyToken", "MTK") {

387

_mint(msg.sender, 1000000 * 10**decimals());

388

}

389

390

function mint(address to, uint256 amount) public onlyOwner {

391

_mint(to, amount);

392

}

393

}

394

```

395

396

### Creating an ERC721 NFT

397

398

```solidity

399

pragma solidity ^0.8.0;

400

401

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";

402

import "@openzeppelin/contracts/utils/Counters.sol";

403

import "@openzeppelin/contracts/access/Ownable.sol";

404

405

contract MyNFT is ERC721, Ownable {

406

using Counters for Counters.Counter;

407

Counters.Counter private _tokenIds;

408

409

constructor() ERC721("MyNFT", "MNFT") {}

410

411

function mintNFT(address recipient, string memory tokenURI) public onlyOwner returns (uint256) {

412

_tokenIds.increment();

413

uint256 newItemId = _tokenIds.current();

414

_mint(recipient, newItemId);

415

_setTokenURI(newItemId, tokenURI);

416

return newItemId;

417

}

418

}

419

```

420

421

### Safe Token Transfers

422

423

```solidity

424

import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

425

426

contract MyContract {

427

using SafeERC20 for IERC20;

428

429

function transferTokens(IERC20 token, address to, uint256 amount) external {

430

token.safeTransfer(to, amount);

431

}

432

}

433

```