Abstract Testnet

Token

Bozon (BZN)
ERC-20

Overview

Max Total Supply

102.99999999999999995 BZN

Holders

1

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
102.99999999999999995 BZN
0x700d7b774f5af65d26e5b9ae969ca9611ff80f6d
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
Bozon

Compiler Version
v0.8.24+commit.e11b9ed9

ZkSolc Version
v1.5.7

Optimization Enabled:
Yes with Mode 3

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 4 : Bozon.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

// -------------------------------------------------------------------
// SOLADY imports (adjust paths as needed if you're using a package manager)
// -------------------------------------------------------------------
import "solady/src/tokens/ERC20.sol";
import "solady/src/auth/Ownable.sol";
import "solady/src/utils/ReentrancyGuard.sol";

/**
 * @title Bozon
 * @notice An ERC20 token with:
 *         - Transfer lock (initially locked)
 *         - Owner-exclusive transfers while locked
 *         - Burn by anyone
 *         - Owner mint with no limit (unless maxSupply is finalized)
 *         - Configurable claim mechanism (time-based, no per-user maximum)
 *         - A one-time finalizable max supply
 *         - Debug-friendly reset of claim timers
 */
contract Bozon is ERC20, Ownable, ReentrancyGuard {
    // -----------------------------------------------------------------------
    // ERC20 Metadata
    // -----------------------------------------------------------------------

    /**
     * @dev Returns the name of the token.
     *      For gas-efficiency, you could hardcode or store in an immutable.
     */
    function name() public view virtual override returns (string memory) {
        return "Bozon";
    }

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() public view virtual override returns (string memory) {
        return "BZN";
    }

    // -----------------------------------------------------------------------
    // Transfer Lock
    // -----------------------------------------------------------------------

    /**
     * @dev Indicates whether token transfers are locked for non-owner addresses.
     *      Initially `true`. Once set to `false`, it cannot be re-locked.
     */
    bool public transfersLocked = true;

    /**
     * @dev Unlocks all transfers definitively. Only callable by the owner.
     *      Once unlocked, cannot be locked again.
     */
    function enableTransfers() external onlyOwner {
        require(transfersLocked, "Transfers already unlocked");
        transfersLocked = false;
    }

    // -----------------------------------------------------------------------
    // Claim Parameters (configurable by owner)
    // -----------------------------------------------------------------------

    /**
     * @dev The number of tokens each user can claim per interval.
     */
    uint256 public claimAmount;

    /**
     * @dev The interval (in seconds) between claims for each user.
     */
    uint256 public claimInterval;

    /**
     * @notice Sets the claim parameters.
     * @param newAmount   The amount of tokens minted per claim.
     * @param newInterval The interval (in seconds) between claims.
     */
    function setClaimParams(uint256 newAmount, uint256 newInterval) external onlyOwner {
        claimAmount = newAmount;
        claimInterval = newInterval;
    }

    // -----------------------------------------------------------------------
    // Finalizable Max Supply
    // -----------------------------------------------------------------------

    /**
     * @dev If `maxSupply == 0`, it means "unlimited".
     *      Otherwise, total supply may never exceed this value.
     */
    uint256 public maxSupply;

    /**
     * @dev True once maxSupply has been finalized. Prevents further changes.
     */
    bool public maxSupplyLocked;

    /**
     * @notice Finalizes the max supply exactly once.
     * @param newMaxSupply The new maximum supply (must be >= current totalSupply).
     */
    function finalizeMaxSupply(uint256 newMaxSupply) external onlyOwner {
        require(!maxSupplyLocked, "Max supply already finalized");
        require(newMaxSupply >= totalSupply(), "newMaxSupply < current supply");

        maxSupply = newMaxSupply;
        maxSupplyLocked = true;
    }

    // -----------------------------------------------------------------------
    // Overriding _mint to enforce maxSupply
    // -----------------------------------------------------------------------

    /**
     * @dev Overridden to ensure we do not exceed `maxSupply` once it is non-zero.
     */
    function _mint(address to, uint256 amount) internal virtual override {
        if (maxSupply != 0) {
            unchecked {
                require(totalSupply() + amount <= maxSupply, "Exceeds max supply");
            }
        }
        super._mint(to, amount);
    }

    // -----------------------------------------------------------------------
    // Burn Function (Public)
    // -----------------------------------------------------------------------

    /**
     * @notice Allows any user to burn their own tokens.
     * @param amount The number of tokens to burn.
     */
    function burn(uint256 amount) external {
        _burn(msg.sender, amount);
    }

    // -----------------------------------------------------------------------
    // Owner Mint Function
    // -----------------------------------------------------------------------

    /**
     * @notice The owner can mint any number of tokens (respecting the maxSupply if finalized).
     * @param to     The address that will receive the minted tokens.
     * @param amount The number of tokens to mint.
     */
    function ownerMint(address to, uint256 amount) external onlyOwner {
        _mint(to, amount);
    }

    // -----------------------------------------------------------------------
    // Claim Logic (Time-based, no per-user max, using lastClaimTime)
    // -----------------------------------------------------------------------

    /**
     * @dev Stores the timestamp of the user's last successful claim.
     */
    mapping(address => uint256) public lastClaimTime;

    /**
     * @notice Mints `claimAmount` tokens if the current block timestamp
     *         is at least `lastClaimTime[msg.sender] + claimInterval`.
     *         Then updates `lastClaimTime[msg.sender]` to `block.timestamp`.
     *
     *         This approach is more flexible if you change `claimInterval` on the fly,
     *         since we always compare to the last claim time + the current interval.
     */
    function claim() external nonReentrant {
        uint256 userLastClaim = lastClaimTime[msg.sender];
        require(
            block.timestamp >= userLastClaim + claimInterval,
            "Claim not ready yet"
        );

        // Update user's last claim time
        lastClaimTime[msg.sender] = block.timestamp;

        // Mint claimAmount tokens to the caller
        _mint(msg.sender, claimAmount);
    }

    // -----------------------------------------------------------------------
    // Debug Functions for Testnet: Reset Claim Timers
    // -----------------------------------------------------------------------

    /**
     * @notice Resets the lastClaimTime of a single user to 0.
     *         This allows immediate claiming for that user on testnet.
     * @param user The address whose claim timer is reset.
     */
    function resetLastClaim(address user) external onlyOwner {
        lastClaimTime[user] = 0;
    }

    /**
     * @notice Resets the lastClaimTime of multiple users to 0 in a single call.
     *         Only use for small batches (for testnet debugging), as it costs
     *         one storage write per user.
     * @param users An array of addresses whose claim timers are reset.
     */
    function resetLastClaimBatch(address[] calldata users) external onlyOwner {
        for (uint256 i = 0; i < users.length; i++) {
            lastClaimTime[users[i]] = 0;
        }
    }

    // -----------------------------------------------------------------------
    // Transfer Hook
    // -----------------------------------------------------------------------

    /**
     * @dev Restricts transfers if `transfersLocked == true`, except if
     *      - It's a mint (from == address(0))
     *      - It's a burn (to == address(0))
     *      - It's a transfer initiated by the owner
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount)
        internal
        virtual
        override
    {
        super._beforeTokenTransfer(from, to, amount);

        // If transfers are still locked, block normal transfers
        // (but allow mint/burn or owner transfers).
        if (transfersLocked && from != address(0) && to != address(0)) {
            if (from != owner()) revert("Transfers locked");
        }
    }

    // -----------------------------------------------------------------------
    // Constructor
    // -----------------------------------------------------------------------

    /**
     * @dev Initializes owner, sets default claim parameters, and keeps
     *      transfers locked initially.
     *      Optionally, you could mint an initial supply to the owner here.
     */
    constructor() {
        // Initialize contract ownership for Solady's Ownable
        _initializeOwner(msg.sender);

        // Example default claim settings
        claimAmount = 20e18;     // 20 tokens per claim
        claimInterval = 2 hours; // claimable once every 2 hours

        // By default, maxSupply = 0 => unlimited,
        // and maxSupplyLocked = false => not finalized yet.
    }
}

File 2 of 4 : ERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple ERC20 + EIP-2612 implementation.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)
///
/// @dev Note:
/// - The ERC20 standard allows minting and transferring to and from the zero address,
///   minting and transferring zero tokens, as well as self-approvals.
///   For performance, this implementation WILL NOT revert for such actions.
///   Please add any checks with overrides if desired.
/// - The `permit` function uses the ecrecover precompile (0x1).
///
/// If you are overriding:
/// - NEVER violate the ERC20 invariant:
///   the total sum of all balances must be equal to `totalSupply()`.
/// - Check that the overridden function is actually used in the function you want to
///   change the behavior of. Much of the code has been manually inlined for performance.
abstract contract ERC20 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The total supply has overflowed.
    error TotalSupplyOverflow();

    /// @dev The allowance has overflowed.
    error AllowanceOverflow();

    /// @dev The allowance has underflowed.
    error AllowanceUnderflow();

    /// @dev Insufficient balance.
    error InsufficientBalance();

    /// @dev Insufficient allowance.
    error InsufficientAllowance();

    /// @dev The permit is invalid.
    error InvalidPermit();

    /// @dev The permit has expired.
    error PermitExpired();

    /// @dev The allowance of Permit2 is fixed at infinity.
    error Permit2AllowanceIsFixedAtInfinity();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Emitted when `amount` tokens is transferred from `from` to `to`.
    event Transfer(address indexed from, address indexed to, uint256 amount);

    /// @dev Emitted when `amount` tokens is approved by `owner` to be used by `spender`.
    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /// @dev `keccak256(bytes("Transfer(address,address,uint256)"))`.
    uint256 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    /// @dev `keccak256(bytes("Approval(address,address,uint256)"))`.
    uint256 private constant _APPROVAL_EVENT_SIGNATURE =
        0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The storage slot for the total supply.
    uint256 private constant _TOTAL_SUPPLY_SLOT = 0x05345cdf77eb68f44c;

    /// @dev The balance slot of `owner` is given by:
    /// ```
    ///     mstore(0x0c, _BALANCE_SLOT_SEED)
    ///     mstore(0x00, owner)
    ///     let balanceSlot := keccak256(0x0c, 0x20)
    /// ```
    uint256 private constant _BALANCE_SLOT_SEED = 0x87a211a2;

    /// @dev The allowance slot of (`owner`, `spender`) is given by:
    /// ```
    ///     mstore(0x20, spender)
    ///     mstore(0x0c, _ALLOWANCE_SLOT_SEED)
    ///     mstore(0x00, owner)
    ///     let allowanceSlot := keccak256(0x0c, 0x34)
    /// ```
    uint256 private constant _ALLOWANCE_SLOT_SEED = 0x7f5e9f20;

    /// @dev The nonce slot of `owner` is given by:
    /// ```
    ///     mstore(0x0c, _NONCES_SLOT_SEED)
    ///     mstore(0x00, owner)
    ///     let nonceSlot := keccak256(0x0c, 0x20)
    /// ```
    uint256 private constant _NONCES_SLOT_SEED = 0x38377508;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev `(_NONCES_SLOT_SEED << 16) | 0x1901`.
    uint256 private constant _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX = 0x383775081901;

    /// @dev `keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")`.
    bytes32 private constant _DOMAIN_TYPEHASH =
        0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f;

    /// @dev `keccak256("1")`.
    /// If you need to use a different version, override `_versionHash`.
    bytes32 private constant _DEFAULT_VERSION_HASH =
        0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6;

    /// @dev `keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)")`.
    bytes32 private constant _PERMIT_TYPEHASH =
        0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;

    /// @dev The canonical Permit2 address.
    /// For signature-based allowance granting for single transaction ERC20 `transferFrom`.
    /// To enable, override `_givePermit2InfiniteAllowance()`.
    /// [Github](https://github.com/Uniswap/permit2)
    /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3)
    address internal constant _PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ERC20 METADATA                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the name of the token.
    function name() public view virtual returns (string memory);

    /// @dev Returns the symbol of the token.
    function symbol() public view virtual returns (string memory);

    /// @dev Returns the decimals places of the token.
    function decimals() public view virtual returns (uint8) {
        return 18;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           ERC20                            */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the amount of tokens in existence.
    function totalSupply() public view virtual returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_TOTAL_SUPPLY_SLOT)
        }
    }

    /// @dev Returns the amount of tokens owned by `owner`.
    function balanceOf(address owner) public view virtual returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x0c, _BALANCE_SLOT_SEED)
            mstore(0x00, owner)
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /// @dev Returns the amount of tokens that `spender` can spend on behalf of `owner`.
    function allowance(address owner, address spender)
        public
        view
        virtual
        returns (uint256 result)
    {
        if (_givePermit2InfiniteAllowance()) {
            if (spender == _PERMIT2) return type(uint256).max;
        }
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, spender)
            mstore(0x0c, _ALLOWANCE_SLOT_SEED)
            mstore(0x00, owner)
            result := sload(keccak256(0x0c, 0x34))
        }
    }

    /// @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
    ///
    /// Emits a {Approval} event.
    function approve(address spender, uint256 amount) public virtual returns (bool) {
        if (_givePermit2InfiniteAllowance()) {
            /// @solidity memory-safe-assembly
            assembly {
                // If `spender == _PERMIT2 && amount != type(uint256).max`.
                if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(amount)))) {
                    mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`.
                    revert(0x1c, 0x04)
                }
            }
        }
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the allowance slot and store the amount.
            mstore(0x20, spender)
            mstore(0x0c, _ALLOWANCE_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x34), amount)
            // Emit the {Approval} event.
            mstore(0x00, amount)
            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x2c)))
        }
        return true;
    }

    /// @dev Transfer `amount` tokens from the caller to `to`.
    ///
    /// Requirements:
    /// - `from` must at least have `amount`.
    ///
    /// Emits a {Transfer} event.
    function transfer(address to, uint256 amount) public virtual returns (bool) {
        _beforeTokenTransfer(msg.sender, to, amount);
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the balance slot and load its value.
            mstore(0x0c, _BALANCE_SLOT_SEED)
            mstore(0x00, caller())
            let fromBalanceSlot := keccak256(0x0c, 0x20)
            let fromBalance := sload(fromBalanceSlot)
            // Revert if insufficient balance.
            if gt(amount, fromBalance) {
                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
                revert(0x1c, 0x04)
            }
            // Subtract and store the updated balance.
            sstore(fromBalanceSlot, sub(fromBalance, amount))
            // Compute the balance slot of `to`.
            mstore(0x00, to)
            let toBalanceSlot := keccak256(0x0c, 0x20)
            // Add and store the updated balance of `to`.
            // Will not overflow because the sum of all user balances
            // cannot exceed the maximum uint256 value.
            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))
            // Emit the {Transfer} event.
            mstore(0x20, amount)
            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c)))
        }
        _afterTokenTransfer(msg.sender, to, amount);
        return true;
    }

    /// @dev Transfers `amount` tokens from `from` to `to`.
    ///
    /// Note: Does not update the allowance if it is the maximum uint256 value.
    ///
    /// Requirements:
    /// - `from` must at least have `amount`.
    /// - The caller must have at least `amount` of allowance to transfer the tokens of `from`.
    ///
    /// Emits a {Transfer} event.
    function transferFrom(address from, address to, uint256 amount) public virtual returns (bool) {
        _beforeTokenTransfer(from, to, amount);
        // Code duplication is for zero-cost abstraction if possible.
        if (_givePermit2InfiniteAllowance()) {
            /// @solidity memory-safe-assembly
            assembly {
                let from_ := shl(96, from)
                if iszero(eq(caller(), _PERMIT2)) {
                    // Compute the allowance slot and load its value.
                    mstore(0x20, caller())
                    mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED))
                    let allowanceSlot := keccak256(0x0c, 0x34)
                    let allowance_ := sload(allowanceSlot)
                    // If the allowance is not the maximum uint256 value.
                    if not(allowance_) {
                        // Revert if the amount to be transferred exceeds the allowance.
                        if gt(amount, allowance_) {
                            mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.
                            revert(0x1c, 0x04)
                        }
                        // Subtract and store the updated allowance.
                        sstore(allowanceSlot, sub(allowance_, amount))
                    }
                }
                // Compute the balance slot and load its value.
                mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))
                let fromBalanceSlot := keccak256(0x0c, 0x20)
                let fromBalance := sload(fromBalanceSlot)
                // Revert if insufficient balance.
                if gt(amount, fromBalance) {
                    mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
                    revert(0x1c, 0x04)
                }
                // Subtract and store the updated balance.
                sstore(fromBalanceSlot, sub(fromBalance, amount))
                // Compute the balance slot of `to`.
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x20)
                // Add and store the updated balance of `to`.
                // Will not overflow because the sum of all user balances
                // cannot exceed the maximum uint256 value.
                sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))
                // Emit the {Transfer} event.
                mstore(0x20, amount)
                log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let from_ := shl(96, from)
                // Compute the allowance slot and load its value.
                mstore(0x20, caller())
                mstore(0x0c, or(from_, _ALLOWANCE_SLOT_SEED))
                let allowanceSlot := keccak256(0x0c, 0x34)
                let allowance_ := sload(allowanceSlot)
                // If the allowance is not the maximum uint256 value.
                if not(allowance_) {
                    // Revert if the amount to be transferred exceeds the allowance.
                    if gt(amount, allowance_) {
                        mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.
                        revert(0x1c, 0x04)
                    }
                    // Subtract and store the updated allowance.
                    sstore(allowanceSlot, sub(allowance_, amount))
                }
                // Compute the balance slot and load its value.
                mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))
                let fromBalanceSlot := keccak256(0x0c, 0x20)
                let fromBalance := sload(fromBalanceSlot)
                // Revert if insufficient balance.
                if gt(amount, fromBalance) {
                    mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
                    revert(0x1c, 0x04)
                }
                // Subtract and store the updated balance.
                sstore(fromBalanceSlot, sub(fromBalance, amount))
                // Compute the balance slot of `to`.
                mstore(0x00, to)
                let toBalanceSlot := keccak256(0x0c, 0x20)
                // Add and store the updated balance of `to`.
                // Will not overflow because the sum of all user balances
                // cannot exceed the maximum uint256 value.
                sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))
                // Emit the {Transfer} event.
                mstore(0x20, amount)
                log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))
            }
        }
        _afterTokenTransfer(from, to, amount);
        return true;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          EIP-2612                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev For more performance, override to return the constant value
    /// of `keccak256(bytes(name()))` if `name()` will never change.
    function _constantNameHash() internal view virtual returns (bytes32 result) {}

    /// @dev If you need a different value, override this function.
    function _versionHash() internal view virtual returns (bytes32 result) {
        result = _DEFAULT_VERSION_HASH;
    }

    /// @dev For inheriting contracts to increment the nonce.
    function _incrementNonce(address owner) internal virtual {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x0c, _NONCES_SLOT_SEED)
            mstore(0x00, owner)
            let nonceSlot := keccak256(0x0c, 0x20)
            sstore(nonceSlot, add(1, sload(nonceSlot)))
        }
    }

    /// @dev Returns the current nonce for `owner`.
    /// This value is used to compute the signature for EIP-2612 permit.
    function nonces(address owner) public view virtual returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the nonce slot and load its value.
            mstore(0x0c, _NONCES_SLOT_SEED)
            mstore(0x00, owner)
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /// @dev Sets `value` as the allowance of `spender` over the tokens of `owner`,
    /// authorized by a signed approval by `owner`.
    ///
    /// Emits a {Approval} event.
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        if (_givePermit2InfiniteAllowance()) {
            /// @solidity memory-safe-assembly
            assembly {
                // If `spender == _PERMIT2 && value != type(uint256).max`.
                if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(value)))) {
                    mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`.
                    revert(0x1c, 0x04)
                }
            }
        }
        bytes32 nameHash = _constantNameHash();
        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.
        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));
        bytes32 versionHash = _versionHash();
        /// @solidity memory-safe-assembly
        assembly {
            // Revert if the block timestamp is greater than `deadline`.
            if gt(timestamp(), deadline) {
                mstore(0x00, 0x1a15a3cc) // `PermitExpired()`.
                revert(0x1c, 0x04)
            }
            let m := mload(0x40) // Grab the free memory pointer.
            // Clean the upper 96 bits.
            owner := shr(96, shl(96, owner))
            spender := shr(96, shl(96, spender))
            // Compute the nonce slot and load its value.
            mstore(0x0e, _NONCES_SLOT_SEED_WITH_SIGNATURE_PREFIX)
            mstore(0x00, owner)
            let nonceSlot := keccak256(0x0c, 0x20)
            let nonceValue := sload(nonceSlot)
            // Prepare the domain separator.
            mstore(m, _DOMAIN_TYPEHASH)
            mstore(add(m, 0x20), nameHash)
            mstore(add(m, 0x40), versionHash)
            mstore(add(m, 0x60), chainid())
            mstore(add(m, 0x80), address())
            mstore(0x2e, keccak256(m, 0xa0))
            // Prepare the struct hash.
            mstore(m, _PERMIT_TYPEHASH)
            mstore(add(m, 0x20), owner)
            mstore(add(m, 0x40), spender)
            mstore(add(m, 0x60), value)
            mstore(add(m, 0x80), nonceValue)
            mstore(add(m, 0xa0), deadline)
            mstore(0x4e, keccak256(m, 0xc0))
            // Prepare the ecrecover calldata.
            mstore(0x00, keccak256(0x2c, 0x42))
            mstore(0x20, and(0xff, v))
            mstore(0x40, r)
            mstore(0x60, s)
            let t := staticcall(gas(), 1, 0x00, 0x80, 0x20, 0x20)
            // If the ecrecover fails, the returndatasize will be 0x00,
            // `owner` will be checked if it equals the hash at 0x00,
            // which evaluates to false (i.e. 0), and we will revert.
            // If the ecrecover succeeds, the returndatasize will be 0x20,
            // `owner` will be compared against the returned address at 0x20.
            if iszero(eq(mload(returndatasize()), owner)) {
                mstore(0x00, 0xddafbaef) // `InvalidPermit()`.
                revert(0x1c, 0x04)
            }
            // Increment and store the updated nonce.
            sstore(nonceSlot, add(nonceValue, t)) // `t` is 1 if ecrecover succeeds.
            // Compute the allowance slot and store the value.
            // The `owner` is already at slot 0x20.
            mstore(0x40, or(shl(160, _ALLOWANCE_SLOT_SEED), spender))
            sstore(keccak256(0x2c, 0x34), value)
            // Emit the {Approval} event.
            log3(add(m, 0x60), 0x20, _APPROVAL_EVENT_SIGNATURE, owner, spender)
            mstore(0x40, m) // Restore the free memory pointer.
            mstore(0x60, 0) // Restore the zero pointer.
        }
    }

    /// @dev Returns the EIP-712 domain separator for the EIP-2612 permit.
    function DOMAIN_SEPARATOR() public view virtual returns (bytes32 result) {
        bytes32 nameHash = _constantNameHash();
        //  We simply calculate it on-the-fly to allow for cases where the `name` may change.
        if (nameHash == bytes32(0)) nameHash = keccak256(bytes(name()));
        bytes32 versionHash = _versionHash();
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Grab the free memory pointer.
            mstore(m, _DOMAIN_TYPEHASH)
            mstore(add(m, 0x20), nameHash)
            mstore(add(m, 0x40), versionHash)
            mstore(add(m, 0x60), chainid())
            mstore(add(m, 0x80), address())
            result := keccak256(m, 0xa0)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  INTERNAL MINT FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Mints `amount` tokens to `to`, increasing the total supply.
    ///
    /// Emits a {Transfer} event.
    function _mint(address to, uint256 amount) internal virtual {
        _beforeTokenTransfer(address(0), to, amount);
        /// @solidity memory-safe-assembly
        assembly {
            let totalSupplyBefore := sload(_TOTAL_SUPPLY_SLOT)
            let totalSupplyAfter := add(totalSupplyBefore, amount)
            // Revert if the total supply overflows.
            if lt(totalSupplyAfter, totalSupplyBefore) {
                mstore(0x00, 0xe5cfe957) // `TotalSupplyOverflow()`.
                revert(0x1c, 0x04)
            }
            // Store the updated total supply.
            sstore(_TOTAL_SUPPLY_SLOT, totalSupplyAfter)
            // Compute the balance slot and load its value.
            mstore(0x0c, _BALANCE_SLOT_SEED)
            mstore(0x00, to)
            let toBalanceSlot := keccak256(0x0c, 0x20)
            // Add and store the updated balance.
            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))
            // Emit the {Transfer} event.
            mstore(0x20, amount)
            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, 0, shr(96, mload(0x0c)))
        }
        _afterTokenTransfer(address(0), to, amount);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  INTERNAL BURN FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Burns `amount` tokens from `from`, reducing the total supply.
    ///
    /// Emits a {Transfer} event.
    function _burn(address from, uint256 amount) internal virtual {
        _beforeTokenTransfer(from, address(0), amount);
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the balance slot and load its value.
            mstore(0x0c, _BALANCE_SLOT_SEED)
            mstore(0x00, from)
            let fromBalanceSlot := keccak256(0x0c, 0x20)
            let fromBalance := sload(fromBalanceSlot)
            // Revert if insufficient balance.
            if gt(amount, fromBalance) {
                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
                revert(0x1c, 0x04)
            }
            // Subtract and store the updated balance.
            sstore(fromBalanceSlot, sub(fromBalance, amount))
            // Subtract and store the updated total supply.
            sstore(_TOTAL_SUPPLY_SLOT, sub(sload(_TOTAL_SUPPLY_SLOT), amount))
            // Emit the {Transfer} event.
            mstore(0x00, amount)
            log3(0x00, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), 0)
        }
        _afterTokenTransfer(from, address(0), amount);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                INTERNAL TRANSFER FUNCTIONS                 */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Moves `amount` of tokens from `from` to `to`.
    function _transfer(address from, address to, uint256 amount) internal virtual {
        _beforeTokenTransfer(from, to, amount);
        /// @solidity memory-safe-assembly
        assembly {
            let from_ := shl(96, from)
            // Compute the balance slot and load its value.
            mstore(0x0c, or(from_, _BALANCE_SLOT_SEED))
            let fromBalanceSlot := keccak256(0x0c, 0x20)
            let fromBalance := sload(fromBalanceSlot)
            // Revert if insufficient balance.
            if gt(amount, fromBalance) {
                mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
                revert(0x1c, 0x04)
            }
            // Subtract and store the updated balance.
            sstore(fromBalanceSlot, sub(fromBalance, amount))
            // Compute the balance slot of `to`.
            mstore(0x00, to)
            let toBalanceSlot := keccak256(0x0c, 0x20)
            // Add and store the updated balance of `to`.
            // Will not overflow because the sum of all user balances
            // cannot exceed the maximum uint256 value.
            sstore(toBalanceSlot, add(sload(toBalanceSlot), amount))
            // Emit the {Transfer} event.
            mstore(0x20, amount)
            log3(0x20, 0x20, _TRANSFER_EVENT_SIGNATURE, shr(96, from_), shr(96, mload(0x0c)))
        }
        _afterTokenTransfer(from, to, amount);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                INTERNAL ALLOWANCE FUNCTIONS                */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Updates the allowance of `owner` for `spender` based on spent `amount`.
    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        if (_givePermit2InfiniteAllowance()) {
            if (spender == _PERMIT2) return; // Do nothing, as allowance is infinite.
        }
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the allowance slot and load its value.
            mstore(0x20, spender)
            mstore(0x0c, _ALLOWANCE_SLOT_SEED)
            mstore(0x00, owner)
            let allowanceSlot := keccak256(0x0c, 0x34)
            let allowance_ := sload(allowanceSlot)
            // If the allowance is not the maximum uint256 value.
            if not(allowance_) {
                // Revert if the amount to be transferred exceeds the allowance.
                if gt(amount, allowance_) {
                    mstore(0x00, 0x13be252b) // `InsufficientAllowance()`.
                    revert(0x1c, 0x04)
                }
                // Subtract and store the updated allowance.
                sstore(allowanceSlot, sub(allowance_, amount))
            }
        }
    }

    /// @dev Sets `amount` as the allowance of `spender` over the tokens of `owner`.
    ///
    /// Emits a {Approval} event.
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        if (_givePermit2InfiniteAllowance()) {
            /// @solidity memory-safe-assembly
            assembly {
                // If `spender == _PERMIT2 && amount != type(uint256).max`.
                if iszero(or(xor(shr(96, shl(96, spender)), _PERMIT2), iszero(not(amount)))) {
                    mstore(0x00, 0x3f68539a) // `Permit2AllowanceIsFixedAtInfinity()`.
                    revert(0x1c, 0x04)
                }
            }
        }
        /// @solidity memory-safe-assembly
        assembly {
            let owner_ := shl(96, owner)
            // Compute the allowance slot and store the amount.
            mstore(0x20, spender)
            mstore(0x0c, or(owner_, _ALLOWANCE_SLOT_SEED))
            sstore(keccak256(0x0c, 0x34), amount)
            // Emit the {Approval} event.
            mstore(0x00, amount)
            log3(0x00, 0x20, _APPROVAL_EVENT_SIGNATURE, shr(96, owner_), shr(96, mload(0x2c)))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     HOOKS TO OVERRIDE                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Hook that is called before any transfer of tokens.
    /// This includes minting and burning.
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /// @dev Hook that is called after any transfer of tokens.
    /// This includes minting and burning.
    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          PERMIT2                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether to fix the Permit2 contract's allowance at infinity.
    ///
    /// This value should be kept constant after contract initialization,
    /// or else the actual allowance values may not match with the {Approval} events.
    /// For best performance, return a compile-time constant for zero-cost abstraction.
    function _givePermit2InfiniteAllowance() internal view virtual returns (bool) {
        return true;
    }
}

File 3 of 4 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev Cannot double-initialize.
    error AlreadyInitialized();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by:
    /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    bytes32 internal constant _OWNER_SLOT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                if sload(ownerSlot) {
                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
                    revert(0x1c, 0x04)
                }
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(_OWNER_SLOT, newOwner)
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, newOwner)
            }
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(_OWNER_SLOT))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_OWNER_SLOT)
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 4 of 4 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Reentrancy guard mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Unauthorized reentrant call.
    error Reentrancy();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Equivalent to: `uint72(bytes9(keccak256("_REENTRANCY_GUARD_SLOT")))`.
    /// 9 bytes is large enough to avoid collisions with lower slots,
    /// but not too large to result in excessive bytecode bloat.
    uint256 private constant _REENTRANCY_GUARD_SLOT = 0x929eee149b4bd21268;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      REENTRANCY GUARD                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Guards a function from reentrancy.
    modifier nonReentrant() virtual {
        /// @solidity memory-safe-assembly
        assembly {
            if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
                mstore(0x00, 0xab143c06) // `Reentrancy()`.
                revert(0x1c, 0x04)
            }
            sstore(_REENTRANCY_GUARD_SLOT, address())
        }
        _;
        /// @solidity memory-safe-assembly
        assembly {
            sstore(_REENTRANCY_GUARD_SLOT, codesize())
        }
    }

    /// @dev Guards a view function from read-only reentrancy.
    modifier nonReadReentrant() virtual {
        /// @solidity memory-safe-assembly
        assembly {
            if eq(sload(_REENTRANCY_GUARD_SLOT), address()) {
                mstore(0x00, 0xab143c06) // `Reentrancy()`.
                revert(0x1c, 0x04)
            }
        }
        _;
    }
}

Settings
{
  "evmVersion": "paris",
  "optimizer": {
    "enabled": true,
    "mode": "3"
  },
  "outputSelection": {
    "*": {
      "*": [
        "abi",
        "metadata"
      ],
      "": [
        "ast"
      ]
    }
  },
  "detectMissingLibraries": false,
  "forceEVMLA": false,
  "enableEraVMExtensions": true,
  "libraries": {}
}

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllowanceOverflow","type":"error"},{"inputs":[],"name":"AllowanceUnderflow","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"InsufficientAllowance","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidPermit","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Permit2AllowanceIsFixedAtInfinity","type":"error"},{"inputs":[],"name":"PermitExpired","type":"error"},{"inputs":[],"name":"Reentrancy","type":"error"},{"inputs":[],"name":"TotalSupplyOverflow","type":"error"},{"inputs":[],"name":"Unauthorized","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":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTransfers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxSupply","type":"uint256"}],"name":"finalizeMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupplyLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","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":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"resetLastClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"}],"name":"resetLastClaimBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAmount","type":"uint256"},{"internalType":"uint256","name":"newInterval","type":"uint256"}],"name":"setClaimParams","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"transfersLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

9c4d535b000000000000000000000000000000000000000000000000000000000000000001000207c347e84fd4c36162ee2943e14f29a64efdaaa6001116e2e1cfd44d4c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x0001000000000002000f000000000002000000000001035500000001002001900000008004000039000000260000c13d00000060021002700000018d02200197000000400040043f000000040020008c000005780000413d000000000301043b000000e003300270000001930030009c000000480000a13d000001940030009c000000990000a13d000001950030009c000000ac0000a13d000001960030009c0000014a0000a13d000001970030009c0000037f0000613d000001980030009c000002660000613d000001990030009c000005780000c13d000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000001c30010009c000005780000213d000001c4020000410000034c0000013d000000400040043f0000000001000416000000000001004b000005780000c13d000000000200041a000001fe0120019700000001011001bf000000000010041b00000000060004110000018e01000041000000000061041b00000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d02000039000000030300003900000190040000410000000005000019063006260000040f0000000100200190000005780000613d00000191010000410000000102000039000000000012041b00001c20010000390000000202000039000000000012041b0000002001000039000001000010044300000120000004430000019201000041000006310001042e000001ac0030009c000000670000213d000001b80030009c000000c10000213d000001be0030009c0000015f0000213d000001c10030009c000002790000613d000001c20030009c000005780000c13d0000000001000416000000000001004b000005780000c13d0630059a0000040f00000000020100190000002001100039000001d0030000410000000000310435000000400100043d000d00000001001d063005850000040f0000000d0200002900000000012100490000018d0010009c0000018d0100804100000060011002100000018d0020009c0000018d020080410000004002200210000000000121019f000006310001042e000001ad0030009c000000cc0000213d000001b30030009c000001680000213d000001b60030009c000002970000613d000001b70030009c000005780000c13d0000000001000416000000000001004b000005780000c13d0630059a0000040f0000002003100039000001d002000041000000000023043500000000020104330000000001030019063005fa0000040f000000400300043d000d00000003001d00000020023000390000000000120435000001d30100004100000040023000390000000000120435000001d40100004100000000001304350000800b01000039000000040300003900000000040004150000000f0440008a0000000504400210000001d5020000410630060f0000040f00000000020004100000000d040000290000008003400039000000000023043500000060024000390000000000120435000000a0020000390000000001040019063005fa0000040f000000400200043d00000000001204350000018d0020009c0000018d020080410000004001200210000001cf011001c7000006310001042e000001a10030009c000000ea0000213d000001a70030009c000001c70000213d000001aa0030009c000003520000613d000001ab0030009c000005780000c13d000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000001c30010009c000005780000213d000001eb020000410000034c0000013d0000019c0030009c000001010000213d0000019f0030009c000002120000613d000001a00030009c000005780000c13d000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000001c30010009c000005780000213d000000000010043f0000000501000039000000200010043f00000040020000390000000001000019000003500000013d000001b90030009c0000017e0000213d000001bc0030009c0000029e0000613d000001bd0030009c000005780000c13d0000000001000416000000000001004b000005780000c13d000001f401000041000003700000013d000001ae0030009c000001ae0000213d000001b10030009c000002b30000613d000001b20030009c000005780000c13d000001c4010000410000000c0010043f0000000001000411000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000001041b00000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d020000390000000203000039000001ec04000041000001a80000013d000001a20030009c000001d00000213d000001a50030009c000003630000613d000001a60030009c000005780000c13d0000000001000416000000000001004b000005780000c13d000000c001000039000000400010043f0000000302000039000000800020043f000001e902000041000000a00020043f0000008002000039063005850000040f000000c00110008a0000018d0010009c0000018d010080410000006001100210000001ea011001c7000006310001042e0000019d0030009c000002270000613d0000019e0030009c000005780000c13d000000e40020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000402100370000000000202043b000d00000002001d000001c30020009c000005780000213d0000002402100370000000000202043b000c00000002001d000001c30020009c000005780000213d0000006402100370000000000202043b000a00000002001d0000004402100370000000000202043b000b00000002001d0000008401100370000000000101043b000900000001001d000000ff0010008c000005780000213d000000010100008a0000000b0010006b000000000100003900000001010060390000000c02000029000001cc0220016700000000001201a0000002d00000613d000000c001000039000000400010043f0000000501000039000000800010043f000001d001000041000000a00010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001d1011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000800000001001d000001c901000041000000000010044300000000010004140000018d0010009c0000018d01008041000000c001100210000001ca011001c70000800b020000390630062b0000040f00000001002001900000057a0000613d000000000101043b0000000a0010006c000004bb0000a13d000001e001000041000000000010043f000001c70100004100000632000104300000019a0030009c000002610000613d0000019b0030009c000005780000c13d000000440020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000402100370000000000202043b000001c30020009c000005780000213d0000002401100370000000000101043b000001c30010009c000005780000213d000001cc0010009c000004540000c13d000000010100008a000004640000013d000001bf0030009c000002bf0000613d000001c00030009c000005780000c13d0000000001000416000000000001004b000005780000c13d0000000201000039000003700000013d000001b40030009c000002d40000613d000001b50030009c000005780000c13d000000440020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000d00000001001d000001c30010009c000005780000213d063005a80000040f00000024010000390000000001100367000000000201043b0000000d01000029063005b20000040f0000000001000019000006310001042e000001ba0030009c000002f20000613d000001bb0030009c000005780000c13d000001c4010000410000000c0010043f0000000001000411000000000010043f000001c901000041000000000010044300000000010004140000018d0010009c0000018d01008041000000c001100210000001ca011001c70000800b020000390630062b0000040f00000001002001900000057a0000613d000000000101043b000d00000001001d00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b0000000d02000029000001f50220009a000000000021041b00000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d020000390000000203000039000001f6040000410000000005000411063006260000040f0000000100200190000005780000613d0000000001000019000006310001042e000001af0030009c000003420000613d000001b00030009c000005780000c13d0000018e01000041000000000101041a0000000005000411000000000015004b000003ae0000c13d00000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d02000039000000030300003900000190040000410000000006000019063006260000040f0000000100200190000005780000613d0000018e01000041000000000001041b0000000001000019000006310001042e000001a80030009c0000036c0000613d000001a90030009c000005780000c13d0000000001000416000000000001004b000005780000c13d000000000100041a000003790000013d000001a30030009c000003740000613d000001a40030009c000005780000c13d000000440020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000402100370000000000202043b000d00000002001d000001c30020009c000005780000213d00000000020004110000002401100370000000000101043b000c00000001001d000000000100041a000000ff00100190000004310000c13d000001e6010000410000000c0010043f000000000020043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a0000000c0220006c000002ee0000413d000000000021041b0000000d01000029000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a0000000c030000290000000002320019000000000021041b000000200030043f0000000c0100043d000000000200041400000060061002700000018d0020009c0000018d02008041000000c001200210000001e7011001c70000800d020000390000000303000039000001e804000041000004140000013d0000000001000416000000000001004b000005780000c13d0000018e01000041000000000101041a0000000002000411000000000012004b000003ae0000c13d000000000100041a000000ff00100190000003e90000c13d000001e301000041000000800010043f0000002001000039000000840010043f0000001a01000039000000a40010043f000001e401000041000000c40010043f000001e5010000410000063200010430000000240020008c000005780000413d0000000003000416000000000003004b000005780000c13d0000000403100370000000000303043b000001e10030009c000005780000213d0000002304300039000000000024004b000005780000813d0000000404300039000000000141034f000000000101043b000c00000001001d000001e10010009c000005780000213d000b00240030003d0000000c0100002900000005011002100000000b01100029000000000021004b000005780000213d0000018e01000041000000000101041a0000000002000411000000000012004b000003ae0000c13d0000000c0000006b000001ac0000613d000000000300001900000005013002100000000b011000290000000001100367000000000101043b000001c30010009c000005780000213d000000000010043f0000000501000039000000200010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001e2011001c70000801002000039000d00000003001d0630062b0000040f0000000d030000290000000100200190000005780000613d000000000101043b000000000001041b00000001033000390000000c0030006c000002470000413d000001ac0000013d0000000001000416000000000001004b000005780000c13d0000000301000039000003700000013d000000240020008c000005780000413d0000000401100370000000000101043b000d00000001001d000001c30010009c000005780000213d0000018e01000041000000000101041a0000000005000411000000000015004b000003ae0000c13d0000000d06000029000000000006004b000004440000c13d000001c601000041000000000010043f000001c7010000410000063200010430000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b0000018e02000041000000000202041a0000000003000411000000000023004b000003ae0000c13d0000000402000039000000000302041a000000ff00300190000003ed0000c13d000001f404000041000000000404041a000000000041004b0000046a0000813d000001e301000041000000800010043f0000002001000039000000840010043f0000001d01000039000000a40010043f000001fd01000041000000c40010043f000001e50100004100000632000104300000000001000416000000000001004b000005780000c13d0000001201000039000000800010043f000001c501000041000006310001042e000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000d00000001001d000001c30010009c000005780000213d063005a80000040f0000000d01000029000000000010043f0000000501000039000000200010043f00000040020000390000000001000019063005fa0000040f000000000001041b0000000001000019000006310001042e0000000001000416000000000001004b000005780000c13d000001ed01000041000000000301041a0000000002000410000000000023004b000003b20000c13d000001f301000041000000000010043f000001c7010000410000063200010430000000440020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000402100370000000000202043b000001c30020009c000005780000213d0000002401100370000000000401043b000001ff0040009c00000000010000390000000101006039000001cc0320016700000000001301a0000003f70000c13d000001fa01000041000000000010043f000001c7010000410000063200010430000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000d00000001001d000001e6010000410000000c0010043f0000000001000411000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a0000000d03000029000000000232004b000004200000813d000001f901000041000000000010043f000001c7010000410000063200010430000000640020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000402100370000000000202043b000d00000002001d000001c30020009c000005780000213d0000002402100370000000000202043b000c00000002001d000001c30020009c000005780000213d000000000200041a0000004401100370000000000101043b000b00000001001d0000000c0000006b0000000d03000029000003110000613d000000000003004b000003110000613d000000ff00200190000003110000613d0000018e01000041000000000101041a000000000131013f000001c3001001980000043a0000c13d00000060043002100000000001000411000001cc0010009c000004710000c13d000001e6014001c70000000c0010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a0000000b0220006c000002ee0000413d000000000021041b0000000c01000029000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a0000000b030000290000000002320019000000000021041b000000200030043f0000000c0100043d000000000200041400000060061002700000018d0020009c0000018d02008041000000c001200210000001e7011001c70000800d020000390000000303000039000001e8040000410000000d05000029000004150000013d000000240020008c000005780000413d0000000002000416000000000002004b000005780000c13d0000000401100370000000000101043b000001c30010009c000005780000213d000001e6020000410000000c0020043f000000000010043f0000000c010000390000002002000039063005fa0000040f000003700000013d000000440020008c000005780000413d0000000001000416000000000001004b000005780000c13d063005a80000040f00000000010003670000000402100370000000000202043b0000000103000039000000000023041b0000002401100370000000000101043b0000000202000039000000000012041b0000000001000019000006310001042e0000000001000416000000000001004b000005780000c13d0000018e01000041000000000101041a000001c301100197000000800010043f000001c501000041000006310001042e0000000001000416000000000001004b000005780000c13d0000000101000039000000000101041a000000800010043f000001c501000041000006310001042e0000000001000416000000000001004b000005780000c13d0000000401000039000000000101041a000000ff001001900000000001000039000000010100c039000000800010043f000001c501000041000006310001042e000000240020008c000005780000413d0000000401100370000000000101043b000d00000001001d000001c30010009c000005780000213d0000018e01000041000000000101041a0000000002000411000000000012004b000003ae0000c13d000001c4010000410000000c0010043f0000000d01000029000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000b00000001001d000000000101041a000c00000001001d000001c901000041000000000010044300000000010004140000018d0010009c0000018d01008041000000c001100210000001ca011001c70000800b020000390630062b0000040f00000001002001900000057a0000613d000000000101043b0000000c0010006c000004a40000a13d000001cb01000041000000000010043f000001c7010000410000063200010430000001fb01000041000000000010043f000001c7010000410000063200010430000000000021041b0000000001000411000000000010043f0000000501000039000000200010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001e2011001c700008010020000390630062b0000040f0000000100200190000005780000613d0000000202000039000000000202041a000000000101043b000000000101041a000d00000002001d000c00000001001d000000000012001a0000057f0000413d000001c901000041000000000010044300000000010004140000018d0010009c0000018d01008041000000c001100210000001ca011001c70000800b020000390630062b0000040f00000001002001900000057a0000613d0000000c030000290000000d02300029000000000101043b000000000021004b000004890000813d000000400100043d0000004402100039000001ef030000410000000000320435000000240210003900000013030000390000000000320435000001e30200004100000000002104350000000402100039000000200300003900000000003204350000018d0010009c0000018d010080410000004001100210000001f0011001c70000063200010430000001fe01100197000000000010041b0000000001000019000006310001042e000001e301000041000000800010043f0000002001000039000000840010043f0000001c01000039000000a40010043f000001fc01000041000000c40010043f000001e5010000410000063200010430000d00000004001d000000200020043f000001cd010000410000000c0010043f0000000001000411000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001ce011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b0000000d02000029000000000021041b000000000020043f0000002c0100043d000000000200041400000060061002700000018d0020009c0000018d02008041000000c001200210000001de011001c70000800d020000390000000303000039000001df040000410000000005000411063006260000040f0000000100200190000005780000613d000000400100043d000000010200003900000000002104350000018d0010009c0000018d010080410000004001100210000001cf011001c7000006310001042e000000000021041b000001f401000041000000000201041a0000000002320049000000000021041b000000000030043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001de011001c70000800d020000390000000303000039000001e80400004100000000050004110000000006000019000001a90000013d0000000d0000006b000001e50000613d000000000002004b000001e50000613d0000018e01000041000000000101041a000001c301100197000000000012004b000001e50000613d000001e301000041000000800010043f0000002001000039000000840010043f0000001001000039000000a40010043f000001f701000041000000c40010043f000001e501000041000006320001043000000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d0200003900000003030000390000019004000041063006260000040f0000000100200190000005780000613d0000018e010000410000000d02000029000000000021041b0000000001000019000006310001042e000000200010043f000001cd010000410000000c0010043f000000000020043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001ce011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000400400043d000000000101043b000000000101041a00000000001404350000018d0040009c0000018d040080410000004001400210000001cf011001c7000006310001042e0000000304000039000000000014041b000001fe0130019700000001011001bf000000000012041b0000000001000019000006310001042e000000200010043f000a00000004001d000001cd014001c70000000c0010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001ce011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000201041a000001ff0020009c0000000a04000029000003150000613d0000000b0220006c000004b90000813d000001f801000041000000000010043f000001c7010000410000063200010430000d00000001001d0000000001000411000000000010043f0000000501000039000000200010043f00000040020000390000000001000019063005fa0000040f0000000d02000029000000000021041b0000000101000039000000000201041a0000000001000411063005b20000040f0000000001000412000e00000001001d0000800201000039000000240300003900000000040004150000000e0440008a0000000504400210000001ee020000410630060f0000040f000001ed02000041000000000012041b0000000001000019000006310001042e0000000b01000029000000000001041b0000018e01000041000000000501041a00000000010004140000018d0010009c0000018d01008041000000c0011002100000018f011001c70000800d02000039000000030300003900000190040000410000000d06000029063006260000040f0000000100200190000005780000613d0000000d010000290000018e02000041000000000012041b0000000001000019000006310001042e000000000021041b000003150000013d000000400100043d000700000001001d000001d2010000410000000e0010043f0000000d01000029000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000300000001001d000000000101041a000600000001001d00000007020000290000004003200039000001d301000041000500000003001d00000000001304350000002001200039000400000001001d00000008030000290000000000310435000001d4010000410000000000120435000001d501000041000000000010044300000000010004140000018d0010009c0000018d01008041000000c001100210000001ca011001c70000800b020000390630062b0000040f00000001002001900000057a0000613d00000007030000290000006002300039000000000101043b000800000002001d000000000012043500000080023000390000000001000410000100000002001d00000000001204350000018d0030009c0000018d010000410000000001034019000200400010021800000000010004140000018d0010009c0000018d01008041000000c00110021000000002011001af000001d6011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b0000002e0010043f000001d701000041000000070300002900000000001304350000000d01000029000000040200002900000000001204350000000c01000029000000050200002900000000001204350000000b0100002900000008020000290000000000120435000000060100002900000001020000290000000000120435000000a0013000390000000a02000029000000000021043500000000010004140000018d0010009c0000018d01008041000000c00110021000000002011001af000001d8011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b0000004e0010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001d9011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b000000000010043f0000000901000029000000200010043f0000000001000367000000a402100370000000000202043b000000400020043f000000c401100370000000000101043b000000600010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001da011001c700000001020000390630062b0000040f00000060031002700000018d03300197000000200030008c000000200400003900000000040340190000001f0540018f00000020064001900000002004600039000005450000613d0000002007000039000000000801034f000000008908043c0000000007970436000000000047004b000005410000c13d000000000005004b000005520000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f000000000014043500000000010304330000000d0010006c0000057b0000c13d000000010120018f00000006011000290000000302000029000000000012041b0000000c01000029000001dc011001c7000000400010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001dd011001c700008010020000390630062b0000040f0000000100200190000005780000613d000000000101043b0000000b02000029000000000021041b00000008010000290000018d0010009c0000018d01008041000000400110021000000000020004140000018d0020009c0000018d02008041000000c002200210000000000112019f000001de011001c70000800d020000390000000303000039000001df040000410000000d050000290000000c06000029000001a90000013d00000000010000190000063200010430000000000001042f000001db01000041000000000010043f000001c7010000410000063200010430000001f101000041000000000010043f0000001101000039000000040010043f000001f201000041000006320001043000000020030000390000000004310436000000003202043400000000002404350000004001100039000000000002004b000005940000613d000000000400001900000000054100190000000006430019000000000606043300000000006504350000002004400039000000000024004b0000058d0000413d000000000321001900000000000304350000001f0220003900000200022001970000000001210019000000000001042d000000400100043d000002010010009c000005a20000813d0000004002100039000000400020043f00000005020000390000000000210435000000000001042d000001f101000041000000000010043f0000004101000039000000040010043f000001f20100004100000632000104300000018e01000041000000000101041a0000000002000411000000000012004b000005ae0000c13d000000000001042d000001fb01000041000000000010043f000001c70100004100000632000104300001000000000002000001f403000041000000000303041a00000000052300190000000304000039000000000404041a000000000004004b000005bc0000613d000000000045004b000005e40000213d000100000002001d000000000035004b000005f50000413d000001f403000041000000000053041b000001e6020000410000000c0020043f000000000010043f00000000010004140000018d0010009c0000018d01008041000000c001100210000001c8011001c700008010020000390630062b0000040f0000000100200190000005e20000613d000000000101043b000000000201041a00000001030000290000000002320019000000000021041b000000200030043f0000000c0100043d000000000200041400000060061002700000018d0020009c0000018d02008041000000c001200210000001e7011001c70000800d020000390000000303000039000001e8040000410000000005000019063006260000040f0000000100200190000005e20000613d000000000001042d00000000010000190000063200010430000000400100043d000000440210003900000203030000410000000000320435000000240210003900000012030000390000000000320435000001e30200004100000000002104350000000402100039000000200300003900000000003204350000018d0010009c0000018d010080410000004001100210000001f0011001c700000632000104300000020201000041000000000010043f000001c7010000410000063200010430000000000001042f0000018d0010009c0000018d0100804100000040011002100000018d0020009c0000018d020080410000006002200210000000000112019f00000000020004140000018d0020009c0000018d02008041000000c002200210000000000112019f0000018f011001c700008010020000390630062b0000040f00000001002001900000060d0000613d000000000101043b000000000001042d0000000001000019000006320001043000000000050100190000000000200443000000040030008c000006160000a13d0000000501400270000000000101003100000004001004430000018d0030009c0000018d03008041000000600130021000000000020004140000018d0020009c0000018d02008041000000c002200210000000000112019f00000204011001c700000000020500190630062b0000040f0000000100200190000006250000613d000000000101043b000000000001042d000000000001042f00000629002104210000000102000039000000000001042d0000000002000019000000000001042d0000062e002104230000000102000039000000000001042d0000000002000019000000000001042d0000063000000432000006310001042e0000063200010430000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392702000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0000000000000000000000000000000000000000000000001158e460913d0000000000002000000000000000000000000000000400000010000000000000000000000000000000000000000000000000000000000000000000000000077f916ef00000000000000000000000000000000000000000000000000000000af35c6c600000000000000000000000000000000000000000000000000000000d5abeb0000000000000000000000000000000000000000000000000000000000f04e283d00000000000000000000000000000000000000000000000000000000f04e283e00000000000000000000000000000000000000000000000000000000f2fde38b00000000000000000000000000000000000000000000000000000000fee81cf400000000000000000000000000000000000000000000000000000000d5abeb0100000000000000000000000000000000000000000000000000000000dd62ed3e00000000000000000000000000000000000000000000000000000000b9ae90e900000000000000000000000000000000000000000000000000000000b9ae90ea00000000000000000000000000000000000000000000000000000000d505accf00000000000000000000000000000000000000000000000000000000af35c6c700000000000000000000000000000000000000000000000000000000b77cf9c6000000000000000000000000000000000000000000000000000000008da5cb5a00000000000000000000000000000000000000000000000000000000a8d0466b00000000000000000000000000000000000000000000000000000000a8d0466c00000000000000000000000000000000000000000000000000000000a9059cbb000000000000000000000000000000000000000000000000000000008da5cb5b0000000000000000000000000000000000000000000000000000000095d89b4100000000000000000000000000000000000000000000000000000000830953aa00000000000000000000000000000000000000000000000000000000830953ab0000000000000000000000000000000000000000000000000000000083f1211b0000000000000000000000000000000000000000000000000000000077f916f0000000000000000000000000000000000000000000000000000000007ecebe0000000000000000000000000000000000000000000000000000000000313ce566000000000000000000000000000000000000000000000000000000004e71d92c0000000000000000000000000000000000000000000000000000000070a082300000000000000000000000000000000000000000000000000000000070a0823100000000000000000000000000000000000000000000000000000000715018a6000000000000000000000000000000000000000000000000000000004e71d92d0000000000000000000000000000000000000000000000000000000054d1f13d0000000000000000000000000000000000000000000000000000000042966c670000000000000000000000000000000000000000000000000000000042966c6800000000000000000000000000000000000000000000000000000000484b973c00000000000000000000000000000000000000000000000000000000313ce567000000000000000000000000000000000000000000000000000000003644e5150000000000000000000000000000000000000000000000000000000012d8635d0000000000000000000000000000000000000000000000000000000023b872dc0000000000000000000000000000000000000000000000000000000023b872dd00000000000000000000000000000000000000000000000000000000256929620000000000000000000000000000000000000000000000000000000012d8635e0000000000000000000000000000000000000000000000000000000018160ddd00000000000000000000000000000000000000000000000000000000095ea7b200000000000000000000000000000000000000000000000000000000095ea7b3000000000000000000000000000000000000000000000000000000000b433a1200000000000000000000000000000000000000000000000000000000016a6a760000000000000000000000000000000000000000000000000000000006fdde03000000000000000000000000ffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000389a75e10000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000000000000000007448fbae00000000000000000000000000000000000000040000001c000000000000000002000000000000000000000000000000000000200000000c0000000000000000796b89b91644bc98cd93958e4c9038275d622183e25ac5af08cc6b5d955391320200000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000006f5e8818000000000000000000000000000000000022d473030f116ddee9f6b43ac78ba3000000000000000000000000000000000000000000000000000000007f5e9f2002000000000000000000000000000000000000340000000c00000000000000000000000000000000000000000000000000000020000000000000000000000000426f7a6f6e0000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000005000000a000000000000000000000000000000000000000000000000000000000000000000000383775081901c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc68b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f9a8a0592ac89c5ad3bc6df8224c17b485976f597df104ee20d0df415241f670b02000000000000000000000000000000000000a00000000000000000000000006e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c902000000000000000000000000000000000000c000000000000000000000000002000000000000000000000000000000000000420000002c0000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000ddafbaef00000000000000007f5e9f20000000000000000000000000000000000000000002000000000000000000000000000000000000340000002c000000000000000002000000000000000000000000000000000000200000000000000000000000008c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925000000000000000000000000000000000000000000000000000000001a15a3cc000000000000000000000000000000000000000000000000ffffffffffffffff020000000000000000000000000000000000004000000000000000000000000008c379a0000000000000000000000000000000000000000000000000000000005472616e736665727320616c726561647920756e6c6f636b656400000000000000000000000000000000000000000000000000640000008000000000000000000000000000000000000000000000000000000000000000000000000087a211a20200000000000000000000000000000000000020000000200000000000000000ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef425a4e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000038377508fa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c920000000000000000000000000000000000000000000000929eee149b4bd212681806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b83436c61696d206e6f74207265616479207965740000000000000000000000000000000000000000000000000000000000000000640000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000ab143c06000000000000000000000000000000000000000000000005345cdf77eb68f44cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd5d00dbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5472616e7366657273206c6f636b6564000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013be252b00000000000000000000000000000000000000000000000000000000f4d678b8000000000000000000000000000000000000000000000000000000003f68539a0000000000000000000000000000000000000000000000000000000082b429004d617820737570706c7920616c72656164792066696e616c697a6564000000006e65774d6178537570706c79203c2063757272656e7420737570706c79000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffffc000000000000000000000000000000000000000000000000000000000e5cfe95745786365656473206d617820737570706c790000000000000000000000000000020000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e6d5f1c0efce7ef8e762fd66ec7b245304a7c9a66b0b0ea1090e470e53b826b

[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.