More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 345 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Approve | 18424587 | 291 days ago | IN | 0 ETH | 0.00031002 | ||||
Approve | 18172553 | 326 days ago | IN | 0 ETH | 0.00033453 | ||||
Approve | 17764236 | 383 days ago | IN | 0 ETH | 0.00130495 | ||||
Approve | 17224103 | 459 days ago | IN | 0 ETH | 0.00355428 | ||||
Approve | 16951413 | 498 days ago | IN | 0 ETH | 0.00060858 | ||||
Approve | 16888554 | 507 days ago | IN | 0 ETH | 0.00027142 | ||||
Approve | 16724780 | 530 days ago | IN | 0 ETH | 0.00047787 | ||||
Approve | 16281953 | 591 days ago | IN | 0 ETH | 0.00030894 | ||||
Approve | 16281929 | 591 days ago | IN | 0 ETH | 0.00037555 | ||||
Approve | 16162762 | 608 days ago | IN | 0 ETH | 0.00043733 | ||||
Approve | 15743932 | 667 days ago | IN | 0 ETH | 0.00036852 | ||||
Approve | 15714675 | 671 days ago | IN | 0 ETH | 0.00082678 | ||||
Approve | 14962824 | 788 days ago | IN | 0 ETH | 0.00146603 | ||||
Approve | 14860462 | 805 days ago | IN | 0 ETH | 0.00050785 | ||||
Withdraw | 14806671 | 814 days ago | IN | 0 ETH | 0.00136317 | ||||
Withdraw | 14714220 | 829 days ago | IN | 0 ETH | 0.00257431 | ||||
Withdraw | 14712160 | 829 days ago | IN | 0 ETH | 0.00374941 | ||||
Withdraw | 14671873 | 835 days ago | IN | 0 ETH | 0.00233236 | ||||
Deposit | 14610072 | 845 days ago | IN | 0 ETH | 0.00406 | ||||
Withdraw | 14591372 | 848 days ago | IN | 0 ETH | 0.00264196 | ||||
Approve | 14584740 | 849 days ago | IN | 0 ETH | 0.00111858 | ||||
Withdraw | 14576208 | 850 days ago | IN | 0 ETH | 0.00217218 | ||||
Withdraw | 14565486 | 852 days ago | IN | 0 ETH | 0.00549863 | ||||
Withdraw | 14565059 | 852 days ago | IN | 0 ETH | 0.00336834 | ||||
Withdraw | 14546662 | 855 days ago | IN | 0 ETH | 0.00322599 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
14226308 | 905 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
Vault
Compiler Version
v0.8.11+commit.d7f03943
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
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
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
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.000008 | 1,554,249.3442 | $12.4 |
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.