ForgeTokenDeployerV4
0xe1f4d29d501d446a6db241f0c72a7c36d881b651
Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
1,983 bytes
ABI entries
15
8 read · 1 write
License
none
Contract information
- Address
- 0xe1f4d29d501d446a6db241f0c72a7c36d881b651
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x74093bC238…DCaD2E42f2
- Creation tx
- 0xc56b8b7f1d…f3f8dde1fc
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (8)
cloneInitCodeHash(address) → bytes32
effectiveSalt(address, bytes32) → bytes32
launchManager() → address
plainImplementation() → address
plainInitCodeHash() → bytes32
predictTokenAddress(bool, address, bytes32) → address
rewardsImplementation() → address
rewardsInitCodeHash() → bytes32
Events (1)
TokenDeployed
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "launchManager_",
"type": "address"
},
{
"internalType": "address",
"name": "plainImplementation_",
"type": "address"
},
{
"internalType": "address",
"name": "rewardsImplementation_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "ERC1167FailedCreateClone",
"type": "error"
},
{
"inputs": [],
"name": "InvalidImplementation",
"type": "error"
},
{
"inputs": [],
"name": "InvalidLaunchManager",
"type": "error"
},
{
"inputs": [],
"name": "Unauthorized",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "userSalt",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "bool",
"name": "rewards",
"type": "bool"
}
],
"name": "TokenDeployed",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "cloneInitCodeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "rewards",
"type": "bool"
},
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "supply",
"type": "uint256"
},
{
"internalType": "address",
"name": "recipient",
"type": "address"
},
{
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"internalType": "bytes32",
"name": "userSalt",
"type": "bytes32"
}
],
"name": "deploy",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"internalType": "bytes32",
"name": "userSalt",
"type": "bytes32"
}
],
"name": "effectiveSalt",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "launchManager",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "plainImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "plainInitCodeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "rewards",
"type": "bool"
},
{
"internalType": "address",
"name": "creator",
"type": "address"
},
{
"internalType": "bytes32",
"name": "userSalt",
"type": "bytes32"
}
],
"name": "predictTokenAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "rewardsImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "rewardsInitCodeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {ForgeTokenV4} from "./ForgeTokenV4.sol";
import {ForgeRewardsTokenV4} from "./ForgeRewardsTokenV4.sol";
contract ForgeTokenDeployerV4 {
address public immutable launchManager;
address public immutable plainImplementation;
address public immutable rewardsImplementation;
event TokenDeployed(address indexed token, address indexed creator, bytes32 indexed userSalt, bool rewards);
error InvalidLaunchManager();
error InvalidImplementation();
error Unauthorized();
constructor(address launchManager_, address plainImplementation_, address rewardsImplementation_) {
if (launchManager_ == address(0)) revert InvalidLaunchManager();
if (
plainImplementation_ == address(0) || rewardsImplementation_ == address(0)
|| plainImplementation_.code.length == 0 || rewardsImplementation_.code.length == 0
) revert InvalidImplementation();
launchManager = launchManager_;
plainImplementation = plainImplementation_;
rewardsImplementation = rewardsImplementation_;
}
function effectiveSalt(address creator, bytes32 userSalt) public pure returns (bytes32) {
return keccak256(abi.encodePacked(creator, userSalt));
}
function predictTokenAddress(bool rewards, address creator, bytes32 userSalt) external view returns (address) {
return Clones.predictDeterministicAddress(
rewards ? rewardsImplementation : plainImplementation, effectiveSalt(creator, userSalt), address(this)
);
}
function plainInitCodeHash() external view returns (bytes32) {
return cloneInitCodeHash(plainImplementation);
}
function rewardsInitCodeHash() external view returns (bytes32) {
return cloneInitCodeHash(rewardsImplementation);
}
function cloneInitCodeHash(address implementation) public pure returns (bytes32) {
return keccak256(
abi.encodePacked(
hex"3d602d80600a3d3981f3",
hex"363d3d373d3d3d363d73",
implementation,
hex"5af43d82803e903d91602b57fd5bf3"
)
);
}
function deploy(
bool rewards,
string calldata name,
string calldata symbol,
uint256 supply,
address recipient,
address creator,
bytes32 userSalt
) external returns (address token) {
if (msg.sender != launchManager) revert Unauthorized();
bytes32 salt = effectiveSalt(creator, userSalt);
if (rewards) {
token = Clones.cloneDeterministic(rewardsImplementation, salt);
ForgeRewardsTokenV4(token).initialize(name, symbol, supply, recipient);
} else {
token = Clones.cloneDeterministic(plainImplementation, salt);
ForgeTokenV4(token).initialize(name, symbol, supply, recipient);
}
emit TokenDeployed(token, creator, userSalt, rewards);
}
}
Chain explorer6542msChain node71ms