FactoryConveyor

0x6044a1cb6a323bfe2caf4a8a0bdaeef4d945aa45

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
11,759 bytes
ABI entries
11
6 read · 2 write
License
none

Contract information

Address
0x6044a1cb6a323bfe2caf4a8a0bdaeef4d945aa45
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0x6438dd248b…f032f46057

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (6)

MAX_SALT_TRIES()uint256
WBNB()address
factory()address
findSaltTokenLTWBNB(string, string, bytes32)bytes32, address
getTokenBytecode(string, string)bytes
indexer()address

ABI

[
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_factory",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "_indexer",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "_wbnb",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "OnlyFactory",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "SaltSearchFailed",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "MAX_SALT_TRIES",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "WBNB",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol",
        "type": "string"
      },
      {
        "internalType": "bytes32",
        "name": "salt",
        "type": "bytes32"
      },
      {
        "internalType": "address",
        "name": "originalDeployer",
        "type": "address"
      }
    ],
    "name": "deployToken",
    "outputs": [
      {
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "predicted",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "factory",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol",
        "type": "string"
      },
      {
        "internalType": "bytes32",
        "name": "baseSalt",
        "type": "bytes32"
      }
    ],
    "name": "findSaltTokenLTWBNB",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "saltFound",
        "type": "bytes32"
      },
      {
        "internalType": "address",
        "name": "predicted",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol",
        "type": "string"
      }
    ],
    "name": "getTokenBytecode",
    "outputs": [
      {
        "internalType": "bytes",
        "name": "",
        "type": "bytes"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "indexer",
    "outputs": [
      {
        "internalType": "contract IIndexer",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "_newIndexer",
        "type": "address"
      }
    ],
    "name": "setIndexer",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Source code

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.9;

import "./Token.sol";

contract FactoryConveyor {
    address public immutable factory;
    address public immutable WBNB;
    uint256 public constant MAX_SALT_TRIES = 1024;

    IIndexer public indexer;

    error OnlyFactory();

    modifier onlyFactory() {
        if (msg.sender != factory) revert OnlyFactory();
        _;
    }

    constructor(address _factory, address _indexer, address _wbnb) {
        factory = _factory;
        indexer = IIndexer(_indexer);
        WBNB = _wbnb;
    }

    function setIndexer(address _newIndexer) external onlyFactory {
        indexer = IIndexer(_newIndexer);
    }

    function _tokenInitCode(
        string memory name,
        string memory symbol
    ) internal view returns (bytes memory) {
        return
            abi.encodePacked(
                type(FunToken).creationCode,
                abi.encode(name, symbol, factory, address(indexer))
            );
    }

    function _predictCreate2(
        bytes32 salt,
        bytes32 initCodeHash
    ) internal view returns (address) {
        bytes32 h = keccak256(
            abi.encodePacked(bytes1(0xff), address(this), salt, initCodeHash)
        );
        return address(uint160(uint256(h)));
    }

    function getTokenBytecode(
        string memory name,
        string memory symbol
    ) external view returns (bytes memory) {
        return _tokenInitCode(name, symbol);
    }

    function findSaltTokenLTWBNB(
        string memory name,
        string memory symbol,
        bytes32 baseSalt
    ) external view onlyFactory returns (bytes32 saltFound, address predicted) {
        bytes memory initCode = _tokenInitCode(name, symbol);
        bytes32 initHash = keccak256(initCode);
        uint160 wbnbNum = uint160(WBNB);

        for (uint256 i; i < MAX_SALT_TRIES; ) {
            bytes32 saltCand = keccak256(abi.encodePacked(baseSalt, i));
            address addr = _predictCreate2(saltCand, initHash);
            if (uint160(addr) > wbnbNum) {
                return (saltCand, addr);
            }
            unchecked {
                ++i;
            }
        }
        revert SaltSearchFailed();
    }

    function deployToken(
        string memory name,
        string memory symbol,
        bytes32 salt,
        address originalDeployer
    ) external onlyFactory returns (address token, address predicted) {
        bytes memory initCode = _tokenInitCode(name, symbol);
        bytes32 initHash = keccak256(initCode);

        FunToken t = new FunToken{salt: salt}(
            name,
            symbol,
            factory,
            address(indexer)
        );
        token = address(t);

        predicted = _predictCreate2(salt, initHash);
        require(token == predicted, "CREATE2 address mismatch");

        indexer.emitSaltBruteforced(salt, token);
        indexer.emitERC20TokenCreated(token, originalDeployer);
        indexer.authorizeAddress(token);
    }
}
Chain explorer6955msChain node74ms