CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-openzeppelin--contracts

Secure Smart Contract library for Solidity with battle-tested implementations of token standards, access control, governance, and essential utilities for building decentralized applications.

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

Comprehensive implementations of Ethereum token standards including ERC20 (fungible tokens), ERC721 (NFTs), and ERC1155 (multi-tokens) with extensive extensions and utilities.

Capabilities

ERC20 Fungible Tokens

Implementation of the ERC20 standard for fungible tokens with full compliance and security features.

/**
 * @dev Implementation of the {IERC20} interface.
 * Abstract contract requiring supply mechanism in derived contracts.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    /**
     * @dev Sets the values for {name} and {symbol}
     * Both values are immutable: they can only be set once during construction
     */
    constructor(string memory name_, string memory symbol_);
    
    /**
     * @dev Returns the name of the token
     */
    function name() public view virtual returns (string memory);
    
    /**
     * @dev Returns the symbol of the token
     */
    function symbol() public view virtual returns (string memory);
    
    /**
     * @dev Returns the number of decimals used to get its user representation
     */
    function decimals() public view virtual returns (uint8);
    
    /**
     * @dev Returns the value of tokens in existence
     */
    function totalSupply() public view virtual returns (uint256);
    
    /**
     * @dev Returns the value of tokens owned by `account`
     */
    function balanceOf(address account) public view virtual returns (uint256);
    
    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     */
    function transfer(address to, uint256 value) public virtual returns (bool);
    
    /**
     * @dev Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner`
     */
    function allowance(address owner, address spender) public view virtual returns (uint256);
    
    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the caller's tokens
     */
    function approve(address spender, uint256 value) public virtual returns (bool);
    
    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     */
    function transferFrom(address from, address to, uint256 value) public virtual returns (bool);
    
    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`
     * Internal function that can be called by derived contracts
     */
    function _mint(address account, uint256 value) internal;
    
    /**
     * @dev Destroys a `value` amount of tokens from `account`
     * Internal function that can be called by derived contracts
     */
    function _burn(address account, uint256 value) internal;
    
    /**
     * @dev Sets `value` as the allowance of `spender` over `owner`'s tokens
     * Internal function that can be called by derived contracts
     */
    function _approve(address owner, address spender, uint256 value) internal;
}

Usage Example:

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

contract MyToken is ERC20, Ownable {
    constructor(address initialOwner) 
        ERC20("MyToken", "MTK") 
        Ownable(initialOwner) 
    {}

    function mint(address to, uint256 amount) public onlyOwner {
        _mint(to, amount);
    }
    
    function burn(uint256 amount) public {
        _burn(msg.sender, amount);
    }
}

ERC20 Extensions

Extended functionality for ERC20 tokens including permits, pausability, burning, and more.

// ERC20 Permit - Gasless approvals via signatures
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
    function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual;
    function nonces(address owner) public view virtual returns (uint256);
    function DOMAIN_SEPARATOR() external view virtual returns (bytes32);
}

// ERC20 Pausable - Emergency pause functionality
abstract contract ERC20Pausable is ERC20, Pausable {
    function _update(address from, address to, uint256 value) internal virtual override whenNotPaused;
}

// ERC20 Burnable - Token burning functionality
abstract contract ERC20Burnable is Context, ERC20 {
    function burn(uint256 value) public virtual;
    function burnFrom(address account, uint256 value) public virtual;
}

// ERC20 Capped - Supply cap functionality
abstract contract ERC20Capped is ERC20 {
    constructor(uint256 cap_);
    function cap() public view virtual returns (uint256);
    function _update(address from, address to, uint256 value) internal virtual override;
}

// ERC20 FlashMint - Flash loan functionality
abstract contract ERC20FlashMint is ERC20, IERC3156FlashLender {
    function maxFlashLoan(address token) public view virtual returns (uint256);
    function flashFee(address token, uint256 value) public view virtual returns (uint256);
    function flashLoan(IERC3156FlashBorrower receiver, address token, uint256 value, bytes calldata data) public virtual returns (bool);
}

// ERC20 Votes - Voting weight tracking for governance
abstract contract ERC20Votes is ERC20, Votes {
    function _update(address from, address to, uint256 value) internal virtual override;
    function getVotes(address account) public view virtual returns (uint256);
    function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256);
}

// ERC4626 Tokenized Vaults - Vault standard for yield-bearing tokens
abstract contract ERC4626 is ERC20, IERC4626 {
    constructor(IERC20 asset_, string memory name_, string memory symbol_);
    function asset() public view virtual returns (address);
    function totalAssets() public view virtual returns (uint256);
    function convertToShares(uint256 assets) public view virtual returns (uint256);
    function convertToAssets(uint256 shares) public view virtual returns (uint256);
    function maxDeposit(address) public view virtual returns (uint256);
    function maxMint(address) public view virtual returns (uint256);
    function maxWithdraw(address owner) public view virtual returns (uint256);
    function maxRedeem(address owner) public view virtual returns (uint256);
    function previewDeposit(uint256 assets) public view virtual returns (uint256);
    function previewMint(uint256 shares) public view virtual returns (uint256);
    function previewWithdraw(uint256 assets) public view virtual returns (uint256);
    function previewRedeem(uint256 shares) public view virtual returns (uint256);
    function deposit(uint256 assets, address receiver) public virtual returns (uint256);
    function mint(uint256 shares, address receiver) public virtual returns (uint256);
    function withdraw(uint256 assets, address receiver, address owner) public virtual returns (uint256);
    function redeem(uint256 shares, address receiver, address owner) public virtual returns (uint256);
}

// ERC1363 Payable Token - Callbacks after transfers and approvals
abstract contract ERC1363 is ERC20, ERC165, IERC1363 {
    function transferAndCall(address to, uint256 value) public returns (bool);
    function transferAndCall(address to, uint256 value, bytes memory data) public virtual returns (bool);
    function transferFromAndCall(address from, address to, uint256 value) public returns (bool);
    function transferFromAndCall(address from, address to, uint256 value, bytes memory data) public virtual returns (bool);
    function approveAndCall(address spender, uint256 value) public returns (bool);
    function approveAndCall(address spender, uint256 value, bytes memory data) public virtual returns (bool);
}

// ERC20Wrapper - Wrap existing ERC20 tokens
abstract contract ERC20Wrapper is ERC20 {
    constructor(IERC20 underlyingToken, string memory name_, string memory symbol_);
    function underlying() public view returns (IERC20);
    function depositFor(address account, uint256 value) public virtual returns (bool);
    function withdrawTo(address account, uint256 value) public virtual returns (bool);
    function recover(address account) public virtual returns (uint256);
}

ERC721 Non-Fungible Tokens

Implementation of the ERC721 standard for non-fungible tokens (NFTs) with metadata support.

/**
 * @dev Implementation of the {IERC721} Non-Fungible Token Standard
 */
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
    /**
     * @dev Sets the values for {name} and {symbol}
     */
    constructor(string memory name_, string memory symbol_);
    
    /**
     * @dev Returns the token collection name
     */
    function name() public view virtual returns (string memory);
    
    /**
     * @dev Returns the token collection symbol
     */
    function symbol() public view virtual returns (string memory);
    
    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token
     */
    function tokenURI(uint256 tokenId) public view virtual returns (string memory);
    
    /**
     * @dev Returns the number of tokens in `owner`'s account
     */
    function balanceOf(address owner) public view virtual returns (uint256);
    
    /**
     * @dev Returns the owner of the `tokenId` token
     */
    function ownerOf(uint256 tokenId) public view virtual returns (address);
    
    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account
     */
    function approve(address to, uint256 tokenId) public virtual;
    
    /**
     * @dev Returns the account approved for `tokenId` token
     */
    function getApproved(uint256 tokenId) public view virtual returns (address);
    
    /**
     * @dev Approve or remove `operator` as an operator for the caller
     */
    function setApprovalForAll(address operator, bool approved) public virtual;
    
    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`
     */
    function isApprovedForAll(address owner, address operator) public view virtual returns (bool);
    
    /**
     * @dev Transfers `tokenId` token from `from` to `to`
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual;
    
    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual;
    
    /**
     * @dev Safely transfers `tokenId` token from `from` to `to` with additional data
     */  
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual;
    
    /**
     * @dev Mints `tokenId` and transfers it to `to`
     * Internal function that can be called by derived contracts
     */
    function _mint(address to, uint256 tokenId) internal;
    
    /**
     * @dev Destroys `tokenId` token
     * Internal function that can be called by derived contracts
     */
    function _burn(uint256 tokenId) internal;
}

Usage Example:

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

contract MyNFT is ERC721, Ownable {
    uint256 private _tokenIdCounter;
    
    constructor(address initialOwner) 
        ERC721("MyNFT", "MNFT") 
        Ownable(initialOwner) 
    {}

    function safeMint(address to) public onlyOwner {
        uint256 tokenId = _tokenIdCounter++;
        _safeMint(to, tokenId);
    }
    
    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        _requireOwned(tokenId);
        return string(abi.encodePacked("https://api.example.com/token/", tokenId));
    }
}

ERC721 Extensions

Extended functionality for ERC721 tokens including enumeration, URI storage, and more.

// ERC721 Enumerable - Token enumeration functionality
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    function totalSupply() public view virtual returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256);
    function tokenByIndex(uint256 index) public view virtual returns (uint256);
}

// ERC721 URI Storage - Per-token URI storage
abstract contract ERC721URIStorage is IERC4906, ERC721 {
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory);
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual;
}

// ERC721 Burnable - Token burning functionality
abstract contract ERC721Burnable is Context, ERC721 {
    function burn(uint256 tokenId) public virtual;
}

// ERC721 Pausable - Emergency pause functionality
abstract contract ERC721Pausable is ERC721, Pausable {
    function _update(address to, uint256 tokenId, address auth) internal virtual override whenNotPaused returns (address);
}

// ERC721 Royalty - EIP-2981 royalty functionality
abstract contract ERC721Royalty is ERC721, ERC2981 {
    function _burn(uint256 tokenId) internal virtual override;
}

ERC1155 Multi-Token Standard

Implementation of the ERC1155 standard supporting multiple token types in a single contract.

/**
 * @dev Implementation of the {IERC1155} Multi Token Standard
 */
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC1155Errors {
    /**
     * @dev Sets the URI for all token types
     */
    constructor(string memory uri_);
    
    /**
     * @dev Returns the URI for token type `id`
     */
    function uri(uint256 id) public view virtual returns (string memory);
    
    /**
     * @dev Returns the value of tokens of token type `id` owned by `account`
     */
    function balanceOf(address account, uint256 id) public view virtual returns (uint256);
    
    /**
     * @dev Batched version of {balanceOf}
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids) public view virtual returns (uint256[] memory);
    
    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens
     */
    function setApprovalForAll(address operator, bool approved) public virtual;
    
    /**
     * @dev Returns true if `operator` is approved to transfer `account`'s tokens
     */
    function isApprovedForAll(address account, address operator) public view virtual returns (bool);
    
    /**
     * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`
     */
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes memory data) public virtual;
    
    /**
     * @dev Batched version of {safeTransferFrom}
     */
    function safeBatchTransferFrom(address from, address to, uint256[] memory ids, uint256[] memory values, bytes memory data) public virtual;
    
    /**
     * @dev Creates a `value` amount of tokens of type `id`, and assigns them to `to`
     * Internal function that can be called by derived contracts
     */
    function _mint(address to, uint256 id, uint256 value, bytes memory data) internal;
    
    /**
     * @dev Batched version of {_mint}
     */
    function _mintBatch(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal;
    
    /**
     * @dev Destroys a `value` amount of tokens of type `id` from `from`
     * Internal function that can be called by derived contracts
     */
    function _burn(address from, uint256 id, uint256 value) internal;
    
    /**
     * @dev Batched version of {_burn}
     */
    function _burnBatch(address from, uint256[] memory ids, uint256[] memory values) internal;
}

Usage Example:

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

contract MyMultiToken is ERC1155, Ownable {
    constructor(address initialOwner) 
        ERC1155("https://api.example.com/token/{id}.json") 
        Ownable(initialOwner) 
    {}

    function mint(address to, uint256 id, uint256 amount, bytes memory data) public onlyOwner {
        _mint(to, id, amount, data);
    }
    
    function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) public onlyOwner {
        _mintBatch(to, ids, amounts, data);
    }
}

ERC6909 Multi-Token with Allowances

Draft implementation of ERC6909 standard providing multi-token functionality with per-token allowances.

/**
 * @dev Implementation of ERC6909 multi-token standard with per-token-type allowances
 * Combines benefits of ERC20 (per-token allowances) with ERC1155 (multi-token support)
 */
abstract contract ERC6909 is Context, ERC165, IERC6909 {
    /**
     * @dev Returns the balance of `owner` for token `id`
     */
    function balanceOf(address owner, uint256 id) public view virtual returns (uint256);
    
    /**
     * @dev Returns the allowance `owner` has given `spender` for token `id`
     */
    function allowance(address owner, address spender, uint256 id) public view virtual returns (uint256);
    
    /**
     * @dev Returns true if `spender` is approved as an operator for `owner`
     */
    function isOperator(address owner, address spender) public view virtual returns (bool);
    
    /**
     * @dev Approve `spender` to spend `amount` of token `id` on behalf of caller
     */
    function approve(address spender, uint256 id, uint256 amount) public virtual returns (bool);
    
    /**
     * @dev Set `spender` as operator for all tokens owned by caller
     */
    function setOperator(address spender, bool approved) public virtual returns (bool);
    
    /**
     * @dev Transfer `amount` of token `id` to `receiver`
     */
    function transfer(address receiver, uint256 id, uint256 amount) public virtual returns (bool);
    
    /**
     * @dev Transfer `amount` of token `id` from `sender` to `receiver`
     */
    function transferFrom(address sender, address receiver, uint256 id, uint256 amount) public virtual returns (bool);
    
    /**
     * @dev Internal function to update balances during transfers
     */
    function _update(address from, address to, uint256 id, uint256 amount) internal virtual;
    
    /**
     * @dev Internal function to mint tokens
     */
    function _mint(address to, uint256 id, uint256 amount) internal;
    
    /**
     * @dev Internal function to burn tokens
     */
    function _burn(address from, uint256 id, uint256 amount) internal;
}

Usage Example:

import "@openzeppelin/contracts/token/ERC6909/draft-ERC6909.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyERC6909Token is ERC6909, Ownable {
    constructor(address initialOwner) Ownable(initialOwner) {}
    
    function mint(address to, uint256 id, uint256 amount) public onlyOwner {
        _mint(to, id, amount);
    }
    
    function burn(address from, uint256 id, uint256 amount) public {
        require(from == msg.sender || isOperator(from, msg.sender) || allowance(from, msg.sender, id) >= amount, "Insufficient permission");
        _burn(from, id, amount);
    }
}

ERC6909 Extensions

ERC6909ContentURI - Provides URI functionality for tokens:

abstract contract ERC6909ContentURI is ERC6909 {
    function contractURI() public view virtual returns (string memory);
    function tokenURI(uint256 id) public view virtual returns (string memory);
}

ERC6909Metadata - Adds name and symbol metadata:

abstract contract ERC6909Metadata is ERC6909 {
    function name(uint256 id) public view virtual returns (string memory);
    function symbol(uint256 id) public view virtual returns (string memory);
    function decimals(uint256 id) public view virtual returns (uint8);
}

ERC6909TokenSupply - Tracks total supply per token:

abstract contract ERC6909TokenSupply is ERC6909 {
    function totalSupply(uint256 id) public view virtual returns (uint256);
    function exists(uint256 id) public view virtual returns (bool);
}

Token Utilities

Utility contracts and libraries for safe token interactions and common patterns.

// Safe ERC20 Operations
library SafeERC20 {
    function safeTransfer(IERC20 token, address to, uint256 value) internal;
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal;
    function safeApprove(IERC20 token, address spender, uint256 value) internal;
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal;
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal;
}

// ERC721 Holder - Safe NFT recipient
contract ERC721Holder is IERC721Receiver {
    function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4);
}

// ERC1155 Holder - Safe multi-token recipient  
contract ERC1155Holder is ERC1155Receiver {
    function onERC1155Received(address, address, uint256, uint256, bytes memory) public virtual returns (bytes4);
    function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory) public virtual returns (bytes4);
}

// ERC2981 Royalty Standard
abstract contract ERC2981 is IERC2981, ERC165 {
    function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual returns (address, uint256);
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator) internal;
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal;
    function _deleteDefaultRoyalty() internal;
    function _deleteTokenRoyalty(uint256 tokenId) internal;
}

Common Interfaces

// ERC20 Interface
interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// ERC721 Interface
interface IERC721 {
    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);
    
    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
    function safeTransferFrom(address from, address to, uint256 tokenId) external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function approve(address to, uint256 tokenId) external;
    function setApprovalForAll(address operator, bool approved) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

// ERC1155 Interface
interface IERC1155 {
    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);
    
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory);
    function setApprovalForAll(address operator, bool approved) external;
    function isApprovedForAll(address account, address operator) external view returns (bool);
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
    function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external;
}

Install with Tessl CLI

npx tessl i tessl/npm-openzeppelin--contracts

docs

access-control.md

account-abstraction.md

finance.md

governance.md

index.md

mathematical-utilities.md

meta-transactions.md

proxy-patterns.md

security-utilities.md

token-standards.md

tile.json