ETH Price: $2,665.98 (+1.16%)
Gas: 1 Gwei

Contract

0x03b20614AF4079b04de65891A084f583193cEE59
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve184245872023-10-25 3:29:11291 days ago1698204551IN
0x03b20614...3193cEE59
0 ETH0.0003100212.77552489
Approve181725532023-09-19 21:11:11326 days ago1695157871IN
0x03b20614...3193cEE59
0 ETH0.0003345313.78562253
Approve177642362023-07-24 16:44:47383 days ago1690217087IN
0x03b20614...3193cEE59
0 ETH0.0013049553.77498466
Approve172241032023-05-09 16:33:35459 days ago1683650015IN
0x03b20614...3193cEE59
0 ETH0.00355428146.46592399
Approve169514132023-04-01 2:43:59498 days ago1680317039IN
0x03b20614...3193cEE59
0 ETH0.0006085825.07859815
Approve168885542023-03-23 6:45:59507 days ago1679553959IN
0x03b20614...3193cEE59
0 ETH0.0002714211.18509251
Approve167247802023-02-28 6:08:35530 days ago1677564515IN
0x03b20614...3193cEE59
0 ETH0.0004778719.69257695
Approve162819532022-12-28 8:08:11591 days ago1672214891IN
0x03b20614...3193cEE59
0 ETH0.0003089412.73127999
Approve162819292022-12-28 8:03:23591 days ago1672214603IN
0x03b20614...3193cEE59
0 ETH0.0003755515.47581627
Approve161627622022-12-11 16:48:23608 days ago1670777303IN
0x03b20614...3193cEE59
0 ETH0.0004373318.02199813
Approve157439322022-10-14 4:21:59667 days ago1665721319IN
0x03b20614...3193cEE59
0 ETH0.0003685215.18625962
Approve157146752022-10-10 2:19:59671 days ago1665368399IN
0x03b20614...3193cEE59
0 ETH0.0008267834.07038451
Approve149628242022-06-14 17:07:35788 days ago1655226455IN
0x03b20614...3193cEE59
0 ETH0.0014660360.4125804
Approve148604622022-05-28 13:10:06805 days ago1653743406IN
0x03b20614...3193cEE59
0 ETH0.0005078520.92799423
Withdraw148066712022-05-19 19:14:47814 days ago1652987687IN
0x03b20614...3193cEE59
0 ETH0.0013631724.65151223
Withdraw147142202022-05-05 1:00:50829 days ago1651712450IN
0x03b20614...3193cEE59
0 ETH0.0025743146.5535479
Withdraw147121602022-05-04 17:03:55829 days ago1651683835IN
0x03b20614...3193cEE59
0 ETH0.0037494151.78893432
Withdraw146718732022-04-28 8:40:53835 days ago1651135253IN
0x03b20614...3193cEE59
0 ETH0.0023323632.21583257
Deposit146100722022-04-18 15:54:16845 days ago1650297256IN
0x03b20614...3193cEE59
0 ETH0.0040651.64277784
Withdraw145913722022-04-15 17:45:39848 days ago1650044739IN
0x03b20614...3193cEE59
0 ETH0.0026419636.49823418
Approve145847402022-04-14 16:55:02849 days ago1649955302IN
0x03b20614...3193cEE59
0 ETH0.0011185846.09476579
Withdraw145762082022-04-13 8:56:45850 days ago1649840205IN
0x03b20614...3193cEE59
0 ETH0.0021721830.00334622
Withdraw145654862022-04-11 16:35:53852 days ago1649694953IN
0x03b20614...3193cEE59
0 ETH0.0054986375.95004983
Withdraw145650592022-04-11 14:53:06852 days ago1649688786IN
0x03b20614...3193cEE59
0 ETH0.0033683446.51774272
Withdraw145466622022-04-08 18:08:58855 days ago1649441338IN
0x03b20614...3193cEE59
0 ETH0.0032259958.33837445
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
142263082022-02-17 22:18:16905 days ago1645136296  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vault

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU AGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-02-23
*/

// Sources flattened with hardhat v2.8.4 https://hardhat.org

// File @rari-capital/solmate/src/auth/[email protected]
// SPDX-License-Identifier: GNU AGPLv3
pragma solidity >=0.8.0;

/// @notice Provides a flexible and updatable auth pattern which is completely separate from application logic.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
abstract contract Auth {
    event OwnerUpdated(address indexed user, address indexed newOwner);

    event AuthorityUpdated(address indexed user, Authority indexed newAuthority);

    address public owner;

    Authority public authority;

    constructor(address _owner, Authority _authority) {
        owner = _owner;
        authority = _authority;

        emit OwnerUpdated(msg.sender, _owner);
        emit AuthorityUpdated(msg.sender, _authority);
    }

    modifier requiresAuth() {
        require(isAuthorized(msg.sender, msg.sig), "UNAUTHORIZED");

        _;
    }

    function isAuthorized(address user, bytes4 functionSig) internal view virtual returns (bool) {
        Authority auth = authority; // Memoizing authority saves us a warm SLOAD, around 100 gas.

        // Checking if the caller is the owner only after calling the authority saves gas in most cases, but be
        // aware that this makes protected functions uncallable even to the owner if the authority is out of order.
        return (address(auth) != address(0) && auth.canCall(user, address(this), functionSig)) || user == owner;
    }

    function setAuthority(Authority newAuthority) public virtual {
        // We check if the caller is the owner first because we want to ensure they can
        // always swap out the authority even if it's reverting or using up a lot of gas.
        require(msg.sender == owner || authority.canCall(msg.sender, address(this), msg.sig));

        authority = newAuthority;

        emit AuthorityUpdated(msg.sender, newAuthority);
    }

    function setOwner(address newOwner) public virtual requiresAuth {
        owner = newOwner;

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

/// @notice A generic interface for a contract which provides authorization data to an Auth instance.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/auth/Auth.sol)
/// @author Modified from Dappsys (https://github.com/dapphub/ds-auth/blob/master/src/auth.sol)
interface Authority {
    function canCall(
        address user,
        address target,
        bytes4 functionSig
    ) external view returns (bool);
}


// File @rari-capital/solmate/src/tokens/[email protected]


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

    bytes32 public constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    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 {
            bytes32 digest = keccak256(
                abi.encodePacked(
                    "\x19\x01",
                    DOMAIN_SEPARATOR(),
                    keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
                )
            );

            address recoveredAddress = ecrecover(digest, 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 @rari-capital/solmate/src/utils/[email protected]


pragma solidity >=0.8.0;

/// @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)
/// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
library SafeTransferLib {
    /*///////////////////////////////////////////////////////////////
                            ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

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

        assembly {
            // Transfer the ETH and store if it succeeded or not.
            callStatus := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(callStatus, "ETH_TRANSFER_FAILED");
    }

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

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

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

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 100 because the calldata length is 4 + 32 * 3.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED");
    }

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

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

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 68 because the calldata length is 4 + 32 * 2.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED");
    }

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

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

            // Write the abi-encoded calldata to memory piece by piece:
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector.
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value.

            // Call the token and store if it succeeded or not.
            // We use 68 because the calldata length is 4 + 32 * 2.
            callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0)
        }

        require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED");
    }

    /*///////////////////////////////////////////////////////////////
                         INTERNAL HELPER LOGIC
    //////////////////////////////////////////////////////////////*/

    function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) {
        assembly {
            // Get how many bytes the call returned.
            let returnDataSize := returndatasize()

            // If the call reverted:
            if iszero(callStatus) {
                // Copy the revert message into memory.
                returndatacopy(0, 0, returnDataSize)

                // Revert with the same message.
                revert(0, returnDataSize)
            }

            switch returnDataSize
            case 32 {
                // Copy the return data into memory.
                returndatacopy(0, 0, returnDataSize)

                // Set success to whether it returned true.
                success := iszero(iszero(mload(0)))
            }
            case 0 {
                // There was no return data.
                success := 1
            }
            default {
                // It returned some malformed input.
                success := 0
            }
        }
    }
}


// File @rari-capital/solmate/src/tokens/[email protected]


pragma solidity >=0.8.0;

/// @notice Minimalist and modern Wrapped Ether implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/WETH.sol)
/// @author Inspired by WETH9 (https://github.com/dapphub/ds-weth/blob/master/src/weth9.sol)
contract WETH is ERC20("Wrapped Ether", "WETH", 18) {
    using SafeTransferLib for address;

    event Deposit(address indexed from, uint256 amount);

    event Withdrawal(address indexed to, uint256 amount);

    function deposit() public payable virtual {
        _mint(msg.sender, msg.value);

        emit Deposit(msg.sender, msg.value);
    }

    function withdraw(uint256 amount) public virtual {
        _burn(msg.sender, amount);

        emit Withdrawal(msg.sender, amount);

        msg.sender.safeTransferETH(amount);
    }

    receive() external payable virtual {
        deposit();
    }
}


// File @rari-capital/solmate/src/utils/[email protected]


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 <= type(uint248).max);

        y = uint248(x);
    }

    function safeCastTo128(uint256 x) internal pure returns (uint128 y) {
        require(x <= type(uint128).max);

        y = uint128(x);
    }

    function safeCastTo96(uint256 x) internal pure returns (uint96 y) {
        require(x <= type(uint96).max);

        y = uint96(x);
    }

    function safeCastTo64(uint256 x) internal pure returns (uint64 y) {
        require(x <= type(uint64).max);

        y = uint64(x);
    }

    function safeCastTo32(uint256 x) internal pure returns (uint32 y) {
        require(x <= type(uint32).max);

        y = uint32(x);
    }
}


// File srcBuild/FixedPointMathLib.sol


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 fmul(
        uint256 x,
        uint256 y,
        uint256 baseUnit
    ) internal pure returns (uint256 z) {
        assembly {
        // Store x * y in z for now.
            z := mul(x, y)

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

        // If baseUnit is zero this will return zero instead of reverting.
            z := div(z, baseUnit)
        }
    }

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

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

        // We ensure y is not zero above, so there is never division by zero here.
            z := div(z, y)
        }
    }

    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.
        // Then multiply it by 0 if z is zero, or 1 otherwise.
            z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
        }
    }

    function rpow(
        uint256 x,
        uint256 n,
        uint256 denominator
    ) internal pure returns (uint256 z) {
        assembly {
            switch x
            case 0 {
                switch n
                case 0 {
                // 0 ** 0 = 1
                    z := denominator
                }
                default {
                // 0 ** n = 0
                    z := 0
                }
            }
            default {
                switch mod(n, 2)
                case 0 {
                // If n is even, store denominator in z for now.
                    z := denominator
                }
                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, denominator)

                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, denominator)

                // 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, denominator)
                    }
                }
            }
        }
    }

    /* ///////////////////////////////////////////////////////////////
    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)
            }
            if iszero(lt(y, 0x10000000000000000)) {
                y := shr(64, y) // Like dividing by 2 ** 64.
                z := shl(32, z)
            }
            if iszero(lt(y, 0x100000000)) {
                y := shr(32, y) // Like dividing by 2 ** 32.
                z := shl(16, z)
            }
            if iszero(lt(y, 0x10000)) {
                y := shr(16, y) // Like dividing by 2 ** 16.
                z := shl(8, z)
            }
            if iszero(lt(y, 0x100)) {
                y := shr(8, y) // Like dividing by 2 ** 8.
                z := shl(4, z)
            }
            if iszero(lt(y, 0x10)) {
                y := shr(4, y) // Like dividing by 2 ** 4.
                z := shl(2, z)
            }
            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 srcBuild/interfaces/Strategy.sol


pragma solidity ^0.8.11;

/// @notice Minimal interface for Vault compatible strategies.
/// @dev Designed for out of the box compatibility with Fuse cTokens.
/// @dev Like cTokens, strategies must be transferrable ERC20s.
abstract contract Strategy is ERC20 {
    /// @notice Returns whether the strategy accepts ETH or an ERC20.
    /// @return True if the strategy accepts ETH, false otherwise.
    /// @dev Only present in Fuse cTokens, not Compound cTokens.
    function isCEther() external view virtual returns (bool);

    /// @notice Withdraws a specific amount of underlying tokens from the strategy.
    /// @param amount The amount of underlying tokens to withdraw.
    /// @return An error code, or 0 if the withdrawal was successful.
    function redeemUnderlying(uint256 amount) external virtual returns (uint256);

    /// @notice Returns a user's strategy balance in underlying tokens.
    /// @param user The user to get the underlying balance of.
    /// @return The user's strategy balance in underlying tokens.
    /// @dev May mutate the state of the strategy by accruing interest.
    function balanceOfUnderlying(address user) external virtual returns (uint256);
}

/// @notice Minimal interface for Vault strategies that accept ERC20s.
/// @dev Designed for out of the box compatibility with Fuse cERC20s.
abstract contract ERC20Strategy is Strategy {
    /// @notice Returns the underlying ERC20 token the strategy accepts.
    /// @return The underlying ERC20 token the strategy accepts.
    function underlying() external view virtual returns (ERC20);

    /// @notice Deposit a specific amount of underlying tokens into the strategy.
    /// @param amount The amount of underlying tokens to deposit.
    /// @return An error code, or 0 if the deposit was successful.
    function mint(uint256 amount) external virtual returns (uint256);
}

/// @notice Minimal interface for Vault strategies that accept ETH.
/// @dev Designed for out of the box compatibility with Fuse cEther.
abstract contract ETHStrategy is Strategy {
    /// @notice Deposit a specific amount of ETH into the strategy.
    /// @dev The amount of ETH is specified via msg.value. Reverts on error.
    function mint() external payable virtual;
}


// File srcBuild/Vault.sol


pragma solidity ^0.8.11;






/// @title Aphra Vault (avToken)
/// @author Transmissions11 and JetJadeja
/// @notice Flexible, minimalist, and gas-optimized yield
/// aggregator for earning interest on any ERC20 token.
/// @notice changes from original are to rename Rari -> Aphra tokens and any usage of rvToken => avToken
contract Vault is ERC20, Auth {
    using SafeCastLib for uint256;
    using SafeTransferLib for ERC20;
    using FixedPointMathLib for uint256;

    /* //////////////////////////////////////////////////////////////
                                 CONSTANTS
    ///////////////////////////////////////////////////////////// */

    /// @notice The maximum number of elements allowed on the withdrawal stack.
    /// @dev Needed to prevent denial of service attacks by queue operators.
    uint256 internal constant MAX_WITHDRAWAL_STACK_SIZE = 32;

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

    /// @notice The underlying token the Vault accepts.
    ERC20 public immutable UNDERLYING;

    /// @notice The base unit of the underlying token and hence avToken.
    /// @dev Equal to 10 ** decimals. Used for fixed point arithmetic.
    uint256 internal immutable BASE_UNIT;

    /// @notice Creates a new Vault that accepts a specific underlying token.
    /// @param _UNDERLYING The ERC20 compliant token the Vault should accept.
    constructor(ERC20 _UNDERLYING)
        ERC20(
            // ex:Aphra Vader Vault
            string(abi.encodePacked("Aphra ", _UNDERLYING.name(), " Vault")),
            // ex: avVader
            string(abi.encodePacked("av", _UNDERLYING.symbol())),
            // ex: 18
            _UNDERLYING.decimals()
        )
        Auth(Auth(msg.sender).owner(), Auth(msg.sender).authority())
    {
        UNDERLYING = _UNDERLYING;

        BASE_UNIT = 10**decimals;

        // Prevent minting of avTokens until
        // the initialize function is called.
        totalSupply = type(uint256).max;
    }

    /* //////////////////////////////////////////////////////////////
                           FEE CONFIGURATION
    ///////////////////////////////////////////////////////////// */

    /// @notice The percentage of profit recognized each harvest to reserve as fees.
    /// @dev A fixed point number where 1e18 represents 100% and 0 represents 0%.
    uint256 public feePercent;

    /// @notice Emitted when the fee percentage is updated.
    /// @param user The authorized user who triggered the update.
    /// @param newFeePercent The new fee percentage.
    event FeePercentUpdated(address indexed user, uint256 newFeePercent);

    /// @notice Sets a new fee percentage.
    /// @param newFeePercent The new fee percentage.
    function setFeePercent(uint256 newFeePercent) external requiresAuth {
        // A fee percentage over 100% doesn't make sense.
        require(newFeePercent <= 1e18, "FEE_TOO_HIGH");

        // Update the fee percentage.
        feePercent = newFeePercent;

        emit FeePercentUpdated(msg.sender, newFeePercent);
    }

    /* //////////////////////////////////////////////////////////////
                        HARVEST CONFIGURATION
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted when the harvest window is updated.
    /// @param user The authorized user who triggered the update.
    /// @param newHarvestWindow The new harvest window.
    event HarvestWindowUpdated(address indexed user, uint128 newHarvestWindow);

    /// @notice Emitted when the harvest delay is updated.
    /// @param user The authorized user who triggered the update.
    /// @param newHarvestDelay The new harvest delay.
    event HarvestDelayUpdated(address indexed user, uint64 newHarvestDelay);

    /// @notice Emitted when the harvest delay is scheduled to be updated next harvest.
    /// @param user The authorized user who triggered the update.
    /// @param newHarvestDelay The scheduled updated harvest delay.
    event HarvestDelayUpdateScheduled(address indexed user, uint64 newHarvestDelay);

    /// @notice The period in seconds during which multiple harvests can occur
    /// regardless if they are taking place before the harvest delay has elapsed.
    /// @dev Long harvest windows open the Vault up to profit distribution slowdown attacks.
    uint128 public harvestWindow;

    /// @notice The period in seconds over which locked profit is unlocked.
    /// @dev Cannot be 0 as it opens harvests up to sandwich attacks.
    uint64 public harvestDelay;

    /// @notice The value that will replace harvestDelay next harvest.
    /// @dev In the case that the next delay is 0, no update will be applied.
    uint64 public nextHarvestDelay;

    /// @notice Sets a new harvest window.
    /// @param newHarvestWindow The new harvest window.
    /// @dev The Vault's harvestDelay must already be set before calling.
    function setHarvestWindow(uint128 newHarvestWindow) external requiresAuth {
        // A harvest window longer than the harvest delay doesn't make sense.
        require(newHarvestWindow <= harvestDelay, "WINDOW_TOO_LONG");

        // Update the harvest window.
        harvestWindow = newHarvestWindow;

        emit HarvestWindowUpdated(msg.sender, newHarvestWindow);
    }

    /// @notice Sets a new harvest delay.
    /// @param newHarvestDelay The new harvest delay to set.
    /// @dev If the current harvest delay is 0, meaning it has not
    /// been set before, it will be updated immediately, otherwise
    /// it will be scheduled to take effect after the next harvest.
    function setHarvestDelay(uint64 newHarvestDelay) external requiresAuth {
        // A harvest delay of 0 makes harvests vulnerable to sandwich attacks.
        require(newHarvestDelay != 0, "DELAY_CANNOT_BE_ZERO");

        // A harvest delay longer than 1 year doesn't make sense.
        require(newHarvestDelay <= 365 days, "DELAY_TOO_LONG");

        // If the harvest delay is 0, meaning it has not been set before:
        if (harvestDelay == 0) {
            // We'll apply the update immediately.
            harvestDelay = newHarvestDelay;

            emit HarvestDelayUpdated(msg.sender, newHarvestDelay);
        } else {
            // We'll apply the update next harvest.
            nextHarvestDelay = newHarvestDelay;

            emit HarvestDelayUpdateScheduled(msg.sender, newHarvestDelay);
        }
    }

    /* //////////////////////////////////////////////////////////////
                       TARGET FLOAT CONFIGURATION
    ///////////////////////////////////////////////////////////// */

    /// @notice The desired percentage of the Vault's holdings to keep as float.
    /// @dev A fixed point number where 1e18 represents 100% and 0 represents 0%.
    uint256 public targetFloatPercent;

    /// @notice Emitted when the target float percentage is updated.
    /// @param user The authorized user who triggered the update.
    /// @param newTargetFloatPercent The new target float percentage.
    event TargetFloatPercentUpdated(address indexed user, uint256 newTargetFloatPercent);

    /// @notice Set a new target float percentage.
    /// @param newTargetFloatPercent The new target float percentage.
    function setTargetFloatPercent(uint256 newTargetFloatPercent) external requiresAuth {
        // A target float percentage over 100% doesn't make sense.
        require(newTargetFloatPercent <= 1e18, "TARGET_TOO_HIGH");

        // Update the target float percentage.
        targetFloatPercent = newTargetFloatPercent;

        emit TargetFloatPercentUpdated(msg.sender, newTargetFloatPercent);
    }

    /* //////////////////////////////////////////////////////////////
                   UNDERLYING IS WETH CONFIGURATION
    ///////////////////////////////////////////////////////////// */

    /// @notice Whether the Vault should treat the underlying token as WETH compatible.
    /// @dev If enabled the Vault will allow trusting strategies that accept Ether.
    bool public underlyingIsWETH;

    /// @notice Emitted when whether the Vault should treat the underlying as WETH is updated.
    /// @param user The authorized user who triggered the update.
    /// @param newUnderlyingIsWETH Whether the Vault nows treats the underlying as WETH.
    event UnderlyingIsWETHUpdated(address indexed user, bool newUnderlyingIsWETH);

    /// @notice Sets whether the Vault treats the underlying as WETH.
    /// @param newUnderlyingIsWETH Whether the Vault should treat the underlying as WETH.
    /// @dev The underlying token must have 18 decimals, to match Ether's decimal scheme.
    function setUnderlyingIsWETH(bool newUnderlyingIsWETH) external requiresAuth {
        // Ensure the underlying token's decimals match ETH if is WETH being set to true.
        require(!newUnderlyingIsWETH || UNDERLYING.decimals() == 18, "WRONG_DECIMALS");

        // Update whether the Vault treats the underlying as WETH.
        underlyingIsWETH = newUnderlyingIsWETH;

        emit UnderlyingIsWETHUpdated(msg.sender, newUnderlyingIsWETH);
    }

    /* //////////////////////////////////////////////////////////////
                          STRATEGY STORAGE
    ///////////////////////////////////////////////////////////// */

    /// @notice The total amount of underlying tokens held in strategies at the time of the last harvest.
    /// @dev Includes maxLockedProfit, must be correctly subtracted to compute available/free holdings.
    uint256 public totalStrategyHoldings;

    /// @dev Packed struct of strategy data.
    /// @param trusted Whether the strategy is trusted.
    /// @param balance The amount of underlying tokens held in the strategy.
    struct StrategyData {
        // Used to determine if the Vault will operate on a strategy.
        bool trusted;
        // Used to determine profit and loss during harvests of the strategy.
        uint248 balance;
    }

    /// @notice Maps strategies to data the Vault holds on them.
    mapping(Strategy => StrategyData) public getStrategyData;

    /* //////////////////////////////////////////////////////////////
                             HARVEST STORAGE
    ///////////////////////////////////////////////////////////// */

    /// @notice A timestamp representing when the first harvest in the most recent harvest window occurred.
    /// @dev May be equal to lastHarvest if there was/has only been one harvest in the most last/current window.
    uint64 public lastHarvestWindowStart;

    /// @notice A timestamp representing when the most recent harvest occurred.
    uint64 public lastHarvest;

    /// @notice The amount of locked profit at the end of the last harvest.
    uint128 public maxLockedProfit;

    /* //////////////////////////////////////////////////////////////
                        WITHDRAWAL STACK STORAGE
    ///////////////////////////////////////////////////////////// */

    /// @notice An ordered array of strategies representing the withdrawal stack.
    /// @dev The stack is processed in descending order, meaning the last index will be withdrawn from first.
    /// @dev Strategies that are untrusted, duplicated, or have no balance are filtered out when encountered at
    /// withdrawal time, not validated upfront, meaning the stack may not reflect the "true" set used for withdrawals.
    Strategy[] public withdrawalStack;

    /// @notice Gets the full withdrawal stack.
    /// @return An ordered array of strategies representing the withdrawal stack.
    /// @dev This is provided because Solidity converts public arrays into index getters,
    /// but we need a way to allow external contracts and users to access the whole array.
    function getWithdrawalStack() external view returns (Strategy[] memory) {
        return withdrawalStack;
    }

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

    /// @notice Emitted after a successful deposit.
    /// @param user The address that deposited into the Vault.
    /// @param underlyingAmount The amount of underlying tokens that were deposited.
    event Deposit(address indexed user, uint256 underlyingAmount);

    /// @notice Emitted after a successful withdrawal.
    /// @param user The address that withdrew from the Vault.
    /// @param underlyingAmount The amount of underlying tokens that were withdrawn.
    event Withdraw(address indexed user, uint256 underlyingAmount);

    /// @notice Deposit a specific amount of underlying tokens.
    /// @param underlyingAmount The amount of the underlying token to deposit.
    function deposit(uint256 underlyingAmount) external {
        // Determine the equivalent amount of avTokens and mint them.
        _mint(msg.sender, underlyingAmount.fdiv(exchangeRate(), BASE_UNIT));

        emit Deposit(msg.sender, underlyingAmount);

        // Transfer in underlying tokens from the user.
        // This will revert if the user does not have the amount specified.
        UNDERLYING.safeTransferFrom(msg.sender, address(this), underlyingAmount);
    }

    /// @notice Withdraw a specific amount of underlying tokens.
    /// @param underlyingAmount The amount of underlying tokens to withdraw.
    function withdraw(uint256 underlyingAmount) external {
        // Determine the equivalent amount of avTokens and burn them.
        // This will revert if the user does not have enough avTokens.
        _burn(msg.sender, underlyingAmount.fdiv(exchangeRate(), BASE_UNIT));

        emit Withdraw(msg.sender, underlyingAmount);

        // Withdraw from strategies if needed and transfer.
        transferUnderlyingTo(msg.sender, underlyingAmount);
    }

    /// @notice Redeem a specific amount of avTokens for underlying tokens.
    /// @param avTokenAmount The amount of avTokens to redeem for underlying tokens.
    function redeem(uint256 avTokenAmount) external {
        // Determine the equivalent amount of underlying tokens.
        uint256 underlyingAmount = avTokenAmount.fmul(exchangeRate(), BASE_UNIT);

        // Burn the provided amount of avTokens.
        // This will revert if the user does not have enough avTokens.
        _burn(msg.sender, avTokenAmount);

        emit Withdraw(msg.sender, underlyingAmount);

        // Withdraw from strategies if needed and transfer.
        transferUnderlyingTo(msg.sender, underlyingAmount);
    }

    /// @dev Transfers a specific amount of underlying tokens held in strategies and/or float to a recipient.
    /// @dev Only withdraws from strategies if needed and maintains the target float percentage if possible.
    /// @param recipient The user to transfer the underlying tokens to.
    /// @param underlyingAmount The amount of underlying tokens to transfer.
    function transferUnderlyingTo(address recipient, uint256 underlyingAmount) internal {
        // Get the Vault's floating balance.
        uint256 float = totalFloat();

        // If the amount is greater than the float, withdraw from strategies.
        if (underlyingAmount > float) {
            // Compute the amount needed to reach our target float percentage.
            uint256 floatMissingForTarget = (totalHoldings() - underlyingAmount).fmul(targetFloatPercent, 1e18);

            // Compute the bare minimum amount we need for this withdrawal.
            uint256 floatMissingForWithdrawal = underlyingAmount - float;

            // Pull enough to cover the withdrawal and reach our target float percentage.
            pullFromWithdrawalStack(floatMissingForWithdrawal + floatMissingForTarget);
        }

        // Transfer the provided amount of underlying tokens.
        UNDERLYING.safeTransfer(recipient, underlyingAmount);
    }

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

    /// @notice Returns a user's Vault balance in underlying tokens.
    /// @param user The user to get the underlying balance of.
    /// @return The user's Vault balance in underlying tokens.
    function balanceOfUnderlying(address user) external view returns (uint256) {
        return balanceOf[user].fmul(exchangeRate(), BASE_UNIT);
    }

    /// @notice Returns the amount of underlying tokens an avToken can be redeemed for.
    /// @return The amount of underlying tokens an avToken can be redeemed for.
    function exchangeRate() public view returns (uint256) {
        // Get the total supply of avTokens.
        uint256 avTokenSupply = totalSupply;

        // If there are no avTokens in circulation, return an exchange rate of 1:1.
        if (avTokenSupply == 0) return BASE_UNIT;

        // Calculate the exchange rate by dividing the total holdings by the avToken supply.
        return totalHoldings().fdiv(avTokenSupply, BASE_UNIT);
    }

    /// @notice Calculates the total amount of underlying tokens the Vault holds.
    /// @return totalUnderlyingHeld The total amount of underlying tokens the Vault holds.
    function totalHoldings() public view returns (uint256 totalUnderlyingHeld) {
        unchecked {
            // Cannot underflow as locked profit can't exceed total strategy holdings.
            totalUnderlyingHeld = totalStrategyHoldings - lockedProfit();
        }

        // Include our floating balance in the total.
        totalUnderlyingHeld += totalFloat();
    }

    /// @notice Calculates the current amount of locked profit.
    /// @return The current amount of locked profit.
    function lockedProfit() public view returns (uint256) {
        // Get the last harvest and harvest delay.
        uint256 previousHarvest = lastHarvest;
        uint256 harvestInterval = harvestDelay;

        unchecked {
            // If the harvest delay has passed, there is no locked profit.
            // Cannot overflow on human timescales since harvestInterval is capped.
            if (block.timestamp >= previousHarvest + harvestInterval) return 0;

            // Get the maximum amount we could return.
            uint256 maximumLockedProfit = maxLockedProfit;

            // Compute how much profit remains locked based on the last harvest and harvest delay.
            // It's impossible for the previous harvest to be in the future, so this will never underflow.
            return maximumLockedProfit - (maximumLockedProfit * (block.timestamp - previousHarvest)) / harvestInterval;
        }
    }

    /// @notice Returns the amount of underlying tokens that idly sit in the Vault.
    /// @return The amount of underlying tokens that sit idly in the Vault.
    function totalFloat() public view returns (uint256) {
        return UNDERLYING.balanceOf(address(this));
    }

    /* //////////////////////////////////////////////////////////////
                             HARVEST LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted after a successful harvest.
    /// @param user The authorized user who triggered the harvest.
    /// @param strategies The trusted strategies that were harvested.
    event Harvest(address indexed user, Strategy[] strategies);

    /// @notice Harvest a set of trusted strategies.
    /// @param strategies The trusted strategies to harvest.
    /// @dev Will always revert if called outside of an active
    /// harvest window or before the harvest delay has passed.
    function harvest(Strategy[] calldata strategies) external requiresAuth {
        // If this is the first harvest after the last window:
        if (block.timestamp >= lastHarvest + harvestDelay) {
            // Set the harvest window's start timestamp.
            // Cannot overflow 64 bits on human timescales.
            lastHarvestWindowStart = uint64(block.timestamp);
        } else {
            // We know this harvest is not the first in the window so we need to ensure it's within it.
            require(block.timestamp <= lastHarvestWindowStart + harvestWindow, "BAD_HARVEST_TIME");
        }

        // Get the Vault's current total strategy holdings.
        uint256 oldTotalStrategyHoldings = totalStrategyHoldings;

        // Used to store the total profit accrued by the strategies.
        uint256 totalProfitAccrued;

        // Used to store the new total strategy holdings after harvesting.
        uint256 newTotalStrategyHoldings = oldTotalStrategyHoldings;

        // Will revert if any of the specified strategies are untrusted.
        for (uint256 i = 0; i < strategies.length; i++) {
            // Get the strategy at the current index.
            Strategy strategy = strategies[i];

            // If an untrusted strategy could be harvested a malicious user could use
            // a fake strategy that over-reports holdings to manipulate the exchange rate.
            require(getStrategyData[strategy].trusted, "UNTRUSTED_STRATEGY");

            // Get the strategy's previous and current balance.
            uint256 balanceLastHarvest = getStrategyData[strategy].balance;
            uint256 balanceThisHarvest = strategy.balanceOfUnderlying(address(this));

            // Update the strategy's stored balance. Cast overflow is unrealistic.
            getStrategyData[strategy].balance = balanceThisHarvest.safeCastTo248();

            // Increase/decrease newTotalStrategyHoldings based on the profit/loss registered.
            // We cannot wrap the subtraction in parenthesis as it would underflow if the strategy had a loss.
            newTotalStrategyHoldings = newTotalStrategyHoldings + balanceThisHarvest - balanceLastHarvest;

            unchecked {
                // Update the total profit accrued while counting losses as zero profit.
                // Cannot overflow as we already increased total holdings without reverting.
                totalProfitAccrued += balanceThisHarvest > balanceLastHarvest
                    ? balanceThisHarvest - balanceLastHarvest // Profits since last harvest.
                    : 0; // If the strategy registered a net loss we don't have any new profit.
            }
        }

        // Compute fees as the fee percent multiplied by the profit.
        uint256 feesAccrued = totalProfitAccrued.fmul(feePercent, 1e18);

        // If we accrued any fees, mint an equivalent amount of avTokens.
        // Authorized users can claim the newly minted avTokens via claimFees.
        _mint(address(this), feesAccrued.fdiv(exchangeRate(), BASE_UNIT));

        // Update max unlocked profit based on any remaining locked profit plus new profit.
        maxLockedProfit = (lockedProfit() + totalProfitAccrued - feesAccrued).safeCastTo128();

        // Set strategy holdings to our new total.
        totalStrategyHoldings = newTotalStrategyHoldings;

        // Update the last harvest timestamp.
        // Cannot overflow on human timescales.
        lastHarvest = uint64(block.timestamp);

        emit Harvest(msg.sender, strategies);

        // Get the next harvest delay.
        uint64 newHarvestDelay = nextHarvestDelay;

        // If the next harvest delay is not 0:
        if (newHarvestDelay != 0) {
            // Update the harvest delay.
            harvestDelay = newHarvestDelay;

            // Reset the next harvest delay.
            nextHarvestDelay = 0;

            emit HarvestDelayUpdated(msg.sender, newHarvestDelay);
        }
    }

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

    /// @notice Emitted after the Vault deposits into a strategy contract.
    /// @param user The authorized user who triggered the deposit.
    /// @param strategy The strategy that was deposited into.
    /// @param underlyingAmount The amount of underlying tokens that were deposited.
    event StrategyDeposit(address indexed user, Strategy indexed strategy, uint256 underlyingAmount);

    /// @notice Emitted after the Vault withdraws funds from a strategy contract.
    /// @param user The authorized user who triggered the withdrawal.
    /// @param strategy The strategy that was withdrawn from.
    /// @param underlyingAmount The amount of underlying tokens that were withdrawn.
    event StrategyWithdrawal(address indexed user, Strategy indexed strategy, uint256 underlyingAmount);

    /// @notice Deposit a specific amount of float into a trusted strategy.
    /// @param strategy The trusted strategy to deposit into.
    /// @param underlyingAmount The amount of underlying tokens in float to deposit.
    function depositIntoStrategy(Strategy strategy, uint256 underlyingAmount) external requiresAuth {
        // A strategy must be trusted before it can be deposited into.
        require(getStrategyData[strategy].trusted, "UNTRUSTED_STRATEGY");

        // Increase totalStrategyHoldings to account for the deposit.
        totalStrategyHoldings += underlyingAmount;

        unchecked {
            // Without this the next harvest would count the deposit as profit.
            // Cannot overflow as the balance of one strategy can't exceed the sum of all.
            getStrategyData[strategy].balance += underlyingAmount.safeCastTo248();
        }

        emit StrategyDeposit(msg.sender, strategy, underlyingAmount);

        // We need to deposit differently if the strategy takes ETH.
        if (strategy.isCEther()) {
            // Unwrap the right amount of WETH.
            WETH(payable(address(UNDERLYING))).withdraw(underlyingAmount);

            // Deposit into the strategy and assume it will revert on error.
            ETHStrategy(address(strategy)).mint{value: underlyingAmount}();
        } else {
            // Approve underlyingAmount to the strategy so we can deposit.
            UNDERLYING.safeApprove(address(strategy), underlyingAmount);

            // Deposit into the strategy and revert if it returns an error code.
            require(ERC20Strategy(address(strategy)).mint(underlyingAmount) == 0, "MINT_FAILED");
        }
    }

    /// @notice Withdraw a specific amount of underlying tokens from a strategy.
    /// @param strategy The strategy to withdraw from.
    /// @param underlyingAmount  The amount of underlying tokens to withdraw.
    /// @dev Withdrawing from a strategy will not remove it from the withdrawal stack.
    function withdrawFromStrategy(Strategy strategy, uint256 underlyingAmount) external requiresAuth {
        // A strategy must be trusted before it can be withdrawn from.
        require(getStrategyData[strategy].trusted, "UNTRUSTED_STRATEGY");

        // Without this the next harvest would count the withdrawal as a loss.
        getStrategyData[strategy].balance -= underlyingAmount.safeCastTo248();

        unchecked {
            // Decrease totalStrategyHoldings to account for the withdrawal.
            // Cannot underflow as the balance of one strategy will never exceed the sum of all.
            totalStrategyHoldings -= underlyingAmount;
        }

        emit StrategyWithdrawal(msg.sender, strategy, underlyingAmount);

        // Withdraw from the strategy and revert if it returns an error code.
        require(strategy.redeemUnderlying(underlyingAmount) == 0, "REDEEM_FAILED");

        // Wrap the withdrawn Ether into WETH if necessary.
        if (strategy.isCEther()) WETH(payable(address(UNDERLYING))).deposit{value: underlyingAmount}();
    }

    /* //////////////////////////////////////////////////////////////
                      STRATEGY TRUST/DISTRUST LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted when a strategy is set to trusted.
    /// @param user The authorized user who trusted the strategy.
    /// @param strategy The strategy that became trusted.
    event StrategyTrusted(address indexed user, Strategy indexed strategy);

    /// @notice Emitted when a strategy is set to untrusted.
    /// @param user The authorized user who untrusted the strategy.
    /// @param strategy The strategy that became untrusted.
    event StrategyDistrusted(address indexed user, Strategy indexed strategy);

    /// @notice Stores a strategy as trusted, enabling it to be harvested.
    /// @param strategy The strategy to make trusted.
    function trustStrategy(Strategy strategy) external requiresAuth {
        // Ensure the strategy accepts the correct underlying token.
        // If the strategy accepts ETH the Vault should accept WETH, it'll handle wrapping when necessary.
        require(
            strategy.isCEther() ? underlyingIsWETH : ERC20Strategy(address(strategy)).underlying() == UNDERLYING,
            "WRONG_UNDERLYING"
        );

        // Store the strategy as trusted.
        getStrategyData[strategy].trusted = true;

        emit StrategyTrusted(msg.sender, strategy);
    }

    /// @notice Stores a strategy as untrusted, disabling it from being harvested.
    /// @param strategy The strategy to make untrusted.
    function distrustStrategy(Strategy strategy) external requiresAuth {
        // Store the strategy as untrusted.
        getStrategyData[strategy].trusted = false;

        emit StrategyDistrusted(msg.sender, strategy);
    }

    /* //////////////////////////////////////////////////////////////
                         WITHDRAWAL STACK LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted when a strategy is pushed to the withdrawal stack.
    /// @param user The authorized user who triggered the push.
    /// @param pushedStrategy The strategy pushed to the withdrawal stack.
    event WithdrawalStackPushed(address indexed user, Strategy indexed pushedStrategy);

    /// @notice Emitted when a strategy is popped from the withdrawal stack.
    /// @param user The authorized user who triggered the pop.
    /// @param poppedStrategy The strategy popped from the withdrawal stack.
    event WithdrawalStackPopped(address indexed user, Strategy indexed poppedStrategy);

    /// @notice Emitted when the withdrawal stack is updated.
    /// @param user The authorized user who triggered the set.
    /// @param replacedWithdrawalStack The new withdrawal stack.
    event WithdrawalStackSet(address indexed user, Strategy[] replacedWithdrawalStack);

    /// @notice Emitted when an index in the withdrawal stack is replaced.
    /// @param user The authorized user who triggered the replacement.
    /// @param index The index of the replaced strategy in the withdrawal stack.
    /// @param replacedStrategy The strategy in the withdrawal stack that was replaced.
    /// @param replacementStrategy The strategy that overrode the replaced strategy at the index.
    event WithdrawalStackIndexReplaced(
        address indexed user,
        uint256 index,
        Strategy indexed replacedStrategy,
        Strategy indexed replacementStrategy
    );

    /// @notice Emitted when an index in the withdrawal stack is replaced with the tip.
    /// @param user The authorized user who triggered the replacement.
    /// @param index The index of the replaced strategy in the withdrawal stack.
    /// @param replacedStrategy The strategy in the withdrawal stack replaced by the tip.
    /// @param previousTipStrategy The previous tip of the stack that replaced the strategy.
    event WithdrawalStackIndexReplacedWithTip(
        address indexed user,
        uint256 index,
        Strategy indexed replacedStrategy,
        Strategy indexed previousTipStrategy
    );

    /// @notice Emitted when the strategies at two indexes are swapped.
    /// @param user The authorized user who triggered the swap.
    /// @param index1 One index involved in the swap
    /// @param index2 The other index involved in the swap.
    /// @param newStrategy1 The strategy (previously at index2) that replaced index1.
    /// @param newStrategy2 The strategy (previously at index1) that replaced index2.
    event WithdrawalStackIndexesSwapped(
        address indexed user,
        uint256 index1,
        uint256 index2,
        Strategy indexed newStrategy1,
        Strategy indexed newStrategy2
    );

    /// @dev Withdraw a specific amount of underlying tokens from strategies in the withdrawal stack.
    /// @param underlyingAmount The amount of underlying tokens to pull into float.
    /// @dev Automatically removes depleted strategies from the withdrawal stack.
    function pullFromWithdrawalStack(uint256 underlyingAmount) internal {
        // We will update this variable as we pull from strategies.
        uint256 amountLeftToPull = underlyingAmount;

        // We'll start at the tip of the stack and traverse backwards.
        uint256 currentIndex = withdrawalStack.length - 1;

        // Iterate in reverse so we pull from the stack in a "last in, first out" manner.
        // Will revert due to underflow if we empty the stack before pulling the desired amount.
        for (; ; currentIndex--) {
            // Get the strategy at the current stack index.
            Strategy strategy = withdrawalStack[currentIndex];

            // Get the balance of the strategy before we withdraw from it.
            uint256 strategyBalance = getStrategyData[strategy].balance;

            // If the strategy is currently untrusted or was already depleted:
            if (!getStrategyData[strategy].trusted || strategyBalance == 0) {
                // Remove it from the stack.
                withdrawalStack.pop();

                emit WithdrawalStackPopped(msg.sender, strategy);

                // Move onto the next strategy.
                continue;
            }

            // We want to pull as much as we can from the strategy, but no more than we need.
            uint256 amountToPull = strategyBalance > amountLeftToPull ? amountLeftToPull : strategyBalance;

            unchecked {
                // Compute the balance of the strategy that will remain after we withdraw.
                // Cannot underflow as we cap the amount to pull at the strategy's balance.
                uint256 strategyBalanceAfterWithdrawal = strategyBalance - amountToPull;

                // Without this the next harvest would count the withdrawal as a loss.
                getStrategyData[strategy].balance = strategyBalanceAfterWithdrawal.safeCastTo248();

                // Adjust our goal based on how much we can pull from the strategy.
                // Cannot underflow as we cap the amount to pull at the amount left to pull.
                amountLeftToPull -= amountToPull;

                emit StrategyWithdrawal(msg.sender, strategy, amountToPull);

                // Withdraw from the strategy and revert if returns an error code.
                require(strategy.redeemUnderlying(amountToPull) == 0, "REDEEM_FAILED");

                // If we fully depleted the strategy:
                if (strategyBalanceAfterWithdrawal == 0) {
                    // Remove it from the stack.
                    withdrawalStack.pop();

                    emit WithdrawalStackPopped(msg.sender, strategy);
                }
            }

            // If we've pulled all we need, exit the loop.
            if (amountLeftToPull == 0) break;
        }

        unchecked {
            // Account for the withdrawals done in the loop above.
            // Cannot underflow as the balances of some strategies cannot exceed the sum of all.
            totalStrategyHoldings -= underlyingAmount;
        }

        // Cache the Vault's balance of ETH.
        uint256 ethBalance = address(this).balance;

        // If the Vault's underlying token is WETH compatible and we have some ETH, wrap it into WETH.
        if (ethBalance != 0 && underlyingIsWETH) WETH(payable(address(UNDERLYING))).deposit{value: ethBalance}();
    }

    /// @notice Pushes a single strategy to front of the withdrawal stack.
    /// @param strategy The strategy to be inserted at the front of the withdrawal stack.
    /// @dev Strategies that are untrusted, duplicated, or have no balance are
    /// filtered out when encountered at withdrawal time, not validated upfront.
    function pushToWithdrawalStack(Strategy strategy) external requiresAuth {
        // Ensure pushing the strategy will not cause the stack exceed its limit.
        require(withdrawalStack.length < MAX_WITHDRAWAL_STACK_SIZE, "STACK_FULL");

        // Push the strategy to the front of the stack.
        withdrawalStack.push(strategy);

        emit WithdrawalStackPushed(msg.sender, strategy);
    }

    /// @notice Removes the strategy at the tip of the withdrawal stack.
    /// @dev Be careful, another authorized user could push a different strategy
    /// than expected to the stack while a popFromWithdrawalStack transaction is pending.
    function popFromWithdrawalStack() external requiresAuth {
        // Get the (soon to be) popped strategy.
        Strategy poppedStrategy = withdrawalStack[withdrawalStack.length - 1];

        // Pop the first strategy in the stack.
        withdrawalStack.pop();

        emit WithdrawalStackPopped(msg.sender, poppedStrategy);
    }

    /// @notice Sets a new withdrawal stack.
    /// @param newStack The new withdrawal stack.
    /// @dev Strategies that are untrusted, duplicated, or have no balance are
    /// filtered out when encountered at withdrawal time, not validated upfront.
    function setWithdrawalStack(Strategy[] calldata newStack) external requiresAuth {
        // Ensure the new stack is not larger than the maximum stack size.
        require(newStack.length <= MAX_WITHDRAWAL_STACK_SIZE, "STACK_TOO_BIG");

        // Replace the withdrawal stack.
        withdrawalStack = newStack;

        emit WithdrawalStackSet(msg.sender, newStack);
    }

    /// @notice Replaces an index in the withdrawal stack with another strategy.
    /// @param index The index in the stack to replace.
    /// @param replacementStrategy The strategy to override the index with.
    /// @dev Strategies that are untrusted, duplicated, or have no balance are
    /// filtered out when encountered at withdrawal time, not validated upfront.
    function replaceWithdrawalStackIndex(uint256 index, Strategy replacementStrategy) external requiresAuth {
        // Get the (soon to be) replaced strategy.
        Strategy replacedStrategy = withdrawalStack[index];

        // Update the index with the replacement strategy.
        withdrawalStack[index] = replacementStrategy;

        emit WithdrawalStackIndexReplaced(msg.sender, index, replacedStrategy, replacementStrategy);
    }

    /// @notice Moves the strategy at the tip of the stack to the specified index and pop the tip off the stack.
    /// @param index The index of the strategy in the withdrawal stack to replace with the tip.
    function replaceWithdrawalStackIndexWithTip(uint256 index) external requiresAuth {
        // Get the (soon to be) previous tip and strategy we will replace at the index.
        Strategy previousTipStrategy = withdrawalStack[withdrawalStack.length - 1];
        Strategy replacedStrategy = withdrawalStack[index];

        // Replace the index specified with the tip of the stack.
        withdrawalStack[index] = previousTipStrategy;

        // Remove the now duplicated tip from the array.
        withdrawalStack.pop();

        emit WithdrawalStackIndexReplacedWithTip(msg.sender, index, replacedStrategy, previousTipStrategy);
    }

    /// @notice Swaps two indexes in the withdrawal stack.
    /// @param index1 One index involved in the swap
    /// @param index2 The other index involved in the swap.
    function swapWithdrawalStackIndexes(uint256 index1, uint256 index2) external requiresAuth {
        // Get the (soon to be) new strategies at each index.
        Strategy newStrategy2 = withdrawalStack[index1];
        Strategy newStrategy1 = withdrawalStack[index2];

        // Swap the strategies at both indexes.
        withdrawalStack[index1] = newStrategy1;
        withdrawalStack[index2] = newStrategy2;

        emit WithdrawalStackIndexesSwapped(msg.sender, index1, index2, newStrategy1, newStrategy2);
    }

    /* //////////////////////////////////////////////////////////////
                         SEIZE STRATEGY LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted after a strategy is seized.
    /// @param user The authorized user who triggered the seize.
    /// @param strategy The strategy that was seized.
    event StrategySeized(address indexed user, Strategy indexed strategy);

    /// @notice Seizes a strategy.
    /// @param strategy The strategy to seize.
    /// @dev Intended for use in emergencies or other extraneous situations where the
    /// strategy requires interaction outside of the Vault's standard operating procedures.
    function seizeStrategy(Strategy strategy) external requiresAuth {
        // Get the strategy's last reported balance of underlying tokens.
        uint256 strategyBalance = getStrategyData[strategy].balance;

        // If the strategy's balance exceeds the Vault's current
        // holdings, instantly unlock any remaining locked profit.
        if (strategyBalance > totalHoldings()) maxLockedProfit = 0;

        // Set the strategy's balance to 0.
        getStrategyData[strategy].balance = 0;

        unchecked {
            // Decrease totalStrategyHoldings to account for the seize.
            // Cannot underflow as the balance of one strategy will never exceed the sum of all.
            totalStrategyHoldings -= strategyBalance;
        }

        emit StrategySeized(msg.sender, strategy);

        // Transfer all of the strategy's tokens to the caller.
        ERC20(strategy).safeTransfer(msg.sender, strategy.balanceOf(address(this)));
    }

    /* //////////////////////////////////////////////////////////////
                             FEE CLAIM LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted after fees are claimed.
    /// @param user The authorized user who claimed the fees.
    /// @param avTokenAmount The amount of avTokens that were claimed.
    event FeesClaimed(address indexed user, uint256 avTokenAmount);

    /// @notice Claims fees accrued from harvests.
    /// @param avTokenAmount The amount of avTokens to claim.
    /// @dev Accrued fees are measured as avTokens held by the Vault.
    function claimFees(uint256 avTokenAmount) external requiresAuth {
        emit FeesClaimed(msg.sender, avTokenAmount);

        // Transfer the provided amount of avTokens to the caller.
        ERC20(this).safeTransfer(msg.sender, avTokenAmount);
    }

    /* //////////////////////////////////////////////////////////////
                    INITIALIZATION AND DESTRUCTION LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @notice Emitted when the Vault is initialized.
    /// @param user The authorized user who triggered the initialization.
    event Initialized(address indexed user);

    /// @notice Whether the Vault has been initialized yet.
    /// @dev Can go from false to true, never from true to false.
    bool public isInitialized;

    /// @notice Initializes the Vault, enabling it to receive deposits.
    /// @dev All critical parameters must already be set before calling.
    function initialize() external requiresAuth {
        // Ensure the Vault has not already been initialized.
        require(!isInitialized, "ALREADY_INITIALIZED");

        // Mark the Vault as initialized.
        isInitialized = true;

        // Open for deposits.
        totalSupply = 0;

        emit Initialized(msg.sender);
    }

    /// @notice Self destructs a Vault, enabling it to be redeployed.
    /// @dev Caller will receive any ETH held as float in the Vault.
    function destroy() external requiresAuth {
        selfdestruct(payable(msg.sender));
    }

    /* //////////////////////////////////////////////////////////////
                          RECIEVE ETHER LOGIC
    ///////////////////////////////////////////////////////////// */

    /// @dev Required for the Vault to receive unwrapped ETH.
    receive() external payable {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"contract ERC20","name":"_UNDERLYING","type":"address"}],"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"},{"indexed":true,"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"newFeePercent","type":"uint256"}],"name":"FeePercentUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"avTokenAmount","type":"uint256"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"contract Strategy[]","name":"strategies","type":"address[]"}],"name":"Harvest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint64","name":"newHarvestDelay","type":"uint64"}],"name":"HarvestDelayUpdateScheduled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint64","name":"newHarvestDelay","type":"uint64"}],"name":"HarvestDelayUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint128","name":"newHarvestWindow","type":"uint128"}],"name":"HarvestWindowUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"StrategyDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"StrategyDistrusted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"StrategySeized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"StrategyTrusted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"strategy","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"StrategyWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTargetFloatPercent","type":"uint256"}],"name":"TargetFloatPercentUpdated","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":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"newUnderlyingIsWETH","type":"bool"}],"name":"UnderlyingIsWETHUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":true,"internalType":"contract Strategy","name":"replacedStrategy","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"replacementStrategy","type":"address"}],"name":"WithdrawalStackIndexReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":true,"internalType":"contract Strategy","name":"replacedStrategy","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"previousTipStrategy","type":"address"}],"name":"WithdrawalStackIndexReplacedWithTip","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"index1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"index2","type":"uint256"},{"indexed":true,"internalType":"contract Strategy","name":"newStrategy1","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"newStrategy2","type":"address"}],"name":"WithdrawalStackIndexesSwapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"poppedStrategy","type":"address"}],"name":"WithdrawalStackPopped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"contract Strategy","name":"pushedStrategy","type":"address"}],"name":"WithdrawalStackPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"contract Strategy[]","name":"replacedWithdrawalStack","type":"address[]"}],"name":"WithdrawalStackSet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","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":"authority","outputs":[{"internalType":"contract Authority","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":"user","type":"address"}],"name":"balanceOfUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"avTokenAmount","type":"uint256"}],"name":"claimFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"strategy","type":"address"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"depositIntoStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"distrustStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"","type":"address"}],"name":"getStrategyData","outputs":[{"internalType":"bool","name":"trusted","type":"bool"},{"internalType":"uint248","name":"balance","type":"uint248"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWithdrawalStack","outputs":[{"internalType":"contract Strategy[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract Strategy[]","name":"strategies","type":"address[]"}],"name":"harvest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"harvestDelay","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"harvestWindow","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHarvest","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHarvestWindowStart","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxLockedProfit","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextHarvestDelay","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"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":[],"name":"popFromWithdrawalStack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"pushToWithdrawalStack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"avTokenAmount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"contract Strategy","name":"replacementStrategy","type":"address"}],"name":"replaceWithdrawalStackIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"replaceWithdrawalStackIndexWithTip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"strategy","type":"address"}],"name":"seizeStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Authority","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeePercent","type":"uint256"}],"name":"setFeePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newHarvestDelay","type":"uint64"}],"name":"setHarvestDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"newHarvestWindow","type":"uint128"}],"name":"setHarvestWindow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTargetFloatPercent","type":"uint256"}],"name":"setTargetFloatPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"newUnderlyingIsWETH","type":"bool"}],"name":"setUnderlyingIsWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy[]","name":"newStack","type":"address[]"}],"name":"setWithdrawalStack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index1","type":"uint256"},{"internalType":"uint256","name":"index2","type":"uint256"}],"name":"swapWithdrawalStackIndexes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"targetFloatPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalFloat","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalHoldings","outputs":[{"internalType":"uint256","name":"totalUnderlyingHeld","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStrategyHoldings","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":"contract Strategy","name":"strategy","type":"address"}],"name":"trustStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlyingIsWETH","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract Strategy","name":"strategy","type":"address"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"withdrawFromStrategy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"withdrawalStack","outputs":[{"internalType":"contract Strategy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101206040523480156200001257600080fd5b506040516200488a3803806200488a8339810160408190526200003591620004db565b336001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000074573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200009a9190620004db565b336001600160a01b031663bf7e214f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620000d9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000ff9190620004db565b826001600160a01b03166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa1580156200013e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526200016891908101906200054b565b6040516020016200017a919062000603565b604051602081830303815290604052836001600160a01b03166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa158015620001c8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620001f291908101906200054b565b60405160200162000204919062000643565b604051602081830303815290604052846001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000252573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200027891906200066f565b82516200028d9060009060208601906200041c565b508151620002a39060019060208501906200041c565b5060ff81166080524660a052620002b962000380565b60c0525050600680546001600160a01b038086166001600160a01b03199283168117909355600780549186169190921617905560405190915033907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a36040516001600160a01b0382169033907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350506001600160a01b03811660e0526080516200036f90600a620007a9565b61010052506000196002556200089b565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620003b49190620007f7565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b8280546200042a90620007ba565b90600052602060002090601f0160209004810192826200044e576000855562000499565b82601f106200046957805160ff191683800117855562000499565b8280016001018555821562000499579182015b82811115620004995782518255916020019190600101906200047c565b50620004a7929150620004ab565b5090565b5b80821115620004a75760008155600101620004ac565b6001600160a01b0381168114620004d857600080fd5b50565b600060208284031215620004ee57600080fd5b8151620004fb81620004c2565b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620005355781810151838201526020016200051b565b8381111562000545576000848401525b50505050565b6000602082840312156200055e57600080fd5b81516001600160401b03808211156200057657600080fd5b818401915084601f8301126200058b57600080fd5b815181811115620005a057620005a062000502565b604051601f8201601f19908116603f01168101908382118183101715620005cb57620005cb62000502565b81604052828152876020848701011115620005e557600080fd5b620005f883602083016020880162000518565b979650505050505050565b65020b8343930960d51b8152600082516200062681600685016020870162000518565b650815985d5b1d60d21b6006939091019283015250600c01919050565b6130bb60f11b8152600082516200066281600285016020870162000518565b9190910160020192915050565b6000602082840312156200068257600080fd5b815160ff81168114620004fb57600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b80851115620006eb578160001904821115620006cf57620006cf62000694565b80851615620006dd57918102915b93841c9390800290620006af565b509250929050565b6000826200070457506001620007a3565b816200071357506000620007a3565b81600181146200072c5760028114620007375762000757565b6001915050620007a3565b60ff8411156200074b576200074b62000694565b50506001821b620007a3565b5060208310610133831016604e8410600b84101617156200077c575081810a620007a3565b620007888383620006aa565b80600019048211156200079f576200079f62000694565b0290505b92915050565b6000620004fb60ff841683620006f3565b600181811c90821680620007cf57607f821691505b60208210811415620007f157634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200081457607f831692505b60208084108214156200083557634e487b7160e01b86526022600452602486fd5b8180156200084c57600181146200085e576200088d565b60ff198616895284890196506200088d565b60008a81526020902060005b86811015620008855781548b8201529085019083016200086a565b505084890196505b509498975050505050505050565b60805160a05160c05160e05161010051613f4f6200093b60003960008181611434015281816116c8015281816116ff0152818161172a0152612c9d0152600081816109db015281816114db01528181611dc701528181612145015281816122110152818161246e0152818161251a01528181612dc8015281816131ed015261377e0152600061167d015260006116480152600061061b0152613f4f6000f3fe60806040526004361061039b5760003560e01c80637ce3489b116101dc578063c5d664c611610102578063e9ec2e99116100a0578063eed74e671161006f578063eed74e6714610b5f578063f1a392da14610b7f578063f84d73f414610ba6578063f97d2ed714610bc057600080fd5b8063e9ec2e9914610af4578063ec523afd14610b09578063ecad956514610b29578063ed2c552114610b3f57600080fd5b8063d00364be116100dc578063d00364be14610a3d578063d505accf14610a7c578063db006a7514610a9c578063dd62ed3e14610abc57600080fd5b8063c5d664c6146109c9578063c866983b146109fd578063c89d346014610a1d57600080fd5b806395d89b411161017a578063b6b55f2511610149578063b6b55f2514610949578063bd662f8814610969578063bdf06c8e14610989578063bf7e214f146109a957600080fd5b806395d89b41146108d4578063a9059cbb146108e9578063ac68a74814610909578063b53d09581461092957600080fd5b80638129fc1c116101b65780638129fc1c1461087557806383197ef01461088a578063841219e51461089f5780638da5cb5b146108b457600080fd5b80637ce3489b146108125780637ecebe00146108325780637fd6f15c1461085f57600080fd5b8063313ce567116102c1578063448f56b91161025f57806370a082311161022e57806370a082311461077e578063797ba463146107ab5780637a9e5e4b146107d25780637b72aeb9146107f257600080fd5b8063448f56b9146106f557806344b81396146107345780634a3c39901461074957806360dc8fac1461076957600080fd5b80633644e5151161029b5780633644e51514610691578063392e53cd146106a65780633af9e669146106c05780633ba0b9a9146106e057600080fd5b8063313ce5671461060957806332ff77321461064f57806334051c031461066f57600080fd5b80631c693478116103395780632493fea6116103085780632493fea6146105365780632968676e146105565780632e1a7d4d146105b557806330adf81f146105d557600080fd5b80631c693478146104c057806320ea2cc3146104d657806323152745146104f657806323b872dd1461051657600080fd5b8063136a8ce711610375578063136a8ce71461042457806313af40351461045c57806316e5440a1461047c57806318160ddd1461049c57600080fd5b806306fdde03146103a757806307b35d1d146103d2578063095ea7b3146103f457600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103bc610be0565b6040516103c99190613865565b60405180910390f35b3480156103de57600080fd5b506103f26103ed3660046138ba565b610c6e565b005b34801561040057600080fd5b5061041461040f3660046138ff565b610d66565b60405190151581526020016103c9565b34801561043057600080fd5b5061044461043f36600461392b565b610dd2565b6040516001600160a01b0390911681526020016103c9565b34801561046857600080fd5b506103f2610477366004613944565b610dfc565b34801561048857600080fd5b506103f261049736600461392b565b610e7a565b3480156104a857600080fd5b506104b260025481565b6040519081526020016103c9565b3480156104cc57600080fd5b506104b2600a5481565b3480156104e257600080fd5b506103f26104f1366004613944565b610fde565b34801561050257600080fd5b506103f2610511366004613961565b611128565b34801561052257600080fd5b506104146105313660046139d5565b6111ef565b34801561054257600080fd5b506103f2610551366004613a16565b6112cf565b34801561056257600080fd5b50610596610571366004613944565b600d6020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b039091166020830152016103c9565b3480156105c157600080fd5b506103f26105d036600461392b565b611421565b3480156105e157600080fd5b506104b27f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b34801561061557600080fd5b5061063d7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103c9565b34801561065b57600080fd5b506103f261066a366004613a46565b61149f565b34801561067b57600080fd5b506106846115e2565b6040516103c99190613a63565b34801561069d57600080fd5b506104b2611644565b3480156106b257600080fd5b506010546104149060ff1681565b3480156106cc57600080fd5b506104b26106db366004613944565b61169f565b3480156106ec57600080fd5b506104b26116f2565b34801561070157600080fd5b5060095461071c90600160801b90046001600160401b031681565b6040516001600160401b0390911681526020016103c9565b34801561074057600080fd5b506104b261175e565b34801561075557600080fd5b506103f2610764366004613944565b6117c5565b34801561077557600080fd5b506103f26118b1565b34801561078a57600080fd5b506104b2610799366004613944565b60036020526000908152604090205481565b3480156107b757600080fd5b5060095461071c90600160c01b90046001600160401b031681565b3480156107de57600080fd5b506103f26107ed366004613944565b61198e565b3480156107fe57600080fd5b506103f261080d366004613ab0565b611a78565b34801561081e57600080fd5b506103f261082d36600461392b565b611c11565b34801561083e57600080fd5b506104b261084d366004613944565b60056020526000908152604090205481565b34801561086b57600080fd5b506104b260085481565b34801561088157600080fd5b506103f2611cc1565b34801561089657600080fd5b506103f2611d7a565b3480156108ab57600080fd5b506104b2611daf565b3480156108c057600080fd5b50600654610444906001600160a01b031681565b3480156108e057600080fd5b506103bc611e3a565b3480156108f557600080fd5b506104146109043660046138ff565b611e47565b34801561091557600080fd5b506103f261092436600461392b565b611ead565b34801561093557600080fd5b506103f26109443660046138ff565b611f1f565b34801561095557600080fd5b506103f261096436600461392b565b6121bb565b34801561097557600080fd5b506103f261098436600461392b565b612239565b34801561099557600080fd5b506103f26109a43660046138ff565b6122ec565b3480156109b557600080fd5b50600754610444906001600160a01b031681565b3480156109d557600080fd5b506104447f000000000000000000000000000000000000000000000000000000000000000081565b348015610a0957600080fd5b506103f2610a18366004613944565b6125e7565b348015610a2957600080fd5b506103f2610a38366004613961565b612663565b348015610a4957600080fd5b50600e54610a6490600160801b90046001600160801b031681565b6040516001600160801b0390911681526020016103c9565b348015610a8857600080fd5b506103f2610a97366004613ae8565b612a3b565b348015610aa857600080fd5b506103f2610ab736600461392b565b612c8c565b348015610ac857600080fd5b506104b2610ad7366004613b59565b600460209081526000928352604080842090915290825290205481565b348015610b0057600080fd5b506104b2612d0c565b348015610b1557600080fd5b506103f2610b24366004613944565b612d2e565b348015610b3557600080fd5b506104b2600c5481565b348015610b4b57600080fd5b506103f2610b5a366004613b92565b612ef4565b348015610b6b57600080fd5b50600e5461071c906001600160401b031681565b348015610b8b57600080fd5b50600e5461071c90600160401b90046001600160401b031681565b348015610bb257600080fd5b50600b546104149060ff1681565b348015610bcc57600080fd5b50600954610a64906001600160801b031681565b60008054610bed90613bb7565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990613bb7565b8015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b505050505081565b610c84336000356001600160e01b031916612fc7565b610ca95760405162461bcd60e51b8152600401610ca090613bf2565b60405180910390fd5b600954600160801b90046001600160401b03166001600160801b0382161115610d065760405162461bcd60e51b815260206004820152600f60248201526e57494e444f575f544f4f5f4c4f4e4760881b6044820152606401610ca0565b600980546fffffffffffffffffffffffffffffffff19166001600160801b03831690811790915560405190815233907ff61ebd3c01f656aba479c738a8744215d6f1ec2c19169500f3bff0a9d8374ce1906020015b60405180910390a250565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610dc19086815260200190565b60405180910390a350600192915050565b600f8181548110610de257600080fd5b6000918252602090912001546001600160a01b0316905081565b610e12336000356001600160e01b031916612fc7565b610e2e5760405162461bcd60e51b8152600401610ca090613bf2565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b610e90336000356001600160e01b031916612fc7565b610eac5760405162461bcd60e51b8152600401610ca090613bf2565b600f805460009190610ec090600190613c2e565b81548110610ed057610ed0613c45565b6000918252602082200154600f80546001600160a01b0390921693509084908110610efd57610efd613c45565b600091825260209091200154600f80546001600160a01b039092169250839185908110610f2c57610f2c613c45565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600f805480610f6b57610f6b613c5b565b600082815260209020810160001990810180546001600160a01b03191690550190556040516001600160a01b03838116919083169033907f473192fe0c9f1496de6fb6e5c8d6ad88651b595d4e00ff84da3824c86bd8fc0c90610fd19088815260200190565b60405180910390a4505050565b610ff4336000356001600160e01b031916612fc7565b6110105760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0381166000908152600d602052604090205461010090046001600160f81b031661103f612d0c565b81111561105657600e80546001600160801b031690555b6001600160a01b0382166000818152600d6020526040808220805460ff169055600c805485900390555133917fe5211b194c7994bf5eba21ddab25713549e67c4c84028d2f28c1377195de0fb991a36040516370a0823160e01b81523060048201526111249033906001600160a01b038516906370a0823190602401602060405180830381865afa1580156110ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111139190613c71565b6001600160a01b0385169190613071565b5050565b61113e336000356001600160e01b031916612fc7565b61115a5760405162461bcd60e51b8152600401610ca090613bf2565b602081111561119b5760405162461bcd60e51b815260206004820152600d60248201526c535441434b5f544f4f5f42494760981b6044820152606401610ca0565b6111a7600f83836137f6565b50336001600160a01b03167ff110ec6f3f76ff60fb27d301a8a5d810ca482392df21dc15cdb1492922b8b0b383836040516111e3929190613c8a565b60405180910390a25050565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019811461124b576112268382613c2e565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611273908490613c2e565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020613efa833981519152906112bc9087815260200190565b60405180910390a3506001949350505050565b6112e5336000356001600160e01b031916612fc7565b6113015760405162461bcd60e51b8152600401610ca090613bf2565b6000600f838154811061131657611316613c45565b6000918252602082200154600f80546001600160a01b039092169350908490811061134357611343613c45565b600091825260209091200154600f80546001600160a01b03909216925082918690811061137257611372613c45565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600f84815481106113b4576113b4613c45565b60009182526020918290200180546001600160a01b0319166001600160a01b03938416179055604080518781529182018690528483169284169133917f5d605201cae91441cf473a96f9217ad688f1ee9d42c1cfb6ed1be9fb50576c30910160405180910390a450505050565b61145d336114586114306116f2565b84907f00000000000000000000000000000000000000000000000000000000000000006130f0565b613112565b60405181815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a261149c338261317c565b50565b6114b5336000356001600160e01b031916612fc7565b6114d15760405162461bcd60e51b8152600401610ca090613bf2565b80158061156257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155b9190613cd8565b60ff166012145b61159f5760405162461bcd60e51b815260206004820152600e60248201526d57524f4e475f444543494d414c5360901b6044820152606401610ca0565b600b805460ff191682151590811790915560405190815233907f6375b140d4463d47b864f1f47e5d2893cc3478e73aedcc268b054fab0230a84190602001610d5b565b6060600f80548060200260200160405190810160405280929190818152602001828054801561163a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161161c575b5050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000000461461167a57611675613219565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b60006116ec6116ac6116f2565b6001600160a01b038416600090815260036020526040902054907f00000000000000000000000000000000000000000000000000000000000000006132b3565b92915050565b60025460009080611724577f000000000000000000000000000000000000000000000000000000000000000091505090565b611758817f0000000000000000000000000000000000000000000000000000000000000000611751612d0c565b91906130f0565b91505090565b600e546009546000916001600160401b03600160401b909104811691600160801b90041680820142106117945760009250505090565b600e54600160801b90046001600160801b031681428490038202816117bb576117bb613cf5565b0490039392505050565b6117db336000356001600160e01b031916612fc7565b6117f75760405162461bcd60e51b8152600401610ca090613bf2565b600f546020116118365760405162461bcd60e51b815260206004820152600a60248201526914d51050d2d7d195531360b21b6044820152606401610ca0565b600f805460018101825560009182527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b038416908117909155604051909133917f5abc18e64ea5219f39a4afb4519bdb3d895e6ec8282ec44db4c253289abdab1b9190a350565b6118c7336000356001600160e01b031916612fc7565b6118e35760405162461bcd60e51b8152600401610ca090613bf2565b600f8054600091906118f790600190613c2e565b8154811061190757611907613c45565b600091825260209091200154600f80546001600160a01b039092169250908061193257611932613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0383169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a350565b6006546001600160a01b0316331480611a23575060075460405163b700961360e01b81526001600160a01b039091169063b7009613906119e290339030906001600160e01b03196000351690600401613d0b565b602060405180830381865afa1580156119ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a239190613d38565b611a2c57600080fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b611a8e336000356001600160e01b031916612fc7565b611aaa5760405162461bcd60e51b8152600401610ca090613bf2565b6001600160401b038116611af75760405162461bcd60e51b815260206004820152601460248201527344454c41595f43414e4e4f545f42455f5a45524f60601b6044820152606401610ca0565b6301e13380816001600160401b03161115611b455760405162461bcd60e51b815260206004820152600e60248201526d44454c41595f544f4f5f4c4f4e4760901b6044820152606401610ca0565b600954600160801b90046001600160401b0316611bb9576009805467ffffffffffffffff60801b1916600160801b6001600160401b0384169081029190911790915560405190815233907fe893fa207c5a5094cad036347b877c23ebecd9df94ae0426f287040c13220b3f90602001610d5b565b600980546001600160c01b0316600160c01b6001600160401b0384169081029190911790915560405190815233907f342b344c0ac2ffff8f84b1d82d8235a2401a0accf4666f1fec4a1c3cdf1d29e790602001610d5b565b611c27336000356001600160e01b031916612fc7565b611c435760405162461bcd60e51b8152600401610ca090613bf2565b670de0b6b3a7640000811115611c8a5760405162461bcd60e51b815260206004820152600c60248201526b08c8a8abea89e9ebe90928e960a31b6044820152606401610ca0565b600881905560405181815233907fec370615cc81fb334e5566fbc80664d9082377bf59288d64a79f3fbecf4323a990602001610d5b565b611cd7336000356001600160e01b031916612fc7565b611cf35760405162461bcd60e51b8152600401610ca090613bf2565b60105460ff1615611d3c5760405162461bcd60e51b81526020600482015260136024820152721053149150511657d253925512505312569151606a1b6044820152606401610ca0565b6010805460ff191660011790556000600281905560405133917f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e691a2565b611d90336000356001600160e01b031916612fc7565b611dac5760405162461bcd60e51b8152600401610ca090613bf2565b33ff5b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611e16573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116759190613c71565b60018054610bed90613bb7565b33600090815260036020526040812080548391908390611e68908490613c2e565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020613efa83398151915290610dc19086815260200190565b611ec3336000356001600160e01b031916612fc7565b611edf5760405162461bcd60e51b8152600401610ca090613bf2565b60405181815233907f9493e5bbe4e8e0ac67284469a2d677403d0378a85a59e341d3abc433d0d9a2099060200160405180910390a261149c303383613071565b611f35336000356001600160e01b031916612fc7565b611f515760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0382166000908152600d602052604090205460ff16611f895760405162461bcd60e51b8152600401610ca090613d55565b611f92816132ce565b6001600160a01b0383166000908152600d602052604090208054600190611fc890849061010090046001600160f81b0316613d81565b82546001600160f81b039182166101009390930a928302919092021990911617905550600c805482900390556040518181526001600160a01b0383169033907f8d851b682e239b1de720e92e5c5cffdb72d353104cc63dc6ed144d7080217fbe9060200160405180910390a360405163852a12e360e01b8152600481018290526001600160a01b0383169063852a12e3906024016020604051808303816000875af115801561207b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209f9190613c71565b156120dc5760405162461bcd60e51b815260206004820152600d60248201526c14915111515357d19052531151609a1b6044820152606401610ca0565b816001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561211a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213e9190613d38565b15611124577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561219e57600080fd5b505af11580156121b2573d6000803e3d6000fd5b50505050505050565b6121cf336121ca6114306116f2565b6132e8565b60405181815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a261149c6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308461333a565b61224f336000356001600160e01b031916612fc7565b61226b5760405162461bcd60e51b8152600401610ca090613bf2565b670de0b6b3a76400008111156122b55760405162461bcd60e51b815260206004820152600f60248201526e0a882a48e8aa8bea89e9ebe90928e9608b1b6044820152606401610ca0565b600a81905560405181815233907f95bc4480b51f4860106d42850bcae222cf3303fb2b7d433e896205e0ebefe36990602001610d5b565b612302336000356001600160e01b031916612fc7565b61231e5760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0382166000908152600d602052604090205460ff166123565760405162461bcd60e51b8152600401610ca090613d55565b80600c60008282546123689190613da9565b909155506123779050816132ce565b6001600160a01b0383166000818152600d60205260409081902080546001600160f81b0361010080830482169096011690940260ff90941693909317909255905133907f49e9138fe0dacf001ea634236e38aa8bd229efd55ec4d7975228d679db6ce8f9906123e99085815260200190565b60405180910390a3816001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561242f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124539190613d38565b1561250d57604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156124ba57600080fd5b505af11580156124ce573d6000803e3d6000fd5b50505050816001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561219e57600080fd5b6125416001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001683836133ce565b60405163140e25ad60e31b8152600481018290526001600160a01b0383169063a0712d68906024016020604051808303816000875af1158015612588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ac9190613c71565b156111245760405162461bcd60e51b815260206004820152600b60248201526a1352539517d1905253115160aa1b6044820152606401610ca0565b6125fd336000356001600160e01b031916612fc7565b6126195760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0381166000818152600d6020526040808220805460ff191690555133917fff8fe190f3935e9e8681ce444b08be824a6be3e5184465ddbd710cc4f1a9f2f291a350565b612679336000356001600160e01b031916612fc7565b6126955760405162461bcd60e51b8152600401610ca090613bf2565b600954600e546126bf916001600160401b03600160801b909104811691600160401b900416613dc1565b6001600160401b031642106126ef57600e805467ffffffffffffffff1916426001600160401b031617905561275c565b600954600e54612711916001600160801b0316906001600160401b0316613dec565b6001600160801b031642111561275c5760405162461bcd60e51b815260206004820152601060248201526f4241445f484152564553545f54494d4560801b6044820152606401610ca0565b600c54600081815b848110156128dc57600086868381811061278057612780613c45565b90506020020160208101906127959190613944565b6001600160a01b0381166000908152600d602052604090205490915060ff166127d05760405162461bcd60e51b8152600401610ca090613d55565b6001600160a01b0381166000818152600d6020526040808220549051633af9e66960e01b81523060048201526101009091046001600160f81b03169290633af9e669906024016020604051808303816000875af1158015612835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128599190613c71565b9050612864816132ce565b6001600160a01b0384166000908152600d6020526040902080546001600160f81b03929092166101000260ff909216919091179055816128a48287613da9565b6128ae9190613c2e565b94508181116128be5760006128c2565b8181035b8601955050505080806128d490613e0e565b915050612764565b506008546000906128f7908490670de0b6b3a76400006132b3565b9050612908306121ca6114306116f2565b61292e818461291561175e565b61291f9190613da9565b6129299190613c2e565b613446565b600e8054600c8590556001600160401b03428116600160401b026fffffffffffffffff0000000000000000196001600160801b0395909516600160801b029490941691161791909117905560405133907f69e9c71f6799744a94d9897e77c3ed426cc2f92ba0ef3300785368209b6f4b2d906129ad9089908990613c8a565b60405180910390a2600954600160c01b90046001600160401b031680156121b257600980546001600160801b0316600160801b6001600160401b0384169081026001600160c01b03169190911790915560405190815233907fe893fa207c5a5094cad036347b877c23ebecd9df94ae0426f287040c13220b3f9060200160405180910390a250505050505050565b42841015612a8b5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610ca0565b6000612a95611644565b6001600160a01b0389811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612bae573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612be45750886001600160a01b0316816001600160a01b0316145b612c215760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610ca0565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000612cc1612c996116f2565b83907f00000000000000000000000000000000000000000000000000000000000000006132b3565b9050612ccd3383613112565b60405181815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a2611124338261317c565b6000612d1661175e565b600c54039050612d24611daf565b6116759082613da9565b612d44336000356001600160e01b031916612fc7565b612d605760405162461bcd60e51b8152600401610ca090613bf2565b806001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc29190613d38565b612e61577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e529190613e29565b6001600160a01b031614612e68565b600b5460ff165b612ea75760405162461bcd60e51b815260206004820152601060248201526f57524f4e475f554e4445524c59494e4760801b6044820152606401610ca0565b6001600160a01b0381166000818152600d6020526040808220805460ff191660011790555133917f2fc1f5b589e399a463bf89605c1539bdd9878a9a3acd089abeca7a15e1fbe6ec91a350565b612f0a336000356001600160e01b031916612fc7565b612f265760405162461bcd60e51b8152600401610ca090613bf2565b6000600f8381548110612f3b57612f3b613c45565b600091825260209091200154600f80546001600160a01b039092169250839185908110612f6a57612f6a613c45565b60009182526020918290200180546001600160a01b0319166001600160a01b039384161790556040518581528483169284169133917f6b3d5cb176c4387df974c7528104dc97592d836de95196de9f68adbb6f46d5ac9101610fd1565b6007546000906001600160a01b03168015801590613051575060405163b700961360e01b81526001600160a01b0382169063b70096139061301090879030908890600401613d0b565b602060405180830381865afa15801561302d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130519190613d38565b8061306957506006546001600160a01b038581169116145b949350505050565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506130ac8161345c565b6130ea5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610ca0565b50505050565b82810282151584158583048414171661310857600080fd5b9190910492915050565b6001600160a01b0382166000908152600360205260408120805483929061313a908490613c2e565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020613efa833981519152906020015b60405180910390a35050565b6000613186611daf565b9050808211156131e05760006131bb600a54670de0b6b3a7640000856131aa612d0c565b6131b49190613c2e565b91906132b3565b905060006131c98385613c2e565b90506131dd6131d88383613da9565b6134a3565b50505b6132146001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168484613071565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161324b9190613e46565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82820283158482048414176132c757600080fd5b0492915050565b60006001600160f81b038211156132e457600080fd5b5090565b80600260008282546132fa9190613da9565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020613efa8339815191529101613170565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af19150506133848161345c565b6133c75760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610ca0565b5050505050565b600060405163095ea7b360e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506134098161345c565b6130ea5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606401610ca0565b60006001600160801b038211156132e457600080fd5b60003d8261346e57806000803e806000fd5b8060208114613486578015613497576000925061349c565b816000803e6000511515925061349c565b600192505b5050919050565b600f5481906000906134b790600190613c2e565b90505b6000600f82815481106134cf576134cf613c45565b60009182526020808320909101546001600160a01b0316808352600d9091526040909120549091506001600160f81b036101008204169060ff161580613513575080155b1561358957600f80548061352957613529613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0384169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a3505061374a565b6000848211613598578161359a565b845b90508082036135a8816132ce565b6001600160a01b0385166000818152600d60205260409081902080546001600160f81b03949094166101000260ff909416939093179092559051968390039633907f8d851b682e239b1de720e92e5c5cffdb72d353104cc63dc6ed144d7080217fbe906136189086815260200190565b60405180910390a360405163852a12e360e01b8152600481018390526001600160a01b0385169063852a12e3906024016020604051808303816000875af1158015613667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368b9190613c71565b156136c85760405162461bcd60e51b815260206004820152600d60248201526c14915111515357d19052531151609a1b6044820152606401610ca0565b8061373857600f8054806136de576136de613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0386169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a35b50846137465750505061375c565b5050505b8061375481613ee2565b9150506134ba565b600c805484900390554780158015906137775750600b5460ff165b156130ea577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156137d757600080fd5b505af11580156137eb573d6000803e3d6000fd5b505050505050505050565b828054828255906000526020600020908101928215613849579160200282015b828111156138495781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190613816565b506132e49291505b808211156132e45760008155600101613851565b600060208083528351808285015260005b8181101561389257858101830151858201604001528201613876565b818111156138a4576000604083870101525b50601f01601f1916929092016040019392505050565b6000602082840312156138cc57600080fd5b81356001600160801b03811681146138e357600080fd5b9392505050565b6001600160a01b038116811461149c57600080fd5b6000806040838503121561391257600080fd5b823561391d816138ea565b946020939093013593505050565b60006020828403121561393d57600080fd5b5035919050565b60006020828403121561395657600080fd5b81356138e3816138ea565b6000806020838503121561397457600080fd5b82356001600160401b038082111561398b57600080fd5b818501915085601f83011261399f57600080fd5b8135818111156139ae57600080fd5b8660208260051b85010111156139c357600080fd5b60209290920196919550909350505050565b6000806000606084860312156139ea57600080fd5b83356139f5816138ea565b92506020840135613a05816138ea565b929592945050506040919091013590565b60008060408385031215613a2957600080fd5b50508035926020909101359150565b801515811461149c57600080fd5b600060208284031215613a5857600080fd5b81356138e381613a38565b6020808252825182820181905260009190848201906040850190845b81811015613aa45783516001600160a01b031683529284019291840191600101613a7f565b50909695505050505050565b600060208284031215613ac257600080fd5b81356001600160401b03811681146138e357600080fd5b60ff8116811461149c57600080fd5b600080600080600080600060e0888a031215613b0357600080fd5b8735613b0e816138ea565b96506020880135613b1e816138ea565b955060408801359450606088013593506080880135613b3c81613ad9565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613b6c57600080fd5b8235613b77816138ea565b91506020830135613b87816138ea565b809150509250929050565b60008060408385031215613ba557600080fd5b823591506020830135613b87816138ea565b600181811c90821680613bcb57607f821691505b60208210811415613bec57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613c4057613c40613c18565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600060208284031215613c8357600080fd5b5051919050565b60208082528181018390526000908460408401835b86811015613ccd578235613cb2816138ea565b6001600160a01b031682529183019190830190600101613c9f565b509695505050505050565b600060208284031215613cea57600080fd5b81516138e381613ad9565b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b600060208284031215613d4a57600080fd5b81516138e381613a38565b602080825260129082015271554e545255535445445f535452415445475960701b604082015260600190565b60006001600160f81b0383811690831681811015613da157613da1613c18565b039392505050565b60008219821115613dbc57613dbc613c18565b500190565b60006001600160401b03808316818516808303821115613de357613de3613c18565b01949350505050565b60006001600160801b03808316818516808303821115613de357613de3613c18565b6000600019821415613e2257613e22613c18565b5060010190565b600060208284031215613e3b57600080fd5b81516138e3816138ea565b600080835481600182811c915080831680613e6257607f831692505b6020808410821415613e8257634e487b7160e01b86526022600452602486fd5b818015613e965760018114613ea757613ed4565b60ff19861689528489019650613ed4565b60008a81526020902060005b86811015613ecc5781548b820152908501908301613eb3565b505084890196505b509498975050505050505050565b600081613ef157613ef1613c18565b50600019019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212208de4f2e4f90038de1484734e50e4731605e2bffe1ecde3badb1f119f1d4a7c3d64736f6c634300080b00330000000000000000000000002602278ee1882889b946eb11dc0e810075650983

Deployed Bytecode

0x60806040526004361061039b5760003560e01c80637ce3489b116101dc578063c5d664c611610102578063e9ec2e99116100a0578063eed74e671161006f578063eed74e6714610b5f578063f1a392da14610b7f578063f84d73f414610ba6578063f97d2ed714610bc057600080fd5b8063e9ec2e9914610af4578063ec523afd14610b09578063ecad956514610b29578063ed2c552114610b3f57600080fd5b8063d00364be116100dc578063d00364be14610a3d578063d505accf14610a7c578063db006a7514610a9c578063dd62ed3e14610abc57600080fd5b8063c5d664c6146109c9578063c866983b146109fd578063c89d346014610a1d57600080fd5b806395d89b411161017a578063b6b55f2511610149578063b6b55f2514610949578063bd662f8814610969578063bdf06c8e14610989578063bf7e214f146109a957600080fd5b806395d89b41146108d4578063a9059cbb146108e9578063ac68a74814610909578063b53d09581461092957600080fd5b80638129fc1c116101b65780638129fc1c1461087557806383197ef01461088a578063841219e51461089f5780638da5cb5b146108b457600080fd5b80637ce3489b146108125780637ecebe00146108325780637fd6f15c1461085f57600080fd5b8063313ce567116102c1578063448f56b91161025f57806370a082311161022e57806370a082311461077e578063797ba463146107ab5780637a9e5e4b146107d25780637b72aeb9146107f257600080fd5b8063448f56b9146106f557806344b81396146107345780634a3c39901461074957806360dc8fac1461076957600080fd5b80633644e5151161029b5780633644e51514610691578063392e53cd146106a65780633af9e669146106c05780633ba0b9a9146106e057600080fd5b8063313ce5671461060957806332ff77321461064f57806334051c031461066f57600080fd5b80631c693478116103395780632493fea6116103085780632493fea6146105365780632968676e146105565780632e1a7d4d146105b557806330adf81f146105d557600080fd5b80631c693478146104c057806320ea2cc3146104d657806323152745146104f657806323b872dd1461051657600080fd5b8063136a8ce711610375578063136a8ce71461042457806313af40351461045c57806316e5440a1461047c57806318160ddd1461049c57600080fd5b806306fdde03146103a757806307b35d1d146103d2578063095ea7b3146103f457600080fd5b366103a257005b600080fd5b3480156103b357600080fd5b506103bc610be0565b6040516103c99190613865565b60405180910390f35b3480156103de57600080fd5b506103f26103ed3660046138ba565b610c6e565b005b34801561040057600080fd5b5061041461040f3660046138ff565b610d66565b60405190151581526020016103c9565b34801561043057600080fd5b5061044461043f36600461392b565b610dd2565b6040516001600160a01b0390911681526020016103c9565b34801561046857600080fd5b506103f2610477366004613944565b610dfc565b34801561048857600080fd5b506103f261049736600461392b565b610e7a565b3480156104a857600080fd5b506104b260025481565b6040519081526020016103c9565b3480156104cc57600080fd5b506104b2600a5481565b3480156104e257600080fd5b506103f26104f1366004613944565b610fde565b34801561050257600080fd5b506103f2610511366004613961565b611128565b34801561052257600080fd5b506104146105313660046139d5565b6111ef565b34801561054257600080fd5b506103f2610551366004613a16565b6112cf565b34801561056257600080fd5b50610596610571366004613944565b600d6020526000908152604090205460ff81169061010090046001600160f81b031682565b6040805192151583526001600160f81b039091166020830152016103c9565b3480156105c157600080fd5b506103f26105d036600461392b565b611421565b3480156105e157600080fd5b506104b27f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b34801561061557600080fd5b5061063d7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016103c9565b34801561065b57600080fd5b506103f261066a366004613a46565b61149f565b34801561067b57600080fd5b506106846115e2565b6040516103c99190613a63565b34801561069d57600080fd5b506104b2611644565b3480156106b257600080fd5b506010546104149060ff1681565b3480156106cc57600080fd5b506104b26106db366004613944565b61169f565b3480156106ec57600080fd5b506104b26116f2565b34801561070157600080fd5b5060095461071c90600160801b90046001600160401b031681565b6040516001600160401b0390911681526020016103c9565b34801561074057600080fd5b506104b261175e565b34801561075557600080fd5b506103f2610764366004613944565b6117c5565b34801561077557600080fd5b506103f26118b1565b34801561078a57600080fd5b506104b2610799366004613944565b60036020526000908152604090205481565b3480156107b757600080fd5b5060095461071c90600160c01b90046001600160401b031681565b3480156107de57600080fd5b506103f26107ed366004613944565b61198e565b3480156107fe57600080fd5b506103f261080d366004613ab0565b611a78565b34801561081e57600080fd5b506103f261082d36600461392b565b611c11565b34801561083e57600080fd5b506104b261084d366004613944565b60056020526000908152604090205481565b34801561086b57600080fd5b506104b260085481565b34801561088157600080fd5b506103f2611cc1565b34801561089657600080fd5b506103f2611d7a565b3480156108ab57600080fd5b506104b2611daf565b3480156108c057600080fd5b50600654610444906001600160a01b031681565b3480156108e057600080fd5b506103bc611e3a565b3480156108f557600080fd5b506104146109043660046138ff565b611e47565b34801561091557600080fd5b506103f261092436600461392b565b611ead565b34801561093557600080fd5b506103f26109443660046138ff565b611f1f565b34801561095557600080fd5b506103f261096436600461392b565b6121bb565b34801561097557600080fd5b506103f261098436600461392b565b612239565b34801561099557600080fd5b506103f26109a43660046138ff565b6122ec565b3480156109b557600080fd5b50600754610444906001600160a01b031681565b3480156109d557600080fd5b506104447f0000000000000000000000002602278ee1882889b946eb11dc0e81007565098381565b348015610a0957600080fd5b506103f2610a18366004613944565b6125e7565b348015610a2957600080fd5b506103f2610a38366004613961565b612663565b348015610a4957600080fd5b50600e54610a6490600160801b90046001600160801b031681565b6040516001600160801b0390911681526020016103c9565b348015610a8857600080fd5b506103f2610a97366004613ae8565b612a3b565b348015610aa857600080fd5b506103f2610ab736600461392b565b612c8c565b348015610ac857600080fd5b506104b2610ad7366004613b59565b600460209081526000928352604080842090915290825290205481565b348015610b0057600080fd5b506104b2612d0c565b348015610b1557600080fd5b506103f2610b24366004613944565b612d2e565b348015610b3557600080fd5b506104b2600c5481565b348015610b4b57600080fd5b506103f2610b5a366004613b92565b612ef4565b348015610b6b57600080fd5b50600e5461071c906001600160401b031681565b348015610b8b57600080fd5b50600e5461071c90600160401b90046001600160401b031681565b348015610bb257600080fd5b50600b546104149060ff1681565b348015610bcc57600080fd5b50600954610a64906001600160801b031681565b60008054610bed90613bb7565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1990613bb7565b8015610c665780601f10610c3b57610100808354040283529160200191610c66565b820191906000526020600020905b815481529060010190602001808311610c4957829003601f168201915b505050505081565b610c84336000356001600160e01b031916612fc7565b610ca95760405162461bcd60e51b8152600401610ca090613bf2565b60405180910390fd5b600954600160801b90046001600160401b03166001600160801b0382161115610d065760405162461bcd60e51b815260206004820152600f60248201526e57494e444f575f544f4f5f4c4f4e4760881b6044820152606401610ca0565b600980546fffffffffffffffffffffffffffffffff19166001600160801b03831690811790915560405190815233907ff61ebd3c01f656aba479c738a8744215d6f1ec2c19169500f3bff0a9d8374ce1906020015b60405180910390a250565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610dc19086815260200190565b60405180910390a350600192915050565b600f8181548110610de257600080fd5b6000918252602090912001546001600160a01b0316905081565b610e12336000356001600160e01b031916612fc7565b610e2e5760405162461bcd60e51b8152600401610ca090613bf2565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b610e90336000356001600160e01b031916612fc7565b610eac5760405162461bcd60e51b8152600401610ca090613bf2565b600f805460009190610ec090600190613c2e565b81548110610ed057610ed0613c45565b6000918252602082200154600f80546001600160a01b0390921693509084908110610efd57610efd613c45565b600091825260209091200154600f80546001600160a01b039092169250839185908110610f2c57610f2c613c45565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600f805480610f6b57610f6b613c5b565b600082815260209020810160001990810180546001600160a01b03191690550190556040516001600160a01b03838116919083169033907f473192fe0c9f1496de6fb6e5c8d6ad88651b595d4e00ff84da3824c86bd8fc0c90610fd19088815260200190565b60405180910390a4505050565b610ff4336000356001600160e01b031916612fc7565b6110105760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0381166000908152600d602052604090205461010090046001600160f81b031661103f612d0c565b81111561105657600e80546001600160801b031690555b6001600160a01b0382166000818152600d6020526040808220805460ff169055600c805485900390555133917fe5211b194c7994bf5eba21ddab25713549e67c4c84028d2f28c1377195de0fb991a36040516370a0823160e01b81523060048201526111249033906001600160a01b038516906370a0823190602401602060405180830381865afa1580156110ef573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111139190613c71565b6001600160a01b0385169190613071565b5050565b61113e336000356001600160e01b031916612fc7565b61115a5760405162461bcd60e51b8152600401610ca090613bf2565b602081111561119b5760405162461bcd60e51b815260206004820152600d60248201526c535441434b5f544f4f5f42494760981b6044820152606401610ca0565b6111a7600f83836137f6565b50336001600160a01b03167ff110ec6f3f76ff60fb27d301a8a5d810ca482392df21dc15cdb1492922b8b0b383836040516111e3929190613c8a565b60405180910390a25050565b6001600160a01b0383166000908152600460209081526040808320338452909152812054600019811461124b576112268382613c2e565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290611273908490613c2e565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020613efa833981519152906112bc9087815260200190565b60405180910390a3506001949350505050565b6112e5336000356001600160e01b031916612fc7565b6113015760405162461bcd60e51b8152600401610ca090613bf2565b6000600f838154811061131657611316613c45565b6000918252602082200154600f80546001600160a01b039092169350908490811061134357611343613c45565b600091825260209091200154600f80546001600160a01b03909216925082918690811061137257611372613c45565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555081600f84815481106113b4576113b4613c45565b60009182526020918290200180546001600160a01b0319166001600160a01b03938416179055604080518781529182018690528483169284169133917f5d605201cae91441cf473a96f9217ad688f1ee9d42c1cfb6ed1be9fb50576c30910160405180910390a450505050565b61145d336114586114306116f2565b84907f0000000000000000000000000000000000000000000000000de0b6b3a76400006130f0565b613112565b60405181815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a261149c338261317c565b50565b6114b5336000356001600160e01b031916612fc7565b6114d15760405162461bcd60e51b8152600401610ca090613bf2565b80158061156257507f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611537573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155b9190613cd8565b60ff166012145b61159f5760405162461bcd60e51b815260206004820152600e60248201526d57524f4e475f444543494d414c5360901b6044820152606401610ca0565b600b805460ff191682151590811790915560405190815233907f6375b140d4463d47b864f1f47e5d2893cc3478e73aedcc268b054fab0230a84190602001610d5b565b6060600f80548060200260200160405190810160405280929190818152602001828054801561163a57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161161c575b5050505050905090565b60007f0000000000000000000000000000000000000000000000000000000000000001461461167a57611675613219565b905090565b507f34e0dafab03f56620b5bcb86935fd3e586183c47913e9e4d0782586782376c6a90565b60006116ec6116ac6116f2565b6001600160a01b038416600090815260036020526040902054907f0000000000000000000000000000000000000000000000000de0b6b3a76400006132b3565b92915050565b60025460009080611724577f0000000000000000000000000000000000000000000000000de0b6b3a764000091505090565b611758817f0000000000000000000000000000000000000000000000000de0b6b3a7640000611751612d0c565b91906130f0565b91505090565b600e546009546000916001600160401b03600160401b909104811691600160801b90041680820142106117945760009250505090565b600e54600160801b90046001600160801b031681428490038202816117bb576117bb613cf5565b0490039392505050565b6117db336000356001600160e01b031916612fc7565b6117f75760405162461bcd60e51b8152600401610ca090613bf2565b600f546020116118365760405162461bcd60e51b815260206004820152600a60248201526914d51050d2d7d195531360b21b6044820152606401610ca0565b600f805460018101825560009182527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b038416908117909155604051909133917f5abc18e64ea5219f39a4afb4519bdb3d895e6ec8282ec44db4c253289abdab1b9190a350565b6118c7336000356001600160e01b031916612fc7565b6118e35760405162461bcd60e51b8152600401610ca090613bf2565b600f8054600091906118f790600190613c2e565b8154811061190757611907613c45565b600091825260209091200154600f80546001600160a01b039092169250908061193257611932613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0383169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a350565b6006546001600160a01b0316331480611a23575060075460405163b700961360e01b81526001600160a01b039091169063b7009613906119e290339030906001600160e01b03196000351690600401613d0b565b602060405180830381865afa1580156119ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a239190613d38565b611a2c57600080fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa3396fd7f6e0a21b50e5089d2da70d5ac0a3bbbd1f617a93f134b7638998019890600090a350565b611a8e336000356001600160e01b031916612fc7565b611aaa5760405162461bcd60e51b8152600401610ca090613bf2565b6001600160401b038116611af75760405162461bcd60e51b815260206004820152601460248201527344454c41595f43414e4e4f545f42455f5a45524f60601b6044820152606401610ca0565b6301e13380816001600160401b03161115611b455760405162461bcd60e51b815260206004820152600e60248201526d44454c41595f544f4f5f4c4f4e4760901b6044820152606401610ca0565b600954600160801b90046001600160401b0316611bb9576009805467ffffffffffffffff60801b1916600160801b6001600160401b0384169081029190911790915560405190815233907fe893fa207c5a5094cad036347b877c23ebecd9df94ae0426f287040c13220b3f90602001610d5b565b600980546001600160c01b0316600160c01b6001600160401b0384169081029190911790915560405190815233907f342b344c0ac2ffff8f84b1d82d8235a2401a0accf4666f1fec4a1c3cdf1d29e790602001610d5b565b611c27336000356001600160e01b031916612fc7565b611c435760405162461bcd60e51b8152600401610ca090613bf2565b670de0b6b3a7640000811115611c8a5760405162461bcd60e51b815260206004820152600c60248201526b08c8a8abea89e9ebe90928e960a31b6044820152606401610ca0565b600881905560405181815233907fec370615cc81fb334e5566fbc80664d9082377bf59288d64a79f3fbecf4323a990602001610d5b565b611cd7336000356001600160e01b031916612fc7565b611cf35760405162461bcd60e51b8152600401610ca090613bf2565b60105460ff1615611d3c5760405162461bcd60e51b81526020600482015260136024820152721053149150511657d253925512505312569151606a1b6044820152606401610ca0565b6010805460ff191660011790556000600281905560405133917f908408e307fc569b417f6cbec5d5a06f44a0a505ac0479b47d421a4b2fd6a1e691a2565b611d90336000356001600160e01b031916612fc7565b611dac5760405162461bcd60e51b8152600401610ca090613bf2565b33ff5b6040516370a0823160e01b81523060048201526000907f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b0316906370a0823190602401602060405180830381865afa158015611e16573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116759190613c71565b60018054610bed90613bb7565b33600090815260036020526040812080548391908390611e68908490613c2e565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020613efa83398151915290610dc19086815260200190565b611ec3336000356001600160e01b031916612fc7565b611edf5760405162461bcd60e51b8152600401610ca090613bf2565b60405181815233907f9493e5bbe4e8e0ac67284469a2d677403d0378a85a59e341d3abc433d0d9a2099060200160405180910390a261149c303383613071565b611f35336000356001600160e01b031916612fc7565b611f515760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0382166000908152600d602052604090205460ff16611f895760405162461bcd60e51b8152600401610ca090613d55565b611f92816132ce565b6001600160a01b0383166000908152600d602052604090208054600190611fc890849061010090046001600160f81b0316613d81565b82546001600160f81b039182166101009390930a928302919092021990911617905550600c805482900390556040518181526001600160a01b0383169033907f8d851b682e239b1de720e92e5c5cffdb72d353104cc63dc6ed144d7080217fbe9060200160405180910390a360405163852a12e360e01b8152600481018290526001600160a01b0383169063852a12e3906024016020604051808303816000875af115801561207b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061209f9190613c71565b156120dc5760405162461bcd60e51b815260206004820152600d60248201526c14915111515357d19052531151609a1b6044820152606401610ca0565b816001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561211a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213e9190613d38565b15611124577f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561219e57600080fd5b505af11580156121b2573d6000803e3d6000fd5b50505050505050565b6121cf336121ca6114306116f2565b6132e8565b60405181815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a261149c6001600160a01b037f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509831633308461333a565b61224f336000356001600160e01b031916612fc7565b61226b5760405162461bcd60e51b8152600401610ca090613bf2565b670de0b6b3a76400008111156122b55760405162461bcd60e51b815260206004820152600f60248201526e0a882a48e8aa8bea89e9ebe90928e9608b1b6044820152606401610ca0565b600a81905560405181815233907f95bc4480b51f4860106d42850bcae222cf3303fb2b7d433e896205e0ebefe36990602001610d5b565b612302336000356001600160e01b031916612fc7565b61231e5760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0382166000908152600d602052604090205460ff166123565760405162461bcd60e51b8152600401610ca090613d55565b80600c60008282546123689190613da9565b909155506123779050816132ce565b6001600160a01b0383166000818152600d60205260409081902080546001600160f81b0361010080830482169096011690940260ff90941693909317909255905133907f49e9138fe0dacf001ea634236e38aa8bd229efd55ec4d7975228d679db6ce8f9906123e99085815260200190565b60405180910390a3816001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561242f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124539190613d38565b1561250d57604051632e1a7d4d60e01b8152600481018290527f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156124ba57600080fd5b505af11580156124ce573d6000803e3d6000fd5b50505050816001600160a01b0316631249c58b826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561219e57600080fd5b6125416001600160a01b037f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509831683836133ce565b60405163140e25ad60e31b8152600481018290526001600160a01b0383169063a0712d68906024016020604051808303816000875af1158015612588573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125ac9190613c71565b156111245760405162461bcd60e51b815260206004820152600b60248201526a1352539517d1905253115160aa1b6044820152606401610ca0565b6125fd336000356001600160e01b031916612fc7565b6126195760405162461bcd60e51b8152600401610ca090613bf2565b6001600160a01b0381166000818152600d6020526040808220805460ff191690555133917fff8fe190f3935e9e8681ce444b08be824a6be3e5184465ddbd710cc4f1a9f2f291a350565b612679336000356001600160e01b031916612fc7565b6126955760405162461bcd60e51b8152600401610ca090613bf2565b600954600e546126bf916001600160401b03600160801b909104811691600160401b900416613dc1565b6001600160401b031642106126ef57600e805467ffffffffffffffff1916426001600160401b031617905561275c565b600954600e54612711916001600160801b0316906001600160401b0316613dec565b6001600160801b031642111561275c5760405162461bcd60e51b815260206004820152601060248201526f4241445f484152564553545f54494d4560801b6044820152606401610ca0565b600c54600081815b848110156128dc57600086868381811061278057612780613c45565b90506020020160208101906127959190613944565b6001600160a01b0381166000908152600d602052604090205490915060ff166127d05760405162461bcd60e51b8152600401610ca090613d55565b6001600160a01b0381166000818152600d6020526040808220549051633af9e66960e01b81523060048201526101009091046001600160f81b03169290633af9e669906024016020604051808303816000875af1158015612835573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128599190613c71565b9050612864816132ce565b6001600160a01b0384166000908152600d6020526040902080546001600160f81b03929092166101000260ff909216919091179055816128a48287613da9565b6128ae9190613c2e565b94508181116128be5760006128c2565b8181035b8601955050505080806128d490613e0e565b915050612764565b506008546000906128f7908490670de0b6b3a76400006132b3565b9050612908306121ca6114306116f2565b61292e818461291561175e565b61291f9190613da9565b6129299190613c2e565b613446565b600e8054600c8590556001600160401b03428116600160401b026fffffffffffffffff0000000000000000196001600160801b0395909516600160801b029490941691161791909117905560405133907f69e9c71f6799744a94d9897e77c3ed426cc2f92ba0ef3300785368209b6f4b2d906129ad9089908990613c8a565b60405180910390a2600954600160c01b90046001600160401b031680156121b257600980546001600160801b0316600160801b6001600160401b0384169081026001600160c01b03169190911790915560405190815233907fe893fa207c5a5094cad036347b877c23ebecd9df94ae0426f287040c13220b3f9060200160405180910390a250505050505050565b42841015612a8b5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610ca0565b6000612a95611644565b6001600160a01b0389811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015612bae573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612be45750886001600160a01b0316816001600160a01b0316145b612c215760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610ca0565b6001600160a01b0390811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000612cc1612c996116f2565b83907f0000000000000000000000000000000000000000000000000de0b6b3a76400006132b3565b9050612ccd3383613112565b60405181815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a2611124338261317c565b6000612d1661175e565b600c54039050612d24611daf565b6116759082613da9565b612d44336000356001600160e01b031916612fc7565b612d605760405162461bcd60e51b8152600401610ca090613bf2565b806001600160a01b031663ac784ddc6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dc29190613d38565b612e61577f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b0316816001600160a01b0316636f307dc36040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e529190613e29565b6001600160a01b031614612e68565b600b5460ff165b612ea75760405162461bcd60e51b815260206004820152601060248201526f57524f4e475f554e4445524c59494e4760801b6044820152606401610ca0565b6001600160a01b0381166000818152600d6020526040808220805460ff191660011790555133917f2fc1f5b589e399a463bf89605c1539bdd9878a9a3acd089abeca7a15e1fbe6ec91a350565b612f0a336000356001600160e01b031916612fc7565b612f265760405162461bcd60e51b8152600401610ca090613bf2565b6000600f8381548110612f3b57612f3b613c45565b600091825260209091200154600f80546001600160a01b039092169250839185908110612f6a57612f6a613c45565b60009182526020918290200180546001600160a01b0319166001600160a01b039384161790556040518581528483169284169133917f6b3d5cb176c4387df974c7528104dc97592d836de95196de9f68adbb6f46d5ac9101610fd1565b6007546000906001600160a01b03168015801590613051575060405163b700961360e01b81526001600160a01b0382169063b70096139061301090879030908890600401613d0b565b602060405180830381865afa15801561302d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130519190613d38565b8061306957506006546001600160a01b038581169116145b949350505050565b600060405163a9059cbb60e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506130ac8161345c565b6130ea5760405162461bcd60e51b815260206004820152600f60248201526e1514905394d1915497d19052531151608a1b6044820152606401610ca0565b50505050565b82810282151584158583048414171661310857600080fd5b9190910492915050565b6001600160a01b0382166000908152600360205260408120805483929061313a908490613c2e565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020613efa833981519152906020015b60405180910390a35050565b6000613186611daf565b9050808211156131e05760006131bb600a54670de0b6b3a7640000856131aa612d0c565b6131b49190613c2e565b91906132b3565b905060006131c98385613c2e565b90506131dd6131d88383613da9565b6134a3565b50505b6132146001600160a01b037f0000000000000000000000002602278ee1882889b946eb11dc0e810075650983168484613071565b505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161324b9190613e46565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b82820283158482048414176132c757600080fd5b0492915050565b60006001600160f81b038211156132e457600080fd5b5090565b80600260008282546132fa9190613da9565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020613efa8339815191529101613170565b60006040516323b872dd60e01b81526001600160a01b03851660048201526001600160a01b038416602482015282604482015260008060648360008a5af19150506133848161345c565b6133c75760405162461bcd60e51b81526020600482015260146024820152731514905394d1915497d19493d357d1905253115160621b6044820152606401610ca0565b5050505050565b600060405163095ea7b360e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506134098161345c565b6130ea5760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b6044820152606401610ca0565b60006001600160801b038211156132e457600080fd5b60003d8261346e57806000803e806000fd5b8060208114613486578015613497576000925061349c565b816000803e6000511515925061349c565b600192505b5050919050565b600f5481906000906134b790600190613c2e565b90505b6000600f82815481106134cf576134cf613c45565b60009182526020808320909101546001600160a01b0316808352600d9091526040909120549091506001600160f81b036101008204169060ff161580613513575080155b1561358957600f80548061352957613529613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0384169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a3505061374a565b6000848211613598578161359a565b845b90508082036135a8816132ce565b6001600160a01b0385166000818152600d60205260409081902080546001600160f81b03949094166101000260ff909416939093179092559051968390039633907f8d851b682e239b1de720e92e5c5cffdb72d353104cc63dc6ed144d7080217fbe906136189086815260200190565b60405180910390a360405163852a12e360e01b8152600481018390526001600160a01b0385169063852a12e3906024016020604051808303816000875af1158015613667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368b9190613c71565b156136c85760405162461bcd60e51b815260206004820152600d60248201526c14915111515357d19052531151609a1b6044820152606401610ca0565b8061373857600f8054806136de576136de613c5b565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b0386169133917f61d23abf676b955085fda50d45f510cdab69e13e63afebdde7f4453b529fbfdc9190a35b50846137465750505061375c565b5050505b8061375481613ee2565b9150506134ba565b600c805484900390554780158015906137775750600b5460ff165b156130ea577f0000000000000000000000002602278ee1882889b946eb11dc0e8100756509836001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156137d757600080fd5b505af11580156137eb573d6000803e3d6000fd5b505050505050505050565b828054828255906000526020600020908101928215613849579160200282015b828111156138495781546001600160a01b0319166001600160a01b03843516178255602090920191600190910190613816565b506132e49291505b808211156132e45760008155600101613851565b600060208083528351808285015260005b8181101561389257858101830151858201604001528201613876565b818111156138a4576000604083870101525b50601f01601f1916929092016040019392505050565b6000602082840312156138cc57600080fd5b81356001600160801b03811681146138e357600080fd5b9392505050565b6001600160a01b038116811461149c57600080fd5b6000806040838503121561391257600080fd5b823561391d816138ea565b946020939093013593505050565b60006020828403121561393d57600080fd5b5035919050565b60006020828403121561395657600080fd5b81356138e3816138ea565b6000806020838503121561397457600080fd5b82356001600160401b038082111561398b57600080fd5b818501915085601f83011261399f57600080fd5b8135818111156139ae57600080fd5b8660208260051b85010111156139c357600080fd5b60209290920196919550909350505050565b6000806000606084860312156139ea57600080fd5b83356139f5816138ea565b92506020840135613a05816138ea565b929592945050506040919091013590565b60008060408385031215613a2957600080fd5b50508035926020909101359150565b801515811461149c57600080fd5b600060208284031215613a5857600080fd5b81356138e381613a38565b6020808252825182820181905260009190848201906040850190845b81811015613aa45783516001600160a01b031683529284019291840191600101613a7f565b50909695505050505050565b600060208284031215613ac257600080fd5b81356001600160401b03811681146138e357600080fd5b60ff8116811461149c57600080fd5b600080600080600080600060e0888a031215613b0357600080fd5b8735613b0e816138ea565b96506020880135613b1e816138ea565b955060408801359450606088013593506080880135613b3c81613ad9565b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613b6c57600080fd5b8235613b77816138ea565b91506020830135613b87816138ea565b809150509250929050565b60008060408385031215613ba557600080fd5b823591506020830135613b87816138ea565b600181811c90821680613bcb57607f821691505b60208210811415613bec57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b600082821015613c4057613c40613c18565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600060208284031215613c8357600080fd5b5051919050565b60208082528181018390526000908460408401835b86811015613ccd578235613cb2816138ea565b6001600160a01b031682529183019190830190600101613c9f565b509695505050505050565b600060208284031215613cea57600080fd5b81516138e381613ad9565b634e487b7160e01b600052601260045260246000fd5b6001600160a01b0393841681529190921660208201526001600160e01b0319909116604082015260600190565b600060208284031215613d4a57600080fd5b81516138e381613a38565b602080825260129082015271554e545255535445445f535452415445475960701b604082015260600190565b60006001600160f81b0383811690831681811015613da157613da1613c18565b039392505050565b60008219821115613dbc57613dbc613c18565b500190565b60006001600160401b03808316818516808303821115613de357613de3613c18565b01949350505050565b60006001600160801b03808316818516808303821115613de357613de3613c18565b6000600019821415613e2257613e22613c18565b5060010190565b600060208284031215613e3b57600080fd5b81516138e3816138ea565b600080835481600182811c915080831680613e6257607f831692505b6020808410821415613e8257634e487b7160e01b86526022600452602486fd5b818015613e965760018114613ea757613ed4565b60ff19861689528489019650613ed4565b60008a81526020902060005b86811015613ecc5781548b820152908501908301613eb3565b505084890196505b509498975050505050505050565b600081613ef157613ef1613c18565b50600019019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa26469706673582212208de4f2e4f90038de1484734e50e4731605e2bffe1ecde3badb1f119f1d4a7c3d64736f6c634300080b0033

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

0000000000000000000000002602278ee1882889b946eb11dc0e810075650983

-----Decoded View---------------
Arg [0] : _UNDERLYING (address): 0x2602278EE1882889B946eb11DC0E810075650983

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000002602278ee1882889b946eb11dc0e810075650983


Deployed Bytecode Sourcemap

29036:44970:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3787:18;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33830:384;;;;;;;;;;-1:-1:-1;33830:384:0;;;;;:::i;:::-;;:::i;:::-;;5423:217;;;;;;;;;;-1:-1:-1;5423:217:0;;;;;:::i;:::-;;:::i;:::-;;;1543:14:1;;1536:22;1518:41;;1506:2;1491:18;5423:217:0;1378:187:1;40390:33:0;;;;;;;;;;-1:-1:-1;40390:33:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1936:32:1;;;1918:51;;1906:2;1891:18;40390:33:0;1755:220:1;2100:151:0;;;;;;;;;;-1:-1:-1;2100:151:0;;;;;:::i;:::-;;:::i;68469:651::-;;;;;;;;;;-1:-1:-1;68469:651:0;;;;;:::i;:::-;;:::i;4071:26::-;;;;;;;;;;;;;;;;;;;2378:25:1;;;2366:2;2351:18;4071:26:0;2232:177:1;35743:33:0;;;;;;;;;;;;;;;;70546:984;;;;;;;;;;-1:-1:-1;70546:984:0;;;;;:::i;:::-;;:::i;67034:384::-;;;;;;;;;;-1:-1:-1;67034:384:0;;;;;:::i;:::-;;:::i;6041:612::-;;;;;;;;;;-1:-1:-1;6041:612:0;;;;;:::i;:::-;;:::i;69303:529::-;;;;;;;;;;-1:-1:-1;69303:529:0;;;;;:::i;:::-;;:::i;39017:56::-;;;;;;;;;;-1:-1:-1;39017:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39017:56:0;;;;;;;4227:14:1;;4220:22;4202:41;;-1:-1:-1;;;;;4279:32:1;;;4274:2;4259:18;;4252:60;4175:18;39017:56:0;4034:284:1;42390:462:0;;;;;;;;;;-1:-1:-1;42390:462:0;;;;;:::i;:::-;;:::i;4422:146::-;;;;;;;;;;;;4473:95;4422:146;;3843:31;;;;;;;;;;;;;;;;;;4677:4:1;4665:17;;;4647:36;;4635:2;4620:18;3843:31:0;4505:184:1;37625:458:0;;;;;;;;;;-1:-1:-1;37625:458:0;;;;;:::i;:::-;;:::i;40747:113::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;7881:179::-;;;;;;;;;;;;;:::i;72942:25::-;;;;;;;;;;-1:-1:-1;72942:25:0;;;;;;;;45320:148;;;;;;;;;;-1:-1:-1;45320:148:0;;;;;:::i;:::-;;:::i;45646:452::-;;;;;;;;;;;;;:::i;33429:26::-;;;;;;;;;;-1:-1:-1;33429:26:0;;;;-1:-1:-1;;;33429:26:0;;-1:-1:-1;;;;;33429:26:0;;;;;;-1:-1:-1;;;;;5905:31:1;;;5887:50;;5875:2;5860:18;33429:26:0;5743:200:1;46789:936:0;;;;;;;;;;;;;:::i;65760:408::-;;;;;;;;;;-1:-1:-1;65760:408:0;;;;;:::i;:::-;;:::i;66423:344::-;;;;;;;;;;;;;:::i;4106:44::-;;;;;;;;;;-1:-1:-1;4106:44:0;;;;;:::i;:::-;;;;;;;;;;;;;;33615:30;;;;;;;;;;-1:-1:-1;33615:30:0;;;;-1:-1:-1;;;33615:30:0;;-1:-1:-1;;;;;33615:30:0;;;1650:442;;;;;;;;;;-1:-1:-1;1650:442:0;;;;;:::i;:::-;;:::i;34532:844::-;;;;;;;;;;-1:-1:-1;34532:844:0;;;;;:::i;:::-;;:::i;31614:332::-;;;;;;;;;;-1:-1:-1;31614:332:0;;;;;:::i;:::-;;:::i;4689:41::-;;;;;;;;;;-1:-1:-1;4689:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;31223:25;;;;;;;;;;;;;;;;73123:348;;;;;;;;;;;;;:::i;73620:93::-;;;;;;;;;;;;;:::i;47895:113::-;;;;;;;;;;;;;:::i;679:20::-;;;;;;;;;;-1:-1:-1;679:20:0;;;;-1:-1:-1;;;;;679:20:0;;;3814;;;;;;;;;;;;;:::i;5648:385::-;;;;;;;;;;-1:-1:-1;5648:385:0;;;;;:::i;:::-;;:::i;72168:258::-;;;;;;;;;;-1:-1:-1;72168:258:0;;;;;:::i;:::-;;:::i;55796:1090::-;;;;;;;;;;-1:-1:-1;55796:1090:0;;;;;:::i;:::-;;:::i;41755:483::-;;;;;;;;;;-1:-1:-1;41755:483:0;;;;;:::i;:::-;;:::i;36209:409::-;;;;;;;;;;-1:-1:-1;36209:409:0;;;;;:::i;:::-;;:::i;53991:1492::-;;;;;;;;;;-1:-1:-1;53991:1492:0;;;;;:::i;:::-;;:::i;708:26::-;;;;;;;;;;-1:-1:-1;708:26:0;;;;-1:-1:-1;;;;;708:26:0;;;29846:33;;;;;;;;;;;;;;;58487:230;;;;;;;;;;-1:-1:-1;58487:230:0;;;;;:::i;:::-;;:::i;48706:4044::-;;;;;;;;;;-1:-1:-1;48706:4044:0;;;;;:::i;:::-;;:::i;39731:30::-;;;;;;;;;;-1:-1:-1;39731:30:0;;;;-1:-1:-1;;;39731:30:0;;-1:-1:-1;;;;;39731:30:0;;;;;;-1:-1:-1;;;;;7661:47:1;;;7643:66;;7631:2;7616:18;39731:30:0;7497:218:1;6850:1023:0;;;;;;;;;;-1:-1:-1;6850:1023:0;;;;;:::i;:::-;;:::i;43023:552::-;;;;;;;;;;-1:-1:-1;43023:552:0;;;;;:::i;:::-;;:::i;4159:64::-;;;;;;;;;;-1:-1:-1;4159:64:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;46281:381;;;;;;;;;;;;;:::i;57760:578::-;;;;;;;;;;-1:-1:-1;57760:578:0;;;;;:::i;:::-;;:::i;38490:36::-;;;;;;;;;;;;;;;;67804:446;;;;;;;;;;-1:-1:-1;67804:446:0;;;;;:::i;:::-;;:::i;39494:36::-;;;;;;;;;;-1:-1:-1;39494:36:0;;;;-1:-1:-1;;;;;39494:36:0;;;39620:25;;;;;;;;;;-1:-1:-1;39620:25:0;;;;-1:-1:-1;;;39620:25:0;;-1:-1:-1;;;;;39620:25:0;;;36996:28;;;;;;;;;;-1:-1:-1;36996:28:0;;;;;;;;33244;;;;;;;;;;-1:-1:-1;33244:28:0;;;;-1:-1:-1;;;;;33244:28:0;;;3787:18;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;33830:384::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;;;;;;;;;34022:12:::1;::::0;-1:-1:-1;;;34022:12:0;::::1;-1:-1:-1::0;;;;;34022:12:0::1;-1:-1:-1::0;;;;;34002:32:0;::::1;;;33994:60;;;::::0;-1:-1:-1;;;33994:60:0;;10303:2:1;33994:60:0::1;::::0;::::1;10285:21:1::0;10342:2;10322:18;;;10315:30;-1:-1:-1;;;10361:18:1;;;10354:45;10416:18;;33994:60:0::1;10101:339:1::0;33994:60:0::1;34106:13;:32:::0;;-1:-1:-1;;34106:32:0::1;-1:-1:-1::0;;;;;34106:32:0;::::1;::::0;;::::1;::::0;;;34156:50:::1;::::0;7643:66:1;;;34177:10:0::1;::::0;34156:50:::1;::::0;7631:2:1;7616:18;34156:50:0::1;;;;;;;;33830:384:::0;:::o;5423:217::-;5524:10;5497:4;5514:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;5514:30:0;;;;;;;;;;:39;;;5571:37;5497:4;;5514:30;;5571:37;;;;5547:6;2378:25:1;;2366:2;2351:18;;2232:177;5571:37:0;;;;;;;;-1:-1:-1;5628:4:0;5423:217;;;;:::o;40390:33::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40390:33:0;;-1:-1:-1;40390:33:0;:::o;2100:151::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;2175:5:::1;:16:::0;;-1:-1:-1;;;;;;2175:16:0::1;-1:-1:-1::0;;;;;2175:16:0;::::1;::::0;;::::1;::::0;;;2209:34:::1;::::0;2222:10:::1;::::0;2209:34:::1;::::0;-1:-1:-1;;2209:34:0::1;2100:151:::0;:::o;68469:651::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;68681:15:::1;68697:22:::0;;68650:28:::1;::::0;68681:15;68697:26:::1;::::0;68722:1:::1;::::0;68697:26:::1;:::i;:::-;68681:43;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;::::0;68763:15:::1;:22:::0;;-1:-1:-1;;;;;68681:43:0;;::::1;::::0;-1:-1:-1;68763:15:0;68779:5;;68763:22;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;68865:15:::1;:22:::0;;-1:-1:-1;;;;;68763:22:0;;::::1;::::0;-1:-1:-1;68890:19:0;;68881:5;;68865:22;::::1;;;;;:::i;:::-;;;;;;;;;:44;;;;;-1:-1:-1::0;;;;;68865:44:0::1;;;;;-1:-1:-1::0;;;;;68865:44:0::1;;;;;;68980:15;:21;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;68980:21:0;;;;;-1:-1:-1;;;;;;68980:21:0::1;::::0;;;;;69019:93:::1;::::0;-1:-1:-1;;;;;69019:93:0;;::::1;::::0;;;::::1;::::0;69055:10:::1;::::0;69019:93:::1;::::0;::::1;::::0;69067:5;2378:25:1;;2366:2;2351:18;;2232:177;69019:93:0::1;;;;;;;;68550:570;;68469:651:::0;:::o;70546:984::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;70722:25:0;::::1;70696:23;70722:25:::0;;;:15:::1;:25;::::0;;;;:33;::::1;::::0;::::1;-1:-1:-1::0;;;;;70722:33:0::1;70924:15;:13;:15::i;:::-;70906;:33;70902:58;;;70941:15;:19:::0;;-1:-1:-1;;;;;70941:19:0::1;::::0;;70902:58:::1;-1:-1:-1::0;;;;;71018:25:0;::::1;71054:1;71018:25:::0;;;:15:::1;:25;::::0;;;;;:37;;;::::1;::::0;;71264:21:::1;:40:::0;;;;::::1;::::0;;71333:36;71348:10:::1;::::0;71333:36:::1;::::0;::::1;71488:33;::::0;-1:-1:-1;;;71488:33:0;;71515:4:::1;71488:33;::::0;::::1;1918:51:1::0;71447:75:0::1;::::0;71476:10:::1;::::0;-1:-1:-1;;;;;71488:18:0;::::1;::::0;::::1;::::0;1891::1;;71488:33:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;71447:28:0;::::1;::::0;:75;:28:::1;:75::i;:::-;70610:920;70546:984:::0;:::o;67034:384::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;29591:2:::1;67209:44:::0;::::1;;67201:70;;;::::0;-1:-1:-1;;;67201:70:0;;11362:2:1;67201:70:0::1;::::0;::::1;11344:21:1::0;11401:2;11381:18;;;11374:30;-1:-1:-1;;;11420:18:1;;;11413:43;11473:18;;67201:70:0::1;11160:337:1::0;67201:70:0::1;67326:26;:15;67344:8:::0;;67326:26:::1;:::i;:::-;;67389:10;-1:-1:-1::0;;;;;67370:40:0::1;;67401:8;;67370:40;;;;;;;:::i;:::-;;;;;;;;67034:384:::0;;:::o;6041:612::-;-1:-1:-1;;;;;6198:15:0;;6163:4;6198:15;;;:9;:15;;;;;;;;6214:10;6198:27;;;;;;;;-1:-1:-1;;6278:28:0;;6274:80;;6338:16;6348:6;6338:7;:16;:::i;:::-;-1:-1:-1;;;;;6308:15:0;;;;;;:9;:15;;;;;;;;6324:10;6308:27;;;;;;;:46;6274:80;-1:-1:-1;;;;;6367:15:0;;;;;;:9;:15;;;;;:25;;6386:6;;6367:15;:25;;6386:6;;6367:25;:::i;:::-;;;;-1:-1:-1;;;;;;;6543:13:0;;;;;;;:9;:13;;;;;;;:23;;;;;;6595:26;6543:13;;6595:26;;;-1:-1:-1;;;;;;;;;;;6595:26:0;;;6560:6;2378:25:1;;2366:2;2351:18;;2232:177;6595:26:0;;;;;;;;-1:-1:-1;6641:4:0;;6041:612;-1:-1:-1;;;;6041:612:0:o;69303:529::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;69467:21:::1;69491:15;69507:6;69491:23;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;::::1;::::0;69549:15:::1;:23:::0;;-1:-1:-1;;;;;69491:23:0;;::::1;::::0;-1:-1:-1;69549:15:0;69565:6;;69549:23;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;69634:15:::1;:23:::0;;-1:-1:-1;;;;;69549:23:0;;::::1;::::0;-1:-1:-1;69549:23:0;;69650:6;;69634:23;::::1;;;;;:::i;:::-;;;;;;;;;:38;;;;;-1:-1:-1::0;;;;;69634:38:0::1;;;;;-1:-1:-1::0;;;;;69634:38:0::1;;;;;;69709:12;69683:15;69699:6;69683:23;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;::::1;:38:::0;;-1:-1:-1;;;;;;69683:38:0::1;-1:-1:-1::0;;;;;69683:38:0;;::::1;;::::0;;69739:85:::1;::::0;;12403:25:1;;;12444:18;;;12437:34;;;69739:85:0;;::::1;::::0;;::::1;::::0;69769:10:::1;::::0;69739:85:::1;::::0;12376:18:1;69739:85:0::1;;;;;;;69393:439;;69303:529:::0;;:::o;42390:462::-;42597:67;42603:10;42615:48;42637:14;:12;:14::i;:::-;42615:16;;42653:9;42615:21;:48::i;:::-;42597:5;:67::i;:::-;42682:38;;2378:25:1;;;42691:10:0;;42682:38;;2366:2:1;2351:18;42682:38:0;;;;;;;42794:50;42815:10;42827:16;42794:20;:50::i;:::-;42390:462;:::o;37625:458::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;37813:19:::1;37812:20;:51;;;;37836:10;-1:-1:-1::0;;;;;37836:19:0::1;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:27;;37861:2;37836:27;37812:51;37804:78;;;::::0;-1:-1:-1;;;37804:78:0;;12936:2:1;37804:78:0::1;::::0;::::1;12918:21:1::0;12975:2;12955:18;;;12948:30;-1:-1:-1;;;12994:18:1;;;12987:44;13048:18;;37804:78:0::1;12734:338:1::0;37804:78:0::1;37963:16;:38:::0;;-1:-1:-1;;37963:38:0::1;::::0;::::1;;::::0;;::::1;::::0;;;38019:56:::1;::::0;1518:41:1;;;38043:10:0::1;::::0;38019:56:::1;::::0;1506:2:1;1491:18;38019:56:0::1;1378:187:1::0;40747:113:0;40800:17;40837:15;40830:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40830:22:0;;;;;;;;;;;;;;;;;;;;;;;40747:113;:::o;7881:179::-;7938:7;7982:16;7965:13;:33;:87;;8028:24;:22;:24::i;:::-;7958:94;;7881:179;:::o;7965:87::-;-1:-1:-1;8001:24:0;;7881:179::o;45320:148::-;45386:7;45413:47;45434:14;:12;:14::i;:::-;-1:-1:-1;;;;;45413:15:0;;;;;;:9;:15;;;;;;;45450:9;45413:20;:47::i;:::-;45406:54;45320:148;-1:-1:-1;;45320:148:0:o;45646:452::-;45781:11;;45691:7;;45894:18;45890:40;;45921:9;45914:16;;;45646:452;:::o;45890:40::-;46044:46;46065:13;46080:9;46044:15;:13;:15::i;:::-;:20;:46;:20;:46::i;:::-;46037:53;;;45646:452;:::o;46789:936::-;46932:11;;46980:12;;46834:7;;-1:-1:-1;;;;;;;;46932:11:0;;;;;;-1:-1:-1;;;46980:12:0;;;47214:33;;;47195:15;:52;47191:66;;47256:1;47249:8;;;;46789:936;:::o;47191:66::-;47360:15;;-1:-1:-1;;;47360:15:0;;-1:-1:-1;;;;;47360:15:0;47691;47653;:33;;;47630:57;;47691:15;47629:77;;;;:::i;:::-;;47607:99;;;46789:936;-1:-1:-1;;;46789:936:0:o;65760:408::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;65934:15:::1;:22:::0;29591:2:::1;-1:-1:-1::0;65926:73:0::1;;;::::0;-1:-1:-1;;;65926:73:0;;13411:2:1;65926:73:0::1;::::0;::::1;13393:21:1::0;13450:2;13430:18;;;13423:30;-1:-1:-1;;;13469:18:1;;;13462:40;13519:18;;65926:73:0::1;13209:334:1::0;65926:73:0::1;66069:15;:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;66069:30:0;;;;::::1;::::0;;-1:-1:-1;;;;;;66069:30:0::1;-1:-1:-1::0;;;;;66069:30:0;::::1;::::0;;::::1;::::0;;;66117:43:::1;::::0;66069:30;;66139:10:::1;::::0;66117:43:::1;::::0;-1:-1:-1;66117:43:0::1;65760:408:::0;:::o;66423:344::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;66566:15:::1;66582:22:::0;;66540:23:::1;::::0;66566:15;66582:26:::1;::::0;66607:1:::1;::::0;66582:26:::1;:::i;:::-;66566:43;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;66671:15:::1;:21:::0;;-1:-1:-1;;;;;66566:43:0;;::::1;::::0;-1:-1:-1;66671:15:0;:21;::::1;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;-1:-1:-1;;66671:21:0;;;;;-1:-1:-1;;;;;;66671:21:0::1;::::0;;;;;;;;66710:49:::1;::::0;-1:-1:-1;;;;;66710:49:0;::::1;::::0;66732:10:::1;::::0;66710:49:::1;::::0;66671:21;66710:49:::1;66479:288;66423:344::o:0;1650:442::-;1924:5;;-1:-1:-1;;;;;1924:5:0;1910:10;:19;;:76;;-1:-1:-1;1933:9:0;;:53;;-1:-1:-1;;;1933:53:0;;-1:-1:-1;;;;;1933:9:0;;;;:17;;:53;;1951:10;;1971:4;;-1:-1:-1;;;;;;1933:9:0;1978:7;;;1933:53;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1902:85;;;;;;2000:9;:24;;-1:-1:-1;;;;;;2000:24:0;-1:-1:-1;;;;;2000:24:0;;;;;;;;2042:42;;2059:10;;2042:42;;-1:-1:-1;;2042:42:0;1650:442;:::o;34532:844::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;34702:20:0;::::1;34694:53;;;::::0;-1:-1:-1;;;34694:53:0;;14405:2:1;34694:53:0::1;::::0;::::1;14387:21:1::0;14444:2;14424:18;;;14417:30;-1:-1:-1;;;14463:18:1;;;14456:50;14523:18;;34694:53:0::1;14203:344:1::0;34694:53:0::1;34854:8;34835:15;-1:-1:-1::0;;;;;34835:27:0::1;;;34827:54;;;::::0;-1:-1:-1;;;34827:54:0;;14754:2:1;34827:54:0::1;::::0;::::1;14736:21:1::0;14793:2;14773:18;;;14766:30;-1:-1:-1;;;14812:18:1;;;14805:44;14866:18;;34827:54:0::1;14552:338:1::0;34827:54:0::1;34973:12;::::0;-1:-1:-1;;;34973:12:0;::::1;-1:-1:-1::0;;;;;34973:12:0::1;34969:400;;35059:12;:30:::0;;-1:-1:-1;;;;35059:30:0::1;-1:-1:-1::0;;;;;;;;35059:30:0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;35111:48:::1;::::0;5887:50:1;;;35131:10:0::1;::::0;35111:48:::1;::::0;5875:2:1;5860:18;35111:48:0::1;5743:200:1::0;34969:400:0::1;35245:16;:34:::0;;-1:-1:-1;;;;;35245:34:0::1;-1:-1:-1::0;;;;;;;;35245:34:0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;35301:56:::1;::::0;5887:50:1;;;35329:10:0::1;::::0;35301:56:::1;::::0;5875:2:1;5860:18;35301:56:0::1;5743:200:1::0;31614:332:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;31777:4:::1;31760:13;:21;;31752:46;;;::::0;-1:-1:-1;;;31752:46:0;;15097:2:1;31752:46:0::1;::::0;::::1;15079:21:1::0;15136:2;15116:18;;;15109:30;-1:-1:-1;;;15155:18:1;;;15148:42;15207:18;;31752:46:0::1;14895:336:1::0;31752:46:0::1;31850:10;:26:::0;;;31894:44:::1;::::0;2378:25:1;;;31912:10:0::1;::::0;31894:44:::1;::::0;2366:2:1;2351:18;31894:44:0::1;2232:177:1::0;73123:348:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;73250:13:::1;::::0;::::1;;73249:14;73241:46;;;::::0;-1:-1:-1;;;73241:46:0;;15438:2:1;73241:46:0::1;::::0;::::1;15420:21:1::0;15477:2;15457:18;;;15450:30;-1:-1:-1;;;15496:18:1;;;15489:49;15555:18;;73241:46:0::1;15236:343:1::0;73241:46:0::1;73343:13;:20:::0;;-1:-1:-1;;73343:20:0::1;73359:4;73343:20;::::0;;:13:::1;73407:11;:15:::0;;;73440:23:::1;::::0;73452:10:::1;::::0;73440:23:::1;::::0;::::1;73123:348::o:0;73620:93::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;73693:10:::1;73672:33;47895:113:::0;47965:35;;-1:-1:-1;;;47965:35:0;;47994:4;47965:35;;;1918:51:1;47938:7:0;;47965:10;-1:-1:-1;;;;;47965:20:0;;;;1891:18:1;;47965:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;3814:20::-;;;;;;;:::i;5648:385::-;5745:10;5718:4;5735:21;;;:9;:21;;;;;:31;;5760:6;;5735:21;5718:4;;5735:31;;5760:6;;5735:31;:::i;:::-;;;;-1:-1:-1;;;;;;;5917:13:0;;;;;;:9;:13;;;;;;;:23;;;;;;5969:32;5978:10;;-1:-1:-1;;;;;;;;;;;5969:32:0;;;5934:6;2378:25:1;;2366:2;2351:18;;2232:177;72168:258:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;72248:38:::1;::::0;2378:25:1;;;72260:10:0::1;::::0;72248:38:::1;::::0;2366:2:1;2351:18;72248:38:0::1;;;;;;;72367:51;72373:4;72392:10;72404:13:::0;72367:24:::1;:51::i;55796:1090::-:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;55984:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:33;::::1;;55976:64;;;;-1:-1:-1::0;;;55976:64:0::1;;;;;;;:::i;:::-;56170:32;:16;:30;:32::i;:::-;-1:-1:-1::0;;;;;56133:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:69;;:33:::1;::::0;:69:::1;::::0;;;::::1;::::0;::::1;-1:-1:-1::0;;;;;56133:69:0::1;;:::i;:::-;::::0;;-1:-1:-1;;;;;56133:69:0;;::::1;;::::0;;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;::::1;;::::0;;-1:-1:-1;56416:21:0::1;:41:::0;;;;::::1;::::0;;56486:58:::1;::::0;2378:25:1;;;-1:-1:-1;;;;;56486:58:0;::::1;::::0;56505:10:::1;::::0;56486:58:::1;::::0;2366:2:1;2351:18;56486:58:0::1;;;;;;;56644:43;::::0;-1:-1:-1;;;56644:43:0;;::::1;::::0;::::1;2378:25:1::0;;;-1:-1:-1;;;;;56644:25:0;::::1;::::0;::::1;::::0;2351:18:1;;56644:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:48:::0;56636:74:::1;;;::::0;-1:-1:-1;;;56636:74:0;;16369:2:1;56636:74:0::1;::::0;::::1;16351:21:1::0;16408:2;16388:18;;;16381:30;-1:-1:-1;;;16427:18:1;;;16420:43;16480:18;;56636:74:0::1;16167:337:1::0;56636:74:0::1;56788:8;-1:-1:-1::0;;;;;56788:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56784:94;;;56830:10;-1:-1:-1::0;;;;;56809:42:0::1;;56859:16;56809:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;55796:1090:::0;;:::o;41755:483::-;41889:67;41895:10;41907:48;41929:14;:12;:14::i;41907:48::-;41889:5;:67::i;:::-;41974:37;;2378:25:1;;;41982:10:0;;41974:37;;2366:2:1;2351:18;41974:37:0;;;;;;;42158:72;-1:-1:-1;;;;;42158:10:0;:27;42186:10;42206:4;42213:16;42158:27;:72::i;36209:409::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;36405:4:::1;36380:21;:29;;36372:57;;;::::0;-1:-1:-1;;;36372:57:0;;16711:2:1;36372:57:0::1;::::0;::::1;16693:21:1::0;16750:2;16730:18;;;16723:30;-1:-1:-1;;;16769:18:1;;;16762:45;16824:18;;36372:57:0::1;16509:339:1::0;36372:57:0::1;36490:18;:42:::0;;;36550:60:::1;::::0;2378:25:1;;;36576:10:0::1;::::0;36550:60:::1;::::0;2366:2:1;2351:18;36550:60:0::1;2232:177:1::0;53991:1492:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;54178:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:33;::::1;;54170:64;;;;-1:-1:-1::0;;;54170:64:0::1;;;;;;;:::i;:::-;54343:16;54318:21;;:41;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;54607:32:0::1;::::0;-1:-1:-1;54607:16:0;:30:::1;:32::i;:::-;-1:-1:-1::0;;;;;54570:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;;;:69;;-1:-1:-1;;;;;54570:69:0::1;::::0;;::::1;::::0;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;54668:55;;54684:10:::1;::::0;54668:55:::1;::::0;::::1;::::0;54706:16;2378:25:1;;2366:2;2351:18;;2232:177;54668:55:0::1;;;;;;;;54810:8;-1:-1:-1::0;;;;;54810:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54806:670;;;54895:61;::::0;-1:-1:-1;;;54895:61:0;;::::1;::::0;::::1;2378:25:1::0;;;54916:10:0::1;-1:-1:-1::0;;;;;54895:43:0::1;::::0;::::1;::::0;2351:18:1;;54895:61:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;55071:8;-1:-1:-1::0;;;;;55051:35:0::1;;55094:16;55051:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;54806:670;55222:59;-1:-1:-1::0;;;;;55222:10:0::1;:22;55253:8:::0;55264:16;55222:22:::1;:59::i;:::-;55388:55;::::0;-1:-1:-1;;;55388:55:0;;::::1;::::0;::::1;2378:25:1::0;;;-1:-1:-1;;;;;55388:37:0;::::1;::::0;::::1;::::0;2351:18:1;;55388:55:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:60:::0;55380:84:::1;;;::::0;-1:-1:-1;;;55380:84:0;;17188:2:1;55380:84:0::1;::::0;::::1;17170:21:1::0;17227:2;17207:18;;;17200:30;-1:-1:-1;;;17246:18:1;;;17239:41;17297:18;;55380:84:0::1;16986:335:1::0;58487:230:0;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;58610:25:0;::::1;58646:5;58610:25:::0;;;:15:::1;:25;::::0;;;;;:41;;-1:-1:-1;;58610:41:0::1;::::0;;58669:40;58688:10:::1;::::0;58669:40:::1;::::0;::::1;58487:230:::0;:::o;48706:4044::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;48889:12:::1;::::0;48875:11:::1;::::0;:26:::1;::::0;-1:-1:-1;;;;;;;;48889:12:0;;::::1;::::0;::::1;::::0;-1:-1:-1;;;48875:11:0;::::1;;:26;:::i;:::-;-1:-1:-1::0;;;;;48856:45:0::1;:15;:45;48852:469;;49037:22;:48:::0;;-1:-1:-1;;49037:48:0::1;49069:15;-1:-1:-1::0;;;;;49037:48:0::1;;::::0;;48852:469:::1;;;49275:13;::::0;49250:22:::1;::::0;:38:::1;::::0;-1:-1:-1;;;;;49275:13:0::1;::::0;-1:-1:-1;;;;;49250:22:0::1;:38;:::i;:::-;-1:-1:-1::0;;;;;49231:57:0::1;:15;:57;;49223:86;;;::::0;-1:-1:-1;;;49223:86:0;;18027:2:1;49223:86:0::1;::::0;::::1;18009:21:1::0;18066:2;18046:18;;;18039:30;-1:-1:-1;;;18085:18:1;;;18078:46;18141:18;;49223:86:0::1;17825:340:1::0;49223:86:0::1;49429:21;::::0;49394:32:::1;49429:21:::0;49394:32;49794:1639:::1;49814:21:::0;;::::1;49794:1639;;;49912:17;49932:10;;49943:1;49932:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;50149:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:33;49912;;-1:-1:-1;50149:33:0::1;;50141:64;;;;-1:-1:-1::0;;;50141:64:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;50316:25:0;::::1;50287:26;50316:25:::0;;;:15:::1;:25;::::0;;;;;:33;50393:43;;-1:-1:-1;;;50393:43:0;;50430:4:::1;50393:43;::::0;::::1;1918:51:1::0;50316:33:0::1;::::0;;::::1;-1:-1:-1::0;;;;;50316:33:0::1;::::0;:25;50393:28:::1;::::0;1891:18:1;;50393:43:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50364:72;;50573:34;:18;:32;:34::i;:::-;-1:-1:-1::0;;;;;50537:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;:70;;-1:-1:-1;;;;;50537:70:0;;;::::1;;;::::0;;;::::1;::::0;;;::::1;::::0;;50907:18;50859:45:::1;50886:18:::0;50859:24;:45:::1;:::i;:::-;:66;;;;:::i;:::-;50832:93;;51198:18;51177;:39;:158;;51334:1;51177:158;;;51261:18;51240;:39;51177:158;51155:180;;;;49842:1591;;;49837:3;;;;;:::i;:::-;;;;49794:1639;;;-1:-1:-1::0;51561:10:0::1;::::0;51515:19:::1;::::0;51537:41:::1;::::0;:18;;51573:4:::1;51537:23;:41::i;:::-;51515:63;;51746:65;51760:4;51767:43;51784:14;:12;:14::i;51746:65::-;51935:67;51974:11;51953:18;51936:14;:12;:14::i;:::-;:35;;;;:::i;:::-;:49;;;;:::i;:::-;51935:65;:67::i;:::-;51917:15;:85:::0;;52067:21:::1;:48:::0;;;-1:-1:-1;;;;;52245:15:0::1;52224:37:::0;::::1;-1:-1:-1::0;;;52224:37:0::1;-1:-1:-1::0;;;;;;;51917:85:0;;;::::1;-1:-1:-1::0;;;51917:85:0::1;52224:37:::0;;;;;;;;;;::::1;::::0;;52279:31:::1;::::0;52287:10:::1;::::0;52279:31:::1;::::0;::::1;::::0;52299:10;;;;52279:31:::1;:::i;:::-;;;;;;;;52388:16;::::0;-1:-1:-1;;;52388:16:0;::::1;-1:-1:-1::0;;;;;52388:16:0::1;52469:20:::0;;52465:278:::1;;52548:12;:30:::0;;-1:-1:-1;;;;;52641:20:0;-1:-1:-1;;;;;;;;52548:30:0;::::1;::::0;;::::1;-1:-1:-1::0;;;;;52641:20:0;;;;;;;;52683:48:::1;::::0;5887:50:1;;;52703:10:0::1;::::0;52683:48:::1;::::0;5875:2:1;5860:18;52683:48:0::1;;;;;;;48777:3973;;;;;48706:4044:::0;;:::o;6850:1023::-;7078:15;7066:8;:27;;7058:63;;;;-1:-1:-1;;;7058:63:0;;18512:2:1;7058:63:0;;;18494:21:1;18551:2;18531:18;;;18524:30;18590:25;18570:18;;;18563:53;18633:18;;7058:63:0;18310:347:1;7058:63:0;7291:14;7408:18;:16;:18::i;:::-;-1:-1:-1;;;;;7510:13:0;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;7459:77;;4473:95;7459:77;;;18949:25:1;19028:18;;;19021:43;;;;19100:15;;;19080:18;;;19073:43;19132:18;;;19125:34;;;19175:19;;;19168:35;;;;19219:19;;;;19212:35;;;7459:77:0;;;;;;;;;;18921:19:1;;;7459:77:0;;;7449:88;;;;;;;;-1:-1:-1;;;7336:220:0;;;19516:27:1;19559:11;;;19552:27;;;;19595:12;;;19588:28;;;;19632:12;;7336:220:0;;;-1:-1:-1;;7336:220:0;;;;;;;;;7308:263;;7336:220;7308:263;;;;7588:24;7615:26;;;;;;;;;19882:25:1;;;19955:4;19943:17;;19923:18;;;19916:45;;;;19977:18;;;19970:34;;;20020:18;;;20013:34;;;7308:263:0;;-1:-1:-1;7588:24:0;7615:26;;19854:19:1;;7615:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7615:26:0;;-1:-1:-1;;7615:26:0;;;-1:-1:-1;;;;;;;7666:30:0;;;;;;:59;;;7720:5;-1:-1:-1;;;;;7700:25:0;:16;-1:-1:-1;;;;;7700:25:0;;7666:59;7658:86;;;;-1:-1:-1;;;7658:86:0;;20260:2:1;7658:86:0;;;20242:21:1;20299:2;20279:18;;;20272:30;-1:-1:-1;;;20318:18:1;;;20311:44;20372:18;;7658:86:0;20058:338:1;7658:86:0;-1:-1:-1;;;;;7761:27:0;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;7834:31;2378:25:1;;;7761:36:0;;-1:-1:-1;7834:31:0;;;;;;2351:18:1;7834:31:0;;;;;;;6850:1023;;;;;;;:::o;43023:552::-;43148:24;43175:45;43194:14;:12;:14::i;:::-;43175:13;;43210:9;43175:18;:45::i;:::-;43148:72;;43355:32;43361:10;43373:13;43355:5;:32::i;:::-;43405:38;;2378:25:1;;;43414:10:0;;43405:38;;2366:2:1;2351:18;43405:38:0;;;;;;;43517:50;43538:10;43550:16;43517:20;:50::i;46281:381::-;46327:27;46526:14;:12;:14::i;:::-;46502:21;;:38;46480:60;;46642:12;:10;:12::i;:::-;46619:35;;;;:::i;57760:578::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;58035:8:::1;-1:-1:-1::0;;;;;58035:17:0::1;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:100;;58125:10;-1:-1:-1::0;;;;;58076:59:0::1;58098:8;-1:-1:-1::0;;;;;58076:43:0::1;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;58076:59:0::1;;58035:100;;;58057:16;::::0;::::1;;58035:100;58013:166;;;::::0;-1:-1:-1;;;58013:166:0;;20872:2:1;58013:166:0::1;::::0;::::1;20854:21:1::0;20911:2;20891:18;;;20884:30;-1:-1:-1;;;20930:18:1;;;20923:46;20986:18;;58013:166:0::1;20670:340:1::0;58013:166:0::1;-1:-1:-1::0;;;;;58235:25:0;::::1;;::::0;;;:15:::1;:25;::::0;;;;;:40;;-1:-1:-1;;58235:40:0::1;58271:4;58235:40;::::0;;58293:37;58309:10:::1;::::0;58293:37:::1;::::0;::::1;57760:578:::0;:::o;67804:446::-;1016:33;1029:10;1041:7;;-1:-1:-1;;;;;;1041:7:0;1016:12;:33::i;:::-;1008:58;;;;-1:-1:-1;;;1008:58:0;;;;;;;:::i;:::-;67971:25:::1;67999:15;68015:5;67999:22;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;68094:15:::1;:22:::0;;-1:-1:-1;;;;;67999:22:0;;::::1;::::0;-1:-1:-1;68119:19:0;;68110:5;;68094:22;::::1;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;;::::1;:44:::0;;-1:-1:-1;;;;;;68094:44:0::1;-1:-1:-1::0;;;;;68094:44:0;;::::1;;::::0;;68156:86:::1;::::0;2378:25:1;;;68156:86:0;;::::1;::::0;;::::1;::::0;68185:10:::1;::::0;68156:86:::1;::::0;2351:18:1;68156:86:0::1;2232:177:1::0;1096:546:0;1217:9;;1183:4;;-1:-1:-1;;;;;1217:9:0;1539:27;;;;;:77;;-1:-1:-1;1570:46:0;;-1:-1:-1;;;1570:46:0;;-1:-1:-1;;;;;1570:12:0;;;;;:46;;1583:4;;1597;;1604:11;;1570:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1538:96;;;-1:-1:-1;1629:5:0;;-1:-1:-1;;;;;1621:13:0;;;1629:5;;1621:13;1538:96;1531:103;1096:546;-1:-1:-1;;;;1096:546:0:o;11956:1065::-;12073:15;12207:4;12201:11;-1:-1:-1;;;12308:17:0;12301:93;-1:-1:-1;;;;;12483:2:0;12479:51;12475:1;12456:17;12452:25;12445:86;12618:6;12613:2;12594:17;12590:26;12583:42;12916:1;12913;12909:2;12890:17;12887:1;12880:5;12873;12868:50;12854:64;;;12949:44;12982:10;12949:32;:44::i;:::-;12941:72;;;;-1:-1:-1;;;12941:72:0;;21217:2:1;12941:72:0;;;21199:21:1;21256:2;21236:18;;;21229:30;-1:-1:-1;;;21275:18:1;;;21268:45;21330:18;;12941:72:0;21015:339:1;12941:72:0;12062:959;11956:1065;;;:::o;19605:579::-;19812:16;;;19953:9;;19946:17;19968:9;;19982;;;19979:23;;19965:38;19942:62;19932:120;;20035:1;20032;20025:12;19932:120;20157:9;;;;;19605:579;-1:-1:-1;;19605:579:0:o;9068:338::-;-1:-1:-1;;;;;9141:15:0;;;;;;:9;:15;;;;;:25;;9160:6;;9141:15;:25;;9160:6;;9141:25;:::i;:::-;;;;-1:-1:-1;;9314:11:0;:21;;;;;;;9364:34;;2378:25:1;;;-1:-1:-1;;;;;;;9364:34:0;;;-1:-1:-1;;;;;;;;;;;9364:34:0;2366:2:1;2351:18;9364:34:0;;;;;;;;9068:338;;:::o;43955:968::-;44096:13;44112:12;:10;:12::i;:::-;44096:28;;44239:5;44220:16;:24;44216:572;;;44341:29;44373:67;44415:18;;44435:4;44392:16;44374:15;:13;:15::i;:::-;:34;;;;:::i;:::-;44373:41;:67;:41;:67::i;:::-;44341:99;-1:-1:-1;44534:33:0;44570:24;44589:5;44570:16;:24;:::i;:::-;44534:60;-1:-1:-1;44702:74:0;44726:49;44754:21;44534:60;44726:49;:::i;:::-;44702:23;:74::i;:::-;44246:542;;44216:572;44863:52;-1:-1:-1;;;;;44863:10:0;:23;44887:9;44898:16;44863:23;:52::i;:::-;44039:884;43955:968;;:::o;8068:457::-;8133:7;8234:95;8368:4;8352:22;;;;;;:::i;:::-;;;;;;;;;;8201:301;;;22856:25:1;;;;22897:18;;22890:34;;;;8397:14:0;22940:18:1;;;22933:34;8434:13:0;22983:18:1;;;22976:34;8478:4:0;23026:19:1;;;23019:61;22828:19;;8201:301:0;;;;;;;;;;;;8173:344;;;;;;8153:364;;8068:457;:::o;19090:507::-;19290:9;;;19390;;19404;;;19401:16;;19387:31;19377:89;;19449:1;19446;19439:12;19377:89;19563:16;;19090:507;-1:-1:-1;;19090:507:0:o;16791:145::-;16848:9;-1:-1:-1;;;;;16878:22:0;;;16870:31;;;;;;-1:-1:-1;16926:1:0;16791:145::o;8725:335::-;8811:6;8796:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;8968:13:0;;;;;;:9;:13;;;;;;;;:23;;;;;;9020:32;2378:25:1;;;-1:-1:-1;;;;;;;;;;;9020:32:0;2351:18:1;9020:32:0;2232:177:1;10706:1242:0;10850:15;10984:4;10978:11;-1:-1:-1;;;11085:17:0;11078:93;-1:-1:-1;;;;;11260:4:0;11256:53;11252:1;11233:17;11229:25;11222:88;-1:-1:-1;;;;;11403:2:0;11399:51;11394:2;11375:17;11371:26;11364:87;11538:6;11533:2;11514:17;11510:26;11503:42;11838:1;11835;11830:3;11811:17;11808:1;11801:5;11794;11789:51;11775:65;;;11871:44;11904:10;11871:32;:44::i;:::-;11863:77;;;;-1:-1:-1;;;11863:77:0;;23293:2:1;11863:77:0;;;23275:21:1;23332:2;23312:18;;;23305:30;-1:-1:-1;;;23351:18:1;;;23344:50;23411:18;;11863:77:0;23091:344:1;11863:77:0;10839:1109;10706:1242;;;;:::o;13029:1063::-;13145:15;13279:4;13273:11;-1:-1:-1;;;13380:17:0;13373:93;-1:-1:-1;;;;;13555:2:0;13551:51;13547:1;13528:17;13524:25;13517:86;13690:6;13685:2;13666:17;13662:26;13655:42;13988:1;13985;13981:2;13962:17;13959:1;13952:5;13945;13940:50;13926:64;;;14021:44;14054:10;14021:32;:44::i;:::-;14013:71;;;;-1:-1:-1;;;14013:71:0;;23642:2:1;14013:71:0;;;23624:21:1;23681:2;23661:18;;;23654:30;-1:-1:-1;;;23700:18:1;;;23693:44;23754:18;;14013:71:0;23440:338:1;16944:145:0;17001:9;-1:-1:-1;;;;;17031:22:0;;;17023:31;;;;;14291:1072;14372:12;14497:16;14577:10;14567:244;;14686:14;14683:1;14680;14665:36;14781:14;14778:1;14771:25;14567:244;14834:14;14867:2;14862:248;;;;15124:99;;;;15329:1;15318:12;;14827:518;;14862:248;14964:14;14961:1;14958;14943:36;15091:1;15085:8;15078:16;15071:24;15060:35;;14862:248;;15124:99;15207:1;15196:12;;14827:518;;;14291:1072;;;:::o;61975:3448::-;62274:15;:22;62150:16;;62123:24;;62274:26;;62299:1;;62274:26;:::i;:::-;62251:49;;62502:2336;62603:17;62623:15;62639:12;62623:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;62623:29:0;62771:25;;;:15;:25;;;;;;;:33;62623:29;;-1:-1:-1;;;;;;62623:29:0;62771:33;;;;62906;;62905:34;;:58;;-1:-1:-1;62943:20:0;;62905:58;62901:313;;;63030:15;:21;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;63030:21:0;;;;;-1:-1:-1;;;;;;63030:21:0;;;;;;;;;63077:43;;-1:-1:-1;;;;;63077:43:0;;;63099:10;;63077:43;;63030:21;63077:43;63190:8;;;;62901:313;63325:20;63366:16;63348:15;:34;:71;;63404:15;63348:71;;;63385:16;63348:71;63325:94;-1:-1:-1;63691:30:0;;;63866:46;63691:30;63866:44;:46::i;:::-;-1:-1:-1;;;;;63830:25:0;;;;;;:15;:25;;;;;;;:82;;-1:-1:-1;;;;;63830:82:0;;;;;;;;;;;;;;;;;64170:54;;64112:32;;;;;64189:10;;64170:54;;;;64132:12;2378:25:1;;2366:2;2351:18;;2232:177;64170:54:0;;;;;;;;64337:39;;-1:-1:-1;;;64337:39:0;;;;;2378:25:1;;;-1:-1:-1;;;;;64337:25:0;;;;;2351:18:1;;64337:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;64329:70;;;;-1:-1:-1;;;64329:70:0;;16369:2:1;64329:70:0;;;16351:21:1;16408:2;16388:18;;;16381:30;-1:-1:-1;;;16427:18:1;;;16420:43;16480:18;;64329:70:0;16167:337:1;64329:70:0;64479:35;64475:228;;64589:15;:21;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;64589:21:0;;;;;-1:-1:-1;;;;;;64589:21:0;;;;;;;;;64640:43;;-1:-1:-1;;;;;64640:43:0;;;64662:10;;64640:43;;64589:21;64640:43;64475:228;-1:-1:-1;64798:21:0;64794:32;;64821:5;;;;;64794:32;62527:2311;;;62502:2336;62511:14;;;;:::i;:::-;;;;62502:2336;;;65041:21;:41;;;;;;;65173:21;65315:15;;;;;:35;;-1:-1:-1;65334:16:0;;;;65315:35;65311:104;;;65373:10;-1:-1:-1;;;;;65352:42:0;;65402:10;65352:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62043:3380;;;61975:3448;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:597:1;126:4;155:2;184;173:9;166:21;216:6;210:13;259:6;254:2;243:9;239:18;232:34;284:1;294:140;308:6;305:1;302:13;294:140;;;403:14;;;399:23;;393:30;369:17;;;388:2;365:26;358:66;323:10;;294:140;;;452:6;449:1;446:13;443:91;;;522:1;517:2;508:6;497:9;493:22;489:31;482:42;443:91;-1:-1:-1;595:2:1;574:15;-1:-1:-1;;570:29:1;555:45;;;;602:2;551:54;;14:597;-1:-1:-1;;;14:597:1:o;616:301::-;675:6;728:2;716:9;707:7;703:23;699:32;696:52;;;744:1;741;734:12;696:52;783:9;770:23;-1:-1:-1;;;;;826:5:1;822:46;815:5;812:57;802:85;;883:1;880;873:12;802:85;906:5;616:301;-1:-1:-1;;;616:301:1:o;922:131::-;-1:-1:-1;;;;;997:31:1;;987:42;;977:70;;1043:1;1040;1033:12;1058:315;1126:6;1134;1187:2;1175:9;1166:7;1162:23;1158:32;1155:52;;;1203:1;1200;1193:12;1155:52;1242:9;1229:23;1261:31;1286:5;1261:31;:::i;:::-;1311:5;1363:2;1348:18;;;;1335:32;;-1:-1:-1;;;1058:315:1:o;1570:180::-;1629:6;1682:2;1670:9;1661:7;1657:23;1653:32;1650:52;;;1698:1;1695;1688:12;1650:52;-1:-1:-1;1721:23:1;;1570:180;-1:-1:-1;1570:180:1:o;1980:247::-;2039:6;2092:2;2080:9;2071:7;2067:23;2063:32;2060:52;;;2108:1;2105;2098:12;2060:52;2147:9;2134:23;2166:31;2191:5;2166:31;:::i;2683:632::-;2786:6;2794;2847:2;2835:9;2826:7;2822:23;2818:32;2815:52;;;2863:1;2860;2853:12;2815:52;2903:9;2890:23;-1:-1:-1;;;;;2973:2:1;2965:6;2962:14;2959:34;;;2989:1;2986;2979:12;2959:34;3027:6;3016:9;3012:22;3002:32;;3072:7;3065:4;3061:2;3057:13;3053:27;3043:55;;3094:1;3091;3084:12;3043:55;3134:2;3121:16;3160:2;3152:6;3149:14;3146:34;;;3176:1;3173;3166:12;3146:34;3229:7;3224:2;3214:6;3211:1;3207:14;3203:2;3199:23;3195:32;3192:45;3189:65;;;3250:1;3247;3240:12;3189:65;3281:2;3273:11;;;;;3303:6;;-1:-1:-1;2683:632:1;;-1:-1:-1;;;;2683:632:1:o;3320:456::-;3397:6;3405;3413;3466:2;3454:9;3445:7;3441:23;3437:32;3434:52;;;3482:1;3479;3472:12;3434:52;3521:9;3508:23;3540:31;3565:5;3540:31;:::i;:::-;3590:5;-1:-1:-1;3647:2:1;3632:18;;3619:32;3660:33;3619:32;3660:33;:::i;:::-;3320:456;;3712:7;;-1:-1:-1;;;3766:2:1;3751:18;;;;3738:32;;3320:456::o;3781:248::-;3849:6;3857;3910:2;3898:9;3889:7;3885:23;3881:32;3878:52;;;3926:1;3923;3916:12;3878:52;-1:-1:-1;;3949:23:1;;;4019:2;4004:18;;;3991:32;;-1:-1:-1;3781:248:1:o;4694:118::-;4780:5;4773:13;4766:21;4759:5;4756:32;4746:60;;4802:1;4799;4792:12;4817:241;4873:6;4926:2;4914:9;4905:7;4901:23;4897:32;4894:52;;;4942:1;4939;4932:12;4894:52;4981:9;4968:23;5000:28;5022:5;5000:28;:::i;5063:675::-;5251:2;5303:21;;;5373:13;;5276:18;;;5395:22;;;5222:4;;5251:2;5474:15;;;;5448:2;5433:18;;;5222:4;5517:195;5531:6;5528:1;5525:13;5517:195;;;5596:13;;-1:-1:-1;;;;;5592:39:1;5580:52;;5687:15;;;;5652:12;;;;5628:1;5546:9;5517:195;;;-1:-1:-1;5729:3:1;;5063:675;-1:-1:-1;;;;;;5063:675:1:o;6217:284::-;6275:6;6328:2;6316:9;6307:7;6303:23;6299:32;6296:52;;;6344:1;6341;6334:12;6296:52;6383:9;6370:23;-1:-1:-1;;;;;6426:5:1;6422:30;6415:5;6412:41;6402:69;;6467:1;6464;6457:12;7720:114;7804:4;7797:5;7793:16;7786:5;7783:27;7773:55;;7824:1;7821;7814:12;7839:801;7950:6;7958;7966;7974;7982;7990;7998;8051:3;8039:9;8030:7;8026:23;8022:33;8019:53;;;8068:1;8065;8058:12;8019:53;8107:9;8094:23;8126:31;8151:5;8126:31;:::i;:::-;8176:5;-1:-1:-1;8233:2:1;8218:18;;8205:32;8246:33;8205:32;8246:33;:::i;:::-;8298:7;-1:-1:-1;8352:2:1;8337:18;;8324:32;;-1:-1:-1;8403:2:1;8388:18;;8375:32;;-1:-1:-1;8459:3:1;8444:19;;8431:33;8473:31;8431:33;8473:31;:::i;:::-;7839:801;;;;-1:-1:-1;7839:801:1;;;;8523:7;8577:3;8562:19;;8549:33;;-1:-1:-1;8629:3:1;8614:19;;;8601:33;;7839:801;-1:-1:-1;;7839:801:1:o;8645:388::-;8713:6;8721;8774:2;8762:9;8753:7;8749:23;8745:32;8742:52;;;8790:1;8787;8780:12;8742:52;8829:9;8816:23;8848:31;8873:5;8848:31;:::i;:::-;8898:5;-1:-1:-1;8955:2:1;8940:18;;8927:32;8968:33;8927:32;8968:33;:::i;:::-;9020:7;9010:17;;;8645:388;;;;;:::o;9038:332::-;9123:6;9131;9184:2;9172:9;9163:7;9159:23;9155:32;9152:52;;;9200:1;9197;9190:12;9152:52;9236:9;9223:23;9213:33;;9296:2;9285:9;9281:18;9268:32;9309:31;9334:5;9309:31;:::i;9375:380::-;9454:1;9450:12;;;;9497;;;9518:61;;9572:4;9564:6;9560:17;9550:27;;9518:61;9625:2;9617:6;9614:14;9594:18;9591:38;9588:161;;;9671:10;9666:3;9662:20;9659:1;9652:31;9706:4;9703:1;9696:15;9734:4;9731:1;9724:15;9588:161;;9375:380;;;:::o;9760:336::-;9962:2;9944:21;;;10001:2;9981:18;;;9974:30;-1:-1:-1;;;10035:2:1;10020:18;;10013:42;10087:2;10072:18;;9760:336::o;10445:127::-;10506:10;10501:3;10497:20;10494:1;10487:31;10537:4;10534:1;10527:15;10561:4;10558:1;10551:15;10577:125;10617:4;10645:1;10642;10639:8;10636:34;;;10650:18;;:::i;:::-;-1:-1:-1;10687:9:1;;10577:125::o;10707:127::-;10768:10;10763:3;10759:20;10756:1;10749:31;10799:4;10796:1;10789:15;10823:4;10820:1;10813:15;10839:127;10900:10;10895:3;10891:20;10888:1;10881:31;10931:4;10928:1;10921:15;10955:4;10952:1;10945:15;10971:184;11041:6;11094:2;11082:9;11073:7;11069:23;11065:32;11062:52;;;11110:1;11107;11100:12;11062:52;-1:-1:-1;11133:16:1;;10971:184;-1:-1:-1;10971:184:1:o;11502:722::-;11700:2;11752:21;;;11725:18;;;11808:22;;;11671:4;;11887:6;11861:2;11846:18;;11671:4;11921:277;11935:6;11932:1;11929:13;11921:277;;;12010:6;11997:20;12030:31;12055:5;12030:31;:::i;:::-;-1:-1:-1;;;;;12086:31:1;12074:44;;12173:15;;;;12138:12;;;;12114:1;11950:9;11921:277;;;-1:-1:-1;12215:3:1;11502:722;-1:-1:-1;;;;;;11502:722:1:o;12482:247::-;12550:6;12603:2;12591:9;12582:7;12578:23;12574:32;12571:52;;;12619:1;12616;12609:12;12571:52;12651:9;12645:16;12670:29;12693:5;12670:29;:::i;13077:127::-;13138:10;13133:3;13129:20;13126:1;13119:31;13169:4;13166:1;13159:15;13193:4;13190:1;13183:15;13548:400;-1:-1:-1;;;;;13804:15:1;;;13786:34;;13856:15;;;;13851:2;13836:18;;13829:43;-1:-1:-1;;;;;;13908:33:1;;;13903:2;13888:18;;13881:61;13736:2;13721:18;;13548:400::o;13953:245::-;14020:6;14073:2;14061:9;14052:7;14048:23;14044:32;14041:52;;;14089:1;14086;14079:12;14041:52;14121:9;14115:16;14140:28;14162:5;14140:28;:::i;15584:342::-;15786:2;15768:21;;;15825:2;15805:18;;;15798:30;-1:-1:-1;;;15859:2:1;15844:18;;15837:48;15917:2;15902:18;;15584:342::o;15931:231::-;15971:4;-1:-1:-1;;;;;16069:10:1;;;;16039;;16091:12;;;16088:38;;;16106:18;;:::i;:::-;16143:13;;15931:231;-1:-1:-1;;;15931:231:1:o;16853:128::-;16893:3;16924:1;16920:6;16917:1;16914:13;16911:39;;;16930:18;;:::i;:::-;-1:-1:-1;16966:9:1;;16853:128::o;17326:236::-;17365:3;-1:-1:-1;;;;;17438:2:1;17435:1;17431:10;17468:2;17465:1;17461:10;17499:3;17495:2;17491:12;17486:3;17483:21;17480:47;;;17507:18;;:::i;:::-;17543:13;;17326:236;-1:-1:-1;;;;17326:236:1:o;17567:253::-;17607:3;-1:-1:-1;;;;;17696:2:1;17693:1;17689:10;17726:2;17723:1;17719:10;17757:3;17753:2;17749:12;17744:3;17741:21;17738:47;;;17765:18;;:::i;18170:135::-;18209:3;-1:-1:-1;;18230:17:1;;18227:43;;;18250:18;;:::i;:::-;-1:-1:-1;18297:1:1;18286:13;;18170:135::o;20401:264::-;20484:6;20537:2;20525:9;20516:7;20512:23;20508:32;20505:52;;;20553:1;20550;20543:12;20505:52;20585:9;20579:16;20604:31;20629:5;20604:31;:::i;21488:1104::-;21618:3;21647:1;21680:6;21674:13;21710:3;21732:1;21760:9;21756:2;21752:18;21742:28;;21820:2;21809:9;21805:18;21842;21832:61;;21886:4;21878:6;21874:17;21864:27;;21832:61;21912:2;21960;21952:6;21949:14;21929:18;21926:38;21923:165;;;-1:-1:-1;;;21987:33:1;;22043:4;22040:1;22033:15;22073:4;21994:3;22061:17;21923:165;22104:18;22131:104;;;;22249:1;22244:323;;;;22097:470;;22131:104;-1:-1:-1;;22164:24:1;;22152:37;;22209:16;;;;-1:-1:-1;22131:104:1;;22244:323;21435:1;21428:14;;;21472:4;21459:18;;22342:1;22356:165;22370:6;22367:1;22364:13;22356:165;;;22448:14;;22435:11;;;22428:35;22491:16;;;;22385:10;;22356:165;;;22360:3;;22550:6;22545:3;22541:16;22534:23;;22097:470;-1:-1:-1;22583:3:1;;21488:1104;-1:-1:-1;;;;;;;;21488:1104:1:o;23783:136::-;23822:3;23850:5;23840:39;;23859:18;;:::i;:::-;-1:-1:-1;;;23895:18:1;;23783:136::o

Swarm Source

ipfs://8de4f2e4f90038de1484734e50e4731605e2bffe1ecde3badb1f119f1d4a7c3d

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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