CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openzeppelin--contracts-upgradeable

Secure Smart Contract library for Solidity with upgradeable implementations of standards like ERC20 and ERC721, flexible role-based permissioning schemes, and reusable components for building custom contracts and complex decentralized systems.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

token-standards.mddocs/

Token Standards

Complete implementations of popular token standards including ERC-20 fungible tokens, ERC-721 NFTs, ERC-1155 multi-tokens, and the draft ERC-6909 standard. All token contracts follow the upgradeable pattern with initialization functions.

Capabilities

ERC-20 Fungible Tokens

Standard implementation of the ERC-20 token interface for fungible tokens.

/**
 * @dev Implementation of the ERC-20 token standard
 */
contract ERC20Upgradeable {
    function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing;
    
    /**
     * @dev Returns the name of the token
     */
    function name() external view returns (string memory);
    
    /**
     * @dev Returns the symbol of the token
     */
    function symbol() external view returns (string memory);
    
    /**
     * @dev Returns the number of decimals used to get user representation
     */
    function decimals() external view returns (uint8);
    
    /**
     * @dev Returns the total token supply
     */
    function totalSupply() external view returns (uint256);
    
    /**
     * @dev Returns the balance of account
     */
    function balanceOf(address account) external view returns (uint256);
    
    /**
     * @dev Moves value tokens from the caller's account to to
     */
    function transfer(address to, uint256 value) external returns (bool);
    
    /**
     * @dev Returns the remaining number of tokens that spender can spend on behalf of owner
     */
    function allowance(address owner, address spender) external view returns (uint256);
    
    /**
     * @dev Sets value as the allowance of spender over the caller's tokens
     */
    function approve(address spender, uint256 value) external returns (bool);
    
    /**
     * @dev Moves value tokens from from to to using the allowance mechanism
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// Events
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);

ERC-20 Extensions

Burnable Extension

/**
 * @dev Extension that allows token holders to destroy tokens
 */
abstract contract ERC20BurnableUpgradeable {
    /**
     * @dev Destroys value tokens from the caller
     */
    function burn(uint256 value) external;
    
    /**
     * @dev Destroys value tokens from account, deducting from the caller's allowance
     */
    function burnFrom(address account, uint256 value) external;
}

Capped Extension

/**
 * @dev Extension that adds a cap to the supply of tokens
 */
abstract contract ERC20CappedUpgradeable {
    function __ERC20Capped_init(uint256 cap_) internal onlyInitializing;
    
    /**
     * @dev Returns the cap on the token's total supply
     */
    function cap() external view returns (uint256);
}

Pausable Extension

/**
 * @dev ERC-20 token with pausable token transfers, minting and burning
 */
abstract contract ERC20PausableUpgradeable {
    function __ERC20Pausable_init() internal onlyInitializing;
    // Inherits pause functionality, automatically pauses transfers when contract is paused
}

Permit Extension (EIP-2612)

/**
 * @dev Implementation of EIP-2612 permit functionality
 */
abstract contract ERC20PermitUpgradeable {
    function __ERC20Permit_init(string memory name) internal onlyInitializing;
    
    /**
     * @dev Sets value as the allowance of spender over owner's tokens via signature
     */
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
    
    /**
     * @dev Returns the current nonce for owner
     */
    function nonces(address owner) external view returns (uint256);
    
    /**
     * @dev Returns the domain separator for the current chain
     */
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

Votes Extension

/**
 * @dev Extension of ERC-20 to support Compound-like voting and delegation
 */
abstract contract ERC20VotesUpgradeable {
    function __ERC20Votes_init() internal onlyInitializing;
    
    /**
     * @dev Returns the current amount of votes that account has
     */
    function getVotes(address account) external view returns (uint256);
    
    /**
     * @dev Returns the amount of votes that account had at the end of the last completed checkpoint
     */
    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);
    
    /**
     * @dev Delegates votes from the sender to delegatee
     */
    function delegate(address delegatee) external;
    
    /**
     * @dev Delegates votes from signer to delegatee
     */
    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}

Wrapper Extension

/**
 * @dev Extension that allows wrapping of an underlying ERC-20 token
 */
abstract contract ERC20WrapperUpgradeable {
    function __ERC20Wrapper_init(IERC20 underlyingToken) internal onlyInitializing;
    
    /**
     * @dev Returns the underlying token
     */
    function underlying() external view returns (IERC20);
    
    /**
     * @dev Allow a user to deposit underlying tokens and mint the corresponding wrapper tokens
     */
    function depositFor(address account, uint256 value) external returns (bool);
    
    /**
     * @dev Allow a user to burn wrapper tokens and withdraw the corresponding underlying tokens
     */
    function withdrawTo(address account, uint256 value) external returns (bool);
}

ERC-4626 Tokenized Vault

/**
 * @dev Implementation of the ERC-4626 "Tokenized Vault Standard"
 */
contract ERC4626Upgradeable {
    function __ERC4626_init(IERC20 asset_) internal onlyInitializing;
    
    /**
     * @dev Returns the address of the underlying token used for the Vault
     */
    function asset() external view returns (address);
    
    /**
     * @dev Returns the total amount of the underlying asset managed by the Vault
     */
    function totalAssets() external view returns (uint256);
    
    /**
     * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided
     */
    function convertToShares(uint256 assets) external view returns (uint256);
    
    /**
     * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided
     */
    function convertToAssets(uint256 shares) external view returns (uint256);
    
    /**
     * @dev Returns the maximum amount of the underlying asset that can be deposited
     */
    function maxDeposit(address receiver) external view returns (uint256);
    
    /**
     * @dev Returns the amount of shares that would be minted for a deposit
     */
    function previewDeposit(uint256 assets) external view returns (uint256);
    
    /**
     * @dev Mints shares to receiver by depositing exactly assets of underlying tokens
     */
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);
    
    /**
     * @dev Mints exactly shares to receiver by depositing assets of underlying tokens
     */
    function mint(uint256 shares, address receiver) external returns (uint256 assets);
    
    /**
     * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver
     */
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
    
    /**
     * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver
     */
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}

// Events
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);

Flash Mint Extension (ERC-3156)

/**
 * @dev Extension that adds flash loan functionality to ERC-20 tokens
 */
abstract contract ERC20FlashMintUpgradeable {
    function __ERC20FlashMint_init() internal onlyInitializing;
    
    /**
     * @dev Returns the maximum amount of tokens available for loan
     */
    function maxFlashLoan(address token) external view returns (uint256);
    
    /**
     * @dev Returns the fee for a flash loan
     */
    function flashFee(address token, uint256 amount) external view returns (uint256);
    
    /**
     * @dev Initiates a flash loan
     */
    function flashLoan(
        IERC3156FlashBorrower receiver,
        address token,
        uint256 amount,
        bytes calldata data
    ) external returns (bool);
}

// Custom errors
error ERC3156UnsupportedToken(address token);
error ERC3156ExceededMaxLoan(uint256 maxLoan);
error ERC3156InvalidReceiver(address receiver);

Wrapper Extension

/**
 * @dev Extension that wraps an existing ERC-20 token
 */
abstract contract ERC20WrapperUpgradeable {
    function __ERC20Wrapper_init(IERC20 underlyingToken) internal onlyInitializing;
    
    /**
     * @dev Returns the underlying token being wrapped
     */
    function underlying() external view returns (IERC20);
    
    /**
     * @dev Deposits underlying tokens and mints wrapper tokens
     */
    function depositFor(address account, uint256 amount) external returns (bool);
    
    /**
     * @dev Withdraws underlying tokens by burning wrapper tokens
     */
    function withdrawTo(address account, uint256 amount) external returns (bool);
    
    /**
     * @dev Recovers any ERC-20 token sent by mistake to the contract
     */
    function _recover(address account) internal returns (uint256);
}

Temporary Approval Extension (Draft)

/**
 * @dev Draft extension for temporary token approvals with expiration
 */
abstract contract ERC20TemporaryApprovalUpgradeable {
    function __ERC20TemporaryApproval_init() internal onlyInitializing;
    
    /**
     * @dev Sets a temporary approval that expires at a specific timestamp
     */
    function temporaryApprove(address spender, uint256 amount, uint256 validUntil) external returns (bool);
    
    /**
     * @dev Returns the temporary allowance details including expiration
     */
    function temporaryAllowance(address owner, address spender) external view returns (uint256 amount, uint256 validUntil);
}

Bridgeable Extension (Draft)

/**
 * @dev Draft extension for cross-chain bridging functionality
 */
abstract contract ERC20BridgeableUpgradeable {
    function __ERC20Bridgeable_init() internal onlyInitializing;
    
    /**
     * @dev Burns tokens for bridging to another chain
     */
    function burnForBridge(address account, uint256 amount, bytes calldata bridgeData) external;
    
    /**
     * @dev Mints tokens from a bridge operation
     */
    function mintFromBridge(address account, uint256 amount, bytes calldata bridgeData) external;
}

ERC-721 Non-Fungible Tokens

Standard implementation of the ERC-721 token interface for non-fungible tokens (NFTs).

/**
 * @dev Implementation of the ERC-721 Non-Fungible Token Standard
 */
contract ERC721Upgradeable {
    function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing;
    
    /**
     * @dev Returns true if this contract implements the interface defined by interfaceId
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    
    /**
     * @dev Returns the number of tokens in owner's account
     */
    function balanceOf(address owner) external view returns (uint256);
    
    /**
     * @dev Returns the owner of the tokenId token
     */
    function ownerOf(uint256 tokenId) external view returns (address);
    
    /**
     * @dev Returns the token collection name
     */
    function name() external view returns (string memory);
    
    /**
     * @dev Returns the token collection symbol
     */
    function symbol() external view returns (string memory);
    
    /**
     * @dev Returns the Uniform Resource Identifier (URI) for tokenId token
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
    
    /**
     * @dev Gives permission to to to transfer tokenId token to another account
     */
    function approve(address to, uint256 tokenId) external;
    
    /**
     * @dev Returns the account approved for tokenId token
     */
    function getApproved(uint256 tokenId) external view returns (address);
    
    /**
     * @dev Approve or remove operator as an operator for the caller
     */
    function setApprovalForAll(address operator, bool approved) external;
    
    /**
     * @dev Returns if the operator is allowed to manage all of the assets of owner
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    
    /**
     * @dev Transfers tokenId token from from to to
     */
    function transferFrom(address from, address to, uint256 tokenId) external;
    
    /**
     * @dev Safely transfers tokenId token from from to to
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    
    /**
     * @dev Safely transfers tokenId token from from to to with additional data
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
}

// Events
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

ERC-721 Extensions

Enumerable Extension

/**
 * @dev Extension of ERC-721 that adds enumerability of all the token ids in the contract
 */
abstract contract ERC721EnumerableUpgradeable {
    function __ERC721Enumerable_init() internal onlyInitializing;
    
    /**
     * @dev Returns a token ID owned by owner at a given index of its token list
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
    
    /**
     * @dev Returns the total amount of tokens stored by the contract
     */
    function totalSupply() external view returns (uint256);
    
    /**
     * @dev Returns a token ID at a given index of all the tokens stored by the contract
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

URI Storage Extension

/**
 * @dev Extension that allows setting individual token URIs
 */
abstract contract ERC721URIStorageUpgradeable {
    function __ERC721URIStorage_init() internal onlyInitializing;
    
    /**
     * @dev Returns the URI for a given token ID
     */
    function tokenURI(uint256 tokenId) external view override returns (string memory);
    
    /**
     * @dev Sets tokenURI as the tokenURI of tokenId
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal;
}

Royalty Extension

/**
 * @dev Extension of ERC-721 that adds ERC-2981 royalty support
 */
abstract contract ERC721RoyaltyUpgradeable {
    function __ERC721Royalty_init() internal onlyInitializing;
    
    /**
     * @dev Returns how much royalty is owed and to whom for tokenId sold at salePrice
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256);
}

Consecutive Extension (ERC-2309)

/**
 * @dev Extension that allows efficient batch minting of consecutive token IDs
 */
abstract contract ERC721ConsecutiveUpgradeable {
    function __ERC721Consecutive_init() internal onlyInitializing;
    
    /**
     * @dev Returns the first token ID in a consecutive batch
     */
    function _firstConsecutiveId() internal view returns (uint96);
    
    /**
     * @dev Returns the next consecutive token ID to be minted
     */
    function _nextConsecutiveId() internal view returns (uint96);
    
    /**
     * @dev Mints consecutive token IDs in a batch
     */
    function _mintConsecutive(address to, uint96 batchSize) internal returns (uint256 first);
    
    /**
     * @dev Maximum batch size for consecutive minting (default: 5000)
     */
    function _maxBatchSize() internal view virtual returns (uint256);
}

// Events (ERC-2309)
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);

Wrapper Extension

/**
 * @dev Extension that wraps existing ERC-721 tokens into new tokens
 */
abstract contract ERC721WrapperUpgradeable {
    function __ERC721Wrapper_init(IERC721 underlyingToken) internal onlyInitializing;
    
    /**
     * @dev Returns the underlying token contract being wrapped
     */
    function underlying() external view returns (IERC721);
    
    /**
     * @dev Deposits an underlying token and mints a wrapped token
     */
    function depositFor(address account, uint256[] calldata tokenIds) external returns (bool);
    
    /**
     * @dev Withdraws underlying tokens by burning wrapped tokens
     */
    function withdrawTo(address account, uint256[] calldata tokenIds) external returns (bool);
}

Burnable Extension

/**
 * @dev Extension that allows token holders to destroy their tokens
 */
abstract contract ERC721BurnableUpgradeable {
    function __ERC721Burnable_init() internal onlyInitializing;
    
    /**
     * @dev Burns tokenId
     */
    function burn(uint256 tokenId) external;
}

Pausable Extension

/**
 * @dev Extension that adds pausable functionality to transfers
 */
abstract contract ERC721PausableUpgradeable {
    function __ERC721Pausable_init() internal onlyInitializing;
    // Inherits pause functionality, automatically pauses transfers when contract is paused
}

Votes Extension

/**
 * @dev Extension that adds vote delegation functionality
 */
abstract contract ERC721VotesUpgradeable {
    function __ERC721Votes_init() internal onlyInitializing;
    
    /**
     * @dev Returns the current amount of votes that account has
     */
    function getVotes(address account) external view returns (uint256);
    
    /**
     * @dev Returns the amount of votes that account had at a specific timepoint
     */
    function getPastVotes(address account, uint256 timepoint) external view returns (uint256);
    
    /**
     * @dev Delegates votes from the sender to delegatee
     */
    function delegate(address delegatee) external;
    
    /**
     * @dev Delegates votes from signer to delegatee using signature
     */
    function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}

ERC-1155 Multi-Token Standard

Implementation of the ERC-1155 Multi Token Standard that supports both fungible and non-fungible tokens.

/**
 * @dev Implementation of the basic standard multi-token
 */
contract ERC1155Upgradeable {
    function __ERC1155_init(string memory uri_) internal onlyInitializing;
    
    /**
     * @dev Returns true if this contract implements the interface defined by interfaceId
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    
    /**
     * @dev Returns the URI for token type id
     */
    function uri(uint256 id) external view returns (string memory);
    
    /**
     * @dev Returns the balance of account's tokens of token type id
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);
    
    /**
     * @dev Returns the balance of multiple account/token pairs
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
    
    /**
     * @dev Grants or revokes permission to operator to transfer the caller's tokens
     */
    function setApprovalForAll(address operator, bool approved) external;
    
    /**
     * @dev Returns true if operator is approved to transfer account's tokens
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);
    
    /**
     * @dev Transfers value tokens of token type id from from to to
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
    
    /**
     * @dev Batch version of safeTransferFrom
     */
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external;
}

// Events
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);

ERC-1155 Extensions

Supply Extension

/**
 * @dev Extension that adds tracking of total supply per token id
 */
abstract contract ERC1155SupplyUpgradeable {
    function __ERC1155Supply_init() internal onlyInitializing;
    
    /**
     * @dev Total value of tokens with a given id
     */
    function totalSupply(uint256 id) external view returns (uint256);
    
    /**
     * @dev Total value of tokens
     */  
    function totalSupply() external view returns (uint256);
    
    /**
     * @dev Indicates whether any token exist with a given id, or not
     */
    function exists(uint256 id) external view returns (bool);
}

Common Token Utilities

ERC-2981 Royalty Standard

/**
 * @dev Implementation of the NFT Royalty Standard
 */
abstract contract ERC2981Upgradeable {
    function __ERC2981_init() internal onlyInitializing;
    
    /**
     * @dev Returns how much royalty is owed and to whom for tokenId sold at salePrice
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256);
    
    /**
     * @dev Sets the royalty information that all ids in this contract will default to
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal;
    
    /**
     * @dev Sets the royalty information for a specific token id
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal;
    
    /**
     * @dev Removes default royalty information
     */
    function _deleteDefaultRoyalty() internal;
    
    /**
     * @dev Resets royalty information for the token id
     */
    function _resetTokenRoyalty(uint256 tokenId) internal;
}

Usage Examples

Basic ERC-20 Token

import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

contract MyToken is ERC20Upgradeable, OwnableUpgradeable {
    function initialize(address initialOwner) initializer public {
        __ERC20_init("MyToken", "MTK");
        __Ownable_init(initialOwner);
    }

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

ERC-721 NFT with Royalties

import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol";
import {ERC721RoyaltyUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721RoyaltyUpgradeable.sol";

contract MyNFT is ERC721Upgradeable, ERC721RoyaltyUpgradeable {
    function initialize() initializer public {
        __ERC721_init("MyNFT", "MNFT");
        __ERC721Royalty_init();
        _setDefaultRoyalty(msg.sender, 250); // 2.5% royalty
    }

    function mint(address to, uint256 tokenId) public {
        _mint(to, tokenId);
    }
}

ERC-4626 Vault

import {ERC4626Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC4626Upgradeable.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract MyVault is ERC4626Upgradeable {
    function initialize(IERC20 asset) initializer public {
        __ERC4626_init(asset);
        __ERC20_init("My Vault Token", "MVT");
    }
    
    function _totalAssets() internal view override returns (uint256) {
        return IERC20(asset()).balanceOf(address(this));
    }
}

Install with Tessl CLI

npx tessl i tessl/npm-openzeppelin--contracts-upgradeable

docs

access-control.md

account-abstraction.md

finance.md

governance.md

index.md

meta-transactions.md

proxy-upgradeability.md

security-utilities.md

token-standards.md

tile.json