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 BZNLoading...
Loading
Loading...
Loading
Loading...
Loading
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)
// 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. } }
// 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; } }
// 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(); _; } }
// 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) } } _; } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "mode": "3" }, "outputSelection": { "*": { "*": [ "abi", "metadata" ], "": [ "ast" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": true, "libraries": {} }
[{"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"}]
Contract Creation Code
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.