ETH Price: $2,936.82 (+4.64%)
 
Transaction Hash
Method
Block
From
To
Claim210989052024-11-02 8:55:596 days ago1730537759IN
0x414CbB5c...C64C10c29
0 ETH0.000347334.57914601
Claim209863442024-10-17 16:01:1121 days ago1729180871IN
0x414CbB5c...C64C10c29
0 ETH0.0012963822.95259834
Claim209015962024-10-05 20:01:5933 days ago1728158519IN
0x414CbB5c...C64C10c29
0 ETH0.000324124.4236857
Claim208195182024-09-24 9:20:1145 days ago1727169611IN
0x414CbB5c...C64C10c29
0 ETH0.0018881125.89185227
Claim207785332024-09-18 16:00:3550 days ago1726675235IN
0x414CbB5c...C64C10c29
0 ETH0.0012441516.4
Claim207420462024-09-13 13:39:1155 days ago1726234751IN
0x414CbB5c...C64C10c29
0 ETH0.000220743
Claim206963522024-09-07 4:32:3562 days ago1725683555IN
0x414CbB5c...C64C10c29
0 ETH0.0000611.09258777
Claim206867812024-09-05 20:29:1163 days ago1725568151IN
0x414CbB5c...C64C10c29
0 ETH0.000417877.48254433
Claim206500512024-08-31 17:29:4768 days ago1725125387IN
0x414CbB5c...C64C10c29
0 ETH0.000176052.32219928
Claim206426272024-08-30 16:36:2369 days ago1725035783IN
0x414CbB5c...C64C10c29
0 ETH0.000212473.76189147
Claim205466802024-08-17 6:53:3583 days ago1723877615IN
0x414CbB5c...C64C10c29
0 ETH0.000065940.9
Claim205153922024-08-12 22:02:2387 days ago1723500143IN
0x414CbB5c...C64C10c29
0 ETH0.000151672
Claim204083612024-07-28 23:32:35102 days ago1722209555IN
0x414CbB5c...C64C10c29
0 ETH0.000081241.07122038
Claim202993002024-07-13 18:14:11117 days ago1720894451IN
0x414CbB5c...C64C10c29
0 ETH0.000180282.46057977
Claim201852832024-06-27 20:02:11133 days ago1719518531IN
0x414CbB5c...C64C10c29
0 ETH0.000523377.11405194
Claim201852802024-06-27 20:01:35133 days ago1719518495IN
0x414CbB5c...C64C10c29
0 ETH0.000543077.15856609
Claim201692342024-06-25 14:16:23135 days ago1719324983IN
0x414CbB5c...C64C10c29
0 ETH0.000478258.17729141
Claim201503692024-06-22 22:58:23138 days ago1719097103IN
0x414CbB5c...C64C10c29
0 ETH0.000099621.81413808
Claim198129432024-05-06 18:51:23185 days ago1715021483IN
0x414CbB5c...C64C10c29
0 ETH0.000312955.35314332
Claim197818572024-05-02 10:31:35190 days ago1714645895IN
0x414CbB5c...C64C10c29
0 ETH0.000507166.68524852
Claim197102732024-04-22 10:14:59200 days ago1713780899IN
0x414CbB5c...C64C10c29
0 ETH0.000747019.84694969
Claim196605572024-04-15 11:17:35207 days ago1713179855IN
0x414CbB5c...C64C10c29
0 ETH0.0008472115
Claim196588762024-04-15 5:37:11207 days ago1713159431IN
0x414CbB5c...C64C10c29
0 ETH0.000694879.48226621
Claim195760562024-04-03 15:11:59218 days ago1712157119IN
0x414CbB5c...C64C10c29
0 ETH0.0035576248.34983998
Claim195371732024-03-29 4:06:23224 days ago1711685183IN
0x414CbB5c...C64C10c29
0 ETH0.0015075520.4950682
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Merkle

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-10-18
*/

// SPDX-License-Identifier: MIT
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);
    }
}

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

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
    /*//////////////////////////////////////////////////////////////
                    SIMPLIFIED FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    uint256 internal constant MAX_UINT256 = 2**256 - 1;

    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.

    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
    }

    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
    }

    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
    }

    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
    }

    /*//////////////////////////////////////////////////////////////
                    LOW LEVEL FIXED POINT OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function mulDivDown(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // Divide x * y by the denominator.
            z := div(mul(x, y), denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))
            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {
                revert(0, 0)
            }

            // If x * y modulo the denominator is strictly greater than 0,
            // 1 is added to round up the division of x * y by the denominator.
            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                    // 0 ** 0 = 1
                    z := scalar
                }
                default {
                    // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                    // If n is even, store scalar in z for now.
                    z := scalar
                }
                default {
                    // If n is odd, store x in z for now.
                    z := x
                }

                // Shifting right by 1 is like dividing by 2.
                let half := shr(1, scalar)

                for {
                    // Shift n right by 1 before looping to halve it.
                    n := shr(1, n)
                } n {
                    // Shift n right by 1 each iteration to halve it.
                    n := shr(1, n)
                } {
                    // Revert immediately if x ** 2 would overflow.
                    // Equivalent to iszero(eq(div(xx, x), x)) here.
                    if shr(128, x) {
                        revert(0, 0)
                    }

                    // Store x squared.
                    let xx := mul(x, x)

                    // Round to the nearest number.
                    let xxRound := add(xx, half)

                    // Revert if xx + half overflowed.
                    if lt(xxRound, xx) {
                        revert(0, 0)
                    }

                    // Set x to scaled xxRound.
                    x := div(xxRound, scalar)

                    // If n is even:
                    if mod(n, 2) {
                        // Compute z * x.
                        let zx := mul(z, x)

                        // If z * x overflowed:
                        if iszero(eq(div(zx, x), z)) {
                            // Revert if x is non-zero.
                            if iszero(iszero(x)) {
                                revert(0, 0)
                            }
                        }

                        // Round to the nearest number.
                        let zxRound := add(zx, half)

                        // Revert if zx + half overflowed.
                        if lt(zxRound, zx) {
                            revert(0, 0)
                        }

                        // Return properly scaled zxRound.
                        z := div(zxRound, scalar)
                    }
                }
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                        GENERAL NUMBER UTILITIES
    //////////////////////////////////////////////////////////////*/

    function sqrt(uint256 x) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            let y := x // We start y at x, which will help us make our initial estimate.

            z := 181 // The "correct" value is 1, but this saves a multiplication later.

            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad
            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.

            // We check y >= 2^(k + 8) but shift right by k bits
            // each branch to ensure that if x >= 256, then y >= 256.
            if iszero(lt(y, 0x10000000000000000000000000000000000)) {
                y := shr(128, y)
                z := shl(64, z)
            }
            if iszero(lt(y, 0x1000000000000000000)) {
                y := shr(64, y)
                z := shl(32, z)
            }
            if iszero(lt(y, 0x10000000000)) {
                y := shr(32, y)
                z := shl(16, z)
            }
            if iszero(lt(y, 0x1000000)) {
                y := shr(16, y)
                z := shl(8, z)
            }

            // Goal was to get z*z*y within a small factor of x. More iterations could
            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).
            // We ensured y >= 256 so that the relative difference between y and y+1 is small.
            // That's not possible if x < 256 but we can just verify those cases exhaustively.

            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.
            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.
            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.

            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range
            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.

            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate
            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.

            // There is no overflow risk here since y < 2^136 after the first branch above.
            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.

            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))
            z := shr(1, add(z, div(x, z)))

            // If x+1 is a perfect square, the Babylonian method cycles between
            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.
            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.
            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.
            z := sub(z, lt(div(x, z), z))
        }
    }

    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Mod x by y. Note this will return
            // 0 instead of reverting if y is zero.
            z := mod(x, y)
        }
    }

    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {
        /// @solidity memory-safe-assembly
        assembly {
            // Divide x by y. Note this will return
            // 0 instead of reverting if y is zero.
            r := div(x, y)
        }
    }

    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {
        /// @solidity memory-safe-assembly
        assembly {
            // Add 1 to x * y if x % y > 0. Note this will
            // return 0 instead of reverting if y is zero.
            z := add(gt(mod(x, y), 0), div(x, y))
        }
    }
}

/// @notice Gas optimized merkle proof verification library.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
library MerkleProofLib {
    function verify(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool isValid) {
        /// @solidity memory-safe-assembly
        assembly {
            if proof.length {
                // Left shifting by 5 is like multiplying by 32.
                let end := add(proof.offset, shl(5, proof.length))

                // Initialize offset to the offset of the proof in calldata.
                let offset := proof.offset

                // Iterate over proof elements to compute root hash.
                // prettier-ignore
                for {} 1 {} {
                    // Slot where the leaf should be put in scratch space. If
                    // leaf > calldataload(offset): slot 32, otherwise: slot 0.
                    let leafSlot := shl(5, gt(leaf, calldataload(offset)))

                    // Store elements to hash contiguously in scratch space.
                    // The xor puts calldataload(offset) in whichever slot leaf
                    // is not occupying, so 0 if leafSlot is 32, and 32 otherwise.
                    mstore(leafSlot, leaf)
                    mstore(xor(leafSlot, 32), calldataload(offset))

                    // Reuse leaf to store the hash to reduce stack operations.
                    leaf := keccak256(0, 64) // Hash both slots of scratch space.

                    offset := add(offset, 32) // Shift 1 word per cycle.

                    // prettier-ignore
                    if iszero(lt(offset, end)) { break }
                }
            }

            isValid := eq(leaf, root) // The proof is valid if the roots match.
        }
    }
}

contract Merkle is Owned {
  using FixedPointMathLib for uint256;
  using SafeTransferLib for ERC20;

  struct claimParam {
      address token;
      uint256 index;
      uint256 amount;
      bytes32[] merkleProof;
  }

  // environment variables for updateable merkle
  mapping(address => bytes32) public merkleRoot;
  mapping(address => uint256) public update;

  // This is a packed array of booleans.
  mapping(address => mapping(uint256 => mapping(uint256 => uint256))) private claimedBitMap;

  constructor(address _owner) Owned(_owner){}

  function isClaimed(address token, uint256 index) public view returns (bool) {
    uint256 claimedWordIndex = index / 256;
    uint256 claimedBitIndex = index % 256;
    uint256 claimedWord = claimedBitMap[token][update[token]][claimedWordIndex];
    uint256 mask = (1 << claimedBitIndex);
    return claimedWord & mask == mask;
  }

  function _setClaimed(address token, uint256 index) private {
    uint256 claimedWordIndex = index / 256;
    uint256 claimedBitIndex = index % 256;
    claimedBitMap[token][update[token]][claimedWordIndex] = claimedBitMap[token][update[token]][claimedWordIndex] | (1 << claimedBitIndex);
  }

  function claim(address token, uint256 index, address account, uint256 amount, bytes32[] calldata merkleProof) public {
    require(merkleRoot[token] != 0, 'frozen');
    require(!isClaimed(token, index), 'Drop already claimed.');

    // Verify the merkle proof.
    bytes32 node = keccak256(abi.encodePacked(index, account, amount));
    require(MerkleProofLib.verify(merkleProof, merkleRoot[token], node), 'Invalid proof.');

    _setClaimed(token, index);
    ERC20(token).safeTransfer(account, amount);

    emit Claimed(token, index, amount, account, update[token]);
  }

  function claimMulti(address account, claimParam[] calldata claims) external {
    for(uint256 i=0;i<claims.length;++i) {
      claim(claims[i].token, claims[i].index, account, claims[i].amount, claims[i].merkleProof);
    }
  }

  // MULTI SIG FUNCTIONS //
  function freeze(address token) public onlyOwner {
    require(merkleRoot[token] != 0, "Already frozen");

    // Set the new merkle root
    merkleRoot[token] = 0;

    emit Frozen(token, update[token]);
  }

  function multiFreeze(address[] calldata tokens) public onlyOwner {
    uint256 length = tokens.length;
    uint256 i = 0;
    for(; i < length; ) {
      freeze(tokens[i]);
      unchecked {
        ++i;
      }
    }
  }

  function updateMerkleRoot(address token, bytes32 _merkleRoot) public onlyOwner {
    require(merkleRoot[token] == 0, "Not frozen");

    // Increment the update (simulates the clearing of the claimedBitMap)
    update[token] += 1;
    // Set the new merkle root
    merkleRoot[token] = _merkleRoot;

    emit MerkleRootUpdated(token, _merkleRoot, update[token]);
  }

  function multiUpdateMerkleRoot(address[] calldata tokens, bytes32[] calldata _merkleRoots) public onlyOwner {
    require(tokens.length == _merkleRoots.length, "!Length");

    uint256 length = tokens.length;
    uint256 i = 0;

    for(; i < length; ) {
      updateMerkleRoot(tokens[i], _merkleRoots[i]);
      unchecked {
        ++i;
      }
    }
  }

  // EVENTS //
  event Claimed(address indexed token, uint256 index, uint256 amount, address indexed account, uint256 indexed update);
  event MerkleRootUpdated(address indexed token, bytes32 indexed merkleRoot, uint256 indexed update);
  event Frozen(address indexed token, uint256 indexed update);
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"uint256","name":"update","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"uint256","name":"update","type":"uint256"}],"name":"Frozen","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"indexed":true,"internalType":"uint256","name":"update","type":"uint256"}],"name":"MerkleRootUpdated","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"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"internalType":"struct Merkle.claimParam[]","name":"claims","type":"tuple[]"}],"name":"claimMulti","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"freeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"multiFreeze","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"bytes32[]","name":"_merkleRoots","type":"bytes32[]"}],"name":"multiUpdateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"update","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"updateMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50604051610dc5380380610dc583398101604081905261002f9161007e565b600080546001600160a01b0319166001600160a01b03831690811782556040518392907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350506100ae565b60006020828403121561009057600080fd5b81516001600160a01b03811681146100a757600080fd5b9392505050565b610d08806100bd6000396000f3fe608060405234801561001057600080fd5b50600436106100a95760003560e01c80638d1fdf2f116100715780638d1fdf2f1461013f5780638da5cb5b14610152578063de1be3c21461017d578063e211158614610190578063e786818e146101b0578063f2fde38b146101c357600080fd5b806312d18ed6146100ae5780631a7ae0b6146100c35780631c1b8772146100d657806320ce64de14610109578063562beba81461011c575b600080fd5b6100c16100bc3660046109e7565b6101d6565b005b6100c16100d1366004610a5f565b6103a3565b6100f66100e4366004610acb565b60026020526000908152604090205481565b6040519081526020015b60405180910390f35b6100c1610117366004610aed565b61046a565b61012f61012a366004610b40565b610543565b6040519015158152602001610100565b6100c161014d366004610acb565b6105ac565b600054610165906001600160a01b031681565b6040516001600160a01b039091168152602001610100565b6100c161018b366004610b6a565b610680565b6100f661019e366004610acb565b60016020526000908152604090205481565b6100c16101be366004610b40565b6106e8565b6100c16101d1366004610acb565b6107ea565b6001600160a01b038616600090815260016020526040812054900361022b5760405162461bcd60e51b8152602060048201526006602482015265333937bd32b760d11b60448201526064015b60405180910390fd5b6102358686610543565b1561027a5760405162461bcd60e51b8152602060048201526015602482015274223937b81030b63932b0b23c9031b630b4b6b2b21760591b6044820152606401610222565b604080516020808201889052606087901b6bffffffffffffffffffffffff191682840152605480830187905283518084039091018152607490920183528151918101919091206001600160a01b03891660009081526001909252919020546102e690849084908461085f565b6103235760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b210383937b7b31760911b6044820152606401610222565b61032d8787610899565b6103416001600160a01b03881686866108fe565b6001600160a01b038781166000818152600260209081526040918290205482518b815291820189905293891692917f4766921f5c59646d22d7d266a29164c8e9623684d8dfdbd931731dfdca025238910160405180910390a450505050505050565b6000546001600160a01b031633146103cd5760405162461bcd60e51b815260040161022290610bac565b8281146104065760405162461bcd60e51b815260206004820152600760248201526604298cadccee8d60cb1b6044820152606401610222565b8260005b818110156104625761045a86868381811061042757610427610bd2565b905060200201602081019061043c9190610acb565b85858481811061044e5761044e610bd2565b905060200201356106e8565b60010161040a565b505050505050565b60005b8181101561053d5761052d83838381811061048a5761048a610bd2565b905060200281019061049c9190610be8565b6104aa906020810190610acb565b8484848181106104bc576104bc610bd2565b90506020028101906104ce9190610be8565b60200135868686868181106104e5576104e5610bd2565b90506020028101906104f79190610be8565b6040013587878781811061050d5761050d610bd2565b905060200281019061051f9190610be8565b6100bc906060810190610c08565b61053681610c68565b905061046d565b50505050565b60008061055261010084610c97565b9050600061056261010085610cab565b6001600160a01b03861660009081526003602090815260408083206002835281842054845282528083209583529490529290922054600190921b9182169091149150505b92915050565b6000546001600160a01b031633146105d65760405162461bcd60e51b815260040161022290610bac565b6001600160a01b038116600090815260016020526040812054900361062e5760405162461bcd60e51b815260206004820152600e60248201526d20b63932b0b23c90333937bd32b760911b6044820152606401610222565b6001600160a01b038116600081815260016020908152604080832083905560029091528082205490519092917f68e0d8c112165d0949ce87205b719ed7d98c7401866c34a159f7c67c6f5620e791a350565b6000546001600160a01b031633146106aa5760405162461bcd60e51b815260040161022290610bac565b8060005b8181101561053d576106e08484838181106106cb576106cb610bd2565b905060200201602081019061014d9190610acb565b6001016106ae565b6000546001600160a01b031633146107125760405162461bcd60e51b815260040161022290610bac565b6001600160a01b038216600090815260016020526040902054156107655760405162461bcd60e51b815260206004820152600a6024820152692737ba10333937bd32b760b11b6044820152606401610222565b6001600160a01b038216600090815260026020526040812080546001929061078e908490610cbf565b90915550506001600160a01b038216600081815260016020908152604080832085905560029091528082205490519092849290917fbdc375de8a677af383c6ee6f8b2027dbd231c3c47453ce81d1ce8f1bcdb722dc9190a45050565b6000546001600160a01b031633146108145760405162461bcd60e51b815260040161022290610bac565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60008315610891578360051b8501855b803580851160051b9485526020948518526040600020930181811061086f5750505b501492915050565b60006108a761010083610c97565b905060006108b761010084610cab565b6001600160a01b03949094166000908152600360209081526040808320600283528184205484528252808320948352939052919091208054600190941b9093179092555050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061053d5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610222565b80356001600160a01b038116811461099657600080fd5b919050565b60008083601f8401126109ad57600080fd5b50813567ffffffffffffffff8111156109c557600080fd5b6020830191508360208260051b85010111156109e057600080fd5b9250929050565b60008060008060008060a08789031215610a0057600080fd5b610a098761097f565b955060208701359450610a1e6040880161097f565b935060608701359250608087013567ffffffffffffffff811115610a4157600080fd5b610a4d89828a0161099b565b979a9699509497509295939492505050565b60008060008060408587031215610a7557600080fd5b843567ffffffffffffffff80821115610a8d57600080fd5b610a998883890161099b565b90965094506020870135915080821115610ab257600080fd5b50610abf8782880161099b565b95989497509550505050565b600060208284031215610add57600080fd5b610ae68261097f565b9392505050565b600080600060408486031215610b0257600080fd5b610b0b8461097f565b9250602084013567ffffffffffffffff811115610b2757600080fd5b610b338682870161099b565b9497909650939450505050565b60008060408385031215610b5357600080fd5b610b5c8361097f565b946020939093013593505050565b60008060208385031215610b7d57600080fd5b823567ffffffffffffffff811115610b9457600080fd5b610ba08582860161099b565b90969095509350505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610bfe57600080fd5b9190910192915050565b6000808335601e19843603018112610c1f57600080fd5b83018035915067ffffffffffffffff821115610c3a57600080fd5b6020019150600581901b36038213156109e057600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610c7a57610c7a610c52565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082610ca657610ca6610c81565b500490565b600082610cba57610cba610c81565b500690565b808201808211156105a6576105a6610c5256fea264697066735822122006eb1757ae857aeef1e90507e4d77b2652562d12ee7c58433f94e80f1241176a64736f6c63430008140033000000000000000000000000f930ebbd05ef8b25b1797b9b2109ddc9b0d43063

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106100a95760003560e01c80638d1fdf2f116100715780638d1fdf2f1461013f5780638da5cb5b14610152578063de1be3c21461017d578063e211158614610190578063e786818e146101b0578063f2fde38b146101c357600080fd5b806312d18ed6146100ae5780631a7ae0b6146100c35780631c1b8772146100d657806320ce64de14610109578063562beba81461011c575b600080fd5b6100c16100bc3660046109e7565b6101d6565b005b6100c16100d1366004610a5f565b6103a3565b6100f66100e4366004610acb565b60026020526000908152604090205481565b6040519081526020015b60405180910390f35b6100c1610117366004610aed565b61046a565b61012f61012a366004610b40565b610543565b6040519015158152602001610100565b6100c161014d366004610acb565b6105ac565b600054610165906001600160a01b031681565b6040516001600160a01b039091168152602001610100565b6100c161018b366004610b6a565b610680565b6100f661019e366004610acb565b60016020526000908152604090205481565b6100c16101be366004610b40565b6106e8565b6100c16101d1366004610acb565b6107ea565b6001600160a01b038616600090815260016020526040812054900361022b5760405162461bcd60e51b8152602060048201526006602482015265333937bd32b760d11b60448201526064015b60405180910390fd5b6102358686610543565b1561027a5760405162461bcd60e51b8152602060048201526015602482015274223937b81030b63932b0b23c9031b630b4b6b2b21760591b6044820152606401610222565b604080516020808201889052606087901b6bffffffffffffffffffffffff191682840152605480830187905283518084039091018152607490920183528151918101919091206001600160a01b03891660009081526001909252919020546102e690849084908461085f565b6103235760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b210383937b7b31760911b6044820152606401610222565b61032d8787610899565b6103416001600160a01b03881686866108fe565b6001600160a01b038781166000818152600260209081526040918290205482518b815291820189905293891692917f4766921f5c59646d22d7d266a29164c8e9623684d8dfdbd931731dfdca025238910160405180910390a450505050505050565b6000546001600160a01b031633146103cd5760405162461bcd60e51b815260040161022290610bac565b8281146104065760405162461bcd60e51b815260206004820152600760248201526604298cadccee8d60cb1b6044820152606401610222565b8260005b818110156104625761045a86868381811061042757610427610bd2565b905060200201602081019061043c9190610acb565b85858481811061044e5761044e610bd2565b905060200201356106e8565b60010161040a565b505050505050565b60005b8181101561053d5761052d83838381811061048a5761048a610bd2565b905060200281019061049c9190610be8565b6104aa906020810190610acb565b8484848181106104bc576104bc610bd2565b90506020028101906104ce9190610be8565b60200135868686868181106104e5576104e5610bd2565b90506020028101906104f79190610be8565b6040013587878781811061050d5761050d610bd2565b905060200281019061051f9190610be8565b6100bc906060810190610c08565b61053681610c68565b905061046d565b50505050565b60008061055261010084610c97565b9050600061056261010085610cab565b6001600160a01b03861660009081526003602090815260408083206002835281842054845282528083209583529490529290922054600190921b9182169091149150505b92915050565b6000546001600160a01b031633146105d65760405162461bcd60e51b815260040161022290610bac565b6001600160a01b038116600090815260016020526040812054900361062e5760405162461bcd60e51b815260206004820152600e60248201526d20b63932b0b23c90333937bd32b760911b6044820152606401610222565b6001600160a01b038116600081815260016020908152604080832083905560029091528082205490519092917f68e0d8c112165d0949ce87205b719ed7d98c7401866c34a159f7c67c6f5620e791a350565b6000546001600160a01b031633146106aa5760405162461bcd60e51b815260040161022290610bac565b8060005b8181101561053d576106e08484838181106106cb576106cb610bd2565b905060200201602081019061014d9190610acb565b6001016106ae565b6000546001600160a01b031633146107125760405162461bcd60e51b815260040161022290610bac565b6001600160a01b038216600090815260016020526040902054156107655760405162461bcd60e51b815260206004820152600a6024820152692737ba10333937bd32b760b11b6044820152606401610222565b6001600160a01b038216600090815260026020526040812080546001929061078e908490610cbf565b90915550506001600160a01b038216600081815260016020908152604080832085905560029091528082205490519092849290917fbdc375de8a677af383c6ee6f8b2027dbd231c3c47453ce81d1ce8f1bcdb722dc9190a45050565b6000546001600160a01b031633146108145760405162461bcd60e51b815260040161022290610bac565b600080546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b60008315610891578360051b8501855b803580851160051b9485526020948518526040600020930181811061086f5750505b501492915050565b60006108a761010083610c97565b905060006108b761010084610cab565b6001600160a01b03949094166000908152600360209081526040808320600283528184205484528252808320948352939052919091208054600190941b9093179092555050565b600060405163a9059cbb60e01b81526001600160a01b0384166004820152826024820152602060006044836000895af13d15601f3d116001600051141617169150508061053d5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610222565b80356001600160a01b038116811461099657600080fd5b919050565b60008083601f8401126109ad57600080fd5b50813567ffffffffffffffff8111156109c557600080fd5b6020830191508360208260051b85010111156109e057600080fd5b9250929050565b60008060008060008060a08789031215610a0057600080fd5b610a098761097f565b955060208701359450610a1e6040880161097f565b935060608701359250608087013567ffffffffffffffff811115610a4157600080fd5b610a4d89828a0161099b565b979a9699509497509295939492505050565b60008060008060408587031215610a7557600080fd5b843567ffffffffffffffff80821115610a8d57600080fd5b610a998883890161099b565b90965094506020870135915080821115610ab257600080fd5b50610abf8782880161099b565b95989497509550505050565b600060208284031215610add57600080fd5b610ae68261097f565b9392505050565b600080600060408486031215610b0257600080fd5b610b0b8461097f565b9250602084013567ffffffffffffffff811115610b2757600080fd5b610b338682870161099b565b9497909650939450505050565b60008060408385031215610b5357600080fd5b610b5c8361097f565b946020939093013593505050565b60008060208385031215610b7d57600080fd5b823567ffffffffffffffff811115610b9457600080fd5b610ba08582860161099b565b90969095509350505050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b60008235607e19833603018112610bfe57600080fd5b9190910192915050565b6000808335601e19843603018112610c1f57600080fd5b83018035915067ffffffffffffffff821115610c3a57600080fd5b6020019150600581901b36038213156109e057600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201610c7a57610c7a610c52565b5060010190565b634e487b7160e01b600052601260045260246000fd5b600082610ca657610ca6610c81565b500490565b600082610cba57610cba610c81565b500690565b808201808211156105a6576105a6610c5256fea264697066735822122006eb1757ae857aeef1e90507e4d77b2652562d12ee7c58433f94e80f1241176a64736f6c63430008140033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000f930ebbd05ef8b25b1797b9b2109ddc9b0d43063

-----Decoded View---------------
Arg [0] : _owner (address): 0xF930EBBd05eF8b25B1797b9b2109DDC9B0d43063

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000f930ebbd05ef8b25b1797b9b2109ddc9b0d43063


Deployed Bytecode Sourcemap

27071:3586:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28285:587;;;;;;:::i;:::-;;:::i;:::-;;29981:367;;;;;;:::i;:::-;;:::i;27406:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;2407:25:1;;;2395:2;2380:18;27406:41:0;;;;;;;;28878:231;;;;;;:::i;:::-;;:::i;27641:337::-;;;;;;:::i;:::-;;:::i;:::-;;;3412:14:1;;3405:22;3387:41;;3375:2;3360:18;27641:337:0;3247:187:1;29144:214:0;;;;;;:::i;:::-;;:::i;695:20::-;;;;;-1:-1:-1;;;;;695:20:0;;;;;;-1:-1:-1;;;;;3603:32:1;;;3585:51;;3573:2;3558:18;695:20:0;3439:203:1;29364:230:0;;;;;;:::i;:::-;;:::i;27356:45::-;;;;;;:::i;:::-;;;;;;;;;;;;;;29600:375;;;;;;:::i;:::-;;:::i;1339:165::-;;;;;;:::i;:::-;;:::i;28285:587::-;-1:-1:-1;;;;;28417:17:0;;;;;;:10;:17;;;;;;:22;;28409:41;;;;-1:-1:-1;;;28409:41:0;;4732:2:1;28409:41:0;;;4714:21:1;4771:1;4751:18;;;4744:29;-1:-1:-1;;;4789:18:1;;;4782:36;4835:18;;28409:41:0;;;;;;;;;28466:23;28476:5;28483;28466:9;:23::i;:::-;28465:24;28457:58;;;;-1:-1:-1;;;28457:58:0;;5066:2:1;28457:58:0;;;5048:21:1;5105:2;5085:18;;;5078:30;-1:-1:-1;;;5124:18:1;;;5117:51;5185:18;;28457:58:0;4864:345:1;28457:58:0;28582:40;;;;;;;5399:19:1;;;5456:2;5452:15;;;-1:-1:-1;;5448:53:1;5434:12;;;5427:75;5518:12;;;;5511:28;;;28582:40:0;;;;;;;;;;5555:12:1;;;;28582:40:0;;28572:51;;;;;;;;;-1:-1:-1;;;;;28673:17:0;;-1:-1:-1;28673:17:0;;;:10;:17;;;;;;;28638:59;;28660:11;;;;28572:51;28638:21;:59::i;:::-;28630:86;;;;-1:-1:-1;;;28630:86:0;;5780:2:1;28630:86:0;;;5762:21:1;5819:2;5799:18;;;5792:30;-1:-1:-1;;;5838:18:1;;;5831:44;5892:18;;28630:86:0;5578:338:1;28630:86:0;28725:25;28737:5;28744;28725:11;:25::i;:::-;28757:42;-1:-1:-1;;;;;28757:25:0;;28783:7;28792:6;28757:25;:42::i;:::-;-1:-1:-1;;;;;28852:13:0;;;;;;;:6;:13;;;;;;;;;;28813:53;;6095:25:1;;;6136:18;;;6129:34;;;28852:13:0;28813:53;;;28852:13;28813:53;;6068:18:1;28813:53:0;;;;;;;28402:470;28285:587;;;;;;:::o;29981:367::-;786:5;;-1:-1:-1;;;;;786:5:0;772:10;:19;764:44;;;;-1:-1:-1;;;764:44:0;;;;;;;:::i;:::-;30104:36;;::::1;30096:56;;;::::0;-1:-1:-1;;;30096:56:0;;6717:2:1;30096:56:0::1;::::0;::::1;6699:21:1::0;6756:1;6736:18;;;6729:29;-1:-1:-1;;;6774:18:1;;;6767:37;6821:18;;30096:56:0::1;6515:330:1::0;30096:56:0::1;30178:6:::0;30161:14:::1;30220:123;30230:6;30226:1;:10;30220:123;;;30249:44;30266:6;;30273:1;30266:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;30277:12;;30290:1;30277:15;;;;;;;:::i;:::-;;;;;;;30249:16;:44::i;:::-;30323:3;;30220:123;;;30089:259;;29981:367:::0;;;;:::o;28878:231::-;28965:9;28961:143;28977:15;;;28961:143;;;29007:89;29013:6;;29020:1;29013:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:15;;;;;;;:::i;:::-;29030:6;;29037:1;29030:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:15;;;29047:7;29056:6;;29063:1;29056:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:16;;;29074:6;;29081:1;29074:9;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;:21;;;;;;;:::i;29007:89::-;28993:3;;;:::i;:::-;;;28961:143;;;;28878:231;;;:::o;27641:337::-;27711:4;;27751:11;27759:3;27751:5;:11;:::i;:::-;27724:38;-1:-1:-1;27769:23:0;27795:11;27803:3;27795:5;:11;:::i;:::-;-1:-1:-1;;;;;27835:20:0;;27813:19;27835:20;;;:13;:20;;;;;;;;27856:6;:13;;;;;;27835:35;;;;;;;:53;;;;;;;;;;;27911:1;:20;;;27946:18;;;:26;;;;-1:-1:-1;;27641:337:0;;;;;:::o;29144:214::-;786:5;;-1:-1:-1;;;;;786:5:0;772:10;:19;764:44;;;;-1:-1:-1;;;764:44:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29207:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;:22;;29199:49:::1;;;::::0;-1:-1:-1;;;29199:49:0;;8712:2:1;29199:49:0::1;::::0;::::1;8694:21:1::0;8751:2;8731:18;;;8724:30;-1:-1:-1;;;8770:18:1;;;8763:44;8824:18;;29199:49:0::1;8510:338:1::0;29199:49:0::1;-1:-1:-1::0;;;;;29289:17:0;::::1;29309:1;29289:17:::0;;;:10:::1;:17;::::0;;;;;;;:21;;;29338:6:::1;:13:::0;;;;;;;29324:28;;29338:13;;29289:17;29324:28:::1;::::0;::::1;29144:214:::0;:::o;29364:230::-;786:5;;-1:-1:-1;;;;;786:5:0;772:10;:19;764:44;;;;-1:-1:-1;;;764:44:0;;;;;;;:::i;:::-;29453:6;29436:14:::1;29493:96;29503:6;29499:1;:10;29493:96;;;29522:17;29529:6;;29536:1;29529:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;29522:17::-;29569:3;;29493:96;;29600:375:::0;786:5;;-1:-1:-1;;;;;786:5:0;772:10;:19;764:44;;;;-1:-1:-1;;;764:44:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29694:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;:22;29686:45:::1;;;::::0;-1:-1:-1;;;29686:45:0;;9055:2:1;29686:45:0::1;::::0;::::1;9037:21:1::0;9094:2;9074:18;;;9067:30;-1:-1:-1;;;9113:18:1;;;9106:40;9163:18;;29686:45:0::1;8853:334:1::0;29686:45:0::1;-1:-1:-1::0;;;;;29815:13:0;::::1;;::::0;;;:6:::1;:13;::::0;;;;:18;;29832:1:::1;::::0;29815:13;:18:::1;::::0;29832:1;;29815:18:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;;;29872:17:0;::::1;;::::0;;;:10:::1;:17;::::0;;;;;;;:31;;;29955:6:::1;:13:::0;;;;;;;29917:52;;29955:13;;29892:11;;29872:17;;29917:52:::1;::::0;29872:17;29917:52:::1;29600:375:::0;;:::o;1339:165::-;786:5;;-1:-1:-1;;;;;786:5:0;772:10;:19;764:44;;;;-1:-1:-1;;;764:44:0;;;;;;;:::i;:::-;1420:5:::1;:16:::0;;-1:-1:-1;;;;;;1420:16:0::1;-1:-1:-1::0;;;;;1420:16:0;::::1;::::0;;::::1;::::0;;1454:42:::1;::::0;1420:16;;1475:10:::1;::::0;1454:42:::1;::::0;1420:5;1454:42:::1;1339:165:::0;:::o;25359:1705::-;25486:12;25582;25579:1384;;;25716:12;25713:1;25709:20;25695:12;25691:39;25842:12;25980:968;26207:20;;26198:30;;;26195:1;26191:38;26496:22;;;26561:2;26547:17;;;26540:47;26713:2;26710:1;26700:16;;26787:15;26903;;;25980:968;26893:36;25984:2;;25579:1384;-1:-1:-1;26990:14:0;;25359:1705;-1:-1:-1;;25359:1705:0:o;27984:295::-;28050:24;28077:11;28085:3;28077:5;:11;:::i;:::-;28050:38;-1:-1:-1;28095:23:0;28121:11;28129:3;28121:5;:11;:::i;:::-;-1:-1:-1;;;;;28195:20:0;;;;;;;;:13;:20;;;;;;;;28216:6;:13;;;;;;28195:35;;;;;;;:53;;;;;;;;;;;;28252:1;:20;;;28195:78;;;28139:134;;;-1:-1:-1;;27984:295:0:o;11523:1637::-;11640:12;11815:4;11809:11;-1:-1:-1;;;11941:17:0;11934:93;-1:-1:-1;;;;;12079:2:0;12075:51;12071:1;12052:17;12048:25;12041:86;12214:6;12209:2;12190:17;12186:26;12179:42;13076:2;13073:1;13069:2;13050:17;13047:1;13040:5;13033;13028:51;12592:16;12585:24;12579:2;12561:16;12558:24;12554:1;12550;12544:8;12541:15;12537:46;12534:76;12331:763;12320:774;;;13125:7;13117:35;;;;-1:-1:-1;;;13117:35:0;;9524:2:1;13117:35:0;;;9506:21:1;9563:2;9543:18;;;9536:30;-1:-1:-1;;;9582:18:1;;;9575:45;9637:18;;13117:35:0;9322:339:1;14:173;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:367::-;255:8;265:6;319:3;312:4;304:6;300:17;296:27;286:55;;337:1;334;327:12;286:55;-1:-1:-1;360:20:1;;403:18;392:30;;389:50;;;435:1;432;425:12;389:50;472:4;464:6;460:17;448:29;;532:3;525:4;515:6;512:1;508:14;500:6;496:27;492:38;489:47;486:67;;;549:1;546;539:12;486:67;192:367;;;;;:::o;564:723::-;686:6;694;702;710;718;726;779:3;767:9;758:7;754:23;750:33;747:53;;;796:1;793;786:12;747:53;819:29;838:9;819:29;:::i;:::-;809:39;;895:2;884:9;880:18;867:32;857:42;;918:38;952:2;941:9;937:18;918:38;:::i;:::-;908:48;;1003:2;992:9;988:18;975:32;965:42;;1058:3;1047:9;1043:19;1030:33;1086:18;1078:6;1075:30;1072:50;;;1118:1;1115;1108:12;1072:50;1157:70;1219:7;1210:6;1199:9;1195:22;1157:70;:::i;:::-;564:723;;;;-1:-1:-1;564:723:1;;-1:-1:-1;564:723:1;;1246:8;;564:723;-1:-1:-1;;;564:723:1:o;1292:773::-;1414:6;1422;1430;1438;1491:2;1479:9;1470:7;1466:23;1462:32;1459:52;;;1507:1;1504;1497:12;1459:52;1547:9;1534:23;1576:18;1617:2;1609:6;1606:14;1603:34;;;1633:1;1630;1623:12;1603:34;1672:70;1734:7;1725:6;1714:9;1710:22;1672:70;:::i;:::-;1761:8;;-1:-1:-1;1646:96:1;-1:-1:-1;1849:2:1;1834:18;;1821:32;;-1:-1:-1;1865:16:1;;;1862:36;;;1894:1;1891;1884:12;1862:36;;1933:72;1997:7;1986:8;1975:9;1971:24;1933:72;:::i;:::-;1292:773;;;;-1:-1:-1;2024:8:1;-1:-1:-1;;;;1292:773:1:o;2070:186::-;2129:6;2182:2;2170:9;2161:7;2157:23;2153:32;2150:52;;;2198:1;2195;2188:12;2150:52;2221:29;2240:9;2221:29;:::i;:::-;2211:39;2070:186;-1:-1:-1;;;2070:186:1:o;2443:540::-;2567:6;2575;2583;2636:2;2624:9;2615:7;2611:23;2607:32;2604:52;;;2652:1;2649;2642:12;2604:52;2675:29;2694:9;2675:29;:::i;:::-;2665:39;;2755:2;2744:9;2740:18;2727:32;2782:18;2774:6;2771:30;2768:50;;;2814:1;2811;2804:12;2768:50;2853:70;2915:7;2906:6;2895:9;2891:22;2853:70;:::i;:::-;2443:540;;2942:8;;-1:-1:-1;2827:96:1;;-1:-1:-1;;;;2443:540:1:o;2988:254::-;3056:6;3064;3117:2;3105:9;3096:7;3092:23;3088:32;3085:52;;;3133:1;3130;3123:12;3085:52;3156:29;3175:9;3156:29;:::i;:::-;3146:39;3232:2;3217:18;;;;3204:32;;-1:-1:-1;;;2988:254:1:o;3647:437::-;3733:6;3741;3794:2;3782:9;3773:7;3769:23;3765:32;3762:52;;;3810:1;3807;3800:12;3762:52;3850:9;3837:23;3883:18;3875:6;3872:30;3869:50;;;3915:1;3912;3905:12;3869:50;3954:70;4016:7;4007:6;3996:9;3992:22;3954:70;:::i;:::-;4043:8;;3928:96;;-1:-1:-1;3647:437:1;-1:-1:-1;;;;3647:437:1:o;6174:336::-;6376:2;6358:21;;;6415:2;6395:18;;;6388:30;-1:-1:-1;;;6449:2:1;6434:18;;6427:42;6501:2;6486:18;;6174:336::o;6850:127::-;6911:10;6906:3;6902:20;6899:1;6892:31;6942:4;6939:1;6932:15;6966:4;6963:1;6956:15;6982:327;7077:4;7135:11;7122:25;7229:3;7225:8;7214;7198:14;7194:29;7190:44;7170:18;7166:69;7156:97;;7249:1;7246;7239:12;7156:97;7270:33;;;;;6982:327;-1:-1:-1;;6982:327:1:o;7314:545::-;7407:4;7413:6;7473:11;7460:25;7567:2;7563:7;7552:8;7536:14;7532:29;7528:43;7508:18;7504:68;7494:96;;7586:1;7583;7576:12;7494:96;7613:33;;7665:20;;;-1:-1:-1;7708:18:1;7697:30;;7694:50;;;7740:1;7737;7730:12;7694:50;7773:4;7761:17;;-1:-1:-1;7824:1:1;7820:14;;;7804;7800:35;7790:46;;7787:66;;;7849:1;7846;7839:12;7864:127;7925:10;7920:3;7916:20;7913:1;7906:31;7956:4;7953:1;7946:15;7980:4;7977:1;7970:15;7996:135;8035:3;8056:17;;;8053:43;;8076:18;;:::i;:::-;-1:-1:-1;8123:1:1;8112:13;;7996:135::o;8136:127::-;8197:10;8192:3;8188:20;8185:1;8178:31;8228:4;8225:1;8218:15;8252:4;8249:1;8242:15;8268:120;8308:1;8334;8324:35;;8339:18;;:::i;:::-;-1:-1:-1;8373:9:1;;8268:120::o;8393:112::-;8425:1;8451;8441:35;;8456:18;;:::i;:::-;-1:-1:-1;8490:9:1;;8393:112::o;9192:125::-;9257:9;;;9278:10;;;9275:36;;;9291:18;;:::i

Swarm Source

ipfs://06eb1757ae857aeef1e90507e4d77b2652562d12ee7c58433f94e80f1241176a

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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  ]

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.