JellyfishHybridToken
0xa305a24ed54bc66dac5c68bb505aacee198fc7c1
Verification
Verified
0.8.26+commit.8a97fa7a
Type
Contract
5,460 bytes
ABI entries
61
30 read · 8 write
License
none
Contract information
- Address
- 0xa305a24ed54bc66dac5c68bb505aacee198fc7c1
- Chain
- Robinhood Chain (4663)
- Compiler
- 0.8.26+commit.8a97fa7a
- Optimization
- Enabled
- Creator
- 0x2c1b9cECeE…E4Dcb3Bf88
- Creation tx
- 0x35de232b71…5f3e2c5861
Token
- Name
- JELLY
- Symbol
- JELLY
- Decimals
- 18
- Holders
- 46
- Market
- View token page →
Read contract (30)
AUCTION_ALLOCATION() → uint256
COMMUNITY_ALLOCATION() → uint256
DEVELOPMENT_ALLOCATION() → uint256
LIQUIDITY_ALLOCATION() → uint256
MAX_BUY_CAP() → uint256
MAX_BUY_GROWTH_PER_SECOND() → uint256
MAX_BUY_PRECISION() → uint256
MAX_LIQUIDITY_ROUNDING_DUST() → uint256
MAX_SYNC() → uint256
START_MAX_BUY() → uint256
TOTAL_SUPPLY() → uint256
TREASURY_ALLOCATION() → uint256
UNIT() → uint256
allowance(address, address) → uint256
balanceOf(address) → uint256
decimals() → uint8
hook() → address
isLaunched() → bool
jellyExcluded(address) → bool
launchConfigured() → bool
launchTime() → uint64
liquidityAllocator() → address
maxBuy() → uint256
name() → string
owner() → address
permanentlyExcluded(address) → bool
poolManager() → address
registry() → address
symbol() → string
totalSupply() → uint256
Events (6)
ApprovalJellyExcludedSetLaunchConfiguredLaunchedOwnershipTransferredTransfer
ABI
[
{
"inputs": [
{
"internalType": "string",
"name": "name_",
"type": "string"
},
{
"internalType": "string",
"name": "symbol_",
"type": "string"
},
{
"internalType": "address",
"name": "poolManager_",
"type": "address"
},
{
"internalType": "address",
"name": "initialOwner",
"type": "address"
},
{
"internalType": "address",
"name": "auctionReserve",
"type": "address"
},
{
"internalType": "address",
"name": "communityReserve",
"type": "address"
},
{
"internalType": "address",
"name": "treasuryVesting",
"type": "address"
},
{
"internalType": "address",
"name": "developmentVesting",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "AlreadyConfigured",
"type": "error"
},
{
"inputs": [],
"name": "AlreadyLaunched",
"type": "error"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "maximum",
"type": "uint256"
}
],
"name": "BuyLimitExceeded",
"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": "LiquidityRouteOnly",
"type": "error"
},
{
"inputs": [],
"name": "NotHook",
"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": [],
"name": "PermanentlyExcluded",
"type": "error"
},
{
"inputs": [],
"name": "UnsafePrelaunchDistribution",
"type": "error"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
},
{
"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": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "JellyExcludedSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "hook",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "registry",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "liquidityAllocator",
"type": "address"
}
],
"name": "LaunchConfigured",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "poolManager",
"type": "address"
},
{
"indexed": false,
"internalType": "uint64",
"name": "launchTime",
"type": "uint64"
}
],
"name": "Launched",
"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": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "AUCTION_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "COMMUNITY_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEVELOPMENT_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "LIQUIDITY_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_BUY_CAP",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_BUY_GROWTH_PER_SECOND",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_BUY_PRECISION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_LIQUIDITY_ROUNDING_DUST",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MAX_SYNC",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "START_MAX_BUY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TOTAL_SUPPLY",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "TREASURY_ALLOCATION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"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": "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": "address",
"name": "hook_",
"type": "address"
},
{
"internalType": "contract IJellyfishTransferSync",
"name": "registry_",
"type": "address"
},
{
"internalType": "address",
"name": "liquidityAllocator_",
"type": "address"
}
],
"name": "configureLaunch",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "hook",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isLaunched",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "jellyExcluded",
"outputs": [
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launchConfigured",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "launchTime",
"outputs": [
{
"internalType": "uint64",
"name": "",
"type": "uint64"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "liquidityAllocator",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxBuy",
"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": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "permanentlyExcluded",
"outputs": [
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "poolManager",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "registry",
"outputs": [
{
"internalType": "contract IJellyfishTransferSync",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
},
{
"internalType": "bool",
"name": "excluded",
"type": "bool"
}
],
"name": "setJellyExcluded",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "start",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"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"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { IJellyfishTransferSync } from "./IJellyfishHybrid.sol";
contract JellyfishHybridToken is ERC20, Ownable {
uint256 public constant TOTAL_SUPPLY = 4_444 ether;
uint256 public constant AUCTION_ALLOCATION = 1_778 ether;
uint256 public constant LIQUIDITY_ALLOCATION = 1_111 ether;
uint256 public constant MAX_LIQUIDITY_ROUNDING_DUST = 1 gwei;
uint256 public constant COMMUNITY_ALLOCATION = 444 ether;
uint256 public constant TREASURY_ALLOCATION = 667 ether;
uint256 public constant DEVELOPMENT_ALLOCATION = 444 ether;
uint256 public constant UNIT = 1 ether;
uint256 public constant MAX_SYNC = 64;
uint256 public constant MAX_BUY_PRECISION = 100_000;
uint256 public constant START_MAX_BUY = (TOTAL_SUPPLY * 250) / MAX_BUY_PRECISION;
uint256 public constant MAX_BUY_CAP = 64 ether;
uint256 public constant MAX_BUY_GROWTH_PER_SECOND = 3;
address public immutable poolManager;
address public hook;
address public liquidityAllocator;
IJellyfishTransferSync public registry;
bool public launchConfigured;
bool public isLaunched;
uint64 public launchTime;
mapping(address account => bool excluded) public jellyExcluded;
mapping(address account => bool excluded) public permanentlyExcluded;
event LaunchConfigured(
address indexed hook, address indexed registry, address indexed liquidityAllocator
);
event Launched(address indexed poolManager, uint64 launchTime);
event JellyExcludedSet(address indexed account, bool excluded);
error ZeroAddress();
error AlreadyConfigured();
error AlreadyLaunched();
error NotHook();
error UnsafePrelaunchDistribution();
error LiquidityRouteOnly();
error PermanentlyExcluded();
error BuyLimitExceeded(uint256 amount, uint256 maximum);
constructor(
string memory name_,
string memory symbol_,
address poolManager_,
address initialOwner,
address auctionReserve,
address communityReserve,
address treasuryVesting,
address developmentVesting
) ERC20(name_, symbol_) Ownable(initialOwner) {
if (
poolManager_.code.length == 0 || initialOwner == address(0)
|| auctionReserve == address(0) || communityReserve == address(0)
|| treasuryVesting == address(0) || developmentVesting == address(0)
) revert ZeroAddress();
poolManager = poolManager_;
_setPermanentExcluded(poolManager_);
_setPermanentExcluded(initialOwner);
_setPermanentExcluded(address(this));
_setPermanentExcluded(address(0xdead));
_setPermanentExcluded(auctionReserve);
_setPermanentExcluded(communityReserve);
_setPermanentExcluded(treasuryVesting);
_setPermanentExcluded(developmentVesting);
_mint(auctionReserve, AUCTION_ALLOCATION);
_mint(address(this), LIQUIDITY_ALLOCATION);
_mint(communityReserve, COMMUNITY_ALLOCATION);
_mint(treasuryVesting, TREASURY_ALLOCATION);
_mint(developmentVesting, DEVELOPMENT_ALLOCATION);
assert(totalSupply() == TOTAL_SUPPLY);
}
function configureLaunch(
address hook_,
IJellyfishTransferSync registry_,
address liquidityAllocator_
) external onlyOwner {
if (launchConfigured || isLaunched) {
revert AlreadyConfigured();
}
if (
hook_.code.length == 0 || address(registry_).code.length == 0
|| liquidityAllocator_.code.length == 0
) revert ZeroAddress();
if (balanceOf(address(this)) != LIQUIDITY_ALLOCATION) revert UnsafePrelaunchDistribution();
hook = hook_;
registry = registry_;
liquidityAllocator = liquidityAllocator_;
_setPermanentExcluded(hook_);
_setPermanentExcluded(address(registry_));
_setPermanentExcluded(liquidityAllocator_);
launchConfigured = true;
_transfer(address(this), liquidityAllocator_, LIQUIDITY_ALLOCATION);
emit LaunchConfigured(hook_, address(registry_), liquidityAllocator_);
}
function start() external {
if (msg.sender != hook || hook == address(0)) revert NotHook();
if (isLaunched) revert AlreadyLaunched();
if (!launchConfigured) revert AlreadyConfigured();
uint256 allocatorBalance = balanceOf(liquidityAllocator);
uint256 poolBalance = balanceOf(poolManager);
if (
allocatorBalance > MAX_LIQUIDITY_ROUNDING_DUST
|| poolBalance < LIQUIDITY_ALLOCATION - MAX_LIQUIDITY_ROUNDING_DUST
|| poolBalance + allocatorBalance < LIQUIDITY_ALLOCATION
) {
revert UnsafePrelaunchDistribution();
}
isLaunched = true;
launchTime = uint64(block.timestamp);
emit Launched(poolManager, launchTime);
}
function setJellyExcluded(address account, bool excluded) external onlyOwner {
if (isLaunched) revert AlreadyLaunched();
if (!excluded && permanentlyExcluded[account]) revert PermanentlyExcluded();
if (excluded) permanentlyExcluded[account] = true;
jellyExcluded[account] = excluded;
emit JellyExcludedSet(account, excluded);
}
function maxBuy() public view returns (uint256) {
if (!isLaunched) return 0;
uint256 value = START_MAX_BUY
+ (TOTAL_SUPPLY * (block.timestamp - launchTime) * MAX_BUY_GROWTH_PER_SECOND)
/ MAX_BUY_PRECISION;
return value > MAX_BUY_CAP ? MAX_BUY_CAP : value;
}
function _update(address from, address to, uint256 amount) internal override {
if (launchConfigured && from == liquidityAllocator && to != poolManager && to != address(0))
{
revert LiquidityRouteOnly();
}
super._update(from, to, amount);
if (!isLaunched || amount == 0 || address(registry) == address(0)) return;
if (from == poolManager && _canReceive(to)) {
uint256 maximum = maxBuy();
if (amount > maximum) revert BuyLimitExceeded(amount, maximum);
}
registry.syncAfterTransfer(from, to, amount, bytes32(0));
}
function _canReceive(address account) private view returns (bool) {
return account != address(0) && account != address(this) && !jellyExcluded[account];
}
function _setPermanentExcluded(address account) private {
permanentlyExcluded[account] = true;
jellyExcluded[account] = true;
emit JellyExcludedSet(account, true);
}
}
Chain explorer6015msChain node87ms