NoxaToken

0x57338fb7e0c0b2ee3d3c4447f7290bc6859834c9

Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
2,604 bytes
ABI entries
25
10 read · 4 write
License
none

Contract information

Address
0x57338fb7e0c0b2ee3d3c4447f7290bc6859834c9
Chain
Robinhood Chain (4663)
Compiler
v0.8.28+commit.7893614a
Optimization
Enabled
Creation tx
0x4218634105…c82283d4c2

Token

Name
Magical Creatures Cake Company | noxafun.eth.limo
Symbol
MCCC
Decimals
18
Holders
11

Read contract (10)

DOMAIN_SEPARATOR()bytes32
allowance(address, address)uint256
balanceOf(address)uint256
decimals()uint8
name()string
nonces(address)uint256
platform()string
symbol()string
totalSupply()uint256
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": "to",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "AllowanceOverflow",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "AllowanceUnderflow",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InsufficientAllowance",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InsufficientBalance",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidPermit",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "Permit2AllowanceIsFixedAtInfinity",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "PermitExpired",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TotalSupplyOverflow",
    "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": "amount",
        "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": "amount",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "DOMAIN_SEPARATOR",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "result",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      }
    ],
    "name": "allowance",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "result",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "result",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      }
    ],
    "name": "nonces",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "result",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "value",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "deadline",
        "type": "uint256"
      },
      {
        "internalType": "uint8",
        "name": "v",
        "type": "uint8"
      },
      {
        "internalType": "bytes32",
        "name": "r",
        "type": "bytes32"
      },
      {
        "internalType": "bytes32",
        "name": "s",
        "type": "bytes32"
      }
    ],
    "name": "permit",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "platform",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "symbol",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "result",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "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": "amount",
        "type": "uint256"
      }
    ],
    "name": "transferFrom",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "website",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "pure",
    "type": "function"
  }
]

Source code

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

import {Ownable} from "../lib/solady/src/auth/Ownable.sol";
import {ERC20} from "../lib/solady/src/tokens/ERC20.sol";

interface IUniswapV2Router02 {
    function factory() external view returns (address);
    function WETH() external view returns (address);

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity);
}

interface IUniswapV2Factory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}

interface IERC20Lite {
    function balanceOf(address) external view returns (uint256);
    function transfer(address, uint256) external returns (bool);
    function approve(address, uint256) external returns (bool);
}

/// @notice NOXA ERC-20. Name is branded with noxafun.eth.limo for discovery.
contract NoxaToken is ERC20 {
    string private _name;
    string private _symbol;

    constructor(string memory name_, string memory symbol_, uint256 supply, address to) {
        _name = name_;
        _symbol = symbol_;
        _mint(to, supply);
    }

    function name() public view override returns (string memory) {
        return _name;
    }

    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    /// @dev Shown on Blockscout "Read contract" — points explorers / users to the pad.
    function website() external pure returns (string memory) {
        return "https://noxafun.eth.limo";
    }

    function platform() external pure returns (string memory) {
        return "NOXA";
    }
}

/// @title NoxaLaunchpad
/// @notice Create ERC-20 + Uniswap V2 ETH pair.
///         Public fee: 0.002 ETH + 5% of LP. Owner / feeExempt: zero fees.
contract NoxaLaunchpad is Ownable {
    uint256 public constant LAUNCH_FEE = 0.002 ether;
    uint256 public constant LP_FEE_BPS = 500; // 5%
    uint256 public constant BPS = 10_000;

    /// @notice Shown on Blockscout read methods for the pad itself.
    string public constant WEBSITE = "https://noxafun.eth.limo";
    string public constant PLATFORM = "NOXA";
    string public constant NAME_SUFFIX = " | noxafun.eth.limo";

    IUniswapV2Router02 public immutable router;
    address public immutable weth;
    address public treasury;

    uint256 public launchCount;

    struct Launch {
        address creator;
        address token;
        address pair;
        uint256 ethLiquidity;
        uint256 tokenLiquidity;
        uint256 lpToCreator;
        uint256 lpToTreasury;
        uint256 timestamp;
    }

    mapping(uint256 => Launch) public launches;
    mapping(address => uint256[]) public launchesByCreator;
    mapping(address => bool) public feeExempt;
    mapping(address => uint256) public launchIdByToken;

    error BadValue();
    error BadConfig();
    error ZeroAddress();
    error TransferFailed();

    event Launched(
        uint256 indexed id,
        address indexed creator,
        address token,
        address pair,
        uint256 ethLiquidity,
        uint256 tokenLiquidity,
        uint256 lpToCreator,
        uint256 lpToTreasury
    );
    event TreasurySet(address treasury);
    event FeeExemptSet(address indexed account, bool exempt);

    constructor(address router_, address treasury_) {
        if (router_ == address(0) || treasury_ == address(0)) revert ZeroAddress();
        _initializeOwner(msg.sender);
        router = IUniswapV2Router02(router_);
        weth = IUniswapV2Router02(router_).WETH();
        treasury = treasury_;
        feeExempt[msg.sender] = true;
        emit FeeExemptSet(msg.sender, true);
    }

    function setTreasury(address treasury_) external onlyOwner {
        if (treasury_ == address(0)) revert ZeroAddress();
        treasury = treasury_;
        emit TreasurySet(treasury_);
    }

    function setFeeExempt(address account, bool exempt) external onlyOwner {
        if (account == address(0)) revert ZeroAddress();
        feeExempt[account] = exempt;
        emit FeeExemptSet(account, exempt);
    }

    function isFeeExempt(address account) public view returns (bool) {
        return account == owner() || feeExempt[account];
    }

    /// @notice Launch token + LP.
    /// @dev Public: msg.value = LAUNCH_FEE + ETH for liquidity.
    ///      Fee-exempt (owner/admin): msg.value = ETH for liquidity only (no pad fee, no LP cut).
    function launch(
        string calldata name_,
        string calldata symbol_,
        uint256 totalSupply,
        uint256 tokenForLp
    ) external payable returns (uint256 id, address token, address pair) {
        if (totalSupply == 0 || tokenForLp == 0 || tokenForLp > totalSupply) revert BadConfig();
        if (bytes(name_).length == 0 || bytes(symbol_).length == 0) revert BadConfig();

        bool exempt = isFeeExempt(msg.sender);
        uint256 fee = exempt ? 0 : LAUNCH_FEE;
        if (msg.value <= fee) revert BadValue();
        uint256 ethForLp = msg.value - fee;

        if (fee != 0) {
            (bool ok,) = treasury.call{value: fee}("");
            if (!ok) revert TransferFailed();
        }

        string memory branded = string.concat(name_, NAME_SUFFIX);
        NoxaToken t = new NoxaToken(branded, symbol_, totalSupply, address(this));
        token = address(t);

        IERC20Lite(token).approve(address(router), tokenForLp);
        uint256 deadline = block.timestamp + 30 minutes;
        (,, uint256 liquidity) =
            router.addLiquidityETH{value: ethForLp}(token, tokenForLp, 0, 0, address(this), deadline);

        pair = IUniswapV2Factory(router.factory()).getPair(token, weth);
        if (pair == address(0)) revert BadConfig();

        uint256 lpTreasury = exempt ? 0 : (liquidity * LP_FEE_BPS) / BPS;
        uint256 lpCreator = liquidity - lpTreasury;
        _splitLp(pair, msg.sender, lpTreasury, lpCreator);

        uint256 leftover = totalSupply - tokenForLp;
        if (leftover != 0) {
            if (!IERC20Lite(token).transfer(msg.sender, leftover)) revert TransferFailed();
        }

        id = ++launchCount;
        Launch storage L = launches[id];
        L.creator = msg.sender;
        L.token = token;
        L.pair = pair;
        L.ethLiquidity = ethForLp;
        L.tokenLiquidity = tokenForLp;
        L.lpToCreator = lpCreator;
        L.lpToTreasury = lpTreasury;
        L.timestamp = block.timestamp;
        launchesByCreator[msg.sender].push(id);
        launchIdByToken[token] = id;

        emit Launched(
            id, msg.sender, token, pair, ethForLp, tokenForLp, lpCreator, lpTreasury
        );
    }

    function _splitLp(address pair, address creator, uint256 lpTreasury, uint256 lpCreator)
        internal
    {
        if (lpTreasury != 0) {
            if (!IERC20Lite(pair).transfer(treasury, lpTreasury)) revert TransferFailed();
        }
        if (lpCreator != 0) {
            if (!IERC20Lite(pair).transfer(creator, lpCreator)) revert TransferFailed();
        }
    }

    function creatorLaunchCount(address creator) external view returns (uint256) {
        return launchesByCreator[creator].length;
    }

    function getLaunch(uint256 id)
        external
        view
        returns (
            address creator,
            address token,
            address pair,
            uint256 ethLiquidity,
            uint256 tokenLiquidity,
            uint256 lpToCreator,
            uint256 lpToTreasury,
            uint256 timestamp
        )
    {
        Launch storage L = launches[id];
        return (
            L.creator,
            L.token,
            L.pair,
            L.ethLiquidity,
            L.tokenLiquidity,
            L.lpToCreator,
            L.lpToTreasury,
            L.timestamp
        );
    }

    receive() external payable {}
}
Chain explorer3502msChain node82ms