LivoFactoryUniV4Unified
0x8024f24df3fe8b45daa0d9d94f59aa7e98da1b7f
Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
17,339 bytes
ABI entries
88
42 read · 7 write
License
none
Contract information
- Address
- 0x8024f24df3fe8b45daa0d9d94f59aa7e98da1b7f
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.28+commit.7893614a
- Optimization
- Enabled
- Creator
- 0xBa489180Ea…15F388f181
- Creation tx
- 0x89c44f2d02…b13b549307
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (42)
BONDING_CURVE() → address
CREATOR_VAULT_BPS_STEP() → uint256
CREATOR_VAULT_FACTORY() → address
GRADUATOR() → address
GRADUATOR_THICK() → address
GRADUATOR_THIN() → address
LAUNCHPAD() → address
MASTER_FEE_HANDLER() → address
MAX_CREATOR_VAULTS() → uint256
MAX_CREATOR_VAULT_TOTAL_BPS() → uint256
MAX_TAX_DECAY_DURATION_SECONDS() → uint256
MAX_TAX_DECAY_START_COMBINED_BPS() → uint256
MAX_TAX_DURATION_SECONDS() → uint256
MAX_TOTAL_FEE_BPS() → uint256
THICK_CURVE_BASE() → address
THICK_VAULT_CURVE_10() → address
THICK_VAULT_CURVE_15() → address
THICK_VAULT_CURVE_20() → address
THICK_VAULT_CURVE_25() → address
THICK_VAULT_CURVE_30() → address
THICK_VAULT_CURVE_5() → address
THIN_CURVE_BASE() → address
THIN_VAULT_CURVE_10() → address
THIN_VAULT_CURVE_15() → address
THIN_VAULT_CURVE_20() → address
THIN_VAULT_CURVE_25() → address
THIN_VAULT_CURVE_30() → address
THIN_VAULT_CURVE_5() → address
TOKEN_IMPL_BASE() → address
TOKEN_IMPL_TAX() → address
UPGRADE_INTERFACE_VERSION() → string
VAULT_CURVE_10() → address
VAULT_CURVE_15() → address
VAULT_CURVE_20() → address
VAULT_CURVE_25() → address
VAULT_CURVE_30() → address
VAULT_CURVE_5() → address
maxBuyOnDeploy(uint8, uint256) → uint256
owner() → address
previewTokenImplementation(tuple[], tuple[], tuple, tuple) → address
proxiableUUID() → bytes32
quoteBuyOnDeploy(uint8, uint256, uint256, tuple, tuple) → uint256
Events (9)
BondingCurveAssignedBuyOnDeployCreatorVaultsCreatedInitializedLpFeeBpsSetOwnershipTransferredTokenCreatedTokenReferralUpgraded
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "launchpad",
"type": "address"
},
{
"components": [
{
"internalType": "address",
"name": "base",
"type": "address"
},
{
"internalType": "address",
"name": "tax",
"type": "address"
}
],
"internalType": "struct ILivoFactory.TokenImpls",
"name": "impls",
"type": "tuple"
},
{
"internalType": "address",
"name": "bondingCurve",
"type": "address"
},
{
"internalType": "address",
"name": "graduator",
"type": "address"
},
{
"internalType": "address",
"name": "masterFeeHandler",
"type": "address"
},
{
"internalType": "address",
"name": "creatorVaultFactory",
"type": "address"
},
{
"internalType": "address[6]",
"name": "vaultBondingCurves",
"type": "address[6]"
},
{
"components": [
{
"components": [
{
"components": [
{
"internalType": "address",
"name": "base",
"type": "address"
},
{
"internalType": "address[6]",
"name": "vaults",
"type": "address[6]"
}
],
"internalType": "struct ILivoFactory.TierCurves",
"name": "thin",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "base",
"type": "address"
},
{
"internalType": "address[6]",
"name": "vaults",
"type": "address[6]"
}
],
"internalType": "struct ILivoFactory.TierCurves",
"name": "thick",
"type": "tuple"
}
],
"internalType": "struct ILivoFactory.LiquidityTierConfig",
"name": "curves",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "thin",
"type": "address"
},
{
"internalType": "address",
"name": "thick",
"type": "address"
}
],
"internalType": "struct LivoFactoryUniV4Unified.TierGraduators",
"name": "graduators",
"type": "tuple"
}
],
"internalType": "struct LivoFactoryUniV4Unified.V4TierConfig",
"name": "v4Tier",
"type": "tuple"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "target",
"type": "address"
}
],
"name": "AddressEmptyCode",
"type": "error"
},
{
"inputs": [],
"name": "CreatorVaultAllocationTooHigh",
"type": "error"
},
{
"inputs": [],
"name": "CreatorVaultDistributionFailed",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "ERC1967InvalidImplementation",
"type": "error"
},
{
"inputs": [],
"name": "ERC1967NonPayable",
"type": "error"
},
{
"inputs": [],
"name": "FailedDeployment",
"type": "error"
},
{
"inputs": [],
"name": "FailedInnerCall",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "InsufficientBalance",
"type": "error"
},
{
"inputs": [],
"name": "InvalidAntiSniperConfig",
"type": "error"
},
{
"inputs": [],
"name": "InvalidCreatorVault",
"type": "error"
},
{
"inputs": [],
"name": "InvalidFeeReceiver",
"type": "error"
},
{
"inputs": [],
"name": "InvalidInitialization",
"type": "error"
},
{
"inputs": [],
"name": "InvalidLpFeeBps",
"type": "error"
},
{
"inputs": [],
"name": "InvalidNameOrSymbol",
"type": "error"
},
{
"inputs": [],
"name": "InvalidShares",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSupplyShares",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTaxBps",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTaxConfig",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTaxDuration",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTokenAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTokenOwner",
"type": "error"
},
{
"inputs": [],
"name": "MultipleDirectFeeReceivers",
"type": "error"
},
{
"inputs": [],
"name": "NotInitializing",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "SafeERC20FailedOperation",
"type": "error"
},
{
"inputs": [],
"name": "TooManyCreatorVaults",
"type": "error"
},
{
"inputs": [],
"name": "UUPSUnauthorizedCallContext",
"type": "error"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "slot",
"type": "bytes32"
}
],
"name": "UUPSUnsupportedProxiableUUID",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "bondingCurve",
"type": "address"
}
],
"name": "BondingCurveAssigned",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "buyer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ethSpent",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokensBought",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address[]",
"name": "recipients",
"type": "address[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "BuyOnDeploy",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "totalVaultAllocation",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address[]",
"name": "vaults",
"type": "address[]"
},
{
"indexed": false,
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "CreatorVaultsCreated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint64",
"name": "version",
"type": "uint64"
}
],
"name": "Initialized",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint16",
"name": "lpFeeBps",
"type": "uint16"
}
],
"name": "LpFeeBpsSet",
"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": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "string",
"name": "name",
"type": "string"
},
{
"indexed": false,
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"internalType": "address",
"name": "tokenOwner",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "launchpad",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "graduator",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "feeHandler",
"type": "address"
}
],
"name": "TokenCreated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "referral",
"type": "address"
}
],
"name": "TokenReferral",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "implementation",
"type": "address"
}
],
"name": "Upgraded",
"type": "event"
},
{
"inputs": [],
"name": "BONDING_CURVE",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "CREATOR_VAULT_BPS_STEP",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "CREATOR_VAULT_FACTORY",
"outputs": [
{
"internalType": "contract ILivoCreatorVaultFactory",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GRADUATOR",
"outputs": [
{
"internalType": "contract ILivoGraduator",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GRADUATOR_THICK",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "GRADUATOR_THIN",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LAUNCHPAD",
"outputs": [
{
"internalType": "contract ILivoLaunchpad",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MASTER_FEE_HANDLER",
"outputs": [
{
"internalType": "contract ILivoMasterFeeHandler",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_CREATOR_VAULTS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_CREATOR_VAULT_TOTAL_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_TAX_DECAY_DURATION_SECONDS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_TAX_DECAY_START_COMBINED_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_TAX_DURATION_SECONDS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_TOTAL_FEE_BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_CURVE_BASE",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_10",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_15",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_20",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_25",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_30",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THICK_VAULT_CURVE_5",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_CURVE_BASE",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_10",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_15",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_20",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_25",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_30",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "THIN_VAULT_CURVE_5",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOKEN_IMPL_BASE",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOKEN_IMPL_TAX",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "UPGRADE_INTERFACE_VERSION",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_10",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_15",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_20",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_25",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_30",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "VAULT_CURVE_5",
"outputs": [
{
"internalType": "contract ILivoBondingCurve",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"internalType": "bool",
"name": "directFeesEnabled",
"type": "bool"
}
],
"internalType": "struct ILivoFactory.FeeShare[]",
"name": "feeShares",
"type": "tuple[]"
},
{
"internalType": "enum LiquidityTier",
"name": "liquidityTier",
"type": "uint8"
}
],
"internalType": "struct ILivoFactory.TokenSetupTiered",
"name": "tokenSetup",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint16",
"name": "buyTaxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDurationSeconds",
"type": "uint32"
},
{
"internalType": "bool",
"name": "startTaxFromLaunch",
"type": "bool"
},
{
"internalType": "uint16",
"name": "buyTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDecayDuration",
"type": "uint32"
}
],
"internalType": "struct TaxConfigs",
"name": "taxConfigs",
"type": "tuple"
},
{
"components": [
{
"internalType": "bool",
"name": "renounceOwnership",
"type": "bool"
},
{
"internalType": "uint16",
"name": "lpFeeBps",
"type": "uint16"
}
],
"internalType": "struct LivoFactoryUniV4Unified.UniV4Configs",
"name": "univ4Configs",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.SupplyShare[]",
"name": "buyOnDeployShares",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "uint16",
"name": "maxBuyPerTxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxWalletBps",
"type": "uint16"
},
{
"internalType": "uint40",
"name": "protectionWindowSeconds",
"type": "uint40"
},
{
"internalType": "address[]",
"name": "whitelist",
"type": "address[]"
}
],
"internalType": "struct AntiSniperConfigs",
"name": "antiSniperConfigs",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "supplyBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "cliffSeconds",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "vestingSeconds",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.CreatorVault[]",
"name": "creatorVaults",
"type": "tuple[]"
},
{
"internalType": "address",
"name": "referral",
"type": "address"
}
],
"name": "createToken",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"internalType": "bool",
"name": "directFeesEnabled",
"type": "bool"
}
],
"internalType": "struct ILivoFactory.FeeShare[]",
"name": "feeReceivers",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.SupplyShare[]",
"name": "supplyShares",
"type": "tuple[]"
},
{
"internalType": "bool",
"name": "renounceOwnership_",
"type": "bool"
},
{
"components": [
{
"internalType": "uint16",
"name": "buyTaxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDurationSeconds",
"type": "uint32"
},
{
"internalType": "bool",
"name": "startTaxFromLaunch",
"type": "bool"
}
],
"internalType": "struct TaxConfigInit",
"name": "taxCfg",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint16",
"name": "maxBuyPerTxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxWalletBps",
"type": "uint16"
},
{
"internalType": "uint40",
"name": "protectionWindowSeconds",
"type": "uint40"
},
{
"internalType": "address[]",
"name": "whitelist",
"type": "address[]"
}
],
"internalType": "struct AntiSniperConfigs",
"name": "antiSniperCfg",
"type": "tuple"
}
],
"name": "createToken",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "string",
"name": "name",
"type": "string"
},
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"internalType": "bool",
"name": "directFeesEnabled",
"type": "bool"
}
],
"internalType": "struct ILivoFactory.FeeShare[]",
"name": "feeShares",
"type": "tuple[]"
},
{
"internalType": "enum LiquidityTier",
"name": "liquidityTier",
"type": "uint8"
}
],
"internalType": "struct ILivoFactory.TokenSetupTiered",
"name": "tokenSetup",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint16",
"name": "buyTaxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDurationSeconds",
"type": "uint32"
},
{
"internalType": "bool",
"name": "startTaxFromLaunch",
"type": "bool"
},
{
"internalType": "uint16",
"name": "buyTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDecayDuration",
"type": "uint32"
}
],
"internalType": "struct TaxConfigs",
"name": "taxConfigs",
"type": "tuple"
},
{
"components": [
{
"internalType": "bool",
"name": "renounceOwnership",
"type": "bool"
},
{
"internalType": "uint16",
"name": "lpFeeBps",
"type": "uint16"
}
],
"internalType": "struct LivoFactoryUniV4Unified.UniV4Configs",
"name": "univ4Configs",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.SupplyShare[]",
"name": "buyOnDeployShares",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "uint16",
"name": "maxBuyPerTxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxWalletBps",
"type": "uint16"
},
{
"internalType": "uint40",
"name": "protectionWindowSeconds",
"type": "uint40"
},
{
"internalType": "address[]",
"name": "whitelist",
"type": "address[]"
}
],
"internalType": "struct AntiSniperConfigs",
"name": "antiSniperConfigs",
"type": "tuple"
},
{
"components": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "supplyBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "cliffSeconds",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "vestingSeconds",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.CreatorVault[]",
"name": "creatorVaults",
"type": "tuple[]"
}
],
"name": "createToken",
"outputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "initialize",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "enum LiquidityTier",
"name": "tier",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "totalLockedInVaultsBps",
"type": "uint256"
}
],
"name": "maxBuyOnDeploy",
"outputs": [
{
"internalType": "uint256",
"name": "maxTokens",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
},
{
"internalType": "bool",
"name": "directFeesEnabled",
"type": "bool"
}
],
"internalType": "struct ILivoFactory.FeeShare[]",
"name": "",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "uint256",
"name": "shares",
"type": "uint256"
}
],
"internalType": "struct ILivoFactory.SupplyShare[]",
"name": "",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "uint16",
"name": "buyTaxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDurationSeconds",
"type": "uint32"
},
{
"internalType": "bool",
"name": "startTaxFromLaunch",
"type": "bool"
},
{
"internalType": "uint16",
"name": "buyTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDecayDuration",
"type": "uint32"
}
],
"internalType": "struct TaxConfigs",
"name": "taxCfg",
"type": "tuple"
},
{
"components": [
{
"internalType": "uint16",
"name": "maxBuyPerTxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "maxWalletBps",
"type": "uint16"
},
{
"internalType": "uint40",
"name": "protectionWindowSeconds",
"type": "uint40"
},
{
"internalType": "address[]",
"name": "whitelist",
"type": "address[]"
}
],
"internalType": "struct AntiSniperConfigs",
"name": "antiSniperCfg",
"type": "tuple"
}
],
"name": "previewTokenImplementation",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "proxiableUUID",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "enum LiquidityTier",
"name": "liquidityTier",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "tokenAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalLockedInVaultsBps",
"type": "uint256"
},
{
"components": [
{
"internalType": "uint16",
"name": "buyTaxBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDurationSeconds",
"type": "uint32"
},
{
"internalType": "bool",
"name": "startTaxFromLaunch",
"type": "bool"
},
{
"internalType": "uint16",
"name": "buyTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint16",
"name": "sellTaxDecayStartBps",
"type": "uint16"
},
{
"internalType": "uint32",
"name": "taxDecayDuration",
"type": "uint32"
}
],
"internalType": "struct TaxConfigs",
"name": "taxCfg",
"type": "tuple"
},
{
"components": [
{
"internalType": "bool",
"name": "renounceOwnership",
"type": "bool"
},
{
"internalType": "uint16",
"name": "lpFeeBps",
"type": "uint16"
}
],
"internalType": "struct LivoFactoryUniV4Unified.UniV4Configs",
"name": "univ4Configs",
"type": "tuple"
}
],
"name": "quoteBuyOnDeploy",
"outputs": [
{
"internalType": "uint256",
"name": "totalEthNeeded",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newImplementation",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "upgradeToAndCall",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;
import {AntiSniperConfigs} from "src/tokens/SniperProtection.sol";
import {TaxConfigInit, TaxConfigs} from "src/interfaces/ILivoTaxableToken.sol";
import {LivoFactoryAbstract} from "src/factories/LivoFactoryAbstract.sol";
import {LiquidityTier} from "src/types/LiquidityTier.sol";
/// @notice Unified factory for the Uniswap V4 token family. Dispatches between two token
/// implementations (`base`, `tax`) based on whether tax is configured; anti-sniper
/// protection is a gated feature of both, not a separate impl.
///
/// Replaces `LivoFactoryUniV4`, `LivoFactoryTaxToken`, `LivoFactoryUniV4SniperProtected`,
/// and `LivoFactoryTaxTokenSniperProtected`.
contract LivoFactoryUniV4Unified is LivoFactoryAbstract {
/// @notice V4-specific config bundle for the struct-based `createToken` overload.
/// @dev `lpFeeBps` is the per-swap LP fee `LivoSwapHook` charges post-graduation. It is stored on
/// the token (via `InitializeParams.swapLpFeeBps`) and read back by the hook through
/// `getSwapFees`. Only `100` (1%) and `50` (0.5%) are accepted; `_validateUniv4Configs`
/// enforces the allowlist so misconfiguration is loud. A single graduator/hook pair serves both
/// fees — the hook reads the rate from the token instead of hardcoding it per variant, so the
/// graduator is selected by liquidity tier alone (`_resolveGraduator(tier)`), not by fee.
struct UniV4Configs {
bool renounceOwnership;
uint16 lpFeeBps;
}
/// @notice Constructor-only bundle of the THIN/THICK tier V4 graduators. One graduator per tier: the
/// hook is fee-agnostic (reads the rate from the token), so a tier needs a single graduator
/// regardless of `lpFeeBps`. The DEFAULT-tier graduator is `GRADUATOR` in the abstract base.
struct TierGraduators {
address thin;
address thick;
}
/// @notice Constructor-only bundle of all the V4 tier additions (curves + graduators), grouped into
/// one struct to keep the constructor's parameter count within the ABI-decode stack limit.
struct V4TierConfig {
LiquidityTierConfig curves;
TierGraduators graduators;
}
/// @notice THIN/THICK tier graduators, one per tier. Each initializes its pool at the tier-specific
/// graduation price and pairs with the single fee-agnostic `LivoSwapHook`. Selected by
/// `_resolveGraduator(tier)`.
address public immutable GRADUATOR_THIN;
address public immutable GRADUATOR_THICK;
/// @notice Pre-graduation launchpad LP fee for V4 tokens (bps), charged on every bonding-curve trade
/// and split treasury/creator by `V4_LAUNCHPAD_TREASURY_SHARE_BPS`. Fixed at 1% for every V4
/// token regardless of the post-graduation hook fee it selects (`UniV4Configs.lpFeeBps`, 50 or
/// 100): the pre-graduation rate is a constant launchpad policy, decoupled from the LP fee the
/// hook charges after graduation.
uint16 internal constant V4_LAUNCHPAD_LP_FEE_BPS = 100;
/// @notice Treasury share of the V4 pre-graduation LP fee (bps): 60 treasury / 40 creator.
uint16 internal constant V4_LAUNCHPAD_TREASURY_SHARE_BPS = 6_000;
error InvalidLpFeeBps();
constructor(
address launchpad,
TokenImpls memory impls,
address bondingCurve,
address graduator,
address masterFeeHandler,
address creatorVaultFactory,
address[6] memory vaultBondingCurves,
V4TierConfig memory v4Tier
)
LivoFactoryAbstract(
launchpad,
impls,
bondingCurve,
graduator,
masterFeeHandler,
creatorVaultFactory,
vaultBondingCurves,
v4Tier.curves
)
{
GRADUATOR_THIN = v4Tier.graduators.thin;
GRADUATOR_THICK = v4Tier.graduators.thick;
}
/////////////////////// EXTERNAL FUNCTIONS /////////////////////////
// V4-only event-emission rule: any event whose presence is meant to signal "this is a V4 token"
// (today: `LpFeeBpsSet`) MUST be emitted here in the V4 factory overloads, never inside the
// shared `_createToken` umbrella in `LivoFactoryAbstract`. The umbrella runs for V2 deploys
// too, so emitting V4-only events from there would leak them onto V2 tokens and break indexers
// that use the event as a V4 marker. When adding a new V4-only event, follow this same pattern
// (emit after `_createToken(...)` returns, in both overloads below).
/// @notice Deploys a V4-family Livo token and registers it in the launchpad.
/// Dispatches between four implementations based on `taxCfg` and `antiSniperCfg`.
/// The per-token fee config is registered with the master fee handler at deploy time.
/// If `msg.value > 0`, buys supply and distributes it across `supplyShares`.
/// @dev DEPRECATED: legacy positional overload, kept for backwards compatibility (unchanged
/// signature). New integrations should use the struct-based overload that takes `creatorVaults`
/// and the full `TaxConfigs`. Always deploys with the DEFAULT-tier graduator and a 100-bps swap
/// fee, no creator vaults and no launch-tax decay — the `TaxConfigInit` is lifted into a
/// `TaxConfigs` with the decay fields zeroed.
function createToken(
string calldata name,
string calldata symbol,
bytes32 salt,
FeeShare[] calldata feeReceivers,
SupplyShare[] calldata supplyShares,
bool renounceOwnership_,
TaxConfigInit calldata taxCfg,
AntiSniperConfigs calldata antiSniperCfg
) external payable returns (address token) {
// Positional overload always uses the 100-bps swap fee — only the struct-based overloads below
// expose the 50-bps variant. See the "V4-only event-emission rule" comment above for why the
// emit lives here.
// Build `tokenSetup` first (consuming the deep `name`/`symbol`/`salt`/`feeReceivers` calldata
// params) before introducing the `taxConfigs` memory local, to keep the stack shallow enough
// to compile without `via_ir`.
// Legacy overload always uses the DEFAULT liquidity tier + the 100-bps swap fee.
TokenSetupTiered memory tokenSetup = TokenSetupTiered({
name: name, symbol: symbol, salt: salt, feeShares: feeReceivers, liquidityTier: LiquidityTier.DEFAULT
});
TaxConfigs memory taxConfigs = _toTaxConfigs(taxCfg);
_validateTotalFee(100, taxConfigs);
token = _createToken(
tokenSetup,
renounceOwnership_ ? address(0) : msg.sender,
address(GRADUATOR),
100, // default swap fee for the legacy overload
supplyShares,
taxConfigs,
antiSniperCfg,
new CreatorVault[](0)
);
emit LpFeeBpsSet(token, 100);
}
/// @notice Struct-based overload taking the full `TaxConfigs` (static tax + optional linear launch-tax
/// decay), a `creatorVaults` array (pass empty for none) and a `TokenSetupTiered` selecting the
/// liquidity tier. `univ4Configs.lpFeeBps` is the post-graduation swap fee stored on the token
/// (100 or 50). Kept for backwards compatibility; new integrations should use the `referral`
/// overload below (the current recommended overload).
function createToken(
TokenSetupTiered calldata tokenSetup,
TaxConfigs calldata taxConfigs,
UniV4Configs calldata univ4Configs,
SupplyShare[] calldata buyOnDeployShares,
AntiSniperConfigs calldata antiSniperConfigs,
CreatorVault[] calldata creatorVaults
) external payable returns (address token) {
token = _createV4(tokenSetup, univ4Configs, buyOnDeployShares, taxConfigs, antiSniperConfigs, creatorVaults);
}
/// @notice Recommended overload: same as the `TokenSetupTiered` overload plus a `referral` address for
/// relayers that forward the creation and are entitled to a cut of the fees. When `referral` is
/// non-zero a `TokenReferral(token, referral)` event is emitted; no token storage or on-chain
/// payout is wired to it yet — it is purely an off-chain signal for now.
function createToken(
TokenSetupTiered calldata tokenSetup,
TaxConfigs calldata taxConfigs,
UniV4Configs calldata univ4Configs,
SupplyShare[] calldata buyOnDeployShares,
AntiSniperConfigs calldata antiSniperConfigs,
CreatorVault[] calldata creatorVaults,
address referral
) external payable returns (address token) {
token = _createV4(tokenSetup, univ4Configs, buyOnDeployShares, taxConfigs, antiSniperConfigs, creatorVaults);
if (referral != address(0)) emit TokenReferral(token, referral);
}
///////////////////////// INTERNAL FUNCTIONS /////////////////////////
/// @dev Shared tail of the two struct-based `createToken` overloads: validates the V4 config, resolves
/// the tier's graduator, deploys via the shared umbrella storing `univ4Configs.lpFeeBps` on the
/// token, and emits the V4-only `LpFeeBpsSet` marker. Factored out to keep each overload's stack
/// shallow enough to compile without `via_ir`. `tokenOwner`/`graduator` are inlined for the same
/// reason. Private to this V4 factory, so the "V4-only event-emission rule" above still holds —
/// the emit never runs for a V2 deploy.
function _createV4(
TokenSetupTiered calldata tokenSetup,
UniV4Configs calldata univ4Configs,
SupplyShare[] calldata buyOnDeployShares,
TaxConfigs calldata taxConfigs,
AntiSniperConfigs calldata antiSniperConfigs,
CreatorVault[] calldata creatorVaults
) private returns (address token) {
_validateUniv4Configs(univ4Configs);
_validateTotalFee(univ4Configs.lpFeeBps, taxConfigs);
token = _createToken(
tokenSetup,
univ4Configs.renounceOwnership ? address(0) : msg.sender,
_resolveGraduator(tokenSetup.liquidityTier),
univ4Configs.lpFeeBps,
buyOnDeployShares,
taxConfigs,
antiSniperConfigs,
creatorVaults
);
emit LpFeeBpsSet(token, univ4Configs.lpFeeBps);
}
/// @dev V4-specific config validation. `lpFeeBps` is the per-swap LP fee stored on the token and
/// read by the hook via `getSwapFees` — only the two supported tiers (100 = 1%, 50 = 0.5%)
/// are accepted, so a typo reverts instead of silently storing an unsupported fee. Add further
/// V4-only invariants here as the struct grows.
function _validateUniv4Configs(UniV4Configs calldata configs) internal pure {
require(configs.lpFeeBps == 100 || configs.lpFeeBps == 50, InvalidLpFeeBps());
}
/// @dev Maps a liquidity `tier` to its graduator, which graduates at the tier's price and pairs with
/// the single fee-agnostic `LivoSwapHook`. The swap fee is not a selection axis: it is stored on
/// the token (`swapLpFeeBps`) and read by the hook, so one graduator serves both 100 and 50 bps.
function _resolveGraduator(LiquidityTier tier) internal view returns (address) {
if (tier == LiquidityTier.DEFAULT) return address(GRADUATOR);
if (tier == LiquidityTier.THIN) return GRADUATOR_THIN;
return GRADUATOR_THICK; // THICK
}
/// @dev Pre-graduation launchpad LP fee, fixed at `V4_LAUNCHPAD_LP_FEE_BPS` (1%) for every V4 token
/// regardless of the post-graduation hook fee it selected. The pre-graduation rate is a constant
/// launchpad policy, decoupled from the post-graduation LP fee, so `graduator` is ignored.
function _launchpadLpFeeBps(
address /* graduator */
)
internal
pure
override
returns (uint16)
{
return V4_LAUNCHPAD_LP_FEE_BPS;
}
/// @inheritdoc LivoFactoryAbstract
function _launchpadTreasuryShareBps() internal pure override returns (uint16) {
return V4_LAUNCHPAD_TREASURY_SHARE_BPS;
}
/// @notice Returns which token implementation `createToken(...)` would clone for the given inputs.
/// @dev Mirrors the dispatch-relevant `createToken` inputs minus the identity fields (`name`,
/// `symbol`, `salt`) and ownership flag so the ABI stays stable when future features change
/// which inputs participate in dispatch. Today `taxCfg.taxDurationSeconds`,
/// `taxCfg.taxDecayDuration` (a decay-only token still clones the taxable impl) and
/// `antiSniperCfg.protectionWindowSeconds` matter for dispatch; disabled configs must
/// have all other tax/anti-sniper fields
/// empty/zero. Used by frontends to compute the initcode hash before mining a salt.
function previewTokenImplementation(
FeeShare[] calldata, /* feeReceivers */
SupplyShare[] calldata, /* supplyShares */
TaxConfigs calldata taxCfg,
AntiSniperConfigs calldata antiSniperCfg
) external view returns (address) {
_validateAntiSniperConfig(antiSniperCfg);
_validateTaxConfig(taxCfg);
return _previewTokenImplementation(taxCfg, antiSniperCfg);
}
/// @notice Quotes the ETH (msg.value) needed to receive ~`tokenAmount` tokens via the deployer buy.
/// Pass the same `taxCfg` and `univ4Configs` you'll pass to `createToken`; the buy fee is
/// derived from them (the fixed pre-graduation launchpad LP fee plus the buy tax) so the
/// frontend doesn't recompute it.
/// @param tokenAmount Amount of tokens to receive
/// @param totalLockedInVaultsBps Sum of `supplyBps` across the creator vaults (0 for none); selects
/// the same curve `createToken` uses. See `_quoteBuyOnDeploy`.
/// @param taxCfg The tax config the token will be created with; only `buyTaxBps` affects the buy,
/// and only when the window is creation-anchored (`startTaxFromLaunch`) — a graduation-anchored
/// tax is not charged on the deploy buy (see `_deployBuyTaxBps`).
/// @param univ4Configs The V4 config the token will be created with; `lpFeeBps` selects the
/// post-graduation hook fee. Validated here so the fee is one of the supported hook variants.
/// The deploy buy is a pre-graduation trade, so it is quoted at the fixed
/// `V4_LAUNCHPAD_LP_FEE_BPS`, not `lpFeeBps`.
/// @return totalEthNeeded The msg.value to pass to createToken
function quoteBuyOnDeploy(
LiquidityTier liquidityTier,
uint256 tokenAmount,
uint256 totalLockedInVaultsBps,
TaxConfigs calldata taxCfg,
UniV4Configs calldata univ4Configs
) external view returns (uint256 totalEthNeeded) {
_validateUniv4Configs(univ4Configs);
return _quoteBuyOnDeploy(
liquidityTier,
tokenAmount,
totalLockedInVaultsBps,
uint256(V4_LAUNCHPAD_LP_FEE_BPS) + _deployBuyTaxBps(taxCfg)
);
}
}
Chain explorer3454msChain node82ms