BurnedLiquidityTokenLauncher

0xf438837d6a90b8f3bcc71c3cb23ed9524123f276

Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
4,943 bytes
ABI entries
19
8 read · 1 write
License
none

Contract information

Address
0xf438837d6a90b8f3bcc71c3cb23ed9524123f276
Chain
Robinhood Chain (4663)
Compiler
v0.8.24+commit.e11b9ed9
Optimization
Enabled
Creation tx
0x9af2c5c65c…06051fa440

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (8)

BPS_DENOMINATOR()uint256
LIQUIDITY_BPS()uint256
LP_BURN_ADDRESS()address
TOKEN_UNIT()uint256
TREASURY_BPS()uint256
router()address
uniswapV2Factory()address
weth()address

Events (1)

TokenLaunched

ABI

[
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "router_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "uniswapV2Factory_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "weth_",
        "type": "address"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "inputs": [],
    "name": "DeadlineExpired",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidAddress",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidLiquidity",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidSupply",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "InvalidTokenData",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "LiquidityWasNotFullyUsed",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "RouterConfigurationMismatch",
    "type": "error"
  },
  {
    "inputs": [],
    "name": "TransferFailed",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "treasuryWallet",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "lpBurnAddress",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "totalSupply",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "treasuryAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "liquidityTokenAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "liquidityEthAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "lpTokensMinted",
        "type": "uint256"
      }
    ],
    "name": "TokenLaunched",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "BPS_DENOMINATOR",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "LIQUIDITY_BPS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "LP_BURN_ADDRESS",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "TOKEN_UNIT",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "TREASURY_BPS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "metadataURI_",
        "type": "string"
      },
      {
        "internalType": "uint256",
        "name": "totalSupplyWhole_",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "treasuryWallet_",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "deadline_",
        "type": "uint256"
      }
    ],
    "name": "launch",
    "outputs": [
      {
        "internalType": "address",
        "name": "tokenAddress",
        "type": "address"
      }
    ],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "router",
    "outputs": [
      {
        "internalType": "contract IUniswapV2Router02",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "uniswapV2Factory",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "weth",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  }
]

Source code

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

import {FixedSupplyToken} from "./FixedSupplyToken.sol";
import {IUniswapV2Router02} from "./interfaces/IUniswapV2Router02.sol";

contract BurnedLiquidityTokenLauncher {
    uint256 public constant TREASURY_BPS = 7_000;
    uint256 public constant LIQUIDITY_BPS = 3_000;
    uint256 public constant BPS_DENOMINATOR = 10_000;
    uint256 public constant TOKEN_UNIT = 1e18;
    address public constant LP_BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

    IUniswapV2Router02 public immutable router;
    address public immutable uniswapV2Factory;
    address public immutable weth;

    error InvalidAddress();
    error InvalidTokenData();
    error InvalidSupply();
    error InvalidLiquidity();
    error DeadlineExpired();
    error RouterConfigurationMismatch();
    error TransferFailed();
    error LiquidityWasNotFullyUsed();

    event TokenLaunched(
        address indexed token,
        address indexed treasuryWallet,
        address indexed lpBurnAddress,
        uint256 totalSupply,
        uint256 treasuryAmount,
        uint256 liquidityTokenAmount,
        uint256 liquidityEthAmount,
        uint256 lpTokensMinted
    );

    struct Allocation {
        uint256 totalSupply;
        uint256 treasuryAmount;
        uint256 liquidityTokenAmount;
    }

    constructor(address router_, address uniswapV2Factory_, address weth_) {
        if (router_ == address(0) || uniswapV2Factory_ == address(0) || weth_ == address(0)) {
            revert InvalidAddress();
        }
        if (router_.code.length == 0 || uniswapV2Factory_.code.length == 0 || weth_.code.length == 0) {
            revert InvalidAddress();
        }

        IUniswapV2Router02 routerContract = IUniswapV2Router02(router_);
        if (routerContract.factory() != uniswapV2Factory_ || routerContract.WETH() != weth_) {
            revert RouterConfigurationMismatch();
        }

        router = routerContract;
        uniswapV2Factory = uniswapV2Factory_;
        weth = weth_;
    }

    function launch(
        string calldata name_,
        string calldata symbol_,
        string calldata metadataURI_,
        uint256 totalSupplyWhole_,
        address treasuryWallet_,
        uint256 deadline_
    ) external payable returns (address tokenAddress) {
        _validateLaunch(name_, symbol_, totalSupplyWhole_, treasuryWallet_, deadline_);

        Allocation memory allocation = _calculateAllocation(totalSupplyWhole_);
        FixedSupplyToken token = new FixedSupplyToken(
            name_,
            symbol_,
            metadataURI_,
            allocation.totalSupply,
            address(this)
        );

        if (!token.transfer(treasuryWallet_, allocation.treasuryAmount)) revert TransferFailed();
        if (!token.approve(address(router), allocation.liquidityTokenAmount)) revert TransferFailed();

        uint256 lpTokensMinted = _addLiquidity(address(token), allocation.liquidityTokenAmount, deadline_);

        tokenAddress = address(token);
        emit TokenLaunched(
            tokenAddress,
            treasuryWallet_,
            LP_BURN_ADDRESS,
            allocation.totalSupply,
            allocation.treasuryAmount,
            allocation.liquidityTokenAmount,
            msg.value,
            lpTokensMinted
        );
    }

    function _validateLaunch(
        string calldata name_,
        string calldata symbol_,
        uint256 totalSupplyWhole_,
        address treasuryWallet_,
        uint256 deadline_
    ) private view {
        if (bytes(name_).length == 0 || bytes(symbol_).length == 0) revert InvalidTokenData();
        if (treasuryWallet_ == address(0)) revert InvalidAddress();
        if (totalSupplyWhole_ == 0 || totalSupplyWhole_ > type(uint256).max / TOKEN_UNIT) {
            revert InvalidSupply();
        }
        if (msg.value == 0) revert InvalidLiquidity();
        if (deadline_ < block.timestamp) revert DeadlineExpired();
    }

    function _calculateAllocation(uint256 totalSupplyWhole_) private pure returns (Allocation memory allocation) {
        allocation.totalSupply = totalSupplyWhole_ * TOKEN_UNIT;
        allocation.liquidityTokenAmount = (allocation.totalSupply * LIQUIDITY_BPS) / BPS_DENOMINATOR;
        allocation.treasuryAmount = allocation.totalSupply - allocation.liquidityTokenAmount;
    }

    function _addLiquidity(
        address token_,
        uint256 liquidityTokenAmount_,
        uint256 deadline_
    ) private returns (uint256 lpTokensMinted) {
        (uint256 usedTokenAmount, uint256 usedEthAmount, uint256 mintedLpTokens) = router.addLiquidityETH{value: msg.value}(
            token_,
            liquidityTokenAmount_,
            liquidityTokenAmount_,
            msg.value,
            LP_BURN_ADDRESS,
            deadline_
        );

        if (usedTokenAmount != liquidityTokenAmount_ || usedEthAmount != msg.value) {
            revert LiquidityWasNotFullyUsed();
        }

        return mintedLpTokens;
    }
}
Chain explorer3371msChain node74ms