// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
type Currency is address;
interface IHooks {}
struct PoolKey {
Currency currency0;
Currency currency1;
uint24 fee;
int24 tickSpacing;
IHooks hooks;
}
interface IERC20Minimal {
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
}
interface IPermit2AllowanceTransfer {
function approve(address token, address spender, uint160 amount, uint48 expiration) external;
}
interface IUniswapV4PositionManager {
function initializePool(PoolKey calldata key, uint160 sqrtPriceX96) external payable returns (int24);
function modifyLiquidities(bytes calldata unlockData, uint256 deadline) external payable;
function nextTokenId() external view returns (uint256);
}
contract BaseLaunchToken {
struct FeeRecipient {
address account;
uint16 bps;
}
uint256 public constant TOTAL_SUPPLY = 100_000_000_000 ether;
uint16 public constant BPS_DENOMINATOR = 10_000;
uint256 public constant MAX_FEE_RECIPIENTS = 20;
string public name;
string public symbol;
string public imageURI;
string public metadataURI;
uint8 public constant decimals = 18;
uint256 public totalSupply;
address public owner;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
FeeRecipient[] private _feeRecipients;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ImageURIUpdated(string imageURI);
event MetadataURIUpdated(string metadataURI);
event FeeRecipientsUpdated(address[] accounts, uint16[] bps);
event ETHDistributed(uint256 amount);
event ERC20Distributed(address indexed token, uint256 amount);
error NotOwner();
error ZeroAddress();
error InvalidFeeBps();
error TooManyFeeRecipients();
error InsufficientBalance();
error InsufficientAllowance();
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
constructor(
string memory name_,
string memory symbol_,
string memory imageURI_,
string memory metadataURI_,
address initialOwner,
address supplyReceiver,
FeeRecipient[] memory feeRecipients_
) {
if (initialOwner == address(0) || supplyReceiver == address(0)) revert ZeroAddress();
name = name_;
symbol = symbol_;
imageURI = imageURI_;
metadataURI = metadataURI_;
owner = initialOwner;
_mint(supplyReceiver, TOTAL_SUPPLY);
_setFeeRecipients(feeRecipients_);
emit OwnershipTransferred(address(0), initialOwner);
emit ImageURIUpdated(imageURI_);
emit MetadataURIUpdated(metadataURI_);
}
receive() external payable {}
function feeRecipientsLength() external view returns (uint256) {
return _feeRecipients.length;
}
function feeRecipientAt(uint256 index) external view returns (address account, uint16 bps) {
FeeRecipient memory recipient = _feeRecipients[index];
return (recipient.account, recipient.bps);
}
function feeRecipients() external view returns (FeeRecipient[] memory) {
return _feeRecipients;
}
function setImageURI(string calldata newImageURI) external onlyOwner {
imageURI = newImageURI;
emit ImageURIUpdated(newImageURI);
}
function setMetadataURI(string calldata newMetadataURI) external onlyOwner {
metadataURI = newMetadataURI;
emit MetadataURIUpdated(newMetadataURI);
}
function setFeeRecipients(FeeRecipient[] calldata newRecipients) external onlyOwner {
_setFeeRecipientsCalldata(newRecipients);
}
function transferOwnership(address newOwner) external onlyOwner {
if (newOwner == address(0)) revert ZeroAddress();
address previousOwner = owner;
owner = newOwner;
emit OwnershipTransferred(previousOwner, newOwner);
}
function renounceOwnership() external onlyOwner {
address previousOwner = owner;
owner = address(0);
emit OwnershipTransferred(previousOwner, address(0));
}
function approve(address spender, uint256 value) external returns (bool) {
allowance[msg.sender][spender] = value;
emit Approval(msg.sender, spender, value);
return true;
}
function transfer(address to, uint256 value) external returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint256 value) external returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) {
if (allowed < value) revert InsufficientAllowance();
unchecked {
allowance[from][msg.sender] = allowed - value;
}
emit Approval(from, msg.sender, allowance[from][msg.sender]);
}
_transfer(from, to, value);
return true;
}
function burn(uint256 value) external {
_burn(msg.sender, value);
}
function burnFrom(address account, uint256 value) external {
uint256 allowed = allowance[account][msg.sender];
if (allowed != type(uint256).max) {
if (allowed < value) revert InsufficientAllowance();
unchecked {
allowance[account][msg.sender] = allowed - value;
}
emit Approval(account, msg.sender, allowance[account][msg.sender]);
}
_burn(account, value);
}
function distributeETH() external onlyOwner {
uint256 amount = address(this).balance;
_distributeETH(amount);
emit ETHDistributed(amount);
}
function distributeERC20(address token) external onlyOwner {
if (token == address(0)) revert ZeroAddress();
uint256 amount = IERC20Minimal(token).balanceOf(address(this));
_distributeERC20(token, amount);
emit ERC20Distributed(token, amount);
}
function _transfer(address from, address to, uint256 value) internal {
if (to == address(0)) revert ZeroAddress();
uint256 fromBalance = balanceOf[from];
if (fromBalance < value) revert InsufficientBalance();
unchecked {
balanceOf[from] = fromBalance - value;
balanceOf[to] += value;
}
emit Transfer(from, to, value);
}
function _mint(address to, uint256 value) internal {
if (to == address(0)) revert ZeroAddress();
totalSupply += value;
balanceOf[to] += value;
emit Transfer(address(0), to, value);
}
function _burn(address from, uint256 value) internal {
uint256 fromBalance = balanceOf[from];
if (fromBalance < value) revert InsufficientBalance();
unchecked {
balanceOf[from] = fromBalance - value;
totalSupply -= value;
}
emit Transfer(from, address(0), value);
}
function _setFeeRecipients(FeeRecipient[] memory recipients) internal {
if (recipients.length > MAX_FEE_RECIPIENTS) revert TooManyFeeRecipients();
delete _feeRecipients;
uint256 totalBps;
address[] memory accounts = new address[](recipients.length);
uint16[] memory bps = new uint16[](recipients.length);
for (uint256 i; i < recipients.length; ++i) {
if (recipients[i].account == address(0)) revert ZeroAddress();
if (recipients[i].bps == 0) revert InvalidFeeBps();
totalBps += recipients[i].bps;
_feeRecipients.push(recipients[i]);
accounts[i] = recipients[i].account;
bps[i] = recipients[i].bps;
}
if (recipients.length != 0 && totalBps != BPS_DENOMINATOR) revert InvalidFeeBps();
emit FeeRecipientsUpdated(accounts, bps);
}
function _setFeeRecipientsCalldata(FeeRecipient[] calldata recipients) internal {
if (recipients.length > MAX_FEE_RECIPIENTS) revert TooManyFeeRecipients();
delete _feeRecipients;
uint256 totalBps;
address[] memory accounts = new address[](recipients.length);
uint16[] memory bps = new uint16[](recipients.length);
for (uint256 i; i < recipients.length; ++i) {
if (recipients[i].account == address(0)) revert ZeroAddress();
if (recipients[i].bps == 0) revert InvalidFeeBps();
totalBps += recipients[i].bps;
_feeRecipients.push(FeeRecipient({account: recipients[i].account, bps: recipients[i].bps}));
accounts[i] = recipients[i].account;
bps[i] = recipients[i].bps;
}
if (recipients.length != 0 && totalBps != BPS_DENOMINATOR) revert InvalidFeeBps();
emit FeeRecipientsUpdated(accounts, bps);
}
function _distributeETH(uint256 amount) internal {
if (_feeRecipients.length == 0 || amount == 0) return;
uint256 sent;
for (uint256 i; i < _feeRecipients.length; ++i) {
uint256 share = i == _feeRecipients.length - 1
? amount - sent
: amount * _feeRecipients[i].bps / BPS_DENOMINATOR;
sent += share;
(bool ok,) = _feeRecipients[i].account.call{value: share}("");
require(ok, "ETH_TRANSFER_FAILED");
}
}
function _distributeERC20(address token, uint256 amount) internal {
if (_feeRecipients.length == 0 || amount == 0) return;
uint256 sent;
for (uint256 i; i < _feeRecipients.length; ++i) {
uint256 share = i == _feeRecipients.length - 1
? amount - sent
: amount * _feeRecipients[i].bps / BPS_DENOMINATOR;
sent += share;
require(IERC20Minimal(token).transfer(_feeRecipients[i].account, share), "ERC20_TRANSFER_FAILED");
}
}
}
contract A20ProtocolLauncher {
uint16 private constant BPS_DENOMINATOR = 10_000;
uint16 public constant OFFICIAL_FEE_BPS = 100;
struct LockedV4Position {
uint256 tokenId;
Currency currency0;
Currency currency1;
bool exists;
}
struct LaunchPoolParams {
PoolKey key;
uint160 sqrtPriceX96;
int24 tickLower;
int24 tickUpper;
uint128 amount0Max;
uint128 amount1Max;
uint256 liquidity;
}
struct TokenParams {
string name;
string symbol;
string imageURI;
string metadataURI;
address owner;
}
address public constant ETHEREUM_V4_POSITION_MANAGER = 0xbD216513d74C8cf14cf4747E6AaA6420FF64ee9e;
address public constant ETHEREUM_PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
address public constant ETHEREUM_WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
uint24 public constant DEFAULT_LP_FEE = 10_000;
int24 public constant DEFAULT_TICK_SPACING = 200;
uint128 public constant DEFAULT_TOKEN_AMOUNT_MAX = 100_000_000_000 ether;
uint160 public constant INITIAL_SQRT_PRICE_X96_TOKEN_PER_WETH_10_ETH_MARKET_CAP =
7_974_470_913_604_094_264_140_738_513_890_252;
uint160 public constant INITIAL_SQRT_PRICE_X96_WETH_PER_TOKEN_10_ETH_MARKET_CAP =
787_149_618_249_685_149_291_181;
int24 public constant INITIAL_TICK_TOKEN_PER_WETH_10_ETH_MARKET_CAP = 230_400;
int24 public constant INITIAL_TICK_WETH_PER_TOKEN_10_ETH_MARKET_CAP = -230_400;
int24 public constant DEFAULT_TOKEN1_TICK_LOWER = 120_000;
int24 public constant DEFAULT_TOKEN1_TICK_UPPER = 230_400;
int24 public constant DEFAULT_TOKEN0_TICK_LOWER = -230_400;
int24 public constant DEFAULT_TOKEN0_TICK_UPPER = -120_000;
uint160 private constant DEFAULT_TOKEN1_SQRT_LOWER = 31_953_335_214_378_312_554_014_683_580_590;
uint160 private constant DEFAULT_TOKEN1_SQRT_UPPER = 7_974_470_913_604_094_264_140_738_513_890_252;
uint160 private constant DEFAULT_TOKEN0_SQRT_LOWER = 787_149_618_249_685_149_291_181;
uint160 private constant DEFAULT_TOKEN0_SQRT_UPPER = 196_445_901_289_268_864_651_836_582;
uint256 private constant Q96 = 2 ** 96;
uint256 private constant MAX_SALT_ATTEMPTS = 64;
uint256 public constant MAX_LOCKED_TOKEN_DUST = 100_000;
bytes1 private constant ACTION_MINT_POSITION = 0x02;
bytes1 private constant ACTION_SETTLE_PAIR = 0x0d;
bytes1 private constant ACTION_DECREASE_LIQUIDITY = 0x01;
bytes1 private constant ACTION_TAKE_PAIR = 0x11;
IUniswapV4PositionManager public immutable positionManager;
IPermit2AllowanceTransfer public immutable permit2;
address public immutable officialFeeRecipient;
mapping(address => LockedV4Position) public lockedV4Positions;
uint256 public launchNonce;
bool private _collectingFees;
event TokenLaunched(
address indexed token,
address indexed owner,
uint256 indexed v4PositionId,
PoolKey poolKey,
int24 tickLower,
int24 tickUpper,
uint256 tokenAmountMax,
uint256 liquidity
);
event V4FeesCollectedAndDistributed(
address indexed token,
address indexed caller,
uint256 indexed v4PositionId,
uint256 amount0,
uint256 amount1
);
event OfficialFeePaid(address indexed token, address indexed recipient, address indexed currency, uint256 amount);
event TokenSaltSelected(address indexed token, bytes32 indexed salt, uint256 indexed launchNonce);
error ZeroAddress();
error ETHNotAccepted();
error V4PositionNotLocked();
error NoFeeRecipients();
error ReentrantCall();
error NoValidTokenAddress();
error ExcessTokenDust(uint256 remaining);
modifier nonReentrant() {
if (_collectingFees) revert ReentrantCall();
_collectingFees = true;
_;
_collectingFees = false;
}
constructor(address officialFeeRecipient_) {
if (officialFeeRecipient_ == address(0)) revert ZeroAddress();
positionManager = IUniswapV4PositionManager(ETHEREUM_V4_POSITION_MANAGER);
permit2 = IPermit2AllowanceTransfer(ETHEREUM_PERMIT2);
officialFeeRecipient = officialFeeRecipient_;
}
receive() external payable {}
function createTokenAndLaunch(
TokenParams calldata tokenParams,
BaseLaunchToken.FeeRecipient[] calldata feeRecipients
) external payable returns (BaseLaunchToken token, uint256 v4PositionId) {
if (msg.value != 0) revert ETHNotAccepted();
if (tokenParams.owner == address(0)) revert ZeroAddress();
BaseLaunchToken.FeeRecipient[] memory feeRecipientsMemory =
new BaseLaunchToken.FeeRecipient[](feeRecipients.length);
for (uint256 i; i < feeRecipients.length; ++i) {
feeRecipientsMemory[i] = feeRecipients[i];
}
token = _deployLaunchToken(tokenParams, feeRecipientsMemory);
LaunchPoolParams memory poolParams = _buildLaunchPoolParams(address(token));
token.approve(address(permit2), type(uint256).max);
permit2.approve(address(token), address(positionManager), type(uint160).max, type(uint48).max);
positionManager.initializePool(poolParams.key, poolParams.sqrtPriceX96);
v4PositionId = positionManager.nextTokenId();
bytes memory actions = abi.encodePacked(ACTION_MINT_POSITION, ACTION_SETTLE_PAIR);
bytes[] memory params = new bytes[](2);
params[0] = abi.encode(
poolParams.key,
poolParams.tickLower,
poolParams.tickUpper,
poolParams.liquidity,
poolParams.amount0Max,
poolParams.amount1Max,
address(this),
bytes("")
);
params[1] = abi.encode(poolParams.key.currency0, poolParams.key.currency1);
positionManager.modifyLiquidities(abi.encode(actions, params), block.timestamp);
lockedV4Positions[address(token)] =
LockedV4Position({
tokenId: v4PositionId,
currency0: poolParams.key.currency0,
currency1: poolParams.key.currency1,
exists: true
});
uint256 remaining = token.balanceOf(address(this));
if (remaining > MAX_LOCKED_TOKEN_DUST) revert ExcessTokenDust(remaining);
emit TokenLaunched(
address(token),
tokenParams.owner,
v4PositionId,
poolParams.key,
poolParams.tickLower,
poolParams.tickUpper,
DEFAULT_TOKEN_AMOUNT_MAX,
poolParams.liquidity
);
}
function collectAndDistributeV4Fees(address token, uint256 deadline) external nonReentrant {
LockedV4Position memory lockedPosition = lockedV4Positions[token];
if (!lockedPosition.exists) revert V4PositionNotLocked();
BaseLaunchToken launchToken = BaseLaunchToken(payable(token));
if (launchToken.feeRecipientsLength() == 0) revert NoFeeRecipients();
uint256 balance0Before = _currencyBalance(lockedPosition.currency0);
uint256 balance1Before = _currencyBalance(lockedPosition.currency1);
bytes memory actions = abi.encodePacked(ACTION_DECREASE_LIQUIDITY, ACTION_TAKE_PAIR);
bytes[] memory params = new bytes[](2);
params[0] = abi.encode(lockedPosition.tokenId, uint256(0), uint128(0), uint128(0), bytes(""));
params[1] = abi.encode(lockedPosition.currency0, lockedPosition.currency1, address(this));
positionManager.modifyLiquidities(abi.encode(actions, params), deadline);
uint256 amount0 = _currencyBalance(lockedPosition.currency0) - balance0Before;
uint256 amount1 = _currencyBalance(lockedPosition.currency1) - balance1Before;
_distributeLaunchFees(launchToken, lockedPosition.currency0, amount0);
_distributeLaunchFees(launchToken, lockedPosition.currency1, amount1);
emit V4FeesCollectedAndDistributed(token, msg.sender, lockedPosition.tokenId, amount0, amount1);
}
function _currencyBalance(Currency currency) internal view returns (uint256) {
address token = Currency.unwrap(currency);
return token == address(0) ? address(this).balance : IERC20Minimal(token).balanceOf(address(this));
}
function _distributeLaunchFees(BaseLaunchToken launchToken, Currency currency, uint256 amount) internal {
if (amount == 0) return;
uint256 recipientsLength = launchToken.feeRecipientsLength();
if (recipientsLength == 0) revert NoFeeRecipients();
address token = Currency.unwrap(currency);
uint256 officialFee = amount * OFFICIAL_FEE_BPS / BPS_DENOMINATOR;
uint256 userFeeAmount = amount - officialFee;
if (officialFee != 0) {
_transferCurrency(token, officialFeeRecipient, officialFee);
emit OfficialFeePaid(address(launchToken), officialFeeRecipient, token, officialFee);
}
if (userFeeAmount == 0) return;
uint256 sent;
for (uint256 i; i < recipientsLength; ++i) {
(address account, uint16 bps) = launchToken.feeRecipientAt(i);
uint256 share = i == recipientsLength - 1 ? userFeeAmount - sent : userFeeAmount * bps / BPS_DENOMINATOR;
sent += share;
_transferCurrency(token, account, share);
}
}
function _transferCurrency(address token, address to, uint256 amount) internal {
if (token == address(0)) {
(bool ok,) = to.call{value: amount}("");
require(ok, "ETH_TRANSFER_FAILED");
} else {
require(IERC20Minimal(token).transfer(to, amount), "ERC20_TRANSFER_FAILED");
}
}
function _buildLaunchPoolParams(address token) internal pure returns (LaunchPoolParams memory params) {
if (uint160(token) >= uint160(ETHEREUM_WETH)) revert NoValidTokenAddress();
params.sqrtPriceX96 = INITIAL_SQRT_PRICE_X96_WETH_PER_TOKEN_10_ETH_MARKET_CAP;
params.tickLower = DEFAULT_TOKEN0_TICK_LOWER;
params.tickUpper = DEFAULT_TOKEN0_TICK_UPPER;
params.amount0Max = DEFAULT_TOKEN_AMOUNT_MAX;
params.liquidity =
_liquidityForAmount0(DEFAULT_TOKEN0_SQRT_LOWER, DEFAULT_TOKEN0_SQRT_UPPER, DEFAULT_TOKEN_AMOUNT_MAX);
params.key = PoolKey({
currency0: Currency.wrap(token),
currency1: Currency.wrap(ETHEREUM_WETH),
fee: DEFAULT_LP_FEE,
tickSpacing: DEFAULT_TICK_SPACING,
hooks: IHooks(address(0))
});
}
function _liquidityForAmount0(uint160 sqrtPriceAX96, uint160 sqrtPriceBX96, uint256 amount0)
internal
pure
returns (uint256)
{
uint256 intermediate = amount0 * uint256(sqrtPriceAX96) / Q96;
uint256 liquidity = intermediate * uint256(sqrtPriceBX96) / (uint256(sqrtPriceBX96) - uint256(sqrtPriceAX96));
return liquidity;
}
function _deployLaunchToken(
TokenParams calldata tokenParams,
BaseLaunchToken.FeeRecipient[] memory feeRecipients
) internal returns (BaseLaunchToken token) {
bytes32 initCodeHash = keccak256(
abi.encodePacked(
type(BaseLaunchToken).creationCode,
abi.encode(
tokenParams.name,
tokenParams.symbol,
tokenParams.imageURI,
tokenParams.metadataURI,
tokenParams.owner,
address(this),
feeRecipients
)
)
);
uint256 currentLaunchNonce = launchNonce++;
bytes32 salt = _findTokenSalt(initCodeHash, currentLaunchNonce);
token = new BaseLaunchToken{salt: salt}(
tokenParams.name,
tokenParams.symbol,
tokenParams.imageURI,
tokenParams.metadataURI,
tokenParams.owner,
address(this),
feeRecipients
);
if (uint160(address(token)) >= uint160(ETHEREUM_WETH)) revert NoValidTokenAddress();
emit TokenSaltSelected(address(token), salt, currentLaunchNonce);
}
function _findTokenSalt(bytes32 initCodeHash, uint256 currentLaunchNonce) internal view returns (bytes32 salt) {
bytes32 seed = keccak256(abi.encode(block.chainid, msg.sender, currentLaunchNonce, initCodeHash));
for (uint256 attempt; attempt < MAX_SALT_ATTEMPTS; ++attempt) {
salt = keccak256(abi.encode(seed, attempt));
address predicted = address(
uint160(
uint256(keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, initCodeHash)))
)
);
if (uint160(predicted) < uint160(ETHEREUM_WETH)) return salt;
}
revert NoValidTokenAddress();
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "name_",
"type": "string",
"internalType": "string"
},
{
"name": "symbol_",
"type": "string",
"internalType": "string"
},
{
"name": "imageURI_",
"type": "string",
"internalType": "string"
},
{
"name": "metadataURI_",
"type": "string",
"internalType": "string"
},
{
"name": "initialOwner",
"type": "address",
"internalType": "address"
},
{
"name": "supplyReceiver",
"type": "address",
"internalType": "address"
},
{
"name": "feeRecipients_",
"type": "tuple[]",
"components": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"internalType": "struct BaseLaunchToken.FeeRecipient[]"
}
],
"stateMutability": "nonpayable"
},
{
"name": "InsufficientAllowance",
"type": "error",
"inputs": []
},
{
"name": "InsufficientBalance",
"type": "error",
"inputs": []
},
{
"name": "InvalidFeeBps",
"type": "error",
"inputs": []
},
{
"name": "NotOwner",
"type": "error",
"inputs": []
},
{
"name": "TooManyFeeRecipients",
"type": "error",
"inputs": []
},
{
"name": "ZeroAddress",
"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": "ERC20Distributed",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "ETHDistributed",
"type": "event",
"inputs": [
{
"name": "amount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeeRecipientsUpdated",
"type": "event",
"inputs": [
{
"name": "accounts",
"type": "address[]",
"indexed": false,
"internalType": "address[]"
},
{
"name": "bps",
"type": "uint16[]",
"indexed": false,
"internalType": "uint16[]"
}
],
"anonymous": false
},
{
"name": "ImageURIUpdated",
"type": "event",
"inputs": [
{
"name": "imageURI",
"type": "string",
"indexed": false,
"internalType": "string"
}
],
"anonymous": false
},
{
"name": "MetadataURIUpdated",
"type": "event",
"inputs": [
{
"name": "metadataURI",
"type": "string",
"indexed": false,
"internalType": "string"
}
],
"anonymous": false
},
{
"name": "OwnershipTransferred",
"type": "event",
"inputs": [
{
"name": "previousOwner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "newOwner",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"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": "BPS_DENOMINATOR",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "MAX_FEE_RECIPIENTS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "TOTAL_SUPPLY",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "allowance",
"type": "function",
"inputs": [
{
"name": "",
"type": "address",
"internalType": "address"
},
{
"name": "",
"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": "",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "burn",
"type": "function",
"inputs": [
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "burnFrom",
"type": "function",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "decimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "distributeERC20",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "distributeETH",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "feeRecipientAt",
"type": "function",
"inputs": [
{
"name": "index",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "feeRecipients",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "tuple[]",
"components": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"internalType": "struct BaseLaunchToken.FeeRecipient[]"
}
],
"stateMutability": "view"
},
{
"name": "feeRecipientsLength",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "imageURI",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"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": "owner",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "renounceOwnership",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFeeRecipients",
"type": "function",
"inputs": [
{
"name": "newRecipients",
"type": "tuple[]",
"components": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "bps",
"type": "uint16",
"internalType": "uint16"
}
],
"internalType": "struct BaseLaunchToken.FeeRecipient[]"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setImageURI",
"type": "function",
"inputs": [
{
"name": "newImageURI",
"type": "string",
"internalType": "string"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"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": "totalSupply",
"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"
},
{
"name": "transferOwnership",
"type": "function",
"inputs": [
{
"name": "newOwner",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x608060405260043610610198575f3560e01c8063750521f5116100e7578063b8b9b54911610087578063cfd94ac911610062578063cfd94ac91461049b578063dd62ed3e146104af578063e1a45218146104e5578063f2fde38b1461050d575f5ffd5b8063b8b9b54914610449578063ba89dfab1461045d578063bce582691461047c575f5ffd5b8063902d55a5116100c2578063902d55a5146103b557806395d89b41146103d5578063a7b09122146103e9578063a9059cbb1461042a575f5ffd5b8063750521f51461034057806379cc67901461035f5780638da5cb5b1461037e575f5ffd5b806318160ddd11610152578063313ce5671161012d578063313ce567146102bc57806342966c68146102e257806370a0823114610301578063715018a61461032c575f5ffd5b806318160ddd1461026657806323b872dd14610289578063300fca82146102a8575f5ffd5b806303ee438c146101a357806304787ca2146101cd57806306fdde03146101ee578063095ea7b3146102025780630adfdcb914610231578063135d088d14610252575f5ffd5b3661019f57005b5f5ffd5b3480156101ae575f5ffd5b506101b761052c565b6040516101c4919061145d565b60405180910390f35b3480156101d8575f5ffd5b506101ec6101e7366004611492565b6105b8565b005b3480156101f9575f5ffd5b506101b761062e565b34801561020d575f5ffd5b5061022161021c36600461151b565b61063a565b60405190151581526020016101c4565b34801561023c575f5ffd5b506102456106a6565b6040516101c49190611543565b34801561025d575f5ffd5b506101b761071b565b348015610271575f5ffd5b5061027b60045481565b6040519081526020016101c4565b348015610294575f5ffd5b506102216102a336600461159e565b610728565b3480156102b3575f5ffd5b5060085461027b565b3480156102c7575f5ffd5b506102d0601281565b60405160ff90911681526020016101c4565b3480156102ed575f5ffd5b506101ec6102fc3660046115d8565b6107ea565b34801561030c575f5ffd5b5061027b61031b3660046115ef565b60066020525f908152604090205481565b348015610337575f5ffd5b506101ec6107f7565b34801561034b575f5ffd5b506101ec61035a366004611492565b61086f565b34801561036a575f5ffd5b506101ec61037936600461151b565b6108d9565b348015610389575f5ffd5b5060055461039d906001600160a01b031681565b6040516001600160a01b0390911681526020016101c4565b3480156103c0575f5ffd5b5061027b6c01431e0fae6d7217caa000000081565b3480156103e0575f5ffd5b506101b7610994565b3480156103f4575f5ffd5b506104086104033660046115d8565b6109a1565b604080516001600160a01b03909316835261ffff9091166020830152016101c4565b348015610435575f5ffd5b5061022161044436600461151b565b6109f9565b348015610454575f5ffd5b506101ec610a0e565b348015610468575f5ffd5b506101ec61047736600461160f565b610a79565b348015610487575f5ffd5b506101ec6104963660046115ef565b610ab2565b3480156104a6575f5ffd5b5061027b601481565b3480156104ba575f5ffd5b5061027b6104c9366004611670565b600760209081525f928352604080842090915290825290205481565b3480156104f0575f5ffd5b506104fa61271081565b60405161ffff90911681526020016101c4565b348015610518575f5ffd5b506101ec6105273660046115ef565b610bbf565b60038054610539906116a1565b80601f0160208091040260200160405190810160405280929190818152602001828054610565906116a1565b80156105b05780601f10610587576101008083540402835291602001916105b0565b820191905f5260205f20905b81548152906001019060200180831161059357829003601f168201915b505050505081565b6005546001600160a01b031633146105e3576040516330cd747160e01b815260040160405180910390fd5b60026105f0828483611743565b507f9b9cd1b6d10196260eb379c94feef6204d1e0244b38efe9d31be6ad4055f22ea82826040516106229291906117fe565b60405180910390a15050565b5f8054610539906116a1565b335f8181526007602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906106949086815260200190565b60405180910390a35060015b92915050565b60606008805480602002602001604051908101604052809291908181526020015f905b82821015610712575f84815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900461ffff16818301528252600190920191016106c9565b50505050905090565b60028054610539906116a1565b6001600160a01b0383165f9081526007602090815260408083203384529091528120545f1981146107d45782811015610774576040516313be252b60e01b815260040160405180910390fd5b6001600160a01b0385165f81815260076020908152604080832033808552908352928190208786039081905590519081529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35b6107df858585610c62565b506001949350505050565b6107f43382610d2f565b50565b6005546001600160a01b03163314610822576040516330cd747160e01b815260040160405180910390fd5b600580546001600160a01b031981169091556040516001600160a01b03909116905f9082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a350565b6005546001600160a01b0316331461089a576040516330cd747160e01b815260040160405180910390fd5b60036108a7828483611743565b507fefafb90526da1636e1335eac0151301742fb755d986954c613b90e891778ba3982826040516106229291906117fe565b6001600160a01b0382165f9081526007602090815260408083203384529091529020545f1981146109855781811015610925576040516313be252b60e01b815260040160405180910390fd5b6001600160a01b0383165f81815260076020908152604080832033808552908352928190208686039081905590519081529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a35b61098f8383610d2f565b505050565b60018054610539906116a1565b5f5f5f600884815481106109b7576109b761182c565b5f918252602091829020604080518082019091529101546001600160a01b038116808352600160a01b90910461ffff1691909201819052909590945092505050565b5f610a05338484610c62565b50600192915050565b6005546001600160a01b03163314610a39576040516330cd747160e01b815260040160405180910390fd5b47610a4381610dc7565b6040518181527f0f73c15fc09bc757caafe571e052b89857e226540f25c1843b6f48923e88684a9060200160405180910390a150565b6005546001600160a01b03163314610aa4576040516330cd747160e01b815260040160405180910390fd5b610aae8282610f21565b5050565b6005546001600160a01b03163314610add576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610b045760405163d92e233d60e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610b48573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b6c9190611840565b9050610b788282611297565b816001600160a01b03167f4e1e88cf5ade6eb9bfc4458c50e0b120968403b23b01de2106d080851f630a5982604051610bb391815260200190565b60405180910390a25050565b6005546001600160a01b03163314610bea576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116610c115760405163d92e233d60e01b815260040160405180910390fd5b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b6001600160a01b038216610c895760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0383165f9081526006602052604090205481811015610cc257604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b038085165f8181526006602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610d219086815260200190565b60405180910390a350505050565b6001600160a01b0382165f9081526006602052604090205481811015610d6857604051631e9acf1760e31b815260040160405180910390fd5b6001600160a01b0383165f8181526006602090815260408083208686039055600480548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b6008541580610dd4575080155b15610ddc5750565b5f5f5b60085481101561098f576008545f90610dfa9060019061186b565b8214610e495761271061ffff1660088381548110610e1a57610e1a61182c565b5f91825260209091200154610e3a90600160a01b900461ffff168661187e565b610e449190611895565b610e53565b610e53838561186b565b9050610e5f81846118b4565b92505f60088381548110610e7557610e7561182c565b5f9182526020822001546040516001600160a01b039091169184919081818185875af1925050503d805f8114610ec6576040519150601f19603f3d011682016040523d82523d5f602084013e610ecb565b606091505b5050905080610f175760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b60448201526064015b60405180910390fd5b5050600101610ddf565b6014811115610f43576040516333adec1360e21b815260040160405180910390fd5b610f4e60085f611420565b5f808267ffffffffffffffff811115610f6957610f696116d9565b604051908082528060200260200182016040528015610f92578160200160208202803683370190505b5090505f8367ffffffffffffffff811115610faf57610faf6116d9565b604051908082528060200260200182016040528015610fd8578160200160208202803683370190505b5090505f5b84811015611227575f868683818110610ff857610ff861182c565b61100e92602060409092020190810191506115ef565b6001600160a01b0316036110355760405163d92e233d60e01b815260040160405180910390fd5b8585828181106110475761104761182c565b905060400201602001602081019061105f91906118c7565b61ffff165f0361108257604051638bff87cf60e01b815260040160405180910390fd5b8585828181106110945761109461182c565b90506040020160200160208101906110ac91906118c7565b6110ba9061ffff16856118b4565b9350600860405180604001604052808888858181106110db576110db61182c565b6110f192602060409092020190810191506115ef565b6001600160a01b031681526020018888858181106111115761111161182c565b905060400201602001602081019061112991906118c7565b61ffff90811690915282546001810184555f9384526020938490208351910180549490930151909116600160a01b026001600160b01b03199093166001600160a01b03909116179190911790558585828181106111885761118861182c565b61119e92602060409092020190810191506115ef565b8382815181106111b0576111b061182c565b60200260200101906001600160a01b031690816001600160a01b0316815250508585828181106111e2576111e261182c565b90506040020160200160208101906111fa91906118c7565b82828151811061120c5761120c61182c565b61ffff90921660209283029190910190910152600101610fdd565b50831580159061123957506127108314155b1561125757604051638bff87cf60e01b815260040160405180910390fd5b7fd07cc7c1e09e9b6d51353256e2187d7d47126dab27451a953524f22f85d8c84882826040516112889291906118e8565b60405180910390a15050505050565b60085415806112a4575080155b156112ad575050565b5f5f5b60085481101561141a576008545f906112cb9060019061186b565b821461131a5761271061ffff16600883815481106112eb576112eb61182c565b5f9182526020909120015461130b90600160a01b900461ffff168661187e565b6113159190611895565b611324565b611324838561186b565b905061133081846118b4565b9250846001600160a01b031663a9059cbb600884815481106113545761135461182c565b5f9182526020909120015460405160e083901b6001600160e01b03191681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af11580156113a9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113cd9190611975565b6114115760405162461bcd60e51b8152602060048201526015602482015274115490cc8c17d514905394d1915497d19052531151605a1b6044820152606401610f0e565b506001016112b0565b50505050565b5080545f8255905f5260205f2090611438919061143a565b565b5f5b8082111561098f5780830180546001600160b01b031916905560010161143c565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f5f602083850312156114a3575f5ffd5b823567ffffffffffffffff8111156114b9575f5ffd5b8301601f810185136114c9575f5ffd5b803567ffffffffffffffff8111156114df575f5ffd5b8560208284010111156114f0575f5ffd5b6020919091019590945092505050565b80356001600160a01b0381168114611516575f5ffd5b919050565b5f5f6040838503121561152c575f5ffd5b61153583611500565b946020939093013593505050565b602080825282518282018190525f918401906040840190835b8181101561159357835180516001600160a01b0316845260209081015161ffff16818501529093019260409092019160010161155c565b509095945050505050565b5f5f5f606084860312156115b0575f5ffd5b6115b984611500565b92506115c760208501611500565b929592945050506040919091013590565b5f602082840312156115e8575f5ffd5b5035919050565b5f602082840312156115ff575f5ffd5b61160882611500565b9392505050565b5f5f60208385031215611620575f5ffd5b823567ffffffffffffffff811115611636575f5ffd5b8301601f81018513611646575f5ffd5b803567ffffffffffffffff81111561165c575f5ffd5b8560208260061b84010111156114f0575f5ffd5b5f5f60408385031215611681575f5ffd5b61168a83611500565b915061169860208401611500565b90509250929050565b600181811c908216806116b557607f821691505b6020821081036116d357634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52604160045260245ffd5b601f82111561098f578282111561098f57805f5260205f20601f840160051c602085101561171857505f5b90810190601f840160051c035f5b8181101561173b575f83820155600101611726565b505050505050565b67ffffffffffffffff83111561175b5761175b6116d9565b61176f8361176983546116a1565b836116ed565b5f601f8411600181146117a0575f85156117895750838201355b5f19600387901b1c1916600186901b1783556117f7565b5f83815260208120601f198716915b828110156117cf57868501358255602094850194600190920191016117af565b50868210156117eb575f1960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215611850575f5ffd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156106a0576106a0611857565b80820281158282048414176106a0576106a0611857565b5f826118af57634e487b7160e01b5f52601260045260245ffd5b500490565b808201808211156106a0576106a0611857565b5f602082840312156118d7575f5ffd5b813561ffff81168114611608575f5ffd5b604080825283519082018190525f9060208501906060840190835b8181101561192a5783516001600160a01b0316835260209384019390920191600101611903565b5050838103602080860191909152855180835291810192508501905f5b8181101561196957825161ffff16845260209384019390920191600101611947565b50919695505050505050565b5f60208284031215611985575f5ffd5b81518015158114611608575f5ffdfea26469706673582212209ea70c3f781b433109d444feb94f9a74d8378fc46498396b26e017cb82db80c664736f6c63430008220033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | Transfer | [0] 0x000000000000…7087c146 [1] 0x000000000000…43e40951 data: 0x000000000000000000…9fff296c |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | Approval | [0] 0x000000000000…7087c146 [1] 0x000000000000…3ac78ba3 data: 0xffffffffffffffffff…ffffffff |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | 0xefafb9…ba39 | data: 0x000000000000000000…00000000 |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | 0x9b9cd1…22ea | data: 0x000000000000000000…00000000 |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | 0x8be007…57e0 | [0] 0x000000000000…00000000 [1] 0x000000000000…b7c4fc3b |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | 0xd07cc7…c848 | data: 0x000000000000000000…00002710 |
| 0xc5c9a0…1da1d1 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…7087c146 data: 0x000000000000000000…a0000000 |
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| 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 ? | ||
|---|---|---|---|---|---|---|---|---|---|
| No direct transactions — this address is only ever reached via internal calls (common for a contract only invoked through a router or proxy). View Internal Transactions → | |||||||||
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 12,167,059 | 31 days agoFri, 17 Jul 2026 13:48:27 UTC | 0xc5c9a0…1da1d1 | CREATE2 | createTokenAndLaunch | 0xe724…c146 | IN | 0x00a6…5dab | 0 ETH |