LemonToken

0xbf4fee7b8f2bce0d62c3d5c4a4d2455495d8013f

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
4,241 bytes
ABI entries
33
18 read · 6 write
License
none

Contract information

Address
0xbf4fee7b8f2bce0d62c3d5c4a4d2455495d8013f
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0xa895edc75f…497701b1d6

Token

Name
Lemonthy The Raccoon
Symbol
Lemonthy
Decimals
18
Holders
52

Read contract (18)

allowance(address, address)uint256
balanceOf(address)uint256
capUntil()uint256
decimals()uint8
description()string
launcher()address
logoURI()string
maxWallet()uint256
name()string
pool()address
poolSetter()address
symbol()string
telegram()string
totalSupply()uint256
tradingOpen()bool
tradingOpensAt()uint256
twitter()string
website()string

Events (2)

ApprovalTransfer

ABI

[
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol_",
        "type": "string"
      },
      {
        "internalType": "uint256",
        "name": "supply_",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "launcher_",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "logoURI_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "description_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "twitter_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "telegram_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "website_",
        "type": "string"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "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"
  },
  {
    "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": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "value",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "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": "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": [],
    "name": "capUntil",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "maxWallet_",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "launchDelaySecs",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "capWindowSecs",
        "type": "uint256"
      }
    ],
    "name": "configureLaunch",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "description",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "setter_",
        "type": "address"
      }
    ],
    "name": "initPoolSetter",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "launcher",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "logoURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "maxWallet",
    "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": "pool",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "poolSetter",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "pool_",
        "type": "address"
      }
    ],
    "name": "setPool",
    "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": "tradingOpen",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "tradingOpensAt",
    "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": [],
    "name": "twitter",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "website",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/// @title LemonToken
/// @notice Immutable ERC-20 launch token with on-chain metadata and a
///         one-time anti-snipe / max-wallet window set by the launcher.
contract LemonToken is ERC20 {
    address public immutable launcher; // the factory / presale contract that launched it

    // on-chain metadata
    string public logoURI;
    string public description;
    string public twitter;
    string public telegram;
    string public website;

    // launch protections (set once at launch)
    address public pool;
    uint256 public maxWallet; // per-wallet cap during the cap window (0 = unset)
    uint256 public tradingOpensAt; // launch-delay gate: public trading blocked before this timestamp
    uint256 public capUntil; // anti-snipe max-wallet cap active until this timestamp
    bool private _configured;

    /// @notice One-shot address (typically the BondingCurve) allowed to wire
    /// the real DEX pool at graduation. Distinct from `launcher` so we never
    /// expose an *unseeded* pool to honeypot scanners during bonding.
    address public poolSetter;
    bool private _poolSetterInit;

    constructor(
        string memory name_,
        string memory symbol_,
        uint256 supply_,
        address launcher_,
        string memory logoURI_,
        string memory description_,
        string memory twitter_,
        string memory telegram_,
        string memory website_
    ) ERC20(name_, symbol_) {
        launcher = launcher_;
        logoURI = logoURI_;
        description = description_;
        twitter = twitter_;
        telegram = telegram_;
        website = website_;
        _mint(launcher_, supply_); // full supply to the launcher; there is no other mint path
    }

    /// @notice One-time wiring by the launcher at launch. Windows are in SECONDS.
    /// @dev The real DEX pool is intentionally NOT set here — see `setPool`.
    /// Advertising an unseeded pool at launch would make honeypot simulators
    /// report "100% sell tax" throughout the bonding-curve phase.
    function configureLaunch(uint256 maxWallet_, uint256 launchDelaySecs, uint256 capWindowSecs)
        external
    {
        require(msg.sender == launcher && !_configured, "not launcher / configured");
        _configured = true;
        maxWallet = maxWallet_;
        tradingOpensAt = block.timestamp + launchDelaySecs;
        capUntil = tradingOpensAt + capWindowSecs;
    }

    /// @notice Launcher assigns the pool-setter role exactly once (the curve).
    function initPoolSetter(address setter_) external {
        require(msg.sender == launcher && !_poolSetterInit, "not launcher / init");
        require(setter_ != address(0), "zero setter");
        _poolSetterInit = true;
        poolSetter = setter_;
    }

    /// @notice Called by the curve at graduation to wire the seeded SushiSwap
    /// V3 pool. One-shot: `pool` can be set exactly once.
    function setPool(address pool_) external {
        require(msg.sender == poolSetter, "not poolSetter");
        require(pool == address(0) && pool_ != address(0), "pool set");
        pool = pool_;
    }

    function tradingOpen() external view returns (bool) {
        return _configured && block.timestamp >= tradingOpensAt;
    }

    /// @dev Launch protections apply only to *public trades* touching the pool.
    /// While `pool == address(0)` (entire bonding-curve phase) the whole branch
    /// is dead and the token behaves as a plain unrestricted ERC-20.
    function _update(address from, address to, uint256 value) internal override {
        if (_configured && pool != address(0) && (from == pool || to == pool) && from != launcher && to != launcher) {
            require(block.timestamp >= tradingOpensAt, "launch: trading not open");
            if (maxWallet != 0 && block.timestamp < capUntil && to != pool && to != address(0)) {
                require(balanceOf(to) + value <= maxWallet, "anti-snipe: max wallet");
            }
        }
        super._update(from, to, value);
    }
}
Chain explorer4098msChain node76ms