TokenFactory
0xb94f65b2a32a5fe9099dd8823f0daf4939b0d0ad
Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
2,804 bytes
ABI entries
20
6 read · 6 write
License
none
Contract information
- Address
- 0xb94f65b2a32a5fe9099dd8823f0daf4939b0d0ad
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.24+commit.e11b9ed9
- Optimization
- Enabled
- Creator
- 0x2d81D59C02…FFe3e95219
- Creation tx
- 0xd25e4b1af6…c9dececb6f
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (6)
feeTo() → address
getTokenCount(address) → uint256
getTokensByCreator(address) → address[]
owner() → address
tierFees(uint256) → uint256
tokensByCreator(address, uint256) → address
Events (4)
FeeToUpdatedOwnershipTransferredTierFeeUpdatedTokenCreated
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_feeTo",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [],
"name": "ReentrancyGuardReentrantCall",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "oldFeeTo",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "newFeeTo",
"type": "address"
}
],
"name": "FeeToUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tier",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "oldFee",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newFee",
"type": "uint256"
}
],
"name": "TierFeeUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tier",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "features",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "name",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "symbol",
"type": "string"
}
],
"name": "TokenCreated",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "bytecode",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "tier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "features",
"type": "uint256"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
}
],
"name": "createToken",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "feeTo",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "creator",
"type": "address"
}
],
"name": "getTokenCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "creator",
"type": "address"
}
],
"name": "getTokensByCreator",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newFeeTo",
"type": "address"
}
],
"name": "setFeeTo",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tier",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "newFee",
"type": "uint256"
}
],
"name": "setTierFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tierFees",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "tokensByCreator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
/**
* @title Tokenry.tools TokenFactory
* @notice Factory contract for deploying token contracts with tiered pricing
*/
contract TokenFactory is Ownable, ReentrancyGuard {
/// @notice Mapping from creator to list of token addresses
mapping(address => address[]) public tokensByCreator;
/// @notice Fee recipient address
address public feeTo;
/// @notice Mapping of Tier ID => Cost in native currency (wei)
/// @dev 0 = Basic, 1 = Advanced
mapping(uint256 => uint256) public tierFees;
/// @notice Event emitted when a token is created
event TokenCreated(
address indexed creator,
address indexed token,
uint256 tier,
uint256 features,
string name,
string symbol
);
/// @notice Event emitted when a tier fee is updated
event TierFeeUpdated(uint256 tier, uint256 oldFee, uint256 newFee);
/// @notice Event emitted when fee recipient is updated
event FeeToUpdated(address oldFeeTo, address newFeeTo);
/**
* @param _feeTo Address to receive creation fees
*/
constructor(address _feeTo) Ownable(msg.sender) {
require(_feeTo != address(0), "TokenFactory: invalid fee recipient");
feeTo = _feeTo;
// Initialize Default Prices (in wei)
tierFees[0] = 1000000000000000; // Basic: 0.001 native currency
tierFees[1] = 3000000000000000; // Advanced: 0.003 native currency
}
/**
* @notice Create a new token contract
* @param bytecode The bytecode of the token contract to deploy
* @param tier The pricing tier (0 for Basic, 1 for Advanced)
* @param features Feature bitmask (for UI/Indexing purposes)
* @param name Token name
* @param symbol Token symbol
* @return token Address of the deployed token contract
*/
function createToken(
bytes memory bytecode,
uint256 tier,
uint256 features,
string memory name,
string memory symbol
) external payable nonReentrant returns (address token) {
uint256 requiredFee = tierFees[tier];
// Ensure the tier exists/has a price set (prevents free deployments on accidental high tiers)
require(requiredFee > 0, "TokenFactory: invalid or disabled tier");
require(msg.value >= requiredFee, "TokenFactory: insufficient fee for this tier");
require(bytecode.length > 0, "TokenFactory: empty bytecode");
assembly {
token := create(0, add(bytecode, 0x20), mload(bytecode))
}
require(token != address(0), "TokenFactory: deployment failed");
tokensByCreator[msg.sender].push(token);
if (msg.value > 0) {
(bool success, ) = feeTo.call{value: msg.value}("");
require(success, "TokenFactory: fee transfer failed");
}
// Emit tier so the UI knows which dashboard to load
emit TokenCreated(msg.sender, token, tier, features, name, symbol);
return token;
}
/**
* @notice Get all tokens created by an address
* @param creator Address of the token creator
* @return Array of token addresses
*/
function getTokensByCreator(address creator) external view returns (address[] memory) {
return tokensByCreator[creator];
}
/**
* @notice Get token count for a creator
* @param creator Address of the token creator
* @return Number of tokens created
*/
function getTokenCount(address creator) external view returns (uint256) {
return tokensByCreator[creator].length;
}
/**
* @notice Update the fee for a specific tier (owner only)
* @param tier The tier ID (0 or 1)
* @param newFee New creation fee in native currency (wei)
*/
function setTierFee(uint256 tier, uint256 newFee) external onlyOwner {
uint256 oldFee = tierFees[tier];
tierFees[tier] = newFee;
emit TierFeeUpdated(tier, oldFee, newFee);
}
/**
* @notice Update the fee recipient (owner only)
* @param newFeeTo New fee recipient address
*/
function setFeeTo(address newFeeTo) external onlyOwner {
require(newFeeTo != address(0), "TokenFactory: invalid fee recipient");
address oldFeeTo = feeTo;
feeTo = newFeeTo;
emit FeeToUpdated(oldFeeTo, newFeeTo);
}
/**
* @notice Withdraw any native currency accidentally sent to this contract (owner only)
*/
function withdraw() external onlyOwner {
(bool success, ) = owner().call{value: address(this).balance}("");
require(success, "TokenFactory: withdraw failed");
}
}
Chain explorer3124msChain node71ms