ETH Price: $2,894.42 (-0.98%)

Contract

0x297bfd15e6AABaC15CDB3D8cc2F07dE9785d9CeB

Overview

ETH Balance

0 ETH

ETH Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Transfer296650652025-10-14 3:43:44104 days ago1760413424IN
0x297bfd15...9785d9CeB
0 ETH00.00000037
Approve296647722025-10-14 3:38:51104 days ago1760413131IN
0x297bfd15...9785d9CeB
0 ETH00.00000038
Claim296647062025-10-14 3:37:45104 days ago1760413065IN
0x297bfd15...9785d9CeB
0 ETH00.000004
Claim282993762025-09-28 8:22:15120 days ago1759047735IN
0x297bfd15...9785d9CeB
0 ETH00.00000403
Claim264317432025-09-06 17:35:02141 days ago1757180102IN
0x297bfd15...9785d9CeB
0 ETH00.00000403
Claim255354182025-08-27 8:36:17152 days ago1756283777IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00000407
Approve211459852025-07-07 13:19:04203 days ago1751894344IN
0x297bfd15...9785d9CeB
0 ETH00.00000673
Claim210251792025-07-06 3:45:38204 days ago1751773538IN
0x297bfd15...9785d9CeB
0 ETH00.00000041
Claim181049752025-06-02 8:35:34238 days ago1748853334IN
0x297bfd15...9785d9CeB
0 ETH0.000000020.00000049
Claim176753412025-05-28 9:15:00243 days ago1748423700IN
0x297bfd15...9785d9CeB
0 ETH0.000000020.00000053
Claim174864262025-05-26 4:46:25245 days ago1748234785IN
0x297bfd15...9785d9CeB
0 ETH00.00000039
Claim173861022025-05-25 0:54:21246 days ago1748134461IN
0x297bfd15...9785d9CeB
0 ETH0.000000040.0003992
Transfer169600502025-05-20 2:33:29251 days ago1747708409IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00000624
Claim169580322025-05-20 1:59:51251 days ago1747706391IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00000868
Approve165337132025-05-15 4:07:52256 days ago1747282072IN
0x297bfd15...9785d9CeB
0 ETH00.00002225
Claim165206422025-05-15 0:30:01256 days ago1747269001IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00000892
Approve164679962025-05-14 9:52:35257 days ago1747216355IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00017735
Claim162756012025-05-12 4:26:00259 days ago1747023960IN
0x297bfd15...9785d9CeB
0 ETH0.000000010.00002976
Claim162273342025-05-11 15:01:33260 days ago1746975693IN
0x297bfd15...9785d9CeB
0 ETH0.000000040.00001496
Approve161519592025-05-10 18:05:18260 days ago1746900318IN
0x297bfd15...9785d9CeB
0 ETH0.000000030.00005763
Claim160393382025-05-09 10:48:17262 days ago1746787697IN
0x297bfd15...9785d9CeB
0 ETH0.000000060.00000043
Approve157827212025-05-06 11:31:20265 days ago1746531080IN
0x297bfd15...9785d9CeB
0 ETH0.000000470.00010034
Claim157119862025-05-05 15:52:25265 days ago1746460345IN
0x297bfd15...9785d9CeB
0 ETH0.00000060.00000054
Transfer155255572025-05-03 12:05:16268 days ago1746273916IN
0x297bfd15...9785d9CeB
0 ETH00.00000035
Claim154920432025-05-03 2:46:42268 days ago1746240402IN
0x297bfd15...9785d9CeB
0 ETH00.00000035
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
151957562025-04-29 16:28:35271 days ago1745944115  Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x0E24aD8e...66F7b7C8e in Base Mainnet
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
RainbowSuperToken

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 1000 runs

Other Settings:
london EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

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

// Contracts
import { Owned } from "lib/solmate/src/auth/Owned.sol";
import { ERC20 } from "lib/solmate/src/tokens/ERC20.sol";

import { MerkleProofLib } from "lib/solady/src/utils/MerkleProofLib.sol";

/// @title RainbowSuperToken
/// @author CopyPaste - for Rainbow with love <3
/// @notice An implementation of ERC20 extending with IERC7802 to allow for unified use across the
///     Superchain.
contract RainbowSuperToken is ERC20, Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    /// @notice Emitted when a crosschain transfer mints tokens.
    /// @param to       Address of the account tokens are being minted for.
    /// @param amount   Amount of tokens minted.
    /// @param sender   Address of the account that finilized the crosschain transfer.
    event CrosschainMint(address indexed to, uint256 amount, address indexed sender);

    /// @notice Emitted when a crosschain transfer burns tokens.
    /// @param from     Address of the account tokens are being burned from.
    /// @param amount   Amount of tokens burned.
    /// @param sender   Address of the account that initiated the crosschain transfer.
    event CrosschainBurn(address indexed from, uint256 amount, address indexed sender);

    /// @notice Emitted when tokens are claimed
    /// @param to The address that claimed the tokens
    /// @param amount The amount of tokens claimed
    event Claim(address indexed to, uint256 amount);
    /*//////////////////////////////////////////////////////////////
                              CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /// @dev The merkle root to be used for claims

    bytes32 public merkleRoot;

    /// @dev The maximum total supply of the token that can be minted
    uint256 public maxTotalMintedSupply;

    /// @dev Original Chain the token was deployed on
    uint256 public originalChainId;

    /// @param name The name of the token
    /// @param symbol The symbol of the token
    /// @param _tokenURI A Url pointing to the metadata for the token
    /// @param _merkleRoot The merkle root to be used for claims
    /// @param _maxTotalMintedSupply The maximum total supply of the token that can be minted
    constructor(
        string memory name,
        string memory symbol,
        string memory _tokenURI,
        bytes32 _merkleRoot,
        uint256 _maxTotalMintedSupply,
        uint256 _originalChainId
    )
        ERC20(name, symbol, 18)
        Owned(msg.sender)
    {
        tokenURI = _tokenURI;
        merkleRoot = _merkleRoot;
        maxTotalMintedSupply = _maxTotalMintedSupply;
        originalChainId = _originalChainId;
    }

    modifier onlyOriginalChain() {
        uint256 id;
        assembly {
            id := chainid()
        }
        if (id != originalChainId) revert Unauthorized();
        _;
    }

    /*//////////////////////////////////////////////////////////////
                                MINTING
    //////////////////////////////////////////////////////////////*/

    /// @dev Tracks the number of tokens we have minted in claims so far
    uint256 public totalMintedSupply;

    /// @dev Tracks if a user has claimed their tokens
    mapping(address => bool) public claimed;

    /// @dev Error emitted when the proof supplied is invalid
    error InvalidProof();

    /// @dev Error emitted when a user has already claimed their tokens
    error AlreadyClaimed();

    /// @dev Error emitted when a user tries to claim 0 tokens
    error CannotClaimZero();

    /// @param proof The merkle proof to verify the claim
    /// @param recipient The address to mint the tokens to
    /// @param amount The amount of tokens to mint
    function claim(bytes32[] calldata proof, address recipient, uint256 amount) external onlyOriginalChain {
        if (claimed[recipient]) revert AlreadyClaimed();

        claimed[recipient] = true;

        bytes32 leaf = keccak256(bytes.concat(keccak256(abi.encode(recipient, amount))));
        if (!MerkleProofLib.verifyCalldata(proof, merkleRoot, leaf)) {
            revert InvalidProof();
        }

        if (amount + totalMintedSupply > maxTotalMintedSupply) {
            amount = maxTotalMintedSupply - totalMintedSupply;
        }

        if (amount == 0) {
            revert CannotClaimZero();
        }

        totalMintedSupply += amount;
        totalSupply += amount;

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

        emit Transfer(address(0), recipient, amount);
        emit Claim(recipient, amount);
    }

    /// @param recipient The address to mint the tokens to
    /// @param amount The amount of tokens to mint
    function mint(address recipient, uint256 amount) external onlyOriginalChain onlyOwner {
        _mint(recipient, amount);
    }

    /*//////////////////////////////////////////////////////////////
                            RAINBOW METADATA
    //////////////////////////////////////////////////////////////*/

    /// @dev tokenURI The URI for the token metadata.
    string public tokenURI;

    /*//////////////////////////////////////////////////////////////
                          SUPERCHAIN FUNCTIONS
    //////////////////////////////////////////////////////////////*/

    /// @dev Error emitted for unauthorized access.
    error Unauthorized();

    /// @dev The precompile for the superchain token bridge.
    address internal constant SUPERCHAIN_TOKEN_BRIDGE = 0x4200000000000000000000000000000000000028;

    /// i@notice Allows the SuperchainTokenBridge to mint tokens.
    /// @param _to     Address to mint tokens to.
    /// @param _amount Amount of tokens to mint.
    function crosschainMint(address _to, uint256 _amount) external {
        if (msg.sender != SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();

        _mint(_to, _amount);

        emit CrosschainMint(_to, _amount, msg.sender);
    }

    /// @notice Allows the SuperchainTokenBridge to burn tokens.
    /// @param _from   Address to burn tokens from.
    /// @param _amount Amount of tokens to burn.
    function crosschainBurn(address _from, uint256 _amount) external {
        if (msg.sender != SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();

        _burn(_from, _amount);

        emit CrosschainBurn(_from, _amount, msg.sender);
    }

    /// @dev ERC165 Interface Id Compatibility check
    /// @param _interfaceId Interface ID to check for support.
    /// @return True if the contract supports the given interface ID.
    function supportsInterface(bytes4 _interfaceId) public pure returns (bool) {
        return _interfaceId == 0x33331994 // ERC7802 Interface ID
            || _interfaceId == 0x36372b07 // ERC20 Interface ID
            || _interfaceId == 0x01ffc9a7; // ERC165 Interface ID
    }
}

// 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);
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

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

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

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

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        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);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        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);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        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);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

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

// 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
        }
    }
}

Settings
{
  "remappings": [
    "lib/solmate/src/auth/=smart-contracts/",
    "lib/solmate/src/tokens/=smart-contracts/",
    "lib/solady/src/utils/=smart-contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@uniswap/v3-core/=lib/v3-core/",
    "@uniswap/v3-periphery/=lib/v3-periphery/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"_tokenURI","type":"string"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"},{"internalType":"uint256","name":"_maxTotalMintedSupply","type":"uint256"},{"internalType":"uint256","name":"_originalChainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyClaimed","type":"error"},{"inputs":[],"name":"CannotClaimZero","type":"error"},{"inputs":[],"name":"InvalidProof","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":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainMint","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":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","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":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","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"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalMintedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","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":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"originalChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMintedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"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":"nonpayable","type":"function"}]

0x60e06040908082523461056657611949803803809161001e828561056b565b833981019060c0818303126105665780516001600160401b0390818111610566578361004b91840161058e565b9060209081840151818111610566578561006691860161058e565b9486850151908282116105665761007e91860161058e565b9460608501519360a0608087015196015196815184811161055057600090806100a783546105fd565b94601f95868111610504575b5088908683116001146104a1578492610496575b50508160011b916000199060031b1c19161781555b835185811161048257806001956100f387546105fd565b868111610434575b5088908683116001146103d55784926103ca575b5050600019600383901b1c191690851b1784555b60126080524660a0528951815490828161013c846105fd565b918282528a8201948b8a821691826000146103af575050600114610372575b6101679250038261056b565b5190208a51878101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f83528c8201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a0815260c081018181108882111761035e578c5251902060c052600680546001600160a01b03191633908117909155817f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a3815194851161034a57610232600c546105fd565b838111610306575b50859285116001146102a2579394508492919083610297575b50501b916000199060031b1c191617600c555b600755600855600955516113119081610638823960805181610ae9015260a05181611088015260c051816110af0152f35b015192503880610253565b600c815285812093958591601f198316915b888383106102ec57505050106102d3575b505050811b01600c55610266565b015160001960f88460031b161c191690553880806102c5565b8587015188559096019594850194879350908101906102b4565b600c82528682208480880160051c820192898910610341575b0160051c019085905b82811061033657505061023a565b838155018590610328565b9250819261031f565b634e487b7160e01b81526041600452602490fd5b634e487b7160e01b84526041600452602484fd5b505083805281898086208987915b858310610396575050610167935082010161015b565b8091929450548385880101520191018a90898593610380565b60ff1916875261016794151560051b840101915061015b9050565b01519050388061010f565b8785528985208894509190601f198416865b8c82821061041e5750508411610405575b505050811b018455610123565b015160001960f88460031b161c191690553880806103f8565b8385015186558b979095019493840193016103e7565b9091508684528884208680850160051c8201928b8610610479575b918991869594930160051c01915b82811061046b5750506100fb565b86815585945089910161045d565b9250819261044f565b634e487b7160e01b82526041600452602482fd5b0151905038806100c7565b8480528985209250601f198416855b8b8282106104ee5750509084600195949392106104d5575b505050811b0181556100dc565b015160001960f88460031b161c191690553880806104c8565b60018596829396860151815501950193016104b0565b9091508380528884208680850160051c8201928b8610610547575b9085949392910160051c01905b81811061053957506100b3565b85815584935060010161052c565b9250819261051f565b634e487b7160e01b600052604160045260246000fd5b600080fd5b601f909101601f19168101906001600160401b0382119082101761055057604052565b919080601f840112156105665782516001600160401b03811161055057602090604051926105c583601f19601f850116018561056b565b8184528282870101116105665760005b8181106105ea57508260009394955001015290565b85810183015184820184015282016105d5565b90600182811c9216801561062d575b602083101461061757565b634e487b7160e01b600052602260045260246000fd5b91607f169161060c56fe60806040908082526004918236101561001757600080fd5b600092833560e01c92836301ffc9a714610ea55750826306fdde0314610dff578263095ea7b314610d8e5782630d788c3614610d6f57826318160ddd14610d5057826318bf507714610cc657826323b872dd14610bf55782632b8c49e314610b2c5782632eb4a7ab14610b0d578263313ce56714610acf5782633644e51514610aab5782633c130d9014610a0357826340c10f19146109ab578263601e26031461098c57826370a08231146109555782637ecebe001461091e5782638da5cb5b146108f657826395d89b4114610813578263a9059cbb14610791578263c884ef8314610755578263ca21b1771461049d578263d505accf14610233578263dd62ed3e146101e557508163f236ceb4146101c2575063f2fde38b1461013a57600080fd5b346101bf5760203660031901126101bf577fffffffffffffffffffffffff000000000000000000000000000000000000000061017461102f565b600654906001600160a01b039061018e828416331461122a565b169182911617600655337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b80fd5b9050346101e157816003193601126101e1576020906008549051908152f35b5080fd5b9091503461022f578160031936011261022f57602092829161020561102f565b61020d61104a565b916001600160a01b038092168452865283832091168252845220549051908152f35b8280fd5b8382346101e15760e03660031901126101e15761024e61102f565b9061025761104a565b91604435606435926084359260ff8416809403610499574285106104565761027d611083565b956001600160a01b038092169586895260209560058752848a209889549960018b01905585519285898501957f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987528b89870152169a8b606086015288608086015260a085015260c084015260c0835260e0830167ffffffffffffffff948482108683111761044257818852845190206101008501927f19010000000000000000000000000000000000000000000000000000000000008452610102860152610122850152604281526101608401948186109086111761042f57848752519020835261018082015260a4356101a082015260c4356101c0909101528780528490889060809060015afa1561042557865116968715158061041c575b156103db5786977f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259596975283528087208688528352818188205551908152a380f35b83606492519162461bcd60e51b8352820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152fd5b50848814610398565b81513d88823e3d90fd5b60248c60418f634e487b7160e01b835252fd5b5060248c60418f634e487b7160e01b835252fd5b606488602084519162461bcd60e51b8352820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152fd5b8680fd5b8382346101e15760603660031901126101e15782359067ffffffffffffffff90818311610751573660238401121561075157828501359082821161074d5760059260248360051b86010194368611610499576104f761104a565b9360443592600954460361073f576001600160a01b0384961697888a52602097600b895260ff878c20541661071757898b52600b8952868b2092600193600160ff198254161790558751908a8201908c8252888a84015289835260608301918383108284111761070357828b5283519020608084019081528c83529260a001908111828210176106ee5789525190206007549590948a91906106a6575b50505050500361067e57956105af96600a5497888092611275565b60085480911161066b575b5050821561064457506105f0827f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4959697611275565b600a556105ff82600254611275565b6002558486526003835280862082815401905584867fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef858451868152a351908152a280f35b90517fb4f1abd2000000000000000000000000000000000000000000000000000000008152fd5b610676929450611060565b9186886105ba565b8682517f09bde339000000000000000000000000000000000000000000000000000000008152fd5b8493929150602401935b6106bc575b8990610594565b9091929389853591828111841b90815218528880888d20950193838510156106e85780939291506106b0565b506106b5565b505060248c60418f634e487b7160e01b835252fd5b8f8f6041602492634e487b7160e01b835252fd5b8b87517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b8985516282b42960e81b8152fd5b8480fd5b8380fd5b8382346101e15760203660031901126101e15760ff816020936001600160a01b0361077e61102f565b168152600b855220541690519015158152f35b8382346101e157806003193601126101e1576020916107ae61102f565b826001600160a01b0360243592338552600387528285206107d0858254611060565b90551692838152600386522081815401905582519081527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef843392a35160018152f35b5082346101bf57806003193601126101bf5781519080600180549061083782610f74565b80865292602092600181169081156108c95750600114610871575b61086d868861086382890383610fae565b5191829182610fe6565b0390f35b9350600184527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8385106108b6575050505081016020016108638261086d86610852565b8054868601840152938201938101610899565b905061086d9795508693506020925061086394915060ff191682840152151560051b820101929486610852565b8382346101e157816003193601126101e1576020906001600160a01b03600654169051908152f35b8382346101e15760203660031901126101e157806020926001600160a01b0361094561102f565b1681526005845220549051908152f35b8382346101e15760203660031901126101e157806020926001600160a01b0361097c61102f565b1681526003845220549051908152f35b8382346101e157816003193601126101e157602090600a549051908152f35b9091503461022f578160031936011261022f576109c661102f565b9160095446036109f757836109f4846109eb6001600160a01b0360065416331461122a565b60243590611282565b80f35b516282b42960e81b8152fd5b5082346101bf57806003193601126101bf5781519080600c5490610a2682610f74565b808552916020916001918281169081156108c95750600114610a535761086d868861086382890383610fae565b9350600c84527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c75b838510610a98575050505081016020016108638261086d86610852565b8054868601840152938201938101610a7b565b8382346101e157816003193601126101e157602090610ac8611083565b9051908152f35b8382346101e157816003193601126101e1576020905160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8382346101e157816003193601126101e1576020906007549051908152f35b91503461022f578060031936011261022f57610b4661102f565b602435927342000000000000000000000000000000000000283303610be857506001600160a01b0316908184526003602052808420610b86848254611060565b9055826002540360025583827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60208451878152a3519182527fb90795a66650155983e242cac3e1ac1a4dc26f8ed2987f3ce416a34e00111fd460203393a380f35b82516282b42960e81b8152fd5b9083346101bf5760603660031901126101bf57610c1061102f565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef610c3961104a565b94604435856001600160a01b0380951694858752602098848a958652838920338a52865283892054856000198203610ca3575b50505086885260038552828820610c84858254611060565b9055169586815260038452208181540190558551908152a35160018152f35b610cac91611060565b90888a528652838920338a528652838920558a8085610c6c565b9091503461022f578160031936011261022f57610ce161102f565b91602435917342000000000000000000000000000000000000283303610d435750610d0c8284611282565b519081527fde22baff038e3a3e08407cbdf617deed74e869a7ba517df611e33131c6e6ea0460206001600160a01b0333941692a380f35b90516282b42960e81b8152fd5b8382346101e157816003193601126101e1576020906002549051908152f35b8382346101e157816003193601126101e1576020906009549051908152f35b9091503461022f578160031936011261022f57602092610dac61102f565b918360243592839233825287526001600160a01b038282209516948582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b5082346101bf57806003193601126101bf5781519080805490610e2182610f74565b808552916020916001918281169081156108c95750600114610e4e5761086d868861086382890383610fae565b80809550527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b838510610e92575050505081016020016108638261086d86610852565b8054868601840152938201938101610e75565b84913461022f57602036600319011261022f57357fffffffff00000000000000000000000000000000000000000000000000000000811680910361022f57602092507f33331994000000000000000000000000000000000000000000000000000000008114908115610f4a575b8115610f20575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483610f19565b7f36372b070000000000000000000000000000000000000000000000000000000081149150610f12565b90600182811c92168015610fa4575b6020831014610f8e57565b634e487b7160e01b600052602260045260246000fd5b91607f1691610f83565b90601f8019910116810190811067ffffffffffffffff821117610fd057604052565b634e487b7160e01b600052604160045260246000fd5b6020808252825181830181905290939260005b82811061101b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610ff9565b600435906001600160a01b038216820361104557565b600080fd5b602435906001600160a01b038216820361104557565b9190820391821161106d57565b634e487b7160e01b600052601160045260246000fd5b6000467f0000000000000000000000000000000000000000000000000000000000000000036110d157507f000000000000000000000000000000000000000000000000000000000000000090565b604051815482916110e182610f74565b80825281602094858201946001908760018216918260001461120c5750506001146111b3575b5061111492500382610fae565b51902091604051918201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f845260408301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a083015260a0825260c082019082821067ffffffffffffffff83111761119f575060405251902090565b80634e487b7160e01b602492526041600452fd5b87805286915087907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8583106111f4575050611114935082010138611107565b805483880185015286945088939092019181016111dd565b60ff1916885261111495151560051b85010192503891506111079050565b1561123157565b606460405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b9190820180921161106d57565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206001600160a01b036000936112bc86600254611275565b60025516938484526003825260408420818154019055604051908152a356fea2646970667358221220b138346dce953fd161a69cf876bb0f9043b87ef5bdede027dcce7fede93019ad64736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001408a4b5642fe18c981c908be8684324aa29577ba9259aecd8f1f5a6c30f3cb4b1c0000000000000000000000000000000000000000000069e10de76676d08000000000000000000000000000000000000000000000000000000000000000000082000000000000000000000000000000000000000000000000000000000000000758204c41594552000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006584c415945520000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006868747470733a2f2f6c61756e636865722e7261696e626f772e6d652f76312f746f6b656e732f307864373064653338353661393836386261636663633232333461653163373139616431393065636464313535333631323132623166623262396536633132616663000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040908082526004918236101561001757600080fd5b600092833560e01c92836301ffc9a714610ea55750826306fdde0314610dff578263095ea7b314610d8e5782630d788c3614610d6f57826318160ddd14610d5057826318bf507714610cc657826323b872dd14610bf55782632b8c49e314610b2c5782632eb4a7ab14610b0d578263313ce56714610acf5782633644e51514610aab5782633c130d9014610a0357826340c10f19146109ab578263601e26031461098c57826370a08231146109555782637ecebe001461091e5782638da5cb5b146108f657826395d89b4114610813578263a9059cbb14610791578263c884ef8314610755578263ca21b1771461049d578263d505accf14610233578263dd62ed3e146101e557508163f236ceb4146101c2575063f2fde38b1461013a57600080fd5b346101bf5760203660031901126101bf577fffffffffffffffffffffffff000000000000000000000000000000000000000061017461102f565b600654906001600160a01b039061018e828416331461122a565b169182911617600655337f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b80fd5b9050346101e157816003193601126101e1576020906008549051908152f35b5080fd5b9091503461022f578160031936011261022f57602092829161020561102f565b61020d61104a565b916001600160a01b038092168452865283832091168252845220549051908152f35b8280fd5b8382346101e15760e03660031901126101e15761024e61102f565b9061025761104a565b91604435606435926084359260ff8416809403610499574285106104565761027d611083565b956001600160a01b038092169586895260209560058752848a209889549960018b01905585519285898501957f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c987528b89870152169a8b606086015288608086015260a085015260c084015260c0835260e0830167ffffffffffffffff948482108683111761044257818852845190206101008501927f19010000000000000000000000000000000000000000000000000000000000008452610102860152610122850152604281526101608401948186109086111761042f57848752519020835261018082015260a4356101a082015260c4356101c0909101528780528490889060809060015afa1561042557865116968715158061041c575b156103db5786977f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259596975283528087208688528352818188205551908152a380f35b83606492519162461bcd60e51b8352820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152fd5b50848814610398565b81513d88823e3d90fd5b60248c60418f634e487b7160e01b835252fd5b5060248c60418f634e487b7160e01b835252fd5b606488602084519162461bcd60e51b8352820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152fd5b8680fd5b8382346101e15760603660031901126101e15782359067ffffffffffffffff90818311610751573660238401121561075157828501359082821161074d5760059260248360051b86010194368611610499576104f761104a565b9360443592600954460361073f576001600160a01b0384961697888a52602097600b895260ff878c20541661071757898b52600b8952868b2092600193600160ff198254161790558751908a8201908c8252888a84015289835260608301918383108284111761070357828b5283519020608084019081528c83529260a001908111828210176106ee5789525190206007549590948a91906106a6575b50505050500361067e57956105af96600a5497888092611275565b60085480911161066b575b5050821561064457506105f0827f47cee97cb7acd717b3c0aa1435d004cd5b3c8c57d70dbceb4e4458bbd60e39d4959697611275565b600a556105ff82600254611275565b6002558486526003835280862082815401905584867fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef858451868152a351908152a280f35b90517fb4f1abd2000000000000000000000000000000000000000000000000000000008152fd5b610676929450611060565b9186886105ba565b8682517f09bde339000000000000000000000000000000000000000000000000000000008152fd5b8493929150602401935b6106bc575b8990610594565b9091929389853591828111841b90815218528880888d20950193838510156106e85780939291506106b0565b506106b5565b505060248c60418f634e487b7160e01b835252fd5b8f8f6041602492634e487b7160e01b835252fd5b8b87517f646cf558000000000000000000000000000000000000000000000000000000008152fd5b8985516282b42960e81b8152fd5b8480fd5b8380fd5b8382346101e15760203660031901126101e15760ff816020936001600160a01b0361077e61102f565b168152600b855220541690519015158152f35b8382346101e157806003193601126101e1576020916107ae61102f565b826001600160a01b0360243592338552600387528285206107d0858254611060565b90551692838152600386522081815401905582519081527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef843392a35160018152f35b5082346101bf57806003193601126101bf5781519080600180549061083782610f74565b80865292602092600181169081156108c95750600114610871575b61086d868861086382890383610fae565b5191829182610fe6565b0390f35b9350600184527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf65b8385106108b6575050505081016020016108638261086d86610852565b8054868601840152938201938101610899565b905061086d9795508693506020925061086394915060ff191682840152151560051b820101929486610852565b8382346101e157816003193601126101e1576020906001600160a01b03600654169051908152f35b8382346101e15760203660031901126101e157806020926001600160a01b0361094561102f565b1681526005845220549051908152f35b8382346101e15760203660031901126101e157806020926001600160a01b0361097c61102f565b1681526003845220549051908152f35b8382346101e157816003193601126101e157602090600a549051908152f35b9091503461022f578160031936011261022f576109c661102f565b9160095446036109f757836109f4846109eb6001600160a01b0360065416331461122a565b60243590611282565b80f35b516282b42960e81b8152fd5b5082346101bf57806003193601126101bf5781519080600c5490610a2682610f74565b808552916020916001918281169081156108c95750600114610a535761086d868861086382890383610fae565b9350600c84527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c75b838510610a98575050505081016020016108638261086d86610852565b8054868601840152938201938101610a7b565b8382346101e157816003193601126101e157602090610ac8611083565b9051908152f35b8382346101e157816003193601126101e1576020905160ff7f0000000000000000000000000000000000000000000000000000000000000012168152f35b8382346101e157816003193601126101e1576020906007549051908152f35b91503461022f578060031936011261022f57610b4661102f565b602435927342000000000000000000000000000000000000283303610be857506001600160a01b0316908184526003602052808420610b86848254611060565b9055826002540360025583827fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60208451878152a3519182527fb90795a66650155983e242cac3e1ac1a4dc26f8ed2987f3ce416a34e00111fd460203393a380f35b82516282b42960e81b8152fd5b9083346101bf5760603660031901126101bf57610c1061102f565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef610c3961104a565b94604435856001600160a01b0380951694858752602098848a958652838920338a52865283892054856000198203610ca3575b50505086885260038552828820610c84858254611060565b9055169586815260038452208181540190558551908152a35160018152f35b610cac91611060565b90888a528652838920338a528652838920558a8085610c6c565b9091503461022f578160031936011261022f57610ce161102f565b91602435917342000000000000000000000000000000000000283303610d435750610d0c8284611282565b519081527fde22baff038e3a3e08407cbdf617deed74e869a7ba517df611e33131c6e6ea0460206001600160a01b0333941692a380f35b90516282b42960e81b8152fd5b8382346101e157816003193601126101e1576020906002549051908152f35b8382346101e157816003193601126101e1576020906009549051908152f35b9091503461022f578160031936011261022f57602092610dac61102f565b918360243592839233825287526001600160a01b038282209516948582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b5082346101bf57806003193601126101bf5781519080805490610e2182610f74565b808552916020916001918281169081156108c95750600114610e4e5761086d868861086382890383610fae565b80809550527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b838510610e92575050505081016020016108638261086d86610852565b8054868601840152938201938101610e75565b84913461022f57602036600319011261022f57357fffffffff00000000000000000000000000000000000000000000000000000000811680910361022f57602092507f33331994000000000000000000000000000000000000000000000000000000008114908115610f4a575b8115610f20575b5015158152f35b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501483610f19565b7f36372b070000000000000000000000000000000000000000000000000000000081149150610f12565b90600182811c92168015610fa4575b6020831014610f8e57565b634e487b7160e01b600052602260045260246000fd5b91607f1691610f83565b90601f8019910116810190811067ffffffffffffffff821117610fd057604052565b634e487b7160e01b600052604160045260246000fd5b6020808252825181830181905290939260005b82811061101b57505060409293506000838284010152601f8019910116010190565b818101860151848201604001528501610ff9565b600435906001600160a01b038216820361104557565b600080fd5b602435906001600160a01b038216820361104557565b9190820391821161106d57565b634e487b7160e01b600052601160045260246000fd5b6000467f0000000000000000000000000000000000000000000000000000000000000082036110d157507fd73b44c68a91f09a8ddb7153441390c6db7a50a83b8f76f242591df8eb20ffbb90565b604051815482916110e182610f74565b80825281602094858201946001908760018216918260001461120c5750506001146111b3575b5061111492500382610fae565b51902091604051918201927f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f845260408301527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a083015260a0825260c082019082821067ffffffffffffffff83111761119f575060405251902090565b80634e487b7160e01b602492526041600452fd5b87805286915087907f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8583106111f4575050611114935082010138611107565b805483880185015286945088939092019181016111dd565b60ff1916885261111495151560051b85010192503891506111079050565b1561123157565b606460405162461bcd60e51b815260206004820152600c60248201527f554e415554484f52495a454400000000000000000000000000000000000000006044820152fd5b9190820180921161106d57565b7fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206001600160a01b036000936112bc86600254611275565b60025516938484526003825260408420818154019055604051908152a356fea2646970667358221220b138346dce953fd161a69cf876bb0f9043b87ef5bdede027dcce7fede93019ad64736f6c63430008190033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.