ETH Price: $3,491.17 (-0.06%)
 

Overview

Max Total Supply

94,191,855.40000000201311 FRIEND

Holders

48,184

Total Transfers

-

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xF83E2736...FDb50CA82
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Points

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 1000000 runs

Other Settings:
paris EvmVersion
File 1 of 4 : Points.sol
/// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import { MerkleProofLib } from "lib/solady/src/utils/MerkleProofLib.sol";
import { Owned } from "lib/solmate/src/auth/Owned.sol";
import { IPoints } from "./interfaces/IPoints.sol";

/// @title Points
/// @author CopyPaste
/// @notice A Standard Implementation of Points for FriendTechV2
contract Points is Owned(msg.sender), IPoints {
    /*//////////////////////////////////////////////////////////////
                                 STORAGE
    //////////////////////////////////////////////////////////////*/
    /// Merkle Root for the point claims
    bytes32 public immutable merkleRootA;
    bytes32 public immutable merkleRootB;

    mapping(address user => uint256 balance) public balanceOf;

    mapping(address owner => mapping(address spender => uint256 amount)) public allowance;

    mapping(address user => bool hasClaimedA) public claimedA;
    mapping(address user => bool hasClaimedB) public claimedB;

    /// The totalSupply of points
    uint256 public totalSupply;

    /*//////////////////////////////////////////////////////////////
                                 CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /*
     * @param _merkleRootA The merkle root for first the point claims
     * @param _merkleRootB The merkle root for second the point claims
     */
    constructor(bytes32 _merkleRootA, bytes32 _merkleRootB) {
        merkleRootA = _merkleRootA;
        merkleRootB = _merkleRootB;
    }

    /*//////////////////////////////////////////////////////////////
                                METADATA
    //////////////////////////////////////////////////////////////*/

    string public name = "Points";
    string public symbol = "PTS";
    uint8 public decimals = 18;

    /*//////////////////////////////////////////////////////////////
                             ACCESS CONTROL
    //////////////////////////////////////////////////////////////*/
    mapping(address _contract => bool isWhitelisted) public isAllowed;
    mapping(bytes4 functionSignature => bool canBeCalled) public isOpen;

    modifier onlyWhitelisted() {
        require(isAllowed[msg.sender] || isOpen[msg.sig], "WHITELIST");
        _;
    }

    /*
     * @param _contract The contract address allowed to interact with points
     * @param toggle The toggle for whether or not the contract is allowed
     */
    function toggleContract(address _contract, bool toggle) external onlyOwner {
        isAllowed[_contract] = toggle;
    }

    /*
     * @param function The function to open to the public
     * @param toggle The toggle for whether or not the contract is allowed
     */
    function toggleFunction(bytes4 functionSig, bool toggle) external onlyOwner {
        isOpen[functionSig] = toggle;
    }

    /*
     * @param to address to recieve the points
     * @param amount The amount of points to mint
     */
    function mint(address to, uint256 amount) external onlyOwner {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    /*//////////////////////////////////////////////////////////////
                             TRANSFER LOGIC
    //////////////////////////////////////////////////////////////*/
    /*
     * @param proof The merkle proof supplied by the user to prove ownership of the claim
     * @param recipient The address that will receive the claimed points
     * @param amount The amount of points claimed
     */
    function claimA(bytes32[] calldata proof, address recipient, uint256 amount, address[] calldata giftRecipients, uint256 giftAmount) external {
        require(!claimedA[msg.sender], "Points: already claimed");
        require(giftAmount <= amount, "Points: gift amount exceeds claim"); // Would underflow anyway but you can never be too safe
        bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(msg.sender, amount))));
        require(MerkleProofLib.verifyCalldata(proof, merkleRootA, leaf), "Points: invalid proof");

        claimedA[msg.sender] = true;

        if (giftAmount != 0) {
            uint256 perUser = giftAmount / giftRecipients.length;

            amount -= giftAmount;

            for (uint256 i = 0; i < giftRecipients.length; ) {
                balanceOf[giftRecipients[i]] += perUser;

                unchecked {
                    ++i;
                }
            }
        }

        totalSupply += amount + giftAmount;

        // Mint the points to the recipient
        unchecked {
            balanceOf[recipient] += amount;
        }

        emit ClaimedA(msg.sender, recipient, amount);
    }

    /*
     * @param proof The merkle proof supplied by the user to prove ownership of the claim
     * @param recipient The address that will receive the claimed points
     * @param amount The amount of points claimed
     */
    function claimB(bytes32[] calldata proof, address recipient, uint256 amount, address[] calldata giftRecipients, uint256 giftAmount) external {
        require(!claimedB[msg.sender], "Points: already claimed");
        require(giftAmount <= amount, "Points: gift amount exceeds claim"); // Would underflow anyway but you can never be too safe

        bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(msg.sender, amount))));
        require(MerkleProofLib.verifyCalldata(proof, merkleRootB, leaf), "Points: invalid proof");

        claimedB[msg.sender] = true;

        if (giftAmount != 0) {
            uint256 perUser = giftAmount / giftRecipients.length;

            amount -= giftAmount;

            for (uint256 i = 0; i < giftRecipients.length; ) {
                balanceOf[giftRecipients[i]] += perUser;

                unchecked {
                    ++i;
                }
            }
        }

        totalSupply += amount + giftAmount;

        // Mint the points to the recipient
        unchecked {
            balanceOf[recipient] += amount;
        }

        emit ClaimedB(msg.sender, recipient, amount);
    }

    /*
     * @notice Unlike ERC20, Points do not return a boolean on transfer
     * @param to The address that will receive the points
     * @param amount The amount of points to transfer
     */
    function transfer(address to, uint256 amount) external onlyWhitelisted {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);
    }

    /*
     * @notice Unlike ERC20, Points do not return a boolean on transfer
     * @param from The address that will send the points
     * @param to The address that will receive the points
     * @param amount The amount of points to transfer
     */
    function transferFrom(address from, address to, uint256 amount) external onlyWhitelisted {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);
    }

    /*
     * @param spender The address that will be allowed to spend the points
     * @param amount The amount of points the spender will be allowed to spend
     */
    function approve(address spender, uint256 amount) external onlyWhitelisted {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);
    }
}

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

/// @notice Gas optimized verification of proof of inclusion for a leaf in a Merkle tree.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/MerkleProof.sol)
library MerkleProofLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*            MERKLE PROOF VERIFICATION OPERATIONS            */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf)
        internal
        pure
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if mload(proof) {
                // Initialize `offset` to the offset of `proof` elements in memory.
                let offset := add(proof, 0x20)
                // Left shift by 5 is equivalent to multiplying by 0x20.
                let end := add(offset, shl(5, mload(proof)))
                // Iterate over proof elements to compute root hash.
                for {} 1 {} {
                    // Slot of `leaf` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(leaf, mload(offset)))
                    // Store elements to hash contiguously in scratch space.
                    // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
                    mstore(scratch, leaf)
                    mstore(xor(scratch, 0x20), mload(offset))
                    // Reuse `leaf` to store the hash to reduce stack operations.
                    leaf := keccak256(0x00, 0x40)
                    offset := add(offset, 0x20)
                    if iszero(lt(offset, end)) { break }
                }
            }
            isValid := eq(leaf, root)
        }
    }

    /// @dev Returns whether `leaf` exists in the Merkle tree with `root`, given `proof`.
    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf)
        internal
        pure
        returns (bool isValid)
    {
        /// @solidity memory-safe-assembly
        assembly {
            if proof.length {
                // Left shift by 5 is equivalent to multiplying by 0x20.
                let end := add(proof.offset, shl(5, proof.length))
                // Initialize `offset` to the offset of `proof` in the calldata.
                let offset := proof.offset
                // Iterate over proof elements to compute root hash.
                for {} 1 {} {
                    // Slot of `leaf` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(leaf, calldataload(offset)))
                    // Store elements to hash contiguously in scratch space.
                    // Scratch space is 64 bytes (0x00 - 0x3f) and both elements are 32 bytes.
                    mstore(scratch, leaf)
                    mstore(xor(scratch, 0x20), calldataload(offset))
                    // Reuse `leaf` to store the hash to reduce stack operations.
                    leaf := keccak256(0x00, 0x40)
                    offset := add(offset, 0x20)
                    if iszero(lt(offset, end)) { break }
                }
            }
            isValid := eq(leaf, root)
        }
    }

    /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
    /// given `proof` and `flags`.
    ///
    /// Note:
    /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
    ///   will always return false.
    /// - The sum of the lengths of `proof` and `leaves` must never overflow.
    /// - Any non-zero word in the `flags` array is treated as true.
    /// - The memory offset of `proof` must be non-zero
    ///   (i.e. `proof` is not pointing to the scratch space).
    function verifyMultiProof(
        bytes32[] memory proof,
        bytes32 root,
        bytes32[] memory leaves,
        bool[] memory flags
    ) internal pure returns (bool isValid) {
        // Rebuilds the root by consuming and producing values on a queue.
        // The queue starts with the `leaves` array, and goes into a `hashes` array.
        // After the process, the last element on the queue is verified
        // to be equal to the `root`.
        //
        // The `flags` array denotes whether the sibling
        // should be popped from the queue (`flag == true`), or
        // should be popped from the `proof` (`flag == false`).
        /// @solidity memory-safe-assembly
        assembly {
            // Cache the lengths of the arrays.
            let leavesLength := mload(leaves)
            let proofLength := mload(proof)
            let flagsLength := mload(flags)

            // Advance the pointers of the arrays to point to the data.
            leaves := add(0x20, leaves)
            proof := add(0x20, proof)
            flags := add(0x20, flags)

            // If the number of flags is correct.
            for {} eq(add(leavesLength, proofLength), add(flagsLength, 1)) {} {
                // For the case where `proof.length + leaves.length == 1`.
                if iszero(flagsLength) {
                    // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
                    isValid := eq(mload(xor(leaves, mul(xor(proof, leaves), proofLength))), root)
                    break
                }

                // The required final proof offset if `flagsLength` is not zero, otherwise zero.
                let proofEnd := add(proof, shl(5, proofLength))
                // We can use the free memory space for the queue.
                // We don't need to allocate, since the queue is temporary.
                let hashesFront := mload(0x40)
                // Copy the leaves into the hashes.
                // Sometimes, a little memory expansion costs less than branching.
                // Should cost less, even with a high free memory offset of 0x7d00.
                leavesLength := shl(5, leavesLength)
                for { let i := 0 } iszero(eq(i, leavesLength)) { i := add(i, 0x20) } {
                    mstore(add(hashesFront, i), mload(add(leaves, i)))
                }
                // Compute the back of the hashes.
                let hashesBack := add(hashesFront, leavesLength)
                // This is the end of the memory for the queue.
                // We recycle `flagsLength` to save on stack variables (sometimes save gas).
                flagsLength := add(hashesBack, shl(5, flagsLength))

                for {} 1 {} {
                    // Pop from `hashes`.
                    let a := mload(hashesFront)
                    // Pop from `hashes`.
                    let b := mload(add(hashesFront, 0x20))
                    hashesFront := add(hashesFront, 0x40)

                    // If the flag is false, load the next proof,
                    // else, pops from the queue.
                    if iszero(mload(flags)) {
                        // Loads the next proof.
                        b := mload(proof)
                        proof := add(proof, 0x20)
                        // Unpop from `hashes`.
                        hashesFront := sub(hashesFront, 0x20)
                    }

                    // Advance to the next flag.
                    flags := add(flags, 0x20)

                    // Slot of `a` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(a, b))
                    // Hash the scratch space and push the result onto the queue.
                    mstore(scratch, a)
                    mstore(xor(scratch, 0x20), b)
                    mstore(hashesBack, keccak256(0x00, 0x40))
                    hashesBack := add(hashesBack, 0x20)
                    if iszero(lt(hashesBack, flagsLength)) { break }
                }
                isValid :=
                    and(
                        // Checks if the last value in the queue is same as the root.
                        eq(mload(sub(hashesBack, 0x20)), root),
                        // And whether all the proofs are used, if required.
                        eq(proofEnd, proof)
                    )
                break
            }
        }
    }

    /// @dev Returns whether all `leaves` exist in the Merkle tree with `root`,
    /// given `proof` and `flags`.
    ///
    /// Note:
    /// - Breaking the invariant `flags.length == (leaves.length - 1) + proof.length`
    ///   will always return false.
    /// - Any non-zero word in the `flags` array is treated as true.
    /// - The calldata offset of `proof` must be non-zero
    ///   (i.e. `proof` is from a regular Solidity function with a 4-byte selector).
    function verifyMultiProofCalldata(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32[] calldata leaves,
        bool[] calldata flags
    ) internal pure returns (bool isValid) {
        // Rebuilds the root by consuming and producing values on a queue.
        // The queue starts with the `leaves` array, and goes into a `hashes` array.
        // After the process, the last element on the queue is verified
        // to be equal to the `root`.
        //
        // The `flags` array denotes whether the sibling
        // should be popped from the queue (`flag == true`), or
        // should be popped from the `proof` (`flag == false`).
        /// @solidity memory-safe-assembly
        assembly {
            // If the number of flags is correct.
            for {} eq(add(leaves.length, proof.length), add(flags.length, 1)) {} {
                // For the case where `proof.length + leaves.length == 1`.
                if iszero(flags.length) {
                    // `isValid = (proof.length == 1 ? proof[0] : leaves[0]) == root`.
                    // forgefmt: disable-next-item
                    isValid := eq(
                        calldataload(
                            xor(leaves.offset, mul(xor(proof.offset, leaves.offset), proof.length))
                        ),
                        root
                    )
                    break
                }

                // The required final proof offset if `flagsLength` is not zero, otherwise zero.
                let proofEnd := add(proof.offset, shl(5, proof.length))
                // We can use the free memory space for the queue.
                // We don't need to allocate, since the queue is temporary.
                let hashesFront := mload(0x40)
                // Copy the leaves into the hashes.
                // Sometimes, a little memory expansion costs less than branching.
                // Should cost less, even with a high free memory offset of 0x7d00.
                calldatacopy(hashesFront, leaves.offset, shl(5, leaves.length))
                // Compute the back of the hashes.
                let hashesBack := add(hashesFront, shl(5, leaves.length))
                // This is the end of the memory for the queue.
                // We recycle `flagsLength` to save on stack variables (sometimes save gas).
                flags.length := add(hashesBack, shl(5, flags.length))

                // We don't need to make a copy of `proof.offset` or `flags.offset`,
                // as they are pass-by-value (this trick may not always save gas).

                for {} 1 {} {
                    // Pop from `hashes`.
                    let a := mload(hashesFront)
                    // Pop from `hashes`.
                    let b := mload(add(hashesFront, 0x20))
                    hashesFront := add(hashesFront, 0x40)

                    // If the flag is false, load the next proof,
                    // else, pops from the queue.
                    if iszero(calldataload(flags.offset)) {
                        // Loads the next proof.
                        b := calldataload(proof.offset)
                        proof.offset := add(proof.offset, 0x20)
                        // Unpop from `hashes`.
                        hashesFront := sub(hashesFront, 0x20)
                    }

                    // Advance to the next flag offset.
                    flags.offset := add(flags.offset, 0x20)

                    // Slot of `a` in scratch space.
                    // If the condition is true: 0x20, otherwise: 0x00.
                    let scratch := shl(5, gt(a, b))
                    // Hash the scratch space and push the result onto the queue.
                    mstore(scratch, a)
                    mstore(xor(scratch, 0x20), b)
                    mstore(hashesBack, keccak256(0x00, 0x40))
                    hashesBack := add(hashesBack, 0x20)
                    if iszero(lt(hashesBack, flags.length)) { break }
                }
                isValid :=
                    and(
                        // Checks if the last value in the queue is same as the root.
                        eq(mload(sub(hashesBack, 0x20)), root),
                        // And whether all the proofs are used, if required.
                        eq(proofEnd, proof.offset)
                    )
                break
            }
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes32 array.
    function emptyProof() internal pure returns (bytes32[] calldata proof) {
        /// @solidity memory-safe-assembly
        assembly {
            proof.length := 0
        }
    }

    /// @dev Returns an empty calldata bytes32 array.
    function emptyLeaves() internal pure returns (bytes32[] calldata leaves) {
        /// @solidity memory-safe-assembly
        assembly {
            leaves.length := 0
        }
    }

    /// @dev Returns an empty calldata bool array.
    function emptyFlags() internal pure returns (bool[] calldata flags) {
        /// @solidity memory-safe-assembly
        assembly {
            flags.length := 0
        }
    }
}

File 3 of 4 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 4 of 4 : IPoints.sol
/// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

interface IPoints {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice By maintaining ERC20 compatibility, transfers and approvals are easier to index
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    /// @notice Keep track of whether or not a user has claimed their points
    event ClaimedA(address indexed _owner, address indexed recipient, uint256 indexed amount);
    event ClaimedB(address indexed _owner, address indexed recipient, uint256 indexed amount);
    /*//////////////////////////////////////////////////////////////
                               FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /*
     * @param proof The merkle proof supplied by the user to prove ownership of the claim
     * @param recipient The address that will receive the claimed points
     * @param amount The amount of points claimed
     */
    function claimA(bytes32[] calldata proof, address recipient, uint256 amount, address[] calldata giftRecipients, uint256 giftAmount) external;

    function claimB(bytes32[] calldata proof, address recipient, uint256 amount, address[] calldata giftRecipients, uint256 giftAmount) external;

    /*
     * @notice Unlike ERC20, Points do not return a boolean on transfer
     * @param to The address that will receive the points
     * @param value The amount of points to transfer
     */
    function transfer(address to, uint256 value) external;

    /*
     * @notice Unlike ERC20, Points do not return a boolean on transfer
     * @param from The address that will send the points
     * @param to The address that will receive the points
     * @param value The amount of points to transfer
     */
    function transferFrom(address from, address to, uint256 value) external;

    /*
     * @param spender The address that will be allowed to spend the points
     * @param amount The amount of points the spender will be allowed to spend
     */
    function approve(address spender, uint256 amount) external;

    /*//////////////////////////////////////////////////////////////
                             VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /*
     * @param _owner The address that will be allowed to spend the points
     * @param _spender The address that will be allowed to spend the points
     * 
     * @return The amount of points the spender is allowed to spend
     */
    function allowance(address _owner, address _spender) external view returns (uint256);

    /*
     * @param _owner The address that will be checked for points
     * 
     * @return The amount of points the owner has
     */
    function balanceOf(address _owner) external view returns (uint256);

    /*
     * @return The root of the Merkle Tree which stores claims
     */
    function merkleRootA() external view returns (bytes32);

    /*//////////////////////////////////////////////////////////////
                             ACCESS CONTROL
    //////////////////////////////////////////////////////////////*/
    /*
     * @param _address The address in question
     * 
     * @return Whether the contract is allowed to interact with points 
     */
    function isAllowed(address _address) external view returns (bool);
}

Settings
{
  "remappings": [
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "forge-std/=lib/forge-std/src/",
    "murky/=lib/murky/",
    "openzeppelin-contracts/=lib/murky/lib/openzeppelin-contracts/",
    "solady/=lib/solady/src/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": false
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"bytes32","name":"_merkleRootA","type":"bytes32"},{"internalType":"bytes32","name":"_merkleRootB","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimedA","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimedB","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","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":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address[]","name":"giftRecipients","type":"address[]"},{"internalType":"uint256","name":"giftAmount","type":"uint256"}],"name":"claimA","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address[]","name":"giftRecipients","type":"address[]"},{"internalType":"uint256","name":"giftAmount","type":"uint256"}],"name":"claimB","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedA","outputs":[{"internalType":"bool","name":"hasClaimedA","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"claimedB","outputs":[{"internalType":"bool","name":"hasClaimedB","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"functionSignature","type":"bytes4"}],"name":"isOpen","outputs":[{"internalType":"bool","name":"canBeCalled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootA","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRootB","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"toggle","type":"bool"}],"name":"toggleContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"functionSig","type":"bytes4"},{"internalType":"bool","name":"toggle","type":"bool"}],"name":"toggleFunction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"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":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610100604052600660c081815265506f696e747360d01b60e05262000025908262000184565b5060408051808201909152600381526250545360e81b60208201526007906200004f908262000184565b506008805460ff191660121790553480156200006a57600080fd5b5060405162001a3e38038062001a3e8339810160408190526200008d9162000250565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060809190915260a05262000275565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200010857607f821691505b6020821081036200012957634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200017f576000816000526020600020601f850160051c810160208610156200015a5750805b601f850160051c820191505b818110156200017b5782815560010162000166565b5050505b505050565b81516001600160401b03811115620001a057620001a0620000dd565b620001b881620001b18454620000f3565b846200012f565b602080601f831160018114620001f05760008415620001d75750858301515b600019600386901b1c1916600185901b1785556200017b565b600085815260208120601f198616915b82811015620002215788860151825594840194600190910190840162000200565b5085821015620002405787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600080604083850312156200026457600080fd5b505080516020909101519092909150565b60805160a051611795620002a9600039600081816103c2015261073901526000818161034d0152610e7001526117956000f3fe608060405234801561001057600080fd5b50600436106101825760003560e01c8063982d364d116100d8578063d5491e5c1161008c578063e5d54fc011610066578063e5d54fc0146103bd578063f2fde38b146103e4578063f3c73ffe146103f757600080fd5b8063d5491e5c14610348578063dd62ed3e1461036f578063e230ffac1461039a57600080fd5b80639d194d18116100bd5780639d194d18146102ff578063a9059cbb14610312578063babcc5391461032557600080fd5b8063982d364d146102a957806399704063146102dc57600080fd5b8063313ce5671161013a5780638da5cb5b116101145780638da5cb5b1461024957806393ee54a81461028e57806395d89b41146102a157600080fd5b8063313ce567146101f757806340c10f191461021657806370a082311461022957600080fd5b806318160ddd1161016b57806318160ddd146101ba5780631c71f9bc146101d157806323b872dd146101e457600080fd5b806306fdde0314610187578063095ea7b3146101a5575b600080fd5b61018f61040a565b60405161019c91906113a9565b60405180910390f35b6101b86101b336600461143f565b610498565b005b6101c360055481565b60405190815260200161019c565b6101b86101df3660046114b5565b6105bf565b6101b86101f236600461154b565b61092c565b6008546102049060ff1681565b60405160ff909116815260200161019c565b6101b861022436600461143f565b610b20565b6101c3610237366004611587565b60016020526000908152604090205481565b6000546102699073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b6101b861029c3660046115b9565b610c12565b61018f610ce9565b6102cc6102b736600461161c565b600a6020526000908152604090205460ff1681565b604051901515815260200161019c565b6102cc6102ea366004611587565b60046020526000908152604090205460ff1681565b6101b861030d3660046114b5565b610cf6565b6101b861032036600461143f565b611063565b6102cc610333366004611587565b60096020526000908152604090205460ff1681565b6101c37f000000000000000000000000000000000000000000000000000000000000000081565b6101c361037d366004611637565b600260209081526000928352604080842090915290825290205481565b6102cc6103a8366004611587565b60036020526000908152604090205460ff1681565b6101c37f000000000000000000000000000000000000000000000000000000000000000081565b6101b86103f2366004611587565b61119b565b6101b8610405366004611661565b61128c565b600680546104179061167d565b80601f01602080910402602001604051908101604052809291908181526020018280546104439061167d565b80156104905780601f1061046557610100808354040283529160200191610490565b820191906000526020600020905b81548152906001019060200180831161047357829003601f168201915b505050505081565b3360009081526009602052604090205460ff16806104e75750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b610552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c495354000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff871680855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a35050565b3360009081526004602052604090205460ff1615610639576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506f696e74733a20616c726561647920636c61696d65640000000000000000006044820152606401610549565b838111156106c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f506f696e74733a206769667420616d6f756e74206578636565647320636c616960448201527f6d000000000000000000000000000000000000000000000000000000000000006064820152608401610549565b60408051336020820152908101859052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905061075e88887f00000000000000000000000000000000000000000000000000000000000000008461136f565b6107c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f506f696e74733a20696e76616c69642070726f6f6600000000000000000000006044820152606401610549565b33600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581156108ac57600061080e84846116ff565b905061081a838761173a565b955060005b848110156108a957816001600088888581811061083e5761083e611753565b90506020020160208101906108539190611587565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461089c9190611782565b909155505060010161081f565b50505b6108b68286611782565b600560008282546108c79190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff86166000818152600160205260408082208054890190555187929133917fc9fd79e1d8d4b01bc31c31591b73449484b8a2cd1e265129297409b468d56d399190a45050505050505050565b3360009081526009602052604090205460ff168061097b5750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b6109e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c49535400000000000000000000000000000000000000000000006044820152606401610549565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a7557610a43828261173a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604081208054849290610aaa90849061173a565b909155505073ffffffffffffffffffffffffffffffffffffffff808416600081815260016020526040908190208054860190555190918616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610b129086815260200190565b60405180910390a350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b8060056000828254610bb39190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016105b3565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600780546104179061167d565b3360009081526003602052604090205460ff1615610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506f696e74733a20616c726561647920636c61696d65640000000000000000006044820152606401610549565b83811115610e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f506f696e74733a206769667420616d6f756e74206578636565647320636c616960448201527f6d000000000000000000000000000000000000000000000000000000000000006064820152608401610549565b60408051336020820152908101859052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050610e9588887f00000000000000000000000000000000000000000000000000000000000000008461136f565b610efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f506f696e74733a20696e76616c69642070726f6f6600000000000000000000006044820152606401610549565b33600090815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558115610fe3576000610f4584846116ff565b9050610f51838761173a565b955060005b84811015610fe0578160016000888885818110610f7557610f75611753565b9050602002016020810190610f8a9190611587565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fd39190611782565b9091555050600101610f56565b50505b610fed8286611782565b60056000828254610ffe9190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff86166000818152600160205260408082208054890190555187929133917f9e530c1f4e73e1ae05ad4b0464ea7f76054a087e37490636b79173927d7044169190a45050505050505050565b3360009081526009602052604090205460ff16806110b25750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c49535400000000000000000000000000000000000000000000006044820152606401610549565b336000908152600160205260408120805483929061113790849061173a565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260016020526040908190208054840190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906105b39085815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff16331461121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60005473ffffffffffffffffffffffffffffffffffffffff16331461130d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b7fffffffff00000000000000000000000000000000000000000000000000000000919091166000908152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600083156113a1578360051b8501855b803580851160051b9485526020948518526040600020930181811061137f5750505b501492915050565b60006020808352835180602085015260005b818110156113d7578581018301518582016040015282016113bb565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461143a57600080fd5b919050565b6000806040838503121561145257600080fd5b61145b83611416565b946020939093013593505050565b60008083601f84011261147b57600080fd5b50813567ffffffffffffffff81111561149357600080fd5b6020830191508360208260051b85010111156114ae57600080fd5b9250929050565b600080600080600080600060a0888a0312156114d057600080fd5b873567ffffffffffffffff808211156114e857600080fd5b6114f48b838c01611469565b909950975087915061150860208b01611416565b965060408a0135955060608a013591508082111561152557600080fd5b506115328a828b01611469565b989b979a50959894979596608090950135949350505050565b60008060006060848603121561156057600080fd5b61156984611416565b925061157760208501611416565b9150604084013590509250925092565b60006020828403121561159957600080fd5b6115a282611416565b9392505050565b8035801515811461143a57600080fd5b600080604083850312156115cc57600080fd5b6115d583611416565b91506115e3602084016115a9565b90509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461143a57600080fd5b60006020828403121561162e57600080fd5b6115a2826115ec565b6000806040838503121561164a57600080fd5b61165383611416565b91506115e360208401611416565b6000806040838503121561167457600080fd5b6115d5836115ec565b600181811c9082168061169157607f821691505b6020821081036116ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611735577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561174d5761174d6116d0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561174d5761174d6116d0563b451926ca3bf79ef43e96709171401da10ae54406412ed3ea67469c44d54a0979899e2485ed85b0e0764cff00b772b58e77fa42c300701f8f0714bf8deb5f10

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101825760003560e01c8063982d364d116100d8578063d5491e5c1161008c578063e5d54fc011610066578063e5d54fc0146103bd578063f2fde38b146103e4578063f3c73ffe146103f757600080fd5b8063d5491e5c14610348578063dd62ed3e1461036f578063e230ffac1461039a57600080fd5b80639d194d18116100bd5780639d194d18146102ff578063a9059cbb14610312578063babcc5391461032557600080fd5b8063982d364d146102a957806399704063146102dc57600080fd5b8063313ce5671161013a5780638da5cb5b116101145780638da5cb5b1461024957806393ee54a81461028e57806395d89b41146102a157600080fd5b8063313ce567146101f757806340c10f191461021657806370a082311461022957600080fd5b806318160ddd1161016b57806318160ddd146101ba5780631c71f9bc146101d157806323b872dd146101e457600080fd5b806306fdde0314610187578063095ea7b3146101a5575b600080fd5b61018f61040a565b60405161019c91906113a9565b60405180910390f35b6101b86101b336600461143f565b610498565b005b6101c360055481565b60405190815260200161019c565b6101b86101df3660046114b5565b6105bf565b6101b86101f236600461154b565b61092c565b6008546102049060ff1681565b60405160ff909116815260200161019c565b6101b861022436600461143f565b610b20565b6101c3610237366004611587565b60016020526000908152604090205481565b6000546102699073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019c565b6101b861029c3660046115b9565b610c12565b61018f610ce9565b6102cc6102b736600461161c565b600a6020526000908152604090205460ff1681565b604051901515815260200161019c565b6102cc6102ea366004611587565b60046020526000908152604090205460ff1681565b6101b861030d3660046114b5565b610cf6565b6101b861032036600461143f565b611063565b6102cc610333366004611587565b60096020526000908152604090205460ff1681565b6101c37f3b451926ca3bf79ef43e96709171401da10ae54406412ed3ea67469c44d54a0981565b6101c361037d366004611637565b600260209081526000928352604080842090915290825290205481565b6102cc6103a8366004611587565b60036020526000908152604090205460ff1681565b6101c37f79899e2485ed85b0e0764cff00b772b58e77fa42c300701f8f0714bf8deb5f1081565b6101b86103f2366004611587565b61119b565b6101b8610405366004611661565b61128c565b600680546104179061167d565b80601f01602080910402602001604051908101604052809291908181526020018280546104439061167d565b80156104905780601f1061046557610100808354040283529160200191610490565b820191906000526020600020905b81548152906001019060200180831161047357829003601f168201915b505050505081565b3360009081526009602052604090205460ff16806104e75750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b610552576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c495354000000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b33600081815260026020908152604080832073ffffffffffffffffffffffffffffffffffffffff871680855290835292819020859055518481529192917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a35050565b3360009081526004602052604090205460ff1615610639576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506f696e74733a20616c726561647920636c61696d65640000000000000000006044820152606401610549565b838111156106c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f506f696e74733a206769667420616d6f756e74206578636565647320636c616960448201527f6d000000000000000000000000000000000000000000000000000000000000006064820152608401610549565b60408051336020820152908101859052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301520160405160208183030381529060405280519060200120905061075e88887f79899e2485ed85b0e0764cff00b772b58e77fa42c300701f8f0714bf8deb5f108461136f565b6107c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f506f696e74733a20696e76616c69642070726f6f6600000000000000000000006044820152606401610549565b33600090815260046020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905581156108ac57600061080e84846116ff565b905061081a838761173a565b955060005b848110156108a957816001600088888581811061083e5761083e611753565b90506020020160208101906108539190611587565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461089c9190611782565b909155505060010161081f565b50505b6108b68286611782565b600560008282546108c79190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff86166000818152600160205260408082208054890190555187929133917fc9fd79e1d8d4b01bc31c31591b73449484b8a2cd1e265129297409b468d56d399190a45050505050505050565b3360009081526009602052604090205460ff168061097b5750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b6109e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c49535400000000000000000000000000000000000000000000006044820152606401610549565b73ffffffffffffffffffffffffffffffffffffffff831660009081526002602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610a7557610a43828261173a565b73ffffffffffffffffffffffffffffffffffffffff851660009081526002602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff841660009081526001602052604081208054849290610aaa90849061173a565b909155505073ffffffffffffffffffffffffffffffffffffffff808416600081815260016020526040908190208054860190555190918616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610b129086815260200190565b60405180910390a350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ba1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b8060056000828254610bb39190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600160209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016105b3565b60005473ffffffffffffffffffffffffffffffffffffffff163314610c93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600780546104179061167d565b3360009081526003602052604090205460ff1615610d70576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f506f696e74733a20616c726561647920636c61696d65640000000000000000006044820152606401610549565b83811115610e00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f506f696e74733a206769667420616d6f756e74206578636565647320636c616960448201527f6d000000000000000000000000000000000000000000000000000000000000006064820152608401610549565b60408051336020820152908101859052600090606001604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201209083015201604051602081830303815290604052805190602001209050610e9588887f3b451926ca3bf79ef43e96709171401da10ae54406412ed3ea67469c44d54a098461136f565b610efb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f506f696e74733a20696e76616c69642070726f6f6600000000000000000000006044820152606401610549565b33600090815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558115610fe3576000610f4584846116ff565b9050610f51838761173a565b955060005b84811015610fe0578160016000888885818110610f7557610f75611753565b9050602002016020810190610f8a9190611587565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fd39190611782565b9091555050600101610f56565b50505b610fed8286611782565b60056000828254610ffe9190611782565b909155505073ffffffffffffffffffffffffffffffffffffffff86166000818152600160205260408082208054890190555187929133917f9e530c1f4e73e1ae05ad4b0464ea7f76054a087e37490636b79173927d7044169190a45050505050505050565b3360009081526009602052604090205460ff16806110b25750600080357fffffffff00000000000000000000000000000000000000000000000000000000168152600a602052604090205460ff165b611118576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f57484954454c49535400000000000000000000000000000000000000000000006044820152606401610549565b336000908152600160205260408120805483929061113790849061173a565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260016020526040908190208054840190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906105b39085815260200190565b60005473ffffffffffffffffffffffffffffffffffffffff16331461121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60005473ffffffffffffffffffffffffffffffffffffffff16331461130d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152606401610549565b7fffffffff00000000000000000000000000000000000000000000000000000000919091166000908152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600083156113a1578360051b8501855b803580851160051b9485526020948518526040600020930181811061137f5750505b501492915050565b60006020808352835180602085015260005b818110156113d7578581018301518582016040015282016113bb565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461143a57600080fd5b919050565b6000806040838503121561145257600080fd5b61145b83611416565b946020939093013593505050565b60008083601f84011261147b57600080fd5b50813567ffffffffffffffff81111561149357600080fd5b6020830191508360208260051b85010111156114ae57600080fd5b9250929050565b600080600080600080600060a0888a0312156114d057600080fd5b873567ffffffffffffffff808211156114e857600080fd5b6114f48b838c01611469565b909950975087915061150860208b01611416565b965060408a0135955060608a013591508082111561152557600080fd5b506115328a828b01611469565b989b979a50959894979596608090950135949350505050565b60008060006060848603121561156057600080fd5b61156984611416565b925061157760208501611416565b9150604084013590509250925092565b60006020828403121561159957600080fd5b6115a282611416565b9392505050565b8035801515811461143a57600080fd5b600080604083850312156115cc57600080fd5b6115d583611416565b91506115e3602084016115a9565b90509250929050565b80357fffffffff000000000000000000000000000000000000000000000000000000008116811461143a57600080fd5b60006020828403121561162e57600080fd5b6115a2826115ec565b6000806040838503121561164a57600080fd5b61165383611416565b91506115e360208401611416565b6000806040838503121561167457600080fd5b6115d5836115ec565b600181811c9082168061169157607f821691505b6020821081036116ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600082611735577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b8181038181111561174d5761174d6116d0565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8082018082111561174d5761174d6116d056

[ 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.