LaunchTokenDeployer
0xde044a3c4321476d9826a98bbc6c50126e29f628
Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
6,296 bytes
ABI entries
10
3 read · 1 write
License
mit
Contract information
- Address
- 0xde044a3c4321476d9826a98bbc6c50126e29f628
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.24+commit.e11b9ed9
- Optimization
- Enabled
- Creator
- 0xF04AA0C4FE…046FA4E0b2
- Creation tx
- 0xc0a8a2ef4f…4a72a97b4a
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (3)
CREATE3_PROXY_BYTECODE_HASH() → bytes32
launchpad() → address
predictTokenAddress(bytes32) → address
Events (1)
TokenDeployed
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "launchpad_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "InvalidAddress",
"type": "error"
},
{
"inputs": [],
"name": "OnlyLaunchpad",
"type": "error"
},
{
"inputs": [],
"name": "ProxyDeploymentFailed",
"type": "error"
},
{
"inputs": [],
"name": "TokenDeploymentFailed",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
}
],
"name": "TokenDeployed",
"type": "event"
},
{
"inputs": [],
"name": "CREATE3_PROXY_BYTECODE_HASH",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
}
],
"name": "deployToken",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "launchpad",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
}
],
"name": "predictTokenAddress",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.24;
import {LaunchToken} from "./LaunchToken.sol";
// ************************************************
// _ _ __ __ ____ ____ ____ _ _ ____ _ _ ____
// / )( \ / \ / \( \( __)( \ ( \/ )( __)( \/ )( __)
// ) __ (( O )( O )) D ( ) _) ) D ( _ / \/ \ ) _) / \/ \ ) _)
// \_)(_/ \__/ \__/(____/(____)(____/(_)\_)(_/(____)\_)(_/(____)
//
// Website: https://hooded.meme
// Author: SwapHood Team (kellkell)
//
// ************************************************
/// @notice Deploys launch tokens to salt-derived addresses with the CREATE3 pattern.
/// @dev The final address depends only on this contract and `salt`, not on token constructor arguments.
contract LaunchTokenDeployer {
error OnlyLaunchpad();
error InvalidAddress();
error ProxyDeploymentFailed();
error TokenDeploymentFailed();
// Creation code for a minimal proxy whose runtime copies calldata into memory and
// CREATEs it. The token is therefore always the proxy's nonce-one CREATE address.
bytes internal constant CREATE3_PROXY_BYTECODE = hex"67363d3d37363d34f03d5260086018f3";
bytes32 public constant CREATE3_PROXY_BYTECODE_HASH = keccak256(CREATE3_PROXY_BYTECODE);
address public immutable launchpad;
event TokenDeployed(address indexed token, bytes32 indexed salt);
constructor(address launchpad_) {
if (launchpad_ == address(0)) revert InvalidAddress();
launchpad = launchpad_;
}
function deployToken(bytes32 salt, string calldata name, string calldata symbol)
external
returns (address token)
{
if (msg.sender != launchpad) revert OnlyLaunchpad();
bytes memory proxyBytecode = CREATE3_PROXY_BYTECODE;
address proxy;
assembly ("memory-safe") {
proxy := create2(0, add(proxyBytecode, 0x20), mload(proxyBytecode), salt)
}
// A used salt leaves the proxy deployed, making CREATE2 return address(0).
if (proxy == address(0)) revert ProxyDeploymentFailed();
token = predictTokenAddress(salt);
bytes memory creationCode =
abi.encodePacked(type(LaunchToken).creationCode, abi.encode(name, symbol, launchpad));
(bool success,) = proxy.call(creationCode);
if (!success || token.code.length == 0) revert TokenDeploymentFailed();
emit TokenDeployed(token, salt);
}
function predictTokenAddress(bytes32 salt) public view returns (address token) {
address proxy = address(
uint160(
uint256(
keccak256(
abi.encodePacked(bytes1(0xff), address(this), salt, CREATE3_PROXY_BYTECODE_HASH)
)
)
)
);
token = address(
uint160(uint256(keccak256(abi.encodePacked(hex"d694", proxy, hex"01"))))
);
}
}
Chain explorer4530msChain node76ms