pragma solidity ^0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract LaunchToken is ERC20 {
address private constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
error AlreadyFinalized();
error InvalidAddress();
error MaxWalletExceeded(address account, uint256 balance, uint256 maximum);
error TradingNotOpen(uint256 opensAt);
error Unauthorized();
uint256 public immutable maxWalletAmount;
uint16 public immutable openingMaxWalletBps;
uint32 public immutable openingProtectionSeconds;
uint32 public immutable tradingDelaySeconds;
address public immutable launchController;
string public metadataURI;
address public pool;
uint256 public tradingOpensAt;
uint256 public openingProtectionEndsAt;
bool public launchFinalized;
mapping(address => bool) public systemExempt;
constructor(
string memory name_,
string memory symbol_,
string memory metadataURI_,
uint256 supply_,
uint16 openingMaxWalletBps_,
uint32 openingProtectionSeconds_,
uint32 tradingDelaySeconds_,
address launchController_
) ERC20(name_, symbol_) {
if (launchController_ == address(0)) revert InvalidAddress();
launchController = launchController_;
metadataURI = metadataURI_;
openingMaxWalletBps = openingMaxWalletBps_;
openingProtectionSeconds = openingProtectionSeconds_;
tradingDelaySeconds = tradingDelaySeconds_;
maxWalletAmount = supply_ * openingMaxWalletBps_ / 10_000;
systemExempt[launchController_] = true;
systemExempt[BURN_ADDRESS] = true;
_mint(launchController_, supply_);
}
function finalizeLaunch(address pool_, address[] calldata exemptions) external {
if (msg.sender != launchController) revert Unauthorized();
if (launchFinalized) revert AlreadyFinalized();
if (pool_ == address(0)) revert InvalidAddress();
pool = pool_;
for (uint256 index; index < exemptions.length; ++index) {
if (exemptions[index] == address(0)) revert InvalidAddress();
systemExempt[exemptions[index]] = true;
}
tradingOpensAt = block.timestamp + tradingDelaySeconds;
openingProtectionEndsAt = tradingOpensAt + openingProtectionSeconds;
launchFinalized = true;
}
function setMetadataURI(string calldata newMetadataURI) external {
if (msg.sender != launchController) revert Unauthorized();
metadataURI = newMetadataURI;
}
function _update(address from, address to, uint256 value) internal override {
if (launchFinalized && from != address(0) && to != address(0)) {
if (block.timestamp < tradingOpensAt && !systemExempt[from] && !systemExempt[to]) {
revert TradingNotOpen(tradingOpensAt);
}
if (
maxWalletAmount != 0 && block.timestamp < openingProtectionEndsAt && to != pool
&& !systemExempt[from] && !systemExempt[to]
) {
uint256 nextBalance = balanceOf(to) + value;
if (nextBalance > maxWalletAmount) {
revert MaxWalletExceeded(to, nextBalance, maxWalletAmount);
}
}
}
super._update(from, to, value);
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "name_",
"type": "string",
"internalType": "string"
},
{
"name": "symbol_",
"type": "string",
"internalType": "string"
},
{
"name": "metadataURI_",
"type": "string",
"internalType": "string"
},
{
"name": "supply_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "openingMaxWalletBps_",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "openingProtectionSeconds_",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "tradingDelaySeconds_",
"type": "uint32",
"internalType": "uint32"
},
{
"name": "launchController_",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AlreadyFinalized",
"type": "error",
"inputs": []
},
{
"name": "ERC20InsufficientAllowance",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "allowance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InsufficientBalance",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InvalidApprover",
"type": "error",
"inputs": [
{
"name": "approver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidReceiver",
"type": "error",
"inputs": [
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSender",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSpender",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "InvalidAddress",
"type": "error",
"inputs": []
},
{
"name": "MaxWalletExceeded",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maximum",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "TradingNotOpen",
"type": "error",
"inputs": [
{
"name": "opensAt",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "Unauthorized",
"type": "error",
"inputs": []
},
{
"name": "Approval",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Transfer",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "allowance",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "approve",
"type": "function",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "decimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "finalizeLaunch",
"type": "function",
"inputs": [
{
"name": "pool_",
"type": "address",
"internalType": "address"
},
{
"name": "exemptions",
"type": "address[]",
"internalType": "address[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "launchController",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "launchFinalized",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "maxWalletAmount",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "metadataURI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "openingMaxWalletBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "openingProtectionEndsAt",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "openingProtectionSeconds",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "pool",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "setMetadataURI",
"type": "function",
"inputs": [
{
"name": "newMetadataURI",
"type": "string",
"internalType": "string"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "symbol",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "systemExempt",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "totalSupply",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "tradingDelaySeconds",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint32",
"internalType": "uint32"
}
],
"stateMutability": "view"
},
{
"name": "tradingOpensAt",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transfer",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "transferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
}
]0x608060408181526004918236101561001657600080fd5b600092833560e01c91826303ee438c14610ae25750816306fdde0314610a1b578163095ea7b31461097157816314b208861461092d57816316f0115b1461090557816318160ddd146108e657816323b872dd146107ee578163250d0b59146107ad578163313ce567146107915781633e39a0cf146105ef5781634889448c146105d0578163558a40ef1461059157816359758dd21461057257816370a082311461053c578163750521f5146103685781638dc3ea6b1461032757816395d89b411461022a57508063a9059cbb146101fa578063aa4bde28146101c0578063d6b5473514610185578063dd62ed3e1461013d5763f6e2f2b51461011757600080fd5b3461013957816003193601126101395760209060ff6009541690519015158152f35b5080fd5b50346101395780600319360112610139578060209261015a610c2a565b610162610c45565b6001600160a01b0391821683526001865283832091168252845220549051908152f35b50346101395760203660031901126101395760ff816020936001600160a01b036101ad610c2a565b168152600a855220541690519015158152f35b5034610139578160031936011261013957602090517f0000000000000000000000000000000000000000000422ca8b0a00a4250000008152f35b5034610139578060031936011261013957602090610223610219610c2a565b6024359033610cb8565b5160018152f35b83833461013957816003193601126101395780519082845461024b81610ba7565b8085529060209060019081811690811561030757506001146102b1575b505050829003601f01601f191682019267ffffffffffffffff84118385101761029e575082918261029a925282610be1565b0390f35b634e487b7160e01b815260418552602490fd5b87875291925085917f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b8484106102f45750505060209150830101858080610268565b80548785018401529282019281016102db565b925050506020925060ff191682850152151560051b830101858080610268565b5050346101395781600319360112610139576020905163ffffffff7f0000000000000000000000000000000000000000000000000000000000000078168152f35b8391503461013957602092602060031936011261053857813567ffffffffffffffff9283821161053457366023830112156105345781810135938411610534576024923660248685010111610530576001600160a01b037f0000000000000000000000006bc352d377167ec262d81861187ad7a77784de811633036105245750506103f4600554610ba7565b601f81116104c5575b508391601f841160011461043d575083839495509261042f575b50508160011b916000199060031b1c19161760055580f35b602492500101358380610417565b91947f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db092601f1985169186915b8383106104a9575050509483600195961061048c575b505050811b0160055580f35b0160240135600019600384901b60f8161c19169055838080610480565b908060018a978483969c8901013581550196019801919061046a565b7f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0601f850160051c8101916020861061051a575b601f0160051c01905b81811061050f57506103fd565b858155600101610502565b90915081906104f9565b516282b42960e81b8152fd5b8580fd5b8480fd5b8280fd5b50503461013957602036600319011261013957806020926001600160a01b03610563610c2a565b16815280845220549051908152f35b5050346101395781600319360112610139576020906008549051908152f35b5050346101395781600319360112610139576020905161ffff7f0000000000000000000000000000000000000000000000000000000000000032168152f35b5050346101395781600319360112610139576020906007549051908152f35b905034610538578160031936011261053857610609610c2a565b67ffffffffffffffff929060243584811161053057366023820112156105305780840135948511610530576024810190602436918760051b010111610530576001600160a01b0391827f0000000000000000000000006bc352d377167ec262d81861187ad7a77784de811633036107825760ff600954166107725782168015610762576001600160a01b03196006541617600655855b85811061071b578661070863ffffffff6106db817f00000000000000000000000000000000000000000000000000000000000000781642610c95565b90816007557f00000000000000000000000000000000000000000000000000000000000000781690610c95565b600855600160ff19600954161760095580f35b8261072f61072a838986610c5b565b610c81565b161561076257808361074761072a6001948a87610c5b565b168852600a602052848820805460ff1916831790550161069f565b5050505163e6c4247b60e01b8152fd5b5050505163475a253560e01b8152fd5b505050516282b42960e81b8152fd5b5050346101395781600319360112610139576020905160128152f35b5050346101395781600319360112610139576020905163ffffffff7f0000000000000000000000000000000000000000000000000000000000000078168152f35b905082346108e35760603660031901126108e35761080a610c2a565b610812610c45565b91604435936001600160a01b03831680835260016020528683203384526020528683205491600019831061084f575b602088610223898989610cb8565b8683106108b75781156108a05733156108895750825260016020908152868320338452815291869020908590039055829061022387610841565b8751634a1406b160e11b8152908101849052602490fd5b875163e602df0560e01b8152908101849052602490fd5b8751637dc7a0d960e11b8152339181019182526020820193909352604081018790528291506060010390fd5b80fd5b5050346101395781600319360112610139576020906002549051908152f35b5050346101395781600319360112610139576020906001600160a01b03600654169051908152f35b505034610139578160031936011261013957602090516001600160a01b037f0000000000000000000000006bc352d377167ec262d81861187ad7a77784de81168152f35b90503461053857816003193601126105385761098b610c2a565b602435903315610a04576001600160a01b03169182156109ed57508083602095338152600187528181208582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b8351634a1406b160e11b8152908101859052602490fd5b835163e602df0560e01b8152808401869052602490fd5b83833461013957816003193601126101395780519082600354610a3d81610ba7565b808552906020906001908181169081156103075750600114610a8b57505050829003601f01601f191682019267ffffffffffffffff84118385101761029e575082918261029a925282610be1565b6003875291925085917fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b848410610acf5750505060209150830101858080610268565b8054878501840152928201928101610ab6565b8490843461053857826003193601126105385782600554610b0281610ba7565b808552906020906001908181169081156103075750600114610b5057505050829003601f01601f191682019267ffffffffffffffff84118385101761029e575082918261029a925282610be1565b6005875291925085917f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db05b848410610b945750505060209150830101858080610268565b8054878501840152928201928101610b7b565b90600182811c92168015610bd7575b6020831014610bc157565b634e487b7160e01b600052602260045260246000fd5b91607f1691610bb6565b6020808252825181830181905290939260005b828110610c1657505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610bf4565b600435906001600160a01b0382168203610c4057565b600080fd5b602435906001600160a01b0382168203610c4057565b9190811015610c6b5760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b0381168103610c405790565b91908201809211610ca257565b634e487b7160e01b600052601160045260246000fd5b90916001600160a01b0391828116928315610ef557808516948515610edc5760ff6009541680610ed4575b80610ecc575b610d81575b505060009083825281602052604082205490838210610d4f575091604082827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef958760209652828652038282205586815220818154019055604051908152a3565b60405163391434e360e21b81526001600160a01b03919091166004820152602481019190915260448101839052606490fd5b60075480421080610eb3575b80610e9a575b610e8257507f0000000000000000000000000000000000000000000422ca8b0a00a425000000918215159081610e76575b81610e67575b5080610e4e575b80610e35575b15610cee57856000526000602052610df484604060002054610c95565b91808311610e025750610cee565b6040516304a43e8b60e51b81526001600160a01b0392909216600483015260248201929092526044810191909152606490fd5b5085600052600a60205260ff6040600020541615610dd7565b5084600052600a60205260ff6040600020541615610dd1565b90506006541686141538610dca565b60085442109150610dc4565b60249060405190630705403160e41b82526004820152fd5b5086600052600a60205260ff6040600020541615610d93565b5085600052600a60205260ff6040600020541615610d8d565b506001610ce9565b506001610ce3565b60405163ec442f0560e01b815260006004820152602490fd5b604051634b637e8f60e11b815260006004820152602490fdfea2646970667358221220f7241b59d011420ecf59af9262211b944589913dd112c10ecba8f487306ea83464736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xf4570c…27935a | 35 days agoMon, 13 Jul 2026 16:13:41 UTC | Transfer | [0] 0x000000000000…a42c1e94 [1] 0x000000000000…61c075cf data: 0x000000000000000000…d5c36b8d |
| 0x2fb4cd…4d952c | 35 days agoMon, 13 Jul 2026 16:12:55 UTC | Approval | [0] 0x000000000000…61c075cf [1] 0x000000000000…3ac78ba3 data: 0xffffffffffffffffff…ffffffff |
| 0xccdd0d…2f3e08 | 35 days agoMon, 13 Jul 2026 16:12:54 UTC | Transfer | [0] 0x000000000000…a42c1e94 [1] 0x000000000000…61c075cf data: 0x000000000000000000…15fb05be |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Approval | [0] 0x000000000000…7784de81 [1] 0x000000000000…6303608a data: 0x000000000000000000…00000000 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Transfer | [0] 0x000000000000…a42c1e94 [1] 0x000000000000…4fed4b11 data: 0x000000000000000000…0979f69e |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Transfer | [0] 0x000000000000…6303608a [1] 0x000000000000…0000dead data: 0x000000000000000000…000030dd |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Approval | [0] 0x000000000000…6303608a [1] 0x000000000000…638de0d3 data: 0x000000000000000000…00000000 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Transfer | [0] 0x000000000000…6303608a [1] 0x000000000000…a42c1e94 data: 0x000000000000000000…e7ffcf23 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Approval | [0] 0x000000000000…6303608a [1] 0x000000000000…638de0d3 data: 0x000000000000000000…e8000000 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Transfer | [0] 0x000000000000…7784de81 [1] 0x000000000000…6303608a data: 0x000000000000000000…e8000000 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Approval | [0] 0x000000000000…7784de81 [1] 0x000000000000…6303608a data: 0x000000000000000000…e8000000 |
| 0xd4a9a7…57f988 | 35 days agoMon, 13 Jul 2026 16:10:46 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…7784de81 data: 0x000000000000000000…e8000000 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x2fb4cd…4d952c | Approve | 8,801,812 | 35 days agoMon, 13 Jul 2026 16:12:55 UTC | 0xebd6…75cf | IN | RobinLiquid | $0.000 ETH | 0.00000236 |