MemesCashV2Token

0x110ee8c641c81e20b08c7bbf20b71bb6a28973a7

Verification
Verified
v0.8.26+commit.8a97fa7a
Type
Contract
4,322 bytes
ABI entries
43
28 read · 4 write
License
none

Contract information

Address
0x110ee8c641c81e20b08c7bbf20b71bb6a28973a7
Chain
Robinhood Chain (4663)
Compiler
v0.8.26+commit.8a97fa7a
Optimization
Enabled
Creation tx
0xcc5bc8c301…6926771ba2

Token

Name
V2 Canary
Symbol
V2CANARY
Decimals
18
Holders
6

Read contract (28)

ARBSYS()address
BURN_ADDRESS()address
BUY_COOLDOWN_L2_BLOCKS()uint256
CREATOR_INITIAL_MAX()uint256
GUARD_L2_BLOCKS()uint256
GUARD_SECONDS()uint256
TOTAL_SUPPLY()uint256
WALLET_MAX()uint256
allowance(address, address)uint256
balanceOf(address)uint256
createdAt()uint256
createdAtL2Block()uint256
creator()address
creatorInitialBuyOpen()bool
currentL2Block()uint256
decimals()uint8
factory()address
lastSuccessfulPoolBuyL2Block()uint256
launchFinalized()bool
launchGuardActive()bool
locker()address
name()string
officialPool()address
router()address
symbol()string
totalSupply()uint256
v3Factory()address
weth()address

Events (4)

ApprovalBuyCooldownStartedLaunchFinalizedTransfer

ABI

[
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "name_",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "symbol_",
        "type": "string"
      },
      {
        "internalType": "address",
        "name": "factory_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "creator_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "router_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "locker_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "weth_",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "v3Factory_",
        "type": "address"
      }
    ],
    "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": "buyer",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "buyL2Block",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "nextEligibleL2Block",
        "type": "uint256"
      }
    ],
    "name": "BuyCooldownStarted",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "timestamp",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "l2Block",
        "type": "uint256"
      }
    ],
    "name": "LaunchFinalized",
    "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": "ARBSYS",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "BURN_ADDRESS",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "BUY_COOLDOWN_L2_BLOCKS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "CREATOR_INITIAL_MAX",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "GUARD_L2_BLOCKS",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "GUARD_SECONDS",
    "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": "WALLET_MAX",
    "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": "createdAt",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "createdAtL2Block",
    "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": "creatorInitialBuyOpen",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "currentL2Block",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "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": "finalizeLaunch",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "lastSuccessfulPoolBuyL2Block",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "launchFinalized",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "launchGuardActive",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "locker",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "officialPool",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "router",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "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"
  },
  {
    "inputs": [],
    "name": "v3Factory",
    "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.26;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IArbSys} from "./interfaces/IMemesCashV2.sol";
import {V3LaunchMath} from "./libraries/V3LaunchMath.sol";

/// @notice Plain ERC20 after an immutable, time-limited launch guard.
contract MemesCashV2Token is ERC20 {
    uint256 public constant TOTAL_SUPPLY = 1_000_000_000 ether;
    uint256 public constant GUARD_SECONDS = 600;
    uint256 public constant GUARD_L2_BLOCKS = 5_000;
    uint256 public constant BUY_COOLDOWN_L2_BLOCKS = 1;
    uint256 public constant WALLET_MAX = 25_000_000 ether;
    uint256 public constant CREATOR_INITIAL_MAX = 500_000_000 ether;
    address public constant ARBSYS = address(0x64);
    address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;

    address public immutable factory;
    address public immutable creator;
    address public immutable router;
    address public immutable locker;
    address public immutable weth;
    address public immutable v3Factory;
    address public immutable officialPool;
    uint256 public immutable createdAt;
    uint256 public immutable createdAtL2Block;

    bool public launchFinalized;
    bool public creatorInitialBuyOpen = true;
    uint256 public lastSuccessfulPoolBuyL2Block;

    event LaunchFinalized(uint256 timestamp, uint256 l2Block);
    event BuyCooldownStarted(address indexed buyer, uint256 buyL2Block, uint256 nextEligibleL2Block);

    constructor(
        string memory name_,
        string memory symbol_,
        address factory_,
        address creator_,
        address router_,
        address locker_,
        address weth_,
        address v3Factory_
    ) ERC20(name_, symbol_) {
        require(
            factory_ != address(0) && creator_ != address(0) && router_ != address(0) && locker_ != address(0)
                && weth_ != address(0) && v3Factory_ != address(0),
            "ZERO_ADDR"
        );
        factory = factory_;
        creator = creator_;
        router = router_;
        locker = locker_;
        weth = weth_;
        v3Factory = v3Factory_;
        officialPool = V3LaunchMath.poolAddress(v3Factory_, address(this), weth_, 10_000);
        createdAt = block.timestamp;
        createdAtL2Block = _l2Block();
        _mint(factory_, TOTAL_SUPPLY);
    }

    function finalizeLaunch() external {
        require(msg.sender == factory, "NOT_FACTORY");
        require(!launchFinalized, "FINALIZED");
        launchFinalized = true;
        creatorInitialBuyOpen = false;
        emit LaunchFinalized(block.timestamp, _l2Block());
    }

    function launchGuardActive() public view returns (bool) {
        return block.timestamp < createdAt + GUARD_SECONDS || _l2Block() < createdAtL2Block + GUARD_L2_BLOCKS;
    }

    function currentL2Block() external view returns (uint256) {
        return _l2Block();
    }

    function _update(address from, address to, uint256 value) internal override {
        if (from != address(0) && to != address(0) && launchGuardActive()) {
            _enforceGuard(from, to, value);
        }
        super._update(from, to, value);
    }

    function _enforceGuard(address from, address to, uint256 value) internal {
        if (to == officialPool || to == locker || to == BURN_ADDRESS) return;
        if (from == locker) return;

        // Website sell transit is allowed; pool-to-router output is forbidden to prevent cap bypass.
        if (to == router) {
            require(from != officialPool, "POOL_TO_ROUTER");
            return;
        }

        if (from == officialPool && to == creator && creatorInitialBuyOpen && !launchFinalized) {
            require(balanceOf(creator) + value <= CREATOR_INITIAL_MAX, "CREATOR_INITIAL_MAX");
            creatorInitialBuyOpen = false;
            _startBuyCooldown(creator);
            return;
        }

        require(balanceOf(to) + value <= WALLET_MAX, "WALLET_MAX");
        if (from == officialPool) _startBuyCooldown(to);
    }

    function _startBuyCooldown(address buyer) internal {
        uint256 l2Block = _l2Block();
        uint256 previousBuy = lastSuccessfulPoolBuyL2Block;
        if (previousBuy != 0) {
            require(l2Block >= previousBuy + BUY_COOLDOWN_L2_BLOCKS + 1, "BUY_COOLDOWN");
        }
        lastSuccessfulPoolBuyL2Block = l2Block;
        emit BuyCooldownStarted(buyer, l2Block, l2Block + BUY_COOLDOWN_L2_BLOCKS + 1);
    }

    function _l2Block() internal view returns (uint256 number) {
        (bool ok, bytes memory data) = ARBSYS.staticcall(abi.encodeCall(IArbSys.arbBlockNumber, ()));
        require(ok && data.length >= 32, "ARBSYS_UNAVAILABLE");
        number = abi.decode(data, (uint256));
    }
}
Chain explorer4038msChain node137ms