Setting Up Your Project

First, given this example and most quickstart documentation will be relying on Forge, make sure you have the latest version of forge installed.

curl -L | bash

Now that you have forge installed, create and navigate to a new directory for your ERC404 project and install ERC404.

forge init
forge install pandora-labs-org/erc404

Creating Your ERC404

An example contract that inherits ERC404 has been provided below. This is just a minimal implementation for quick setup.

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC404} from "erc404/ERC404.sol";

contract ExampleERC404 is Ownable, ERC404 {
    string memory name_,
    string memory symbol_,
    uint8 decimals_,
    uint256 maxTotalSupplyERC721_,
    address initialOwner_
  ) ERC404(name_, symbol_, decimals_) Ownable(initialOwner_) {
    _setERC721TransferExempt(initialOwner_, true);
    _mintERC20(initialOwner_, maxTotalSupplyERC721_ * units, false);

  function tokenURI(uint256 id_) public pure override returns (string memory) {
    return string.concat("", Strings.toString(id_));

  function setERC721TransferExempt(address account_, bool value_) external onlyOwner {
    _setERC721TransferExempt(account_, value_);

That’s it, your all set up with your first ERC404 contract!


To deploy, we’ll again use our current project and set up a simple script, provided below.

contract Deploy is Script {
    string memory name = "Example";
    string memory symbol = "EXMPL";
    uint8 decimals = 18;
    uint256 maxTotalSupplyERC721 = 10000;

    modifier broadcast(address deployer) {

    function run() external override {
        deploy(<Your Deployer Address>);

    function deploy(address deployer) public broadcast(deployer) {
        new ExampleERC404(name, symbol, decimals, maxTotalSupplyERC721, deployer);

Now, you’ll need to run the script through the following command, having defined the deployer private key and rpc endpoint in your local environment.

forge script ./script/Deploy.s.sol:Deploy --broadcast --rpc-url $MAINNET_RPC_URL --private-key $PRIVATE_KEY -vvvv