FactoryFeeToken
0xb2a9a1d670155deffdff950985b5b4a587a9b583
Verification
Verified
v0.8.25+commit.b61c2a91
Type
Contract
13,040 bytes
ABI entries
115
39 read · 26 write
License
none
Contract information
- Address
- 0xb2a9a1d670155deffdff950985b5b4a587a9b583
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.25+commit.b61c2a91
- Optimization
- Enabled
- Creator
- 0x6a851Ef33b…e6a1785cD1
- Creation tx
- 0xdfc59e8f8b…7ad3004f04
Token
- Name
- Nocturn
- Symbol
- NOC
- Decimals
- 18
- Holders
- 227
- Market
- View token page →
Read contract (39)
allowance(address, address) → uint256
ammContracts(address) → bool
balanceOf(address) → uint256
burnBps() → uint256
decimals() → uint8
devBps() → uint256
devWallet() → address
dexRouter() → address
discord() → string
distributorGas() → uint256
dividendDistributor() → address
feeEnabled() → bool
feesPaused() → bool
imageURI() → string
isExcludedFromDividends(address) → bool
isExcludedFromFees(address) → bool
isExcludedFromLimits(address) → bool
isExcludedFromMaxWallet(address) → bool
isTradingEnabled() → bool
isTransferEnabled() → bool
launchBlock() → uint256
launchFee() → uint256
maxFee() → uint256
maxWalletAmount() → uint256
minAmountForSwap() → uint256
name() → string
owner() → address
platformBps() → uint256
platformWallet1() → address
platformWallet2() → address
projectDescription() → string
rewardBps() → uint256
symbol() → string
telegram() → string
totalSupply() → uint256
tradingFee() → uint256
twitter() → string
uniswapV2Pair() → address
website() → string
Events (26)
AmmPoolSetApprovalBurnBpsUpdatedClaimedTokensDevRewardSplitUpdatedDevShareSentDevWalletUpdatedExcludedFromDividendsExcludedFromFeesExcludedFromLimitsFeeCollectedFeeIsDisabledFeeSetFeesPausedFeesResumedLiquidityAddedMaxFeeLoweredOwnershipTransferredPlatformShareSentProcessDividendFailedSetDividendShareFailedTokenProfileUpdatedTokensBurnedTradingEnabledTransferTransferEnabled
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "_name",
"type": "string"
},
{
"internalType": "string",
"name": "_symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "_totalSupply",
"type": "uint256"
},
{
"internalType": "address",
"name": "_devWallet",
"type": "address"
},
{
"internalType": "address",
"name": "_platformWallet1",
"type": "address"
},
{
"internalType": "address",
"name": "_platformWallet2",
"type": "address"
},
{
"internalType": "uint256",
"name": "_platformBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_launchFee",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_tradingFee",
"type": "uint256"
},
{
"internalType": "address",
"name": "_routerAddr",
"type": "address"
},
{
"internalType": "string",
"name": "_imageURI",
"type": "string"
},
{
"internalType": "string",
"name": "_description",
"type": "string"
},
{
"internalType": "string",
"name": "_website",
"type": "string"
},
{
"internalType": "string",
"name": "_twitter",
"type": "string"
},
{
"internalType": "string",
"name": "_telegram",
"type": "string"
},
{
"internalType": "string",
"name": "_discord",
"type": "string"
},
{
"internalType": "address",
"name": "_initialOwner",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "BurnBpsTooHigh",
"type": "error"
},
{
"inputs": [],
"name": "CannotClaimFeeToken",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "allowance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientAllowance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"internalType": "uint256",
"name": "balance",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "needed",
"type": "uint256"
}
],
"name": "ERC20InsufficientBalance",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "approver",
"type": "address"
}
],
"name": "ERC20InvalidApprover",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
}
],
"name": "ERC20InvalidReceiver",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "ERC20InvalidSender",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "ERC20InvalidSpender",
"type": "error"
},
{
"inputs": [],
"name": "FeeDisabled",
"type": "error"
},
{
"inputs": [],
"name": "FeeTooHigh",
"type": "error"
},
{
"inputs": [],
"name": "GasTooHigh",
"type": "error"
},
{
"inputs": [],
"name": "InvalidSplit",
"type": "error"
},
{
"inputs": [],
"name": "InvalidTokenProfile",
"type": "error"
},
{
"inputs": [],
"name": "MaxFeeNotLower",
"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": "TradingAlreadyEnabled",
"type": "error"
},
{
"inputs": [],
"name": "TradingDisabled",
"type": "error"
},
{
"inputs": [],
"name": "TransferAlreadyEnabled",
"type": "error"
},
{
"inputs": [],
"name": "TransferDisabled",
"type": "error"
},
{
"inputs": [],
"name": "UnsupportedChain",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "pool",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "enabled",
"type": "bool"
}
],
"name": "AmmPoolSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "newBurnBps",
"type": "uint256"
}
],
"name": "BurnBpsUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimedTokens",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "newDevBps",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newRewardBps",
"type": "uint256"
}
],
"name": "DevRewardSplitUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "DevShareSent",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "newDevWallet",
"type": "address"
}
],
"name": "DevWalletUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "ExcludedFromDividends",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "ExcludedFromFees",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "ExcludedFromLimits",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FeeCollected",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "FeeIsDisabled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "newFee",
"type": "uint256"
}
],
"name": "FeeSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "FeesPaused",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "FeesResumed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "nativeAmount",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bool",
"name": "lpBurned",
"type": "bool"
}
],
"name": "LiquidityAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "oldMax",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newMax",
"type": "uint256"
}
],
"name": "MaxFeeLowered",
"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": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "PlatformShareSent",
"type": "event"
},
{
"anonymous": false,
"inputs": [],
"name": "ProcessDividendFailed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "SetDividendShareFailed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "string",
"name": "imageURI",
"type": "string"
}
],
"name": "TokenProfileUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "TokensBurned",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "state",
"type": "bool"
}
],
"name": "TradingEnabled",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bool",
"name": "state",
"type": "bool"
}
],
"name": "TransferEnabled",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "ammContracts",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "burnBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "claimETH",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "claimTokens",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "devBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "devWallet",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "dexRouter",
"outputs": [
{
"internalType": "contract IUniswapV2Router02",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "disableFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "discord",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "distributorGas",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "dividendDistributor",
"outputs": [
{
"internalType": "contract MultiDexUserDividendDistributor",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "burnLP",
"type": "bool"
},
{
"internalType": "uint256",
"name": "tokenAmount",
"type": "uint256"
}
],
"name": "enableTrading",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "excludeFromDividends",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "excludeFromFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "excludeFromLimits",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "feeEnabled",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "feesPaused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "imageURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromDividends",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromFees",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromLimits",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "isExcludedFromMaxWallet",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isTradingEnabled",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isTransferEnabled",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launchBlock",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launchFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_newMax",
"type": "uint256"
}
],
"name": "lowerMaxFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "maxFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxWalletAmount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "minAmountForSwap",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pauseFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "platformBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "platformWallet1",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "platformWallet2",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "projectDescription",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "resumeFees",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "rewardBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pool",
"type": "address"
},
{
"internalType": "bool",
"name": "enabled",
"type": "bool"
}
],
"name": "setAmmPool",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_burnBps",
"type": "uint256"
}
],
"name": "setBurnBps",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "_devBps",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_rewardBps",
"type": "uint256"
}
],
"name": "setDevRewardSplit",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_devWallet",
"type": "address"
}
],
"name": "setDevWallet",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "gas",
"type": "uint256"
}
],
"name": "setDistributorGas",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "setExcludedFromMaxWallet",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "setMaxWalletAmount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "setMinAmountForSwap",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_imageURI",
"type": "string"
},
{
"internalType": "string",
"name": "_description",
"type": "string"
},
{
"internalType": "string",
"name": "_website",
"type": "string"
},
{
"internalType": "string",
"name": "_twitter",
"type": "string"
},
{
"internalType": "string",
"name": "_telegram",
"type": "string"
},
{
"internalType": "string",
"name": "_discord",
"type": "string"
}
],
"name": "setTokenProfile",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "setTransferEnabled",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "telegram",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tradingFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "twitter",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "uniswapV2Pair",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "website",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { MultiDexUserDividendDistributor } from "./MultiDexUserDividendDistributor.sol";
// ─── Interfaces ────────────────────────────────────────────────────────────
interface IUniswapV2Factory {
function createPair(address tokenA, address tokenB) external returns (address pair);
}
interface IUniswapV2Router02 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
// ─── Contract ──────────────────────────────────────────────────────────────
contract FactoryFeeToken is ERC20, Ownable {
// ─── Immutables ────────────────────────────────────────────────────
MultiDexUserDividendDistributor public immutable dividendDistributor;
IUniswapV2Router02 public immutable dexRouter;
address public immutable uniswapV2Pair;
address public immutable platformWallet1;
address public immutable platformWallet2;
uint public immutable platformBps; // basis points of native for platform
uint public immutable launchFee; // per-mille, max 300 (30 %)
uint public immutable tradingFee; // per-mille, max 300 (30 %)
// ─── State ─────────────────────────────────────────────────────────
address public devWallet;
bool public isTradingEnabled;
bool public isTransferEnabled;
bool public feeEnabled;
bool public feesPaused;
bool private isSwapping;
uint public maxFee; // set to tradingFee initially, can only be lowered
uint public minAmountForSwap;
uint public maxWalletAmount;
uint public distributorGas;
uint public launchBlock;
string public imageURI;
string public projectDescription;
string public website;
string public twitter;
string public telegram;
string public discord;
// Fee-split (basis points out of 10 000) — for the REMAINING after platform cut
uint public burnBps = 3300; // 33 % of accumulated tokens burned
uint public devBps = 5000; // 50 % of remaining native to dev
uint public rewardBps = 5000; // 50 % of remaining native to distributor
mapping(address => bool) public isExcludedFromFees;
mapping(address => bool) public isExcludedFromLimits;
mapping(address => bool) public isExcludedFromDividends;
mapping(address => bool) public isExcludedFromMaxWallet;
mapping(address => bool) public ammContracts;
// ─── Errors ────────────────────────────────────────────────────────
error TransferDisabled();
error TradingDisabled();
error TradingAlreadyEnabled();
error TransferAlreadyEnabled();
error FeeTooHigh();
error FeeDisabled();
error GasTooHigh();
error InvalidSplit();
error BurnBpsTooHigh();
error MaxFeeNotLower();
error UnsupportedChain();
error CannotClaimFeeToken();
error InvalidTokenProfile();
// ─── Events ────────────────────────────────────────────────────────
event FeeIsDisabled();
event FeesPaused();
event FeesResumed();
event TradingEnabled(bool state);
event TransferEnabled(bool state);
event FeeSet(uint newFee);
event AmmPoolSet(address pool, bool enabled);
event ExcludedFromFees(address account, bool excluded);
event ExcludedFromLimits(address account, bool excluded);
event ExcludedFromDividends(address account, bool excluded);
event ClaimedTokens(address token, address to, uint amount);
event FeeCollected(address from, uint amount);
event TokensBurned(uint amount);
event PlatformShareSent(uint amount);
event DevShareSent(uint amount);
event SetDividendShareFailed(address account);
event ProcessDividendFailed();
event DevWalletUpdated(address newDevWallet);
event BurnBpsUpdated(uint newBurnBps);
event DevRewardSplitUpdated(uint newDevBps, uint newRewardBps);
event MaxFeeLowered(uint oldMax, uint newMax);
event LiquidityAdded(uint tokenAmount, uint nativeAmount, bool lpBurned);
event TokenProfileUpdated(string imageURI);
// ─── Constructor ───────────────────────────────────────────────────
/// @param _name Token name
/// @param _symbol Token symbol
/// @param _totalSupply Total supply in whole tokens (18-decimal mint)
/// @param _devWallet Address that receives the deployer dev share of fees
/// @param _platformWallet1 First platform wallet (immutable)
/// @param _platformWallet2 Second platform wallet (immutable)
/// @param _platformBps Basis points of swapped native that go to platform (immutable)
/// @param _launchFee Launch-block fee in per-mille (max 300)
/// @param _tradingFee Ongoing trading fee in per-mille (max 300)
/// @param _routerAddr DEX router address
/// @param _imageURI IPFS URI for the token logo
/// @param _description Project description stored onchain
/// @param _website Project website stored onchain
/// @param _twitter X / Twitter link stored onchain
/// @param _telegram Telegram link stored onchain
/// @param _discord Discord link stored onchain
/// @param _initialOwner Initial owner (factory address); factory later transfers to deployer
constructor(
string memory _name,
string memory _symbol,
uint256 _totalSupply,
address _devWallet,
address _platformWallet1,
address _platformWallet2,
uint256 _platformBps,
uint256 _launchFee,
uint256 _tradingFee,
address _routerAddr,
string memory _imageURI,
string memory _description,
string memory _website,
string memory _twitter,
string memory _telegram,
string memory _discord,
address _initialOwner
) ERC20(_name, _symbol) Ownable(_initialOwner) {
require(_launchFee <= 300, "launch fee > 30%");
require(_tradingFee <= 300, "trading fee > 30%");
require(_platformBps <= 5000, "platform > 50%");
require(_platformWallet1 != address(0), "zero platform1");
require(_platformWallet2 != address(0), "zero platform2");
require(_devWallet != address(0), "zero devWallet");
require(_routerAddr != address(0), "zero router");
platformWallet1 = _platformWallet1;
platformWallet2 = _platformWallet2;
platformBps = _platformBps;
launchFee = _launchFee;
tradingFee = _tradingFee;
maxFee = _tradingFee; // can only be lowered from here
devWallet = _devWallet;
_setTokenProfile(_imageURI, _description, _website, _twitter, _telegram, _discord);
feeEnabled = true;
distributorGas = 500_000;
minAmountForSwap = (_totalSupply * 1e18) / 1000; // 0.1 % of total supply
// ── Router & pair ──
dexRouter = IUniswapV2Router02(_routerAddr);
uniswapV2Pair = IUniswapV2Factory(dexRouter.factory()).createPair(
address(this),
dexRouter.WETH()
);
ammContracts[uniswapV2Pair] = true;
isExcludedFromDividends[uniswapV2Pair] = true;
// ── Create distributor (factory is initial owner; factory transfers to deployer) ──
dividendDistributor = new MultiDexUserDividendDistributor(
_initialOwner,
_routerAddr
);
// ── Exclusions for factory (_initialOwner) ──
isExcludedFromFees[_initialOwner] = true;
isExcludedFromLimits[_initialOwner] = true;
isExcludedFromLimits[address(this)] = true;
isExcludedFromLimits[_routerAddr] = true;
isExcludedFromDividends[address(this)] = true;
isExcludedFromDividends[address(dividendDistributor)] = true;
isExcludedFromMaxWallet[_initialOwner] = true;
isExcludedFromMaxWallet[address(this)] = true;
isExcludedFromMaxWallet[_routerAddr] = true;
_mint(_initialOwner, _totalSupply * 1e18);
}
receive() external payable {}
// ─── Owner: configuration ──────────────────────────────────────────
function setDevWallet(address _devWallet) external onlyOwner {
require(_devWallet != address(0), "zero devWallet");
devWallet = _devWallet;
emit DevWalletUpdated(_devWallet);
}
/// @notice Update the IPFS logo and onchain project/social profile.
/// @dev The current token owner controls the profile, including after ownership transfers.
function setTokenProfile(
string calldata _imageURI,
string calldata _description,
string calldata _website,
string calldata _twitter,
string calldata _telegram,
string calldata _discord
) external onlyOwner {
_setTokenProfile(_imageURI, _description, _website, _twitter, _telegram, _discord);
}
function _setTokenProfile(
string memory _imageURI,
string memory _description,
string memory _website,
string memory _twitter,
string memory _telegram,
string memory _discord
) internal {
if (
bytes(_imageURI).length == 0 ||
bytes(_imageURI).length > 256 ||
bytes(_description).length > 1000 ||
bytes(_website).length > 256 ||
bytes(_twitter).length > 256 ||
bytes(_telegram).length > 256 ||
bytes(_discord).length > 256
) revert InvalidTokenProfile();
imageURI = _imageURI;
projectDescription = _description;
website = _website;
twitter = _twitter;
telegram = _telegram;
discord = _discord;
emit TokenProfileUpdated(_imageURI);
}
function setMaxWalletAmount(uint amount) external onlyOwner {
maxWalletAmount = amount;
}
function setExcludedFromMaxWallet(address account, bool excluded) external onlyOwner {
isExcludedFromMaxWallet[account] = excluded;
}
function setMinAmountForSwap(uint amount) external onlyOwner {
minAmountForSwap = amount;
}
function setDistributorGas(uint gas) external onlyOwner {
if (gas > 1_000_000) revert GasTooHigh();
distributorGas = gas;
}
/// @notice Enable trading. Optionally pull tokens from the owner into the
/// contract, then create V2 LP if native is sent.
/// @param burnLP If true and LP is created, LP tokens are sent to 0xdead (burned).
/// If false, LP tokens are sent to the caller (owner).
/// @param tokenAmount Tokens to move from the owner wallet onto this contract
/// for LP (0 = use whatever is already on the contract).
function enableTrading(bool burnLP, uint256 tokenAmount) external payable onlyOwner {
if (isTradingEnabled) revert TradingAlreadyEnabled();
// Pull LP inventory from the owner in the same transaction (no prior transfer needed).
if (tokenAmount > 0) {
_transfer(msg.sender, address(this), tokenAmount);
}
// If native sent, create LP with tokens sitting on the contract
if (msg.value > 0) {
uint tokenBalance = balanceOf(address(this));
require(tokenBalance > 0, "No tokens on contract for LP");
// Guard with isSwapping so the router's transferFrom bypasses
// fee collection and sell-processing (pair has no liquidity yet).
isSwapping = true;
_approve(address(this), address(dexRouter), tokenBalance);
address lpTo = burnLP ? address(0x000000000000000000000000000000000000dEaD) : msg.sender;
dexRouter.addLiquidityETH{value: msg.value}(
address(this),
tokenBalance,
0,
0,
lpTo,
block.timestamp
);
isSwapping = false;
emit LiquidityAdded(tokenBalance, msg.value, burnLP);
}
isTradingEnabled = true;
isTransferEnabled = true;
launchBlock = block.number;
emit TradingEnabled(true);
emit TransferEnabled(true);
}
function setTransferEnabled() external onlyOwner {
if (isTransferEnabled) revert TransferAlreadyEnabled();
isTransferEnabled = true;
emit TransferEnabled(true);
}
function setAmmPool(address pool, bool enabled) external onlyOwner {
ammContracts[pool] = enabled;
isExcludedFromDividends[pool] = true;
emit AmmPoolSet(pool, enabled);
}
// ─── Owner: fee management ─────────────────────────────────────────
/// @notice Lower the max fee ceiling. Can only decrease, never increase.
/// Also lowers the current maxFee.
function lowerMaxFee(uint _newMax) external onlyOwner {
if (_newMax >= maxFee) revert MaxFeeNotLower();
uint oldMax = maxFee;
maxFee = _newMax;
emit MaxFeeLowered(oldMax, _newMax);
}
function disableFee() external onlyOwner {
feeEnabled = false;
emit FeeIsDisabled();
}
/// @notice Temporarily pause fee collection (e.g. Block 0 bundle buys).
/// Unlike disableFee, this can be reversed with resumeFees().
function pauseFees() external onlyOwner {
feesPaused = true;
emit FeesPaused();
}
/// @notice Resume fee collection after pauseFees().
function resumeFees() external onlyOwner {
feesPaused = false;
emit FeesResumed();
}
// ─── Owner: fee split ──────────────────────────────────────────────
/// @param _burnBps Basis points of accumulated fee tokens to burn (max 10 000).
function setBurnBps(uint _burnBps) external onlyOwner {
if (_burnBps > 10000) revert BurnBpsTooHigh();
burnBps = _burnBps;
emit BurnBpsUpdated(_burnBps);
}
/// @param _devBps Basis points of remaining native to dev wallet.
/// @param _rewardBps Basis points of remaining native to distributor.
/// Must sum to 10 000.
function setDevRewardSplit(uint _devBps, uint _rewardBps) external onlyOwner {
if (_devBps + _rewardBps != 10000) revert InvalidSplit();
devBps = _devBps;
rewardBps = _rewardBps;
emit DevRewardSplitUpdated(_devBps, _rewardBps);
}
// ─── Owner: exclusions ─────────────────────────────────────────────
function excludeFromFees(address account, bool excluded) external onlyOwner {
isExcludedFromFees[account] = excluded;
emit ExcludedFromFees(account, excluded);
}
function excludeFromLimits(address account, bool excluded) external onlyOwner {
isExcludedFromLimits[account] = excluded;
emit ExcludedFromLimits(account, excluded);
}
function excludeFromDividends(address account, bool excluded) external onlyOwner {
isExcludedFromDividends[account] = excluded;
if (excluded) {
dividendDistributor.setShare(account, 0);
} else {
dividendDistributor.setShare(account, balanceOf(account));
}
emit ExcludedFromDividends(account, excluded);
}
// ─── Owner: rescue (restricted) ────────────────────────────────────
/// @notice Rescue ERC20 tokens accidentally sent to the contract.
/// Cannot rescue the fee token itself (this contract's token).
function claimTokens(address token, address to, uint amount) external onlyOwner {
if (token == address(this)) revert CannotClaimFeeToken();
SafeERC20.safeTransfer(IERC20(token), to, amount);
emit ClaimedTokens(token, to, amount);
}
function claimETH(address to, uint amount) external onlyOwner {
(bool success,) = to.call{value: amount}("");
require(success, "ETH transfer failed");
}
// ─── Internal: swap fee tokens -> native ───────────────────────────
/// @dev Caller MUST set isSwapping = true before calling and = false after.
function _swapTokensForNative(uint256 tokenAmount) private returns (uint) {
uint balanceBefore = address(this).balance;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = dexRouter.WETH();
_approve(address(this), address(dexRouter), tokenAmount);
dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
address(this),
block.timestamp
);
return address(this).balance - balanceBefore;
}
// ─── Internal: current fee (anti-snipe) ────────────────────────────
function _getCurrentFee() internal view returns (uint) {
if (!feeEnabled || feesPaused) return 0;
// Launch block gets the high anti-snipe fee
if (launchBlock > 0 && block.number <= launchBlock) {
return launchFee;
}
// After launch block, use the trading fee (capped by maxFee)
uint _tradingFee = tradingFee;
return _tradingFee > maxFee ? maxFee : _tradingFee;
}
// ─── Core: _update (fee collection + distribution trigger) ─────────
function _update(address from, address to, uint256 amount) internal override {
// During our own swaps, bypass all logic
if (isSwapping) {
super._update(from, to, amount);
return;
}
bool isSell = ammContracts[to];
bool isBuy = ammContracts[from];
uint _fee = _getCurrentFee();
uint caBalance = balanceOf(address(this));
uint _maxWallet = maxWalletAmount;
// Transfer gate
if (!isTransferEnabled && !isExcludedFromLimits[from] && !isExcludedFromLimits[to])
revert TransferDisabled();
// Trading gate
if ((isSell || isBuy) && !isTradingEnabled && !isExcludedFromLimits[from] && !isExcludedFromLimits[to])
revert TradingDisabled();
// Max wallet
if (_maxWallet > 0) {
if (balanceOf(to) + amount > _maxWallet && !isExcludedFromMaxWallet[to]) {
revert("Max wallet amount exceeded");
}
}
// Collect fee
if (_fee > 0 && !isExcludedFromFees[from] && !isExcludedFromFees[to]) {
uint feeAmount = amount * _fee / 1000;
super._update(from, address(this), feeAmount);
amount -= feeAmount;
emit FeeCollected(from, feeAmount);
}
// On sell, process accumulated fee tokens (capped to prevent large dumps)
if (isSell && caBalance >= minAmountForSwap) {
// Guard entire fee-processing block against reentrancy via
// .call{value:} to devWallet / platform wallets.
isSwapping = true;
// Cap: swap the larger of minAmountForSwap or the user's sell amount,
// but never more than what's accumulated
uint swapCap = amount > minAmountForSwap ? amount : minAmountForSwap;
uint toProcess = caBalance > swapCap ? swapCap : caBalance;
// 1. Burn portion
uint burnAmount = toProcess * burnBps / 10000;
if (burnAmount > 0) {
_burn(address(this), burnAmount);
emit TokensBurned(burnAmount);
}
// 2. Swap remainder -> native (skip if burnBps == 100 %)
uint swapAmount = toProcess - burnAmount;
if (swapAmount > 0) {
uint nativeReceived = _swapTokensForNative(swapAmount);
// 3. Platform cut (split 50/50)
uint platformShare = nativeReceived * platformBps / 10000;
uint platformHalf = platformShare / 2;
if (platformHalf > 0) {
(bool s1,) = platformWallet1.call{value: platformHalf}("");
(bool s2,) = platformWallet2.call{value: platformShare - platformHalf}("");
if (s1 || s2) emit PlatformShareSent(platformShare);
}
// 4. Split remaining native between dev and distributor
uint remaining = nativeReceived - platformShare;
uint devShare = remaining * devBps / 10000;
uint rewardShare = remaining - devShare;
if (devShare > 0) {
(bool sent,) = devWallet.call{value: devShare}("");
if (sent) emit DevShareSent(devShare);
}
if (rewardShare > 0) {
try dividendDistributor.deposit{value: rewardShare}() {} catch {}
}
}
isSwapping = false;
}
super._update(from, to, amount);
// ── Dividend tracker ──
if (!isExcludedFromDividends[from]) {
try dividendDistributor.setShare(from, balanceOf(from)) {} catch {
emit SetDividendShareFailed(from);
}
}
if (!isExcludedFromDividends[to]) {
try dividendDistributor.setShare(to, balanceOf(to)) {} catch {
emit SetDividendShareFailed(to);
}
}
try dividendDistributor.process(distributorGas) {} catch {
emit ProcessDividendFailed();
}
}
// ─── Public: burn ──────────────────────────────────────────────────
function burn(uint256 amount) external {
super._burn(msg.sender, amount);
}
}
Chain explorer5320msChain node72ms