Contract 0x3808708e761B988d23Ae011Ed0e12674Fb66bD62 1

 
Txn Hash
Method
Block
From
To
Value
0x6325b24a310630a447e8131121c9c811af0800a91cfce352931aba5a6a538a6eDeposit156488842022-09-30 21:37:111 hr 2 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.001097513.82887416
0xda912e134eafaa0e146cbd029e888c5850f3eb1b70b3fe92f481e7be7f0a8d90Deposit156488412022-09-30 21:28:351 hr 11 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0011789114.85248818
0x986d6ac4ba7cbb0cd3529296dff3c0eac645d533962b05c48d536877905e08dbTransfer156488062022-09-30 21:21:351 hr 18 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620.16416413 Ether0.000656331.25270265
0x757cde4abd8fff974e7eae472fcd3a4446718547719009e9435cd887aa1ec80fDeposit156475572022-09-30 17:10:595 hrs 29 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0015347224.64912975
0xac0823ca5e9de5c97b3bc364c046b24e03fca42b15736f076fce7f4fc02b55f9Deposit156450752022-09-30 8:52:1113 hrs 47 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0010347813.03869348
0xce06028fba907a4787b5baaddf5a1d96f38208612ec2d50f1e4f2e483085e9dbWithdraw156398912022-09-29 15:27:591 day 7 hrs ago0x0a9a4dbaf06e99e8847cfdc2e55734eba499b111 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00128717 17.66905154
0x1b01be8c74c4d5dc2a97de80dd0eda5bb64ab26545994e8c294710df01bbf2f3Deposit156382132022-09-29 9:49:231 day 12 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0009115211.4854792
0xf63be8ee7ad6ffc741b1c31d348e10893114246e3917b44a659da6290216a896Deposit156372632022-09-29 6:38:471 day 16 hrs ago0x9813c1f451da4b6e85305e225382590a974f8a9b IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0005894 10.25705533
0xc49267cf32df859f46fa1f1c4119fb06ab5ec326425fdebc57054774d8eb94d2Deposit156284832022-09-28 1:13:592 days 21 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0011910119.13243906
0xd1742d39c5277d653c3e4b124d505c99f57881dd4816a973ebfdd6d4ece18b86Deposit156252292022-09-27 14:16:353 days 8 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0012419219.94643686
0x9f99983cdc83dec8821216c2767a746d1ea589fd381bb15f68fd14880147ed66Deposit156217762022-09-27 2:41:353 days 19 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0009597915.41516308
0x9ffb2a34e6a23ac18fd7a99973a1e48e31875a851469343238e87b2233e87fffTransfer156205172022-09-26 22:28:234 days 11 mins ago0x288ba0d95476bda324ac6673832e02b68cfb6538 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00060977 12.90701673
0x75aef47fe3765d5fedeeb59ab9ad9b0cf444e72e718f0af8bae4873fdf986cbcClaim Shares156174852022-09-26 12:15:474 days 10 hrs ago0x89842332ca286e915a4e42d257cfd58dad628206 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0005831 6.2229519
0x8d9490e9f0992e68490cfcb126e76290eca3bf668a9ba0295d563e0553ed657dClaim Shares156111572022-09-25 15:02:475 days 7 hrs ago0x000000000d5a50614bcdf08700fe6ceb1c7dad4b IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00107198 11.45309487
0x288256afab3754a2101fe32a643e9b66cc15350287725611e426efbe407594caDeposit156065542022-09-24 23:38:595 days 23 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000373574.7071484
0x16cad5d071cc685acaed91c7893486cfced32e5448003279d10d594c6132b25bDeposit156047732022-09-24 17:40:236 days 4 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000570397.1871921
0xc493612d12a9e00e4f5bc7c36f8c0cf4fb4eff36f3635b099bb5a611d9d0bbaaDeposit156039052022-09-24 14:45:596 days 7 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000289864.65636295
0x068fdbab5cf02acee635a72a0e7c2016d78e67b5d1f970245a150ff3b7563deaDeposit156010432022-09-24 5:11:116 days 17 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000461665.8171897
0x77dabd7b23271c6071fdcc3d4841dff59d9f52ea5ec3615cc2caf9b537811d28Deposit156009562022-09-24 4:53:476 days 17 hrs ago0xa5b3e71cb6130636df4f54ee3d76158ada4ba085 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00028543 4.96839819
0x3df115219f47faf7000481bea324d8adf4c49c33d93f9936249849ad3b469db2Deposit156008962022-09-24 4:41:476 days 17 hrs ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000481256.06402153
0xe8f0f86e8ed2db279209daa313610fd1fa2a379e3ce72687cdd8f76ebb31caa6Deposit155990682022-09-23 22:35:237 days 4 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00056859.12902077
0xcd7d1ed9e8fd3490f1eb53f4bcb6157288d7f8d9d132fb9da1d7125a1228f9ffDeposit155990092022-09-23 22:23:357 days 16 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000458587.36380589
0x71e988cb1d91d4020997bc836c5e91c27d273977b19ae2742b21d70518bf3c78Deposit155989692022-09-23 22:15:357 days 24 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.000518928.33281496
0xf1ffefcdfe8a4f59ca2a1f28de4881ec2446e0046526163d3dc3966d40c1dbbdDeposit155989432022-09-23 22:10:117 days 29 mins ago0xcdd37ada79f589c15bd4f8fd2083dc88e34a2af2 IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.0009382615.06648377
0x4707c9528c7a31cd6d45daa227635a7408674a807d907b44e6d1970cb8156c5fWithdraw155983572022-09-23 20:12:477 days 2 hrs agoENS Name yielder.eth IN  0x3808708e761b988d23ae011ed0e12674fb66bd620 Ether0.00038111 6.83618547
[ Download CSV Export 
View more zero value Internal Transactions in Advanced View mode
Loading

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

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


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.

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