TokenFactory
0x31321e9fef6ff05c5c9c823306fc25f29a33eae8
Verification
Verified
v0.8.20+commit.a1b79de6
Type
Contract
8,897 bytes
ABI entries
27
14 read · 6 write
License
none
Contract information
- Address
- 0x31321e9fef6ff05c5c9c823306fc25f29a33eae8
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.20+commit.a1b79de6
- Optimization
- Enabled
- Creator
- 0x038C66BDA2…831a448385
- Creation tx
- 0xed24e5a797…a20502a942
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (14)
CREATOR_ALLOCATION() → uint256
LIQUIDITY_ALLOCATION() → uint256
feeDistributor() → address
launchCreator(uint256) → address
launchIdByToken(address) → uint256
launchPool(uint256) → address
launchTimestamp(uint256) → uint256
launchToken(uint256) → address
launchTokenId(uint256) → uint256
launcher() → address
nextLaunchId() → uint256
owner() → address
predictTokenAddress(string, string, bytes32) → address
totalLaunches() → uint256
Events (5)
BnbWithdrawnOwnershipTransferredTokenCreatorRecipientUpdatedTokenLaunchedTokenWithdrawn
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "launcher_",
"type": "address"
},
{
"internalType": "address",
"name": "feeDistributor_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "BnbWithdrawn",
"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": true,
"internalType": "uint256",
"name": "launchId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "previousRecipient",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "newRecipient",
"type": "address"
}
],
"name": "TokenCreatorRecipientUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "launchId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes32",
"name": "deploySalt",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "creatorAllocation",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "liquidityAllocation",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "pool",
"type": "address"
}
],
"name": "TokenLaunched",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TokenWithdrawn",
"type": "event"
},
{
"inputs": [],
"name": "CREATOR_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIQUIDITY_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "uint256",
"name": "devBnbAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "minDevTokenAmount",
"type": "uint256"
}
],
"name": "createAndLaunch",
"outputs": [
{
"internalType": "address",
"name": "tokenAddress",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "launchId",
"type": "uint256"
},
{
"internalType": "address",
"name": "pool",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "feeDistributor",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "launchCreator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "launchIdByToken",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "launchPool",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "launchTimestamp",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "launchToken",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "launchTokenId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launcher",
"outputs": [
{
"internalType": "contract LiquidityLauncherV3",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "nextLaunchId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"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"
}
],
"name": "predictTokenAddress",
"outputs": [
{
"internalType": "address",
"name": "tokenAddress",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "launchId",
"type": "uint256"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "setLaunchCreatorRecipient",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "setTokenCreatorRecipient",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "totalLaunches",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "recipient",
"type": "address"
}
],
"name": "withdrawAllBNB",
"outputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "withdrawAllToken",
"outputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import "./StandardToken.sol";
import "./LiquidityLauncherV3.sol";
interface IRescueToken {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
}
interface IFactorySwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
returns (uint256 amountOut);
}
interface IFeeRecipientManager {
function setTokenCreatorRecipientByManager(address token, address creator, address recipient) external;
function tokenCreatorRecipient(address token) external view returns (address);
}
contract TokenFactory {
LiquidityLauncherV3 public immutable launcher;
address public immutable feeDistributor;
address internal constant WETH = 0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73;
address internal constant SWAP_ROUTER = 0xCaf681a66D020601342297493863E78C959E5cb2;
uint24 internal constant FEE = 10000;
uint256 public constant CREATOR_ALLOCATION = 0;
uint256 public constant LIQUIDITY_ALLOCATION = 1_000_000_000 * 10 ** 18;
address public owner;
uint256 public nextLaunchId = 1;
mapping(uint256 => address) public launchToken;
mapping(uint256 => address) public launchCreator;
mapping(uint256 => address) public launchPool;
mapping(uint256 => uint256) public launchTokenId;
mapping(uint256 => uint256) public launchTimestamp;
mapping(address => uint256) public launchIdByToken;
event TokenLaunched(
uint256 indexed launchId,
address indexed token,
address indexed creator,
bytes32 deploySalt,
uint256 creatorAllocation,
uint256 liquidityAllocation,
uint256 tokenId,
address pool
);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event BnbWithdrawn(address indexed recipient, uint256 amount);
event TokenWithdrawn(address indexed token, address indexed recipient, uint256 amount);
event TokenCreatorRecipientUpdated(
uint256 indexed launchId,
address indexed token,
address indexed creator,
address previousRecipient,
address newRecipient
);
modifier onlyOwner() {
require(msg.sender == owner, "ONLY_OWNER");
_;
}
constructor(address launcher_, address feeDistributor_) {
require(launcher_ != address(0), "ZERO_LAUNCHER");
require(feeDistributor_ != address(0), "ZERO_DISTRIBUTOR");
launcher = LiquidityLauncherV3(payable(launcher_));
feeDistributor = feeDistributor_;
owner = msg.sender;
emit OwnershipTransferred(address(0), msg.sender);
}
receive() external payable {}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "ZERO_OWNER");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function withdrawAllBNB(address payable recipient) external onlyOwner returns (uint256 amount) {
require(recipient != address(0), "ZERO_RECIPIENT");
amount = address(this).balance;
(bool ok, ) = recipient.call{value: amount}("");
require(ok, "BNB_WITHDRAW_FAILED");
emit BnbWithdrawn(recipient, amount);
}
function withdrawAllToken(address token, address recipient) external onlyOwner returns (uint256 amount) {
require(token != address(0), "ZERO_TOKEN");
require(recipient != address(0), "ZERO_RECIPIENT");
amount = IRescueToken(token).balanceOf(address(this));
(bool ok, bytes memory data) = token.call(
abi.encodeWithSelector(IRescueToken.transfer.selector, recipient, amount)
);
require(ok && (data.length == 0 || abi.decode(data, (bool))), "TOKEN_WITHDRAW_FAILED");
emit TokenWithdrawn(token, recipient, amount);
}
function setTokenCreatorRecipient(address token, address recipient) external onlyOwner {
require(token != address(0), "ZERO_TOKEN");
uint256 launchId = launchIdByToken[token];
require(launchId != 0, "UNKNOWN_TOKEN");
_setLaunchCreatorRecipient(launchId, recipient);
}
function setLaunchCreatorRecipient(uint256 launchId, address recipient) external onlyOwner {
_setLaunchCreatorRecipient(launchId, recipient);
}
function createAndLaunch(
string calldata name,
string calldata symbol,
bytes32 salt,
uint256 devBnbAmount,
uint256 minDevTokenAmount
) external payable returns (address tokenAddress, uint256 tokenId, uint256 launchId, address pool) {
require(salt != bytes32(0), "SALT_REQUIRED");
require(msg.value >= devBnbAmount, "INSUFFICIENT_BNB");
uint256 previousBalance = address(this).balance - msg.value;
uint256 launchBnbAmount = msg.value - devBnbAmount;
launchId = nextLaunchId++;
tokenAddress = _deployToken(name, symbol, salt);
StandardToken newToken = StandardToken(payable(tokenAddress));
require(newToken.balanceOf(address(this)) == CREATOR_ALLOCATION + LIQUIDITY_ALLOCATION, "BAD_SUPPLY");
newToken.approve(address(launcher), LIQUIDITY_ALLOCATION);
(tokenId, pool) = launcher.launchAndLock{value: launchBnbAmount}(
tokenAddress,
LIQUIDITY_ALLOCATION,
msg.sender
);
if (devBnbAmount > 0) {
uint256 beforeDevBalance = newToken.balanceOf(msg.sender);
_devBuy(tokenAddress, devBnbAmount);
uint256 receivedDevTokens = newToken.balanceOf(msg.sender) - beforeDevBalance;
require(receivedDevTokens >= minDevTokenAmount, "DEV_BUY_SLIPPAGE");
}
uint256 dust = newToken.balanceOf(address(this));
if (dust > 0) newToken.transfer(msg.sender, dust);
uint256 refundable = address(this).balance - previousBalance;
if (refundable > 0) {
(bool ok, ) = payable(msg.sender).call{value: refundable}("");
require(ok, "REFUND_FAILED");
}
launchToken[launchId] = tokenAddress;
launchCreator[launchId] = msg.sender;
launchPool[launchId] = pool;
launchTokenId[launchId] = tokenId;
launchTimestamp[launchId] = block.timestamp;
launchIdByToken[tokenAddress] = launchId;
emit TokenLaunched(
launchId,
tokenAddress,
msg.sender,
salt,
CREATOR_ALLOCATION,
LIQUIDITY_ALLOCATION,
tokenId,
pool
);
}
function _deployToken(
string calldata name,
string calldata symbol,
bytes32 salt
) internal returns (address tokenAddress) {
bytes memory bytecode = abi.encodePacked(
type(StandardToken).creationCode,
abi.encode(name, symbol)
);
tokenAddress = address(
uint160(uint256(keccak256(abi.encodePacked(hex"ff", address(this), salt, keccak256(bytecode)))))
);
StandardToken newToken = new StandardToken{salt: salt}(
name,
symbol
);
require(address(newToken) == tokenAddress, "CREATE2_MISMATCH");
}
function _devBuy(address tokenAddress, uint256 devBnbAmount)
internal
returns (uint256)
{
IFactorySwapRouter.ExactInputSingleParams memory params = IFactorySwapRouter.ExactInputSingleParams({
tokenIn: WETH,
tokenOut: tokenAddress,
fee: FEE,
recipient: msg.sender,
amountIn: devBnbAmount,
amountOutMinimum: 0,
sqrtPriceLimitX96: 0
});
return IFactorySwapRouter(SWAP_ROUTER).exactInputSingle{value: devBnbAmount}(params);
}
function predictTokenAddress(
string calldata name,
string calldata symbol,
bytes32 salt
) external view returns (address tokenAddress) {
bytes memory bytecode = abi.encodePacked(
type(StandardToken).creationCode,
abi.encode(name, symbol)
);
tokenAddress = address(
uint160(uint256(keccak256(abi.encodePacked(hex"ff", address(this), salt, keccak256(bytecode)))))
);
}
function totalLaunches() external view returns (uint256) {
return nextLaunchId - 1;
}
function _setLaunchCreatorRecipient(uint256 launchId, address recipient) internal {
require(launchId > 0 && launchId < nextLaunchId, "UNKNOWN_LAUNCH");
require(recipient != address(0), "ZERO_RECIPIENT");
address token = launchToken[launchId];
address creator = launchCreator[launchId];
require(token != address(0), "TOKEN_NOT_SET");
require(creator != address(0), "CREATOR_NOT_SET");
address previousRecipient = IFeeRecipientManager(feeDistributor).tokenCreatorRecipient(token);
IFeeRecipientManager(feeDistributor).setTokenCreatorRecipientByManager(token, creator, recipient);
emit TokenCreatorRecipientUpdated(launchId, token, creator, previousRecipient, recipient);
}
}
Chain explorer1860msChain node89ms