ETH Price: $2,474.87 (-1.93%)
Gas: 0.62 Gwei

Token

SideShift SideShift Token Vault (svXAI)
 

Overview

Max Total Supply

90,072,845.534413016597561641 svXAI

Holders

335

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
405.57338200679440532 svXAI

Value
$0.00
0x9a72a6ce8fb11af96b2b47241150a471ccf63632
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
SideShiftVault

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 9 : SideShiftVault.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {SafeCastLib} from '@rari-capital/solmate/src/utils/SafeCastLib.sol';
import {SafeTransferLib} from '@rari-capital/solmate/src/utils/SafeTransferLib.sol';
import {FixedPointMathLib} from '@rari-capital/solmate/src/utils/FixedPointMathLib.sol';
import {ERC4626} from '@rari-capital/solmate/src/mixins/ERC4626.sol';
import {ERC20} from '@rari-capital/solmate/src/tokens/ERC20.sol';
import '@openzeppelin/contracts/utils/cryptography/MerkleProof.sol';
import '@openzeppelin/contracts/access/Ownable.sol';

contract SideShiftVault is ERC4626, Ownable {
    using SafeCastLib for uint256;
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /// @notice the underlying token the vault accepts
    ERC20 public immutable UNDERLYING;

    /// @notice bool clarifying vault's have been initialized
    bool public contractInitialized;

    /// @notice Event emits when vault is initialized
    event ContractInitialization(address indexed user);

    /// @notice bool clarifying if shares have been minted for merkle claimees
    bool public merkleMinted;

    /// @notice The root hash of the Merkle tree - as it won't change made immutable
    bytes32 public immutable merkleRoot;

    /// @notice The number of shares in the vault not claimed from the merkle tree
    uint256 public merkleUnclaimed;

    /// @notice mapping for addresses in merkle that have claimed
    mapping(address => bool) public merkleClaimed;

    /// @notice Event emits when shares for address in merkle are minted
    event MerkleSharesMinted(address indexed user, uint256 shares);

    /// @notice Event emits when address in merkle claims shares
    event MerkleClaim(address indexed user, uint256 amount);

    /// Merkle root used as a param at deployment
    constructor(ERC20 _UNDERLYING, bytes32 _merkleRoot)
        ERC4626(
            _UNDERLYING,
            string(
                abi.encodePacked('SideShift ', _UNDERLYING.name(), ' Vault')
            ),
            string(abi.encodePacked('sv', _UNDERLYING.symbol()))
        )
    {
        UNDERLYING = _UNDERLYING;
        totalSupply = type(uint256).max;
        merkleRoot = _merkleRoot;
    }

    // ================ VAULT ACCOUNTING ==================== //
    /// @notice Calculates the current balance of the underlying token i.e. XAI
    /// @return The contract's balance of XAI
    function totalAssets() public view override returns (uint256) {
        return UNDERLYING.balanceOf(address(this));
    }

    /// @notice Calculates the max depositable amount of the underlying token
    /// @return The outstanding balance of XAI token not staked in the contract
    function maxDeposit(address _address)
        public
        view
        override
        returns (uint256)
    {
        return UNDERLYING.balanceOf(_address);
    }

    /// @notice Calculates the max mintable shares
    /// @return The amount of shares mintable for total supply of unstaked XAI
    function maxMint(address _address) public view override returns (uint256) {
        return previewDeposit(UNDERLYING.balanceOf(_address));
    }

    // ================== MERKLE TREE CLAIM ========================== //
    /// @notice Mints shares to contract that can be claimed by addresses in merkle
    function merkleMint(
        uint256 _shares,
        uint256 _amount,
        address _sender
    ) internal {
        require(_amount == _shares, 'INSUFFICIENT_AMOUNT');
        merkleMinted = true;
        merkleUnclaimed = _shares;
        _mint(address(this), _shares);
        emit MerkleSharesMinted(_sender, _shares);
    }

    /// @notice Claims eligible amount of shares for address in merkle
    function claimShares(
        address _sender,
        uint256 _amount,
        bytes32[] calldata merkleProof
    ) external {
        require(!merkleClaimed[_sender], 'ALREADY_CLAIMED');
        // Verify the merkle proof
        bytes32 node = keccak256(abi.encodePacked(_sender, _amount));
        require(
            MerkleProof.verify(merkleProof, merkleRoot, node),
            'INVALID_PROOF'
        );
        // Set address to claimed and deduct shares from merkle unclaimed total
        merkleClaimed[_sender] = true;
        merkleUnclaimed -= _amount;

        // Mint shares and burn contract shares --> Transfer uses callers as msg.sender
        // And TransferFrom would require allowance for every merkle address
        _burn(address(this), _amount);
        _mint(_sender, _amount);

        // Emit claim event
        emit MerkleClaim(_sender, _amount);
    }

    function checkMerkle(
        address _sender,
        uint256 _amount,
        bytes32[] calldata merkleProof
    ) external view returns (bool) {
        bytes32 node = keccak256(abi.encodePacked(_sender, _amount));
        require(
            MerkleProof.verify(merkleProof, merkleRoot, node),
            'INVALID_PROOF'
        );
        return true;
    }

    /// @notice Emergency function to transfer shares to owner if the merkle root missed an address
    /// Shares can then be transferred from the owner to the address missed from the merkle
    function emergencyMerkleTransfer(uint256 _amount) external onlyOwner {
        require(_amount <= merkleUnclaimed, 'CLAIM_TOO_HIGH');
        merkleUnclaimed -= _amount;
        _burn(address(this), _amount);
        _mint(msg.sender, _amount);
    }

    // ================= ADMIN FUNCTIONs =============== //
    /// @notice Initializes contract by setting totalSupply to 0 from type(uint256).max
    /// Added merkle + deposit to avoid front run risk on the deposit
    function vaultInitialize(uint256 _shares, uint256 _amount)
        external
        onlyOwner
    {
        require(!contractInitialized, 'ALREADY_INITIALIZED');

        // Setting supply to 0 to initialize contract from overflow state
        contractInitialized = true;
        totalSupply = 0;

        // Mint shares for all addresses in merkle tree and hold in contract
        merkleMint(_shares, _amount, msg.sender);
        require(
            UNDERLYING.transferFrom(msg.sender, address(this), _amount),
            'TRANSFER_FAIL'
        );
        emit ContractInitialization(msg.sender);
    }
}

File 2 of 9 : SafeCastLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Safe unsigned integer casting library that reverts on overflow.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeCastLib.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeCast.sol)
library SafeCastLib {
    function safeCastTo248(uint256 x) internal pure returns (uint248 y) {
        require(x < 1 << 248);

        y = uint248(x);
    }

    function safeCastTo224(uint256 x) internal pure returns (uint224 y) {
        require(x < 1 << 224);

        y = uint224(x);
    }

    function safeCastTo192(uint256 x) internal pure returns (uint192 y) {
        require(x < 1 << 192);

        y = uint192(x);
    }

    function safeCastTo160(uint256 x) internal pure returns (uint160 y) {
        require(x < 1 << 160);

        y = uint160(x);
    }

    function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
        require(x < 1 << 128);

        y = uint128(x);
    }

    function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
        require(x < 1 << 96);

        y = uint96(x);
    }

    function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
        require(x < 1 << 64);

        y = uint64(x);
    }

    function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
        require(x < 1 << 32);

        y = uint32(x);
    }

    function safeCastTo8(uint256 x) internal pure returns (uint8 y) {
        require(x < 1 << 8);

        y = uint8(x);
    }
}

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

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/Rari-Capital/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;

        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;

        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), from) // Append the "from" argument.
            mstore(add(freeMemoryPointer, 36), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument.

            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;

        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), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

            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;

        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), to) // Append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument.

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

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

/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/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 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) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // Divide z by the denominator.
            z := div(z, denominator)
        }
    }

    function mulDivUp(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            // Store x * y in z for now.
            z := mul(x, y)

            // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
            if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
                revert(0, 0)
            }

            // First, divide z - 1 by the denominator and add 1.
            // We allow z - 1 to underflow if z is 0, because we multiply the
            // end result by 0 if z is zero, ensuring we return 0 if z is zero.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 scalar
    ) internal pure returns (uint256 z) {
        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) {
        assembly {
            // Start off with z at 1.
            z := 1

            // Used below to help find a nearby power of 2.
            let y := x

            // Find the lowest power of 2 that is at least sqrt(x).
            if iszero(lt(y, 0x100000000000000000000000000000000)) {
                y := shr(128, y) // Like dividing by 2 ** 128.
                z := shl(64, z) // Like multiplying by 2 ** 64.
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z) // Like multiplying by 2 ** 32.
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z) // Like multiplying by 2 ** 16.
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z) // Like multiplying by 2 ** 8.
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z) // Like multiplying by 2 ** 4.
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z) // Like multiplying by 2 ** 2.
            }
            if iszero(lt(y, 0x8)) {
                // Equivalent to 2 ** z.
                z := shl(1, z)
            }

            // Shifting right by 1 is like dividing by 2.
            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)))

            // Compute a rounded down version of z.
            let zRoundDown := div(x, z)

            // If zRoundDown is smaller, use it.
            if lt(zRoundDown, z) {
                z := zRoundDown
            }
        }
    }
}

File 5 of 9 : ERC4626.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";
import {SafeTransferLib} from "../utils/SafeTransferLib.sol";
import {FixedPointMathLib} from "../utils/FixedPointMathLib.sol";

/// @notice Minimal ERC4626 tokenized Vault implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/mixins/ERC4626.sol)
abstract contract ERC4626 is ERC20 {
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares);

    event Withdraw(
        address indexed caller,
        address indexed receiver,
        address indexed owner,
        uint256 assets,
        uint256 shares
    );

    /*//////////////////////////////////////////////////////////////
                               IMMUTABLES
    //////////////////////////////////////////////////////////////*/

    ERC20 public immutable asset;

    constructor(
        ERC20 _asset,
        string memory _name,
        string memory _symbol
    ) ERC20(_name, _symbol, _asset.decimals()) {
        asset = _asset;
    }

    /*//////////////////////////////////////////////////////////////
                        DEPOSIT/WITHDRAWAL LOGIC
    //////////////////////////////////////////////////////////////*/

    function deposit(uint256 assets, address receiver) public virtual returns (uint256 shares) {
        // Check for rounding error since we round down in previewDeposit.
        require((shares = previewDeposit(assets)) != 0, "ZERO_SHARES");

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function mint(uint256 shares, address receiver) public virtual returns (uint256 assets) {
        assets = previewMint(shares); // No need to check for rounding error, previewMint rounds up.

        // Need to transfer before minting or ERC777s could reenter.
        asset.safeTransferFrom(msg.sender, address(this), assets);

        _mint(receiver, shares);

        emit Deposit(msg.sender, receiver, assets, shares);

        afterDeposit(assets, shares);
    }

    function withdraw(
        uint256 assets,
        address receiver,
        address owner
    ) public virtual returns (uint256 shares) {
        shares = previewWithdraw(assets); // No need to check for rounding error, previewWithdraw rounds up.

        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    function redeem(
        uint256 shares,
        address receiver,
        address owner
    ) public virtual returns (uint256 assets) {
        if (msg.sender != owner) {
            uint256 allowed = allowance[owner][msg.sender]; // Saves gas for limited approvals.

            if (allowed != type(uint256).max) allowance[owner][msg.sender] = allowed - shares;
        }

        // Check for rounding error since we round down in previewRedeem.
        require((assets = previewRedeem(shares)) != 0, "ZERO_ASSETS");

        beforeWithdraw(assets, shares);

        _burn(owner, shares);

        emit Withdraw(msg.sender, receiver, owner, assets, shares);

        asset.safeTransfer(receiver, assets);
    }

    /*//////////////////////////////////////////////////////////////
                            ACCOUNTING LOGIC
    //////////////////////////////////////////////////////////////*/

    function totalAssets() public view virtual returns (uint256);

    function convertToShares(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivDown(supply, totalAssets());
    }

    function convertToAssets(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivDown(totalAssets(), supply);
    }

    function previewDeposit(uint256 assets) public view virtual returns (uint256) {
        return convertToShares(assets);
    }

    function previewMint(uint256 shares) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? shares : shares.mulDivUp(totalAssets(), supply);
    }

    function previewWithdraw(uint256 assets) public view virtual returns (uint256) {
        uint256 supply = totalSupply; // Saves an extra SLOAD if totalSupply is non-zero.

        return supply == 0 ? assets : assets.mulDivUp(supply, totalAssets());
    }

    function previewRedeem(uint256 shares) public view virtual returns (uint256) {
        return convertToAssets(shares);
    }

    /*//////////////////////////////////////////////////////////////
                     DEPOSIT/WITHDRAWAL LIMIT LOGIC
    //////////////////////////////////////////////////////////////*/

    function maxDeposit(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxMint(address) public view virtual returns (uint256) {
        return type(uint256).max;
    }

    function maxWithdraw(address owner) public view virtual returns (uint256) {
        return convertToAssets(balanceOf[owner]);
    }

    function maxRedeem(address owner) public view virtual returns (uint256) {
        return balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HOOKS LOGIC
    //////////////////////////////////////////////////////////////*/

    function beforeWithdraw(uint256 assets, uint256 shares) internal virtual {}

    function afterDeposit(uint256 assets, uint256 shares) internal virtual {}
}

File 6 of 9 : ERC20.sol
// 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/Rari-Capital/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);
    }
}

File 7 of 9 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 *
 * WARNING: You should avoid using leaf values that are 64 bytes long prior to
 * hashing, or use a hash function other than keccak256 for hashing leaves.
 * This is because the concatenation of a sorted pair of internal nodes in
 * the merkle tree could be reinterpreted as a leaf value.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = _efficientHash(computedHash, proofElement);
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = _efficientHash(proofElement, computedHash);
            }
        }
        return computedHash;
    }

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

File 8 of 9 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 9 of 9 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ERC20","name":"_UNDERLYING","type":"address"},{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ContractInitialization","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"MerkleClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"MerkleSharesMinted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UNDERLYING","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"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":[],"name":"asset","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"checkMerkle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"convertToAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"convertToShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"emergencyMerkleTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"maxDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"maxWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"merkleClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleUnclaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"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":"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":"uint256","name":"assets","type":"uint256"}],"name":"previewDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewRedeem","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"previewWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"redeem","outputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAssets","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"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"vaultInitialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]

6101406040523480156200001257600080fd5b506040516200495f3803806200495f833981810160405281019062000038919062000601565b818273ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b815260040160006040518083038186803b1580156200008057600080fd5b505afa15801562000095573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190620000c0919062000642565b604051602001620000d291906200085c565b6040516020818303038152906040528373ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b1580156200012857600080fd5b505afa1580156200013d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019062000168919062000642565b6040516020016200017a919062000836565b60405160208183030381529060405281818473ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015620001d257600080fd5b505afa158015620001e7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020d919062000687565b8260009080519060200190620002259291906200049a565b5081600190805190602001906200023e9291906200049a565b508060ff1660808160ff1660f81b815250504660a08181525050620002686200033c60201b60201c565b60c081815250505050508273ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505050620002cc620002c0620003cc60201b60201c565b620003d460201b60201c565b8173ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff1660601b815250507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600281905550806101208181525050505062000bc4565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60006040516200037091906200081d565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc64630604051602001620003b19594939291906200088f565b60405160208183030381529060405280519060200120905090565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620004a89062000a20565b90600052602060002090601f016020900481019282620004cc576000855562000518565b82601f10620004e757805160ff191683800117855562000518565b8280016001018555821562000518579182015b8281111562000517578251825591602001919060010190620004fa565b5b5090506200052791906200052b565b5090565b5b80821115620005465760008160009055506001016200052c565b5090565b6000620005616200055b8462000915565b620008ec565b9050828152602081018484840111156200057a57600080fd5b62000587848285620009ea565b509392505050565b600081519050620005a08162000b76565b92915050565b600081519050620005b78162000b90565b92915050565b600082601f830112620005cf57600080fd5b8151620005e18482602086016200054a565b91505092915050565b600081519050620005fb8162000baa565b92915050565b600080604083850312156200061557600080fd5b60006200062585828601620005a6565b925050602062000638858286016200058f565b9150509250929050565b6000602082840312156200065557600080fd5b600082015167ffffffffffffffff8111156200067057600080fd5b6200067e84828501620005bd565b91505092915050565b6000602082840312156200069a57600080fd5b6000620006aa84828501620005ea565b91505092915050565b620006be8162000981565b82525050565b620006cf8162000995565b82525050565b60008154620006e48162000a20565b620006f081866200096b565b945060018216600081146200070e5760018114620007205762000757565b60ff1983168652818601935062000757565b6200072b856200094b565b60005b838110156200074f578154818901526001820191506020810190506200072e565b838801955050505b50505092915050565b60006200076d8262000960565b62000779818562000976565b93506200078b818560208601620009ea565b80840191505092915050565b6000620007a660068362000976565b9150620007b38262000afb565b600682019050919050565b6000620007cd60028362000976565b9150620007da8262000b24565b600282019050919050565b6000620007f4600a8362000976565b9150620008018262000b4d565b600a82019050919050565b6200081781620009d3565b82525050565b60006200082b8284620006d5565b915081905092915050565b60006200084382620007be565b915062000851828462000760565b915081905092915050565b60006200086982620007e5565b915062000877828462000760565b9150620008848262000797565b915081905092915050565b600060a082019050620008a66000830188620006c4565b620008b56020830187620006c4565b620008c46040830186620006c4565b620008d360608301856200080c565b620008e26080830184620006b3565b9695505050505050565b6000620008f86200090b565b905062000906828262000a56565b919050565b6000604051905090565b600067ffffffffffffffff82111562000933576200093262000abb565b5b6200093e8262000aea565b9050602081019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600081905092915050565b60006200098e82620009b3565b9050919050565b6000819050919050565b6000620009ac8262000981565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101562000a0a578082015181840152602081019050620009ed565b8381111562000a1a576000848401525b50505050565b6000600282049050600182168062000a3957607f821691505b6020821081141562000a505762000a4f62000a8c565b5b50919050565b62000a618262000aea565b810181811067ffffffffffffffff8211171562000a835762000a8262000abb565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f205661756c740000000000000000000000000000000000000000000000000000600082015250565b7f7376000000000000000000000000000000000000000000000000000000000000600082015250565b7f5369646553686966742000000000000000000000000000000000000000000000600082015250565b62000b818162000995565b811462000b8d57600080fd5b50565b62000b9b816200099f565b811462000ba757600080fd5b50565b62000bb581620009dd565b811462000bc157600080fd5b50565b60805160f81c60a05160c05160e05160601c6101005160601c61012051613cfc62000c6360003960008181610c860152818161101001526113ce0152600081816108aa015281816110db015281816118eb01528181611f5b0152611f840152600081816110b5015281816111f30152818161158701528181611c690152611f080152600061108e0152600061105a015260006110340152613cfc6000f3fe608060405234801561001057600080fd5b50600436106102525760003560e01c80637a7ec16711610146578063ba087652116100c3578063ce96cb7711610087578063ce96cb771461079b578063d505accf146107cb578063d905777e146107e7578063dd62ed3e14610817578063ef8b30f714610847578063f2fde38b1461087757610252565b8063ba087652146106cf578063c5b97dc2146106ff578063c5d664c61461071d578063c63d75b61461073b578063c6e6f5921461076b57610252565b806395d89b411161010a57806395d89b4114610605578063a9059cbb14610623578063b27c846b14610653578063b3d7f6b91461066f578063b460af941461069f57610252565b80637a7ec1671461053b5780637ecebe001461056b5780638da5cb5b1461059b5780638e759e6c146105b957806394bf804d146105d557610252565b806323b872dd116101d4578063402d267d11610198578063402d267d146104715780634cdad506146104a15780636e553f65146104d157806370a0823114610501578063715018a61461053157610252565b806323b872dd146103c95780632eb4a7ab146103f9578063313ce567146104175780633644e5151461043557806338d52e0f1461045357610252565b8063095ea7b31161021b578063095ea7b3146103115780630a28a4771461034157806317a8d8621461037157806318160ddd1461038f5780631d310f36146103ad57610252565b8062b347471461025757806301e1d1141461027557806305b0e4ae1461029357806306fdde03146102c357806307a2d13a146102e1575b600080fd5b61025f610893565b60405161026c9190613385565b60405180910390f35b61027d6108a6565b60405161028a91906136b1565b60405180910390f35b6102ad60048036038101906102a89190612c19565b610956565b6040516102ba9190613385565b60405180910390f35b6102cb610976565b6040516102d891906134cf565b60405180910390f35b6102fb60048036038101906102f69190612e3c565b610a04565b60405161030891906136b1565b60405180910390f35b61032b60048036038101906103269190612d6b565b610a3f565b6040516103389190613385565b60405180910390f35b61035b60048036038101906103569190612e3c565b610b31565b60405161036891906136b1565b60405180910390f35b610379610b6c565b6040516103869190613385565b60405180910390f35b610397610b7f565b6040516103a491906136b1565b60405180910390f35b6103c760048036038101906103c29190612da7565b610b85565b005b6103e360048036038101906103de9190612c7e565b610dc4565b6040516103f09190613385565b60405180910390f35b61040161100e565b60405161040e91906133a0565b60405180910390f35b61041f611032565b60405161042c91906136f5565b60405180910390f35b61043d611056565b60405161044a91906133a0565b60405180910390f35b61045b6110b3565b60405161046891906134b4565b60405180910390f35b61048b60048036038101906104869190612c19565b6110d7565b60405161049891906136b1565b60405180910390f35b6104bb60048036038101906104b69190612e3c565b611189565b6040516104c891906136b1565b60405180910390f35b6104eb60048036038101906104e69190612e8e565b61119b565b6040516104f891906136b1565b60405180910390f35b61051b60048036038101906105169190612c19565b6112b9565b60405161052891906136b1565b60405180910390f35b6105396112d1565b005b61055560048036038101906105509190612da7565b611359565b6040516105629190613385565b60405180910390f35b61058560048036038101906105809190612c19565b61143f565b60405161059291906136b1565b60405180910390f35b6105a3611457565b6040516105b09190613333565b60405180910390f35b6105d360048036038101906105ce9190612e3c565b611481565b005b6105ef60048036038101906105ea9190612e8e565b611572565b6040516105fc91906136b1565b60405180910390f35b61060d61164d565b60405161061a91906134cf565b60405180910390f35b61063d60048036038101906106389190612d6b565b6116db565b60405161064a9190613385565b60405180910390f35b61066d60048036038101906106689190612f19565b6117ef565b005b61068960048036038101906106849190612e3c565b611a1e565b60405161069691906136b1565b60405180910390f35b6106b960048036038101906106b49190612eca565b611a59565b6040516106c691906136b1565b60405180910390f35b6106e960048036038101906106e49190612eca565b611cb4565b6040516106f691906136b1565b60405180910390f35b610707611f53565b60405161071491906136b1565b60405180910390f35b610725611f59565b60405161073291906134b4565b60405180910390f35b61075560048036038101906107509190612c19565b611f7d565b60405161076291906136b1565b60405180910390f35b61078560048036038101906107809190612e3c565b612037565b60405161079291906136b1565b60405180910390f35b6107b560048036038101906107b09190612c19565b612072565b6040516107c291906136b1565b60405180910390f35b6107e560048036038101906107e09190612ccd565b6120c3565b005b61080160048036038101906107fc9190612c19565b6123bc565b60405161080e91906136b1565b60405180910390f35b610831600480360381019061082c9190612c42565b612405565b60405161083e91906136b1565b60405180910390f35b610861600480360381019061085c9190612e3c565b61242a565b60405161086e91906136b1565b60405180910390f35b610891600480360381019061088c9190612c19565b61243c565b005b600660149054906101000a900460ff1681565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109019190613333565b60206040518083038186803b15801561091957600080fd5b505afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109519190612e65565b905090565b60086020528060005260406000206000915054906101000a900460ff1681565b6000805461098390613897565b80601f01602080910402602001604051908101604052809291908181526020018280546109af90613897565b80156109fc5780601f106109d1576101008083540402835291602001916109fc565b820191906000526020600020905b8154815290600101906020018083116109df57829003601f168201915b505050505081565b600080600254905060008114610a3557610a30610a1f6108a6565b82856125349092919063ffffffff16565b610a37565b825b915050919050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610b1f91906136b1565b60405180910390a36001905092915050565b600080600254905060008114610b6257610b5d81610b4d6108a6565b8561255c9092919063ffffffff16565b610b64565b825b915050919050565b600660159054906101000a900460ff1681565b60025481565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0990613691565b60405180910390fd5b60008484604051602001610c279291906132b9565b604051602081830303815290604052805190602001209050610cab838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f00000000000000000000000000000000000000000000000000000000000000008361258e565b610cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce190613551565b60405180910390fd5b6001600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508360076000828254610d5491906137ad565b92505081905550610d6530856125a5565b610d6f8585612675565b8473ffffffffffffffffffffffffffffffffffffffff167f106e78f4438686ffff0ca4b3ec52c71cf3ef479de98aeaad834f46f440552e9785604051610db591906136b1565b60405180910390a25050505050565b600080600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610efa578281610e7991906137ad565b600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b82600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f4991906137ad565b9250508190555082600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffa91906136b1565b60405180910390a360019150509392505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f0000000000000000000000000000000000000000000000000000000000000000461461108c57611087612745565b6110ae565b7f00000000000000000000000000000000000000000000000000000000000000005b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016111329190613333565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e65565b9050919050565b600061119482610a04565b9050919050565b6000806111a78461242a565b91508114156111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e2906134f1565b60405180910390fd5b6112383330857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6112428282612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d785846040516112a19291906136cc565b60405180910390a36112b38382612870565b92915050565b60036020528060005260406000206000915090505481565b6112d9612874565b73ffffffffffffffffffffffffffffffffffffffff166112f7611457565b73ffffffffffffffffffffffffffffffffffffffff161461134d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611344906135d1565b60405180910390fd5b611357600061287c565b565b600080858560405160200161136f9291906132b9565b6040516020818303038152906040528051906020012090506113f3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f00000000000000000000000000000000000000000000000000000000000000008361258e565b611432576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142990613551565b60405180910390fd5b6001915050949350505050565b60056020528060005260406000206000915090505481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611489612874565b73ffffffffffffffffffffffffffffffffffffffff166114a7611457565b73ffffffffffffffffffffffffffffffffffffffff16146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f4906135d1565b60405180910390fd5b600754811115611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906135f1565b60405180910390fd5b806007600082825461155491906137ad565b9250508190555061156530826125a5565b61156f3382612675565b50565b600061157d83611a1e565b90506115cc3330837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6115d68284612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d783866040516116359291906136cc565b60405180910390a36116478184612870565b92915050565b6001805461165a90613897565b80601f016020809104026020016040519081016040528092919081815260200182805461168690613897565b80156116d35780601f106116a8576101008083540402835291602001916116d3565b820191906000526020600020905b8154815290600101906020018083116116b657829003601f168201915b505050505081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172c91906137ad565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516117dd91906136b1565b60405180910390a36001905092915050565b6117f7612874565b73ffffffffffffffffffffffffffffffffffffffff16611815611457565b73ffffffffffffffffffffffffffffffffffffffff161461186b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611862906135d1565b60405180910390fd5b600660149054906101000a900460ff16156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b290613511565b60405180910390fd5b6001600660146101000a81548160ff02191690831515021790555060006002819055506118e9828233612942565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b81526004016119469392919061334e565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612e13565b6119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce90613571565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f2a1fd7531301a9bc9c459bb79a90dafb0f939766e2a8cec6931cb9034d9c1c0160405160405180910390a25050565b600080600254905060008114611a4f57611a4a611a396108a6565b828561255c9092919063ffffffff16565b611a51565b825b915050919050565b6000611a6484610b31565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bd0576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bce578181611b4d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b611bda8482612a03565b611be482826125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8785604051611c5a9291906136cc565b60405180910390a4611cad83857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e20576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1e578481611d9d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b6000611e2b85611189565b9150811415611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690613631565b60405180910390fd5b611e798185612a03565b611e8382856125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8488604051611ef99291906136cc565b60405180910390a4611f4c83827f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60075481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60006120307f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401611fdb9190613333565b60206040518083038186803b158015611ff357600080fd5b505afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b9190612e65565b61242a565b9050919050565b60008060025490506000811461206857612063816120536108a6565b856125349092919063ffffffff16565b61206a565b825b915050919050565b60006120bc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a04565b9050919050565b42841015612106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fd90613651565b60405180910390fd5b60006001612112611056565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a600560008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050558b60405160200161219a969594939291906133bb565b604051602081830303815290604052805190602001206040516020016121c19291906132fc565b60405160208183030381529060405280519060200120858585604051600081526020016040526040516121f7949392919061346f565b6020604051602081039080840390855afa158015612219573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561228d57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c390613611565b60405180910390fd5b85600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925876040516123ab91906136b1565b60405180910390a350505050505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600061243582612037565b9050919050565b612444612874565b73ffffffffffffffffffffffffffffffffffffffff16612462611457565b73ffffffffffffffffffffffffffffffffffffffff16146124b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124af906135d1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161251f90613531565b60405180910390fd5b6125318161287c565b50565b6000828402905082848204148415178215151661255057600080fd5b81810490509392505050565b6000828402905082848204148415178215151661257857600080fd5b6001826001830304018115150290509392505050565b60008261259b8584612a9f565b1490509392505050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125f491906137ad565b9250508190555080600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161266991906136b1565b60405180910390a35050565b80600260008282546126879190613757565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161273991906136b1565b60405180910390a35050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161277791906132e5565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016127b695949392919061341c565b60405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090613591565b60405180910390fd5b5050505050565b5050565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828214612984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297b90613671565b60405180910390fd5b6001600660156101000a81548160ff021916908315150217905550826007819055506129b03084612675565b8073ffffffffffffffffffffffffffffffffffffffff167f5e2721114e39241d48a241ba2ab0e6ed19218ce65096c56e4f5b90f9fbcdd821846040516129f691906136b1565b60405180910390a2505050565b5050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080612a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a90906135b1565b60405180910390fd5b50505050565b60008082905060005b8451811015612b2f576000858281518110612aec577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050808311612b0e57612b078382612b3a565b9250612b1b565b612b188184612b3a565b92505b508080612b27906138c9565b915050612aa8565b508091505092915050565b600082600052816020526040600020905092915050565b600081359050612b6081613c53565b92915050565b60008083601f840112612b7857600080fd5b8235905067ffffffffffffffff811115612b9157600080fd5b602083019150836020820283011115612ba957600080fd5b9250929050565b600081519050612bbf81613c6a565b92915050565b600081359050612bd481613c81565b92915050565b600081359050612be981613c98565b92915050565b600081519050612bfe81613c98565b92915050565b600081359050612c1381613caf565b92915050565b600060208284031215612c2b57600080fd5b6000612c3984828501612b51565b91505092915050565b60008060408385031215612c5557600080fd5b6000612c6385828601612b51565b9250506020612c7485828601612b51565b9150509250929050565b600080600060608486031215612c9357600080fd5b6000612ca186828701612b51565b9350506020612cb286828701612b51565b9250506040612cc386828701612bda565b9150509250925092565b600080600080600080600060e0888a031215612ce857600080fd5b6000612cf68a828b01612b51565b9750506020612d078a828b01612b51565b9650506040612d188a828b01612bda565b9550506060612d298a828b01612bda565b9450506080612d3a8a828b01612c04565b93505060a0612d4b8a828b01612bc5565b92505060c0612d5c8a828b01612bc5565b91505092959891949750929550565b60008060408385031215612d7e57600080fd5b6000612d8c85828601612b51565b9250506020612d9d85828601612bda565b9150509250929050565b60008060008060608587031215612dbd57600080fd5b6000612dcb87828801612b51565b9450506020612ddc87828801612bda565b935050604085013567ffffffffffffffff811115612df957600080fd5b612e0587828801612b66565b925092505092959194509250565b600060208284031215612e2557600080fd5b6000612e3384828501612bb0565b91505092915050565b600060208284031215612e4e57600080fd5b6000612e5c84828501612bda565b91505092915050565b600060208284031215612e7757600080fd5b6000612e8584828501612bef565b91505092915050565b60008060408385031215612ea157600080fd5b6000612eaf85828601612bda565b9250506020612ec085828601612b51565b9150509250929050565b600080600060608486031215612edf57600080fd5b6000612eed86828701612bda565b9350506020612efe86828701612b51565b9250506040612f0f86828701612b51565b9150509250925092565b60008060408385031215612f2c57600080fd5b6000612f3a85828601612bda565b9250506020612f4b85828601612bda565b9150509250929050565b612f5e816137e1565b82525050565b612f75612f70826137e1565b613912565b82525050565b612f84816137f3565b82525050565b612f93816137ff565b82525050565b612faa612fa5826137ff565b613924565b82525050565b60008154612fbd81613897565b612fc78186613730565b94506001821660008114612fe25760018114612ff357613026565b60ff19831686528186019350613026565b612ffc85613710565b60005b8381101561301e57815481890152600182019150602081019050612fff565b838801955050505b50505092915050565b61303881613840565b82525050565b600061304982613725565b613053818561373b565b9350613063818560208601613864565b61306c816139a8565b840191505092915050565b6000613084600b8361373b565b915061308f826139c6565b602082019050919050565b60006130a760138361373b565b91506130b2826139ef565b602082019050919050565b60006130ca60268361373b565b91506130d582613a18565b604082019050919050565b60006130ed60028361374c565b91506130f882613a67565b600282019050919050565b6000613110600d8361373b565b915061311b82613a90565b602082019050919050565b6000613133600d8361373b565b915061313e82613ab9565b602082019050919050565b600061315660148361373b565b915061316182613ae2565b602082019050919050565b6000613179600f8361373b565b915061318482613b0b565b602082019050919050565b600061319c60208361373b565b91506131a782613b34565b602082019050919050565b60006131bf600e8361373b565b91506131ca82613b5d565b602082019050919050565b60006131e2600e8361373b565b91506131ed82613b86565b602082019050919050565b6000613205600b8361373b565b915061321082613baf565b602082019050919050565b600061322860178361373b565b915061323382613bd8565b602082019050919050565b600061324b60138361373b565b915061325682613c01565b602082019050919050565b600061326e600f8361373b565b915061327982613c2a565b602082019050919050565b61328d81613829565b82525050565b6132a461329f82613829565b613940565b82525050565b6132b381613833565b82525050565b60006132c58285612f64565b6014820191506132d58284613293565b6020820191508190509392505050565b60006132f18284612fb0565b915081905092915050565b6000613307826130e0565b91506133138285612f99565b6020820191506133238284612f99565b6020820191508190509392505050565b60006020820190506133486000830184612f55565b92915050565b60006060820190506133636000830186612f55565b6133706020830185612f55565b61337d6040830184613284565b949350505050565b600060208201905061339a6000830184612f7b565b92915050565b60006020820190506133b56000830184612f8a565b92915050565b600060c0820190506133d06000830189612f8a565b6133dd6020830188612f55565b6133ea6040830187612f55565b6133f76060830186613284565b6134046080830185613284565b61341160a0830184613284565b979650505050505050565b600060a0820190506134316000830188612f8a565b61343e6020830187612f8a565b61344b6040830186612f8a565b6134586060830185613284565b6134656080830184612f55565b9695505050505050565b60006080820190506134846000830187612f8a565b61349160208301866132aa565b61349e6040830185612f8a565b6134ab6060830184612f8a565b95945050505050565b60006020820190506134c9600083018461302f565b92915050565b600060208201905081810360008301526134e9818461303e565b905092915050565b6000602082019050818103600083015261350a81613077565b9050919050565b6000602082019050818103600083015261352a8161309a565b9050919050565b6000602082019050818103600083015261354a816130bd565b9050919050565b6000602082019050818103600083015261356a81613103565b9050919050565b6000602082019050818103600083015261358a81613126565b9050919050565b600060208201905081810360008301526135aa81613149565b9050919050565b600060208201905081810360008301526135ca8161316c565b9050919050565b600060208201905081810360008301526135ea8161318f565b9050919050565b6000602082019050818103600083015261360a816131b2565b9050919050565b6000602082019050818103600083015261362a816131d5565b9050919050565b6000602082019050818103600083015261364a816131f8565b9050919050565b6000602082019050818103600083015261366a8161321b565b9050919050565b6000602082019050818103600083015261368a8161323e565b9050919050565b600060208201905081810360008301526136aa81613261565b9050919050565b60006020820190506136c66000830184613284565b92915050565b60006040820190506136e16000830185613284565b6136ee6020830184613284565b9392505050565b600060208201905061370a60008301846132aa565b92915050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061376282613829565b915061376d83613829565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a2576137a161394a565b5b828201905092915050565b60006137b882613829565b91506137c383613829565b9250828210156137d6576137d561394a565b5b828203905092915050565b60006137ec82613809565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061384b82613852565b9050919050565b600061385d82613809565b9050919050565b60005b83811015613882578082015181840152602081019050613867565b83811115613891576000848401525b50505050565b600060028204905060018216806138af57607f821691505b602082108114156138c3576138c2613979565b5b50919050565b60006138d482613829565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156139075761390661394a565b5b600182019050919050565b600061391d8261392e565b9050919050565b6000819050919050565b6000613939826139b9565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f5a45524f5f534841524553000000000000000000000000000000000000000000600082015250565b7f414c52454144595f494e495449414c495a454400000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f494e56414c49445f50524f4f4600000000000000000000000000000000000000600082015250565b7f5452414e534645525f4641494c00000000000000000000000000000000000000600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f434c41494d5f544f4f5f48494748000000000000000000000000000000000000600082015250565b7f494e56414c49445f5349474e4552000000000000000000000000000000000000600082015250565b7f5a45524f5f415353455453000000000000000000000000000000000000000000600082015250565b7f5045524d49545f444541444c494e455f45585049524544000000000000000000600082015250565b7f494e53554646494349454e545f414d4f554e5400000000000000000000000000600082015250565b7f414c52454144595f434c41494d45440000000000000000000000000000000000600082015250565b613c5c816137e1565b8114613c6757600080fd5b50565b613c73816137f3565b8114613c7e57600080fd5b50565b613c8a816137ff565b8114613c9557600080fd5b50565b613ca181613829565b8114613cac57600080fd5b50565b613cb881613833565b8114613cc357600080fd5b5056fea264697066735822122043d69df03a002bac0a079a7abac53568908dfb3ac6776337f411081088e36c5064736f6c6343000804003300000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23228b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102525760003560e01c80637a7ec16711610146578063ba087652116100c3578063ce96cb7711610087578063ce96cb771461079b578063d505accf146107cb578063d905777e146107e7578063dd62ed3e14610817578063ef8b30f714610847578063f2fde38b1461087757610252565b8063ba087652146106cf578063c5b97dc2146106ff578063c5d664c61461071d578063c63d75b61461073b578063c6e6f5921461076b57610252565b806395d89b411161010a57806395d89b4114610605578063a9059cbb14610623578063b27c846b14610653578063b3d7f6b91461066f578063b460af941461069f57610252565b80637a7ec1671461053b5780637ecebe001461056b5780638da5cb5b1461059b5780638e759e6c146105b957806394bf804d146105d557610252565b806323b872dd116101d4578063402d267d11610198578063402d267d146104715780634cdad506146104a15780636e553f65146104d157806370a0823114610501578063715018a61461053157610252565b806323b872dd146103c95780632eb4a7ab146103f9578063313ce567146104175780633644e5151461043557806338d52e0f1461045357610252565b8063095ea7b31161021b578063095ea7b3146103115780630a28a4771461034157806317a8d8621461037157806318160ddd1461038f5780631d310f36146103ad57610252565b8062b347471461025757806301e1d1141461027557806305b0e4ae1461029357806306fdde03146102c357806307a2d13a146102e1575b600080fd5b61025f610893565b60405161026c9190613385565b60405180910390f35b61027d6108a6565b60405161028a91906136b1565b60405180910390f35b6102ad60048036038101906102a89190612c19565b610956565b6040516102ba9190613385565b60405180910390f35b6102cb610976565b6040516102d891906134cf565b60405180910390f35b6102fb60048036038101906102f69190612e3c565b610a04565b60405161030891906136b1565b60405180910390f35b61032b60048036038101906103269190612d6b565b610a3f565b6040516103389190613385565b60405180910390f35b61035b60048036038101906103569190612e3c565b610b31565b60405161036891906136b1565b60405180910390f35b610379610b6c565b6040516103869190613385565b60405180910390f35b610397610b7f565b6040516103a491906136b1565b60405180910390f35b6103c760048036038101906103c29190612da7565b610b85565b005b6103e360048036038101906103de9190612c7e565b610dc4565b6040516103f09190613385565b60405180910390f35b61040161100e565b60405161040e91906133a0565b60405180910390f35b61041f611032565b60405161042c91906136f5565b60405180910390f35b61043d611056565b60405161044a91906133a0565b60405180910390f35b61045b6110b3565b60405161046891906134b4565b60405180910390f35b61048b60048036038101906104869190612c19565b6110d7565b60405161049891906136b1565b60405180910390f35b6104bb60048036038101906104b69190612e3c565b611189565b6040516104c891906136b1565b60405180910390f35b6104eb60048036038101906104e69190612e8e565b61119b565b6040516104f891906136b1565b60405180910390f35b61051b60048036038101906105169190612c19565b6112b9565b60405161052891906136b1565b60405180910390f35b6105396112d1565b005b61055560048036038101906105509190612da7565b611359565b6040516105629190613385565b60405180910390f35b61058560048036038101906105809190612c19565b61143f565b60405161059291906136b1565b60405180910390f35b6105a3611457565b6040516105b09190613333565b60405180910390f35b6105d360048036038101906105ce9190612e3c565b611481565b005b6105ef60048036038101906105ea9190612e8e565b611572565b6040516105fc91906136b1565b60405180910390f35b61060d61164d565b60405161061a91906134cf565b60405180910390f35b61063d60048036038101906106389190612d6b565b6116db565b60405161064a9190613385565b60405180910390f35b61066d60048036038101906106689190612f19565b6117ef565b005b61068960048036038101906106849190612e3c565b611a1e565b60405161069691906136b1565b60405180910390f35b6106b960048036038101906106b49190612eca565b611a59565b6040516106c691906136b1565b60405180910390f35b6106e960048036038101906106e49190612eca565b611cb4565b6040516106f691906136b1565b60405180910390f35b610707611f53565b60405161071491906136b1565b60405180910390f35b610725611f59565b60405161073291906134b4565b60405180910390f35b61075560048036038101906107509190612c19565b611f7d565b60405161076291906136b1565b60405180910390f35b61078560048036038101906107809190612e3c565b612037565b60405161079291906136b1565b60405180910390f35b6107b560048036038101906107b09190612c19565b612072565b6040516107c291906136b1565b60405180910390f35b6107e560048036038101906107e09190612ccd565b6120c3565b005b61080160048036038101906107fc9190612c19565b6123bc565b60405161080e91906136b1565b60405180910390f35b610831600480360381019061082c9190612c42565b612405565b60405161083e91906136b1565b60405180910390f35b610861600480360381019061085c9190612e3c565b61242a565b60405161086e91906136b1565b60405180910390f35b610891600480360381019061088c9190612c19565b61243c565b005b600660149054906101000a900460ff1681565b60007f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016109019190613333565b60206040518083038186803b15801561091957600080fd5b505afa15801561092d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109519190612e65565b905090565b60086020528060005260406000206000915054906101000a900460ff1681565b6000805461098390613897565b80601f01602080910402602001604051908101604052809291908181526020018280546109af90613897565b80156109fc5780601f106109d1576101008083540402835291602001916109fc565b820191906000526020600020905b8154815290600101906020018083116109df57829003601f168201915b505050505081565b600080600254905060008114610a3557610a30610a1f6108a6565b82856125349092919063ffffffff16565b610a37565b825b915050919050565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051610b1f91906136b1565b60405180910390a36001905092915050565b600080600254905060008114610b6257610b5d81610b4d6108a6565b8561255c9092919063ffffffff16565b610b64565b825b915050919050565b600660159054906101000a900460ff1681565b60025481565b600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610c12576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c0990613691565b60405180910390fd5b60008484604051602001610c279291906132b9565b604051602081830303815290604052805190602001209050610cab838380806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f188361258e565b610cea576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce190613551565b60405180910390fd5b6001600860008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508360076000828254610d5491906137ad565b92505081905550610d6530856125a5565b610d6f8585612675565b8473ffffffffffffffffffffffffffffffffffffffff167f106e78f4438686ffff0ca4b3ec52c71cf3ef479de98aeaad834f46f440552e9785604051610db591906136b1565b60405180910390a25050505050565b600080600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610efa578281610e7991906137ad565b600460008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b82600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610f4991906137ad565b9250508190555082600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051610ffa91906136b1565b60405180910390a360019150509392505050565b7f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f1881565b7f000000000000000000000000000000000000000000000000000000000000001281565b60007f0000000000000000000000000000000000000000000000000000000000000001461461108c57611087612745565b6110ae565b7f25397cdf941a1602956af6334de7c2e9c07bfd9c86b545cbdc4f7976dc4aa0a85b905090565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23281565b60007f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016111329190613333565b60206040518083038186803b15801561114a57600080fd5b505afa15801561115e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111829190612e65565b9050919050565b600061119482610a04565b9050919050565b6000806111a78461242a565b91508114156111eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111e2906134f1565b60405180910390fd5b6112383330857f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6112428282612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d785846040516112a19291906136cc565b60405180910390a36112b38382612870565b92915050565b60036020528060005260406000206000915090505481565b6112d9612874565b73ffffffffffffffffffffffffffffffffffffffff166112f7611457565b73ffffffffffffffffffffffffffffffffffffffff161461134d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611344906135d1565b60405180910390fd5b611357600061287c565b565b600080858560405160200161136f9291906132b9565b6040516020818303038152906040528051906020012090506113f3848480806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050507f28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f188361258e565b611432576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161142990613551565b60405180910390fd5b6001915050949350505050565b60056020528060005260406000206000915090505481565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b611489612874565b73ffffffffffffffffffffffffffffffffffffffff166114a7611457565b73ffffffffffffffffffffffffffffffffffffffff16146114fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f4906135d1565b60405180910390fd5b600754811115611542576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611539906135f1565b60405180910390fd5b806007600082825461155491906137ad565b9250508190555061156530826125a5565b61156f3382612675565b50565b600061157d83611a1e565b90506115cc3330837f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166127d1909392919063ffffffff16565b6115d68284612675565b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d783866040516116359291906136cc565b60405180910390a36116478184612870565b92915050565b6001805461165a90613897565b80601f016020809104026020016040519081016040528092919081815260200182805461168690613897565b80156116d35780601f106116a8576101008083540402835291602001916116d3565b820191906000526020600020905b8154815290600101906020018083116116b657829003601f168201915b505050505081565b600081600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461172c91906137ad565b9250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516117dd91906136b1565b60405180910390a36001905092915050565b6117f7612874565b73ffffffffffffffffffffffffffffffffffffffff16611815611457565b73ffffffffffffffffffffffffffffffffffffffff161461186b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611862906135d1565b60405180910390fd5b600660149054906101000a900460ff16156118bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118b290613511565b60405180910390fd5b6001600660146101000a81548160ff02191690831515021790555060006002819055506118e9828233612942565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166323b872dd3330846040518463ffffffff1660e01b81526004016119469392919061334e565b602060405180830381600087803b15801561196057600080fd5b505af1158015611974573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119989190612e13565b6119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce90613571565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f2a1fd7531301a9bc9c459bb79a90dafb0f939766e2a8cec6931cb9034d9c1c0160405160405180910390a25050565b600080600254905060008114611a4f57611a4a611a396108a6565b828561255c9092919063ffffffff16565b611a51565b825b915050919050565b6000611a6484610b31565b90508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611bd0576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611bce578181611b4d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b611bda8482612a03565b611be482826125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8785604051611c5a9291906136cc565b60405180910390a4611cad83857f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e20576000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611e1e578481611d9d91906137ad565b600460008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505b505b6000611e2b85611189565b9150811415611e6f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e6690613631565b60405180910390fd5b611e798185612a03565b611e8382856125a5565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167ffbde797d201c681b91056529119e0b02407c7bb96a4a2c75c01fc9667232c8db8488604051611ef99291906136cc565b60405180910390a4611f4c83827f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff16612a079092919063ffffffff16565b9392505050565b60075481565b7f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23281565b60006120307f00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23273ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b8152600401611fdb9190613333565b60206040518083038186803b158015611ff357600080fd5b505afa158015612007573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202b9190612e65565b61242a565b9050919050565b60008060025490506000811461206857612063816120536108a6565b856125349092919063ffffffff16565b61206a565b825b915050919050565b60006120bc600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610a04565b9050919050565b42841015612106576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fd90613651565b60405180910390fd5b60006001612112611056565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98a8a8a600560008f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000815480929190600101919050558b60405160200161219a969594939291906133bb565b604051602081830303815290604052805190602001206040516020016121c19291906132fc565b60405160208183030381529060405280519060200120858585604051600081526020016040526040516121f7949392919061346f565b6020604051602081039080840390855afa158015612219573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415801561228d57508773ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b6122cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c390613611565b60405180910390fd5b85600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925876040516123ab91906136b1565b60405180910390a350505050505050565b6000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6004602052816000526040600020602052806000526040600020600091509150505481565b600061243582612037565b9050919050565b612444612874565b73ffffffffffffffffffffffffffffffffffffffff16612462611457565b73ffffffffffffffffffffffffffffffffffffffff16146124b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124af906135d1565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161251f90613531565b60405180910390fd5b6125318161287c565b50565b6000828402905082848204148415178215151661255057600080fd5b81810490509392505050565b6000828402905082848204148415178215151661257857600080fd5b6001826001830304018115150290509392505050565b60008261259b8584612a9f565b1490509392505050565b80600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125f491906137ad565b9250508190555080600260008282540392505081905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161266991906136b1565b60405180910390a35050565b80600260008282546126879190613757565b9250508190555080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161273991906136b1565b60405180910390a35050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161277791906132e5565b60405180910390207fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016127b695949392919061341c565b60405160208183030381529060405280519060200120905090565b60006040517f23b872dd0000000000000000000000000000000000000000000000000000000081528460048201528360248201528260448201526020600060648360008a5af13d15601f3d1160016000511416171691505080612869576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286090613591565b60405180910390fd5b5050505050565b5050565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828214612984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161297b90613671565b60405180910390fd5b6001600660156101000a81548160ff021916908315150217905550826007819055506129b03084612675565b8073ffffffffffffffffffffffffffffffffffffffff167f5e2721114e39241d48a241ba2ab0e6ed19218ce65096c56e4f5b90f9fbcdd821846040516129f691906136b1565b60405180910390a2505050565b5050565b60006040517fa9059cbb000000000000000000000000000000000000000000000000000000008152836004820152826024820152602060006044836000895af13d15601f3d1160016000511416171691505080612a99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a90906135b1565b60405180910390fd5b50505050565b60008082905060005b8451811015612b2f576000858281518110612aec577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101519050808311612b0e57612b078382612b3a565b9250612b1b565b612b188184612b3a565b92505b508080612b27906138c9565b915050612aa8565b508091505092915050565b600082600052816020526040600020905092915050565b600081359050612b6081613c53565b92915050565b60008083601f840112612b7857600080fd5b8235905067ffffffffffffffff811115612b9157600080fd5b602083019150836020820283011115612ba957600080fd5b9250929050565b600081519050612bbf81613c6a565b92915050565b600081359050612bd481613c81565b92915050565b600081359050612be981613c98565b92915050565b600081519050612bfe81613c98565b92915050565b600081359050612c1381613caf565b92915050565b600060208284031215612c2b57600080fd5b6000612c3984828501612b51565b91505092915050565b60008060408385031215612c5557600080fd5b6000612c6385828601612b51565b9250506020612c7485828601612b51565b9150509250929050565b600080600060608486031215612c9357600080fd5b6000612ca186828701612b51565b9350506020612cb286828701612b51565b9250506040612cc386828701612bda565b9150509250925092565b600080600080600080600060e0888a031215612ce857600080fd5b6000612cf68a828b01612b51565b9750506020612d078a828b01612b51565b9650506040612d188a828b01612bda565b9550506060612d298a828b01612bda565b9450506080612d3a8a828b01612c04565b93505060a0612d4b8a828b01612bc5565b92505060c0612d5c8a828b01612bc5565b91505092959891949750929550565b60008060408385031215612d7e57600080fd5b6000612d8c85828601612b51565b9250506020612d9d85828601612bda565b9150509250929050565b60008060008060608587031215612dbd57600080fd5b6000612dcb87828801612b51565b9450506020612ddc87828801612bda565b935050604085013567ffffffffffffffff811115612df957600080fd5b612e0587828801612b66565b925092505092959194509250565b600060208284031215612e2557600080fd5b6000612e3384828501612bb0565b91505092915050565b600060208284031215612e4e57600080fd5b6000612e5c84828501612bda565b91505092915050565b600060208284031215612e7757600080fd5b6000612e8584828501612bef565b91505092915050565b60008060408385031215612ea157600080fd5b6000612eaf85828601612bda565b9250506020612ec085828601612b51565b9150509250929050565b600080600060608486031215612edf57600080fd5b6000612eed86828701612bda565b9350506020612efe86828701612b51565b9250506040612f0f86828701612b51565b9150509250925092565b60008060408385031215612f2c57600080fd5b6000612f3a85828601612bda565b9250506020612f4b85828601612bda565b9150509250929050565b612f5e816137e1565b82525050565b612f75612f70826137e1565b613912565b82525050565b612f84816137f3565b82525050565b612f93816137ff565b82525050565b612faa612fa5826137ff565b613924565b82525050565b60008154612fbd81613897565b612fc78186613730565b94506001821660008114612fe25760018114612ff357613026565b60ff19831686528186019350613026565b612ffc85613710565b60005b8381101561301e57815481890152600182019150602081019050612fff565b838801955050505b50505092915050565b61303881613840565b82525050565b600061304982613725565b613053818561373b565b9350613063818560208601613864565b61306c816139a8565b840191505092915050565b6000613084600b8361373b565b915061308f826139c6565b602082019050919050565b60006130a760138361373b565b91506130b2826139ef565b602082019050919050565b60006130ca60268361373b565b91506130d582613a18565b604082019050919050565b60006130ed60028361374c565b91506130f882613a67565b600282019050919050565b6000613110600d8361373b565b915061311b82613a90565b602082019050919050565b6000613133600d8361373b565b915061313e82613ab9565b602082019050919050565b600061315660148361373b565b915061316182613ae2565b602082019050919050565b6000613179600f8361373b565b915061318482613b0b565b602082019050919050565b600061319c60208361373b565b91506131a782613b34565b602082019050919050565b60006131bf600e8361373b565b91506131ca82613b5d565b602082019050919050565b60006131e2600e8361373b565b91506131ed82613b86565b602082019050919050565b6000613205600b8361373b565b915061321082613baf565b602082019050919050565b600061322860178361373b565b915061323382613bd8565b602082019050919050565b600061324b60138361373b565b915061325682613c01565b602082019050919050565b600061326e600f8361373b565b915061327982613c2a565b602082019050919050565b61328d81613829565b82525050565b6132a461329f82613829565b613940565b82525050565b6132b381613833565b82525050565b60006132c58285612f64565b6014820191506132d58284613293565b6020820191508190509392505050565b60006132f18284612fb0565b915081905092915050565b6000613307826130e0565b91506133138285612f99565b6020820191506133238284612f99565b6020820191508190509392505050565b60006020820190506133486000830184612f55565b92915050565b60006060820190506133636000830186612f55565b6133706020830185612f55565b61337d6040830184613284565b949350505050565b600060208201905061339a6000830184612f7b565b92915050565b60006020820190506133b56000830184612f8a565b92915050565b600060c0820190506133d06000830189612f8a565b6133dd6020830188612f55565b6133ea6040830187612f55565b6133f76060830186613284565b6134046080830185613284565b61341160a0830184613284565b979650505050505050565b600060a0820190506134316000830188612f8a565b61343e6020830187612f8a565b61344b6040830186612f8a565b6134586060830185613284565b6134656080830184612f55565b9695505050505050565b60006080820190506134846000830187612f8a565b61349160208301866132aa565b61349e6040830185612f8a565b6134ab6060830184612f8a565b95945050505050565b60006020820190506134c9600083018461302f565b92915050565b600060208201905081810360008301526134e9818461303e565b905092915050565b6000602082019050818103600083015261350a81613077565b9050919050565b6000602082019050818103600083015261352a8161309a565b9050919050565b6000602082019050818103600083015261354a816130bd565b9050919050565b6000602082019050818103600083015261356a81613103565b9050919050565b6000602082019050818103600083015261358a81613126565b9050919050565b600060208201905081810360008301526135aa81613149565b9050919050565b600060208201905081810360008301526135ca8161316c565b9050919050565b600060208201905081810360008301526135ea8161318f565b9050919050565b6000602082019050818103600083015261360a816131b2565b9050919050565b6000602082019050818103600083015261362a816131d5565b9050919050565b6000602082019050818103600083015261364a816131f8565b9050919050565b6000602082019050818103600083015261366a8161321b565b9050919050565b6000602082019050818103600083015261368a8161323e565b9050919050565b600060208201905081810360008301526136aa81613261565b9050919050565b60006020820190506136c66000830184613284565b92915050565b60006040820190506136e16000830185613284565b6136ee6020830184613284565b9392505050565b600060208201905061370a60008301846132aa565b92915050565b60008190508160005260206000209050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b600061376282613829565b915061376d83613829565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156137a2576137a161394a565b5b828201905092915050565b60006137b882613829565b91506137c383613829565b9250828210156137d6576137d561394a565b5b828203905092915050565b60006137ec82613809565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b600061384b82613852565b9050919050565b600061385d82613809565b9050919050565b60005b83811015613882578082015181840152602081019050613867565b83811115613891576000848401525b50505050565b600060028204905060018216806138af57607f821691505b602082108114156138c3576138c2613979565b5b50919050565b60006138d482613829565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156139075761390661394a565b5b600182019050919050565b600061391d8261392e565b9050919050565b6000819050919050565b6000613939826139b9565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f5a45524f5f534841524553000000000000000000000000000000000000000000600082015250565b7f414c52454144595f494e495449414c495a454400000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b7f494e56414c49445f50524f4f4600000000000000000000000000000000000000600082015250565b7f5452414e534645525f4641494c00000000000000000000000000000000000000600082015250565b7f5452414e534645525f46524f4d5f4641494c4544000000000000000000000000600082015250565b7f5452414e534645525f4641494c45440000000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f434c41494d5f544f4f5f48494748000000000000000000000000000000000000600082015250565b7f494e56414c49445f5349474e4552000000000000000000000000000000000000600082015250565b7f5a45524f5f415353455453000000000000000000000000000000000000000000600082015250565b7f5045524d49545f444541444c494e455f45585049524544000000000000000000600082015250565b7f494e53554646494349454e545f414d4f554e5400000000000000000000000000600082015250565b7f414c52454144595f434c41494d45440000000000000000000000000000000000600082015250565b613c5c816137e1565b8114613c6757600080fd5b50565b613c73816137f3565b8114613c7e57600080fd5b50565b613c8a816137ff565b8114613c9557600080fd5b50565b613ca181613829565b8114613cac57600080fd5b50565b613cb881613833565b8114613cc357600080fd5b5056fea264697066735822122043d69df03a002bac0a079a7abac53568908dfb3ac6776337f411081088e36c5064736f6c63430008040033

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

00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe23228b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18

-----Decoded View---------------
Arg [0] : _UNDERLYING (address): 0x35e78b3982E87ecfD5b3f3265B601c046cDBe232
Arg [1] : _merkleRoot (bytes32): 0x28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000035e78b3982e87ecfd5b3f3265b601c046cdbe232
Arg [1] : 28b0741a22d989deaf7e2182634898a13e217d4997b3a4094779c5227e104f18


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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