LaunchToken

0x302f79bec07bbefe627649c4739fa8d677777777

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
3,405 bytes
ABI entries
35
17 read · 4 write
License
none

Contract information

Address
0x302f79bec07bbefe627649c4739fa8d677777777
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0x5fdd939757…348acadd66

Token

Name
777
Symbol
777
Decimals
18
Holders
106

Read contract (17)

TOTAL_SUPPLY()uint256
allowance(address, address)uint256
balanceOf(address)uint256
creator()address
decimals()uint8
factory()address
feeLocker()address
launchBlock()uint256
logoURI()string
maxBuyBps()uint16
maxHoldBps()uint16
name()string
pool()address
protectionEndBlock()uint256
socials()string
symbol()string
totalSupply()uint256

Events (2)

ApprovalTransfer

ABI

[
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "logoURI_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "socials_",
        "type": "string"
      },
      {
        "internalType": "address",
        "name": "creator_",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "BuyExceedsCap",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "CreatorOnlyBlock",
    "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": "HoldExceedsCap",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "OnlyFactory",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "PoolAlreadySet",
    "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": [],
    "name": "TOTAL_SUPPLY",
    "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": [],
    "name": "creator",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "factory",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "feeLocker",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "launchBlock",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "logoURI",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "maxBuyBps",
    "outputs": [
      {
        "internalType": "uint16",
        "name": "",
        "type": "uint16"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "maxHoldBps",
    "outputs": [
      {
        "internalType": "uint16",
        "name": "",
        "type": "uint16"
      }
    ],
    "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": "protectionEndBlock",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "pool_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "feeLocker_",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "protectionBlocks",
        "type": "uint256"
      },
      {
        "internalType": "uint16",
        "name": "maxBuyBps_",
        "type": "uint16"
      },
      {
        "internalType": "uint16",
        "name": "maxHoldBps_",
        "type": "uint16"
      }
    ],
    "name": "setPool",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "socials",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "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"
  }
]

Source code

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

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

/// Fixed-supply launch token (UPDATE-05 §2).
///
/// Properties, permanent by construction:
///  - total supply minted once to the factory at construction; no mint, no
///    burn hooks, no owner, no pause;
///  - self-describing on-chain: logoURI + socials stored at launch, so
///    indexers and the web need no external metadata service;
///  - launch protection active only inside the protection window, then the
///    hook short-circuits forever.
///
/// Launch protection (Pons-style, parameters in JackpotFactory):
///  - on the launch block, buys from the pool are creator-only;
///  - until `protectionEndBlock`, a single buy may not exceed
///    `maxBuyBps` of supply and no wallet may hold more than `maxHoldBps`.
/// Only transfers FROM the pool (i.e. buys) are constrained; sells and plain
/// transfers are never blocked.
contract LaunchToken is ERC20 {
    uint256 public constant TOTAL_SUPPLY = 1_000_000_000e18;

    address public immutable factory;
    address public immutable creator;
    string public logoURI;
    /// Opaque JSON blob (website/x/telegram...); the keeper indexes it as-is.
    string public socials;

    /// Set once by the factory in the launch tx, after the pool exists.
    address public pool;
    /// The FeeLocker — exempt from the protection hook so LP fee collection
    /// (a pool -> locker transfer) can never revert inside the window.
    address public feeLocker;
    uint256 public launchBlock;
    uint256 public protectionEndBlock;
    uint16 public maxBuyBps;
    uint16 public maxHoldBps;

    error OnlyFactory();
    error PoolAlreadySet();
    error CreatorOnlyBlock();
    error BuyExceedsCap();
    error HoldExceedsCap();

    constructor(
        string memory name_,
        string memory symbol_,
        string memory logoURI_,
        string memory socials_,
        address creator_
    ) ERC20(name_, symbol_) {
        factory = msg.sender;
        creator = creator_;
        logoURI = logoURI_;
        socials = socials_;
        _mint(msg.sender, TOTAL_SUPPLY);
    }

    /// Called by the factory in the same tx as pool creation.
    function setPool(
        address pool_,
        address feeLocker_,
        uint256 protectionBlocks,
        uint16 maxBuyBps_,
        uint16 maxHoldBps_
    ) external {
        if (msg.sender != factory) revert OnlyFactory();
        if (pool != address(0)) revert PoolAlreadySet();
        pool = pool_;
        feeLocker = feeLocker_;
        launchBlock = block.number;
        protectionEndBlock = block.number + protectionBlocks;
        maxBuyBps = maxBuyBps_;
        maxHoldBps = maxHoldBps_;
    }

    function _update(address from, address to, uint256 value) internal override {
        // Constrain buys (pool -> wallet) during the protection window only.
        // The FeeLocker is exempt: a pool -> locker transfer is LP fee
        // collection, not a buy, and must never be blocked.
        if (from == pool && pool != address(0) && to != feeLocker && block.number <= protectionEndBlock) {
            if (block.number == launchBlock && to != creator) revert CreatorOnlyBlock();
            if (value > (TOTAL_SUPPLY * maxBuyBps) / 10_000) revert BuyExceedsCap();
            if (balanceOf(to) + value > (TOTAL_SUPPLY * maxHoldBps) / 10_000) {
                revert HoldExceedsCap();
            }
        }
        super._update(from, to, value);
    }
}
Chain explorer3140msChain node77ms