UERC20Factory

0x000000e200088d55c39a11f609e5f667729ad49b

Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
13,380 bytes
ABI entries
6
2 read · 1 write
License
none

Contract information

Address
0x000000e200088d55c39a11f609e5f667729ad49b
Chain
Robinhood Chain (4663)
Compiler
v0.8.28+commit.7893614a
Optimization
Enabled
Creation tx
0x98ef78b13a…d5127a07ff

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (2)

getParameters()tuple
getUERC20Address(string, string, uint8, address, bytes32)address

Events (1)

TokenCreated

ABI

[
  {
    "inputs": [],
    "name": "RecipientCannotBeZeroAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TotalSupplyCannotBeZero",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "tokenAddress",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "string",
            "name": "description",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "website",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "image",
            "type": "string"
          },
          {
            "internalType": "bytes",
            "name": "extraData",
            "type": "bytes"
          }
        ],
        "indexed": false,
        "internalType": "struct UERC20Metadata",
        "name": "metadata",
        "type": "tuple"
      }
    ],
    "name": "TokenCreated",
    "type": "event"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol",
        "type": "string"
      },
      {
        "internalType": "uint8",
        "name": "decimals",
        "type": "uint8"
      },
      {
        "internalType": "uint256",
        "name": "totalSupply",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "recipient",
        "type": "address"
      },
      {
        "internalType": "bytes",
        "name": "data",
        "type": "bytes"
      },
      {
        "internalType": "bytes32",
        "name": "graffiti",
        "type": "bytes32"
      }
    ],
    "name": "createToken",
    "outputs": [
      {
        "internalType": "address",
        "name": "tokenAddress",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "getParameters",
    "outputs": [
      {
        "components": [
          {
            "internalType": "uint256",
            "name": "totalSupply",
            "type": "uint256"
          },
          {
            "internalType": "bytes32",
            "name": "graffiti",
            "type": "bytes32"
          },
          {
            "internalType": "address",
            "name": "recipient",
            "type": "address"
          },
          {
            "internalType": "address",
            "name": "creator",
            "type": "address"
          },
          {
            "internalType": "uint8",
            "name": "decimals",
            "type": "uint8"
          },
          {
            "internalType": "string",
            "name": "name",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "symbol",
            "type": "string"
          },
          {
            "components": [
              {
                "internalType": "string",
                "name": "description",
                "type": "string"
              },
              {
                "internalType": "string",
                "name": "website",
                "type": "string"
              },
              {
                "internalType": "string",
                "name": "image",
                "type": "string"
              },
              {
                "internalType": "bytes",
                "name": "extraData",
                "type": "bytes"
              }
            ],
            "internalType": "struct UERC20Metadata",
            "name": "metadata",
            "type": "tuple"
          }
        ],
        "internalType": "struct IUERC20Factory.Parameters",
        "name": "",
        "type": "tuple"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol",
        "type": "string"
      },
      {
        "internalType": "uint8",
        "name": "decimals",
        "type": "uint8"
      },
      {
        "internalType": "address",
        "name": "creator",
        "type": "address"
      },
      {
        "internalType": "bytes32",
        "name": "graffiti",
        "type": "bytes32"
      }
    ],
    "name": "getUERC20Address",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

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

import {UERC20} from "../tokens/UERC20.sol";
import {IUERC20Factory} from "../interfaces/IUERC20Factory.sol";
import {ITokenFactory} from "../interfaces/ITokenFactory.sol";
import {UERC20Metadata} from "../libraries/UERC20MetadataLibrary.sol";
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";

/// @title UERC20Factory
/// @notice Deploys new UERC20 contracts
contract UERC20Factory is IUERC20Factory {
    /// @dev Parameters stored transiently for token initialization
    Parameters private parameters;

    /// @inheritdoc IUERC20Factory
    function getUERC20Address(
        string memory name,
        string memory symbol,
        uint8 decimals,
        address creator,
        bytes32 graffiti
    ) external view returns (address) {
        bytes32 salt = keccak256(abi.encode(name, symbol, decimals, creator, graffiti));
        bytes32 initCodeHash = keccak256(abi.encodePacked(type(UERC20).creationCode));
        return Create2.computeAddress(salt, initCodeHash, address(this));
    }

    /// @inheritdoc IUERC20Factory
    function getParameters() external view returns (Parameters memory) {
        return parameters;
    }

    /// @inheritdoc ITokenFactory
    function createToken(
        string memory name,
        string memory symbol,
        uint8 decimals,
        uint256 totalSupply,
        address recipient,
        bytes calldata data,
        bytes32 graffiti
    ) external returns (address tokenAddress) {
        (UERC20Metadata memory metadata) = abi.decode(data, (UERC20Metadata));

        if (recipient == address(0)) {
            revert RecipientCannotBeZeroAddress();
        }
        if (totalSupply == 0) {
            revert TotalSupplyCannotBeZero();
        }
        // Store parameters transiently for token to access during construction
        parameters = Parameters({
            name: name,
            symbol: symbol,
            totalSupply: totalSupply,
            recipient: recipient,
            decimals: decimals,
            creator: msg.sender,
            metadata: metadata,
            graffiti: graffiti
        });

        // Compute salt based on the core parameters that define a token's identity
        bytes32 salt = keccak256(abi.encode(name, symbol, decimals, msg.sender, graffiti));

        // Deploy the token with the computed salt
        tokenAddress = address(new UERC20{salt: salt}());

        // Clear parameters after deployment
        delete parameters;

        emit TokenCreated(tokenAddress, metadata);
    }
}
Chain explorer4081msChain node105ms