S Price: $0.402738 (-7.89%)
    /

    Contract

    0xE313b3af009Ce13E63647f7c6D56d1705c4cD3aD

    Overview

    S Balance

    Sonic LogoSonic LogoSonic Logo0 S

    S Value

    $0.00

    Multichain Info

    No addresses found
    Age:180D
    Amount:Between 1-100
    Reset Filter

    Transaction Hash
    Method
    Block
    Age
    From
    To
    Amount

    There are no matching entries

    Update your filters to view other transactions

    Parent Transaction Hash Block Age From To Amount
    View All Internal Transactions
    Loading...
    Loading

    Contract Source Code Verified (Exact Match)

    Contract Name:
    IchiSwapXFarmStrategy

    Compiler Version
    v0.8.23+commit.f704f362

    Optimization Enabled:
    Yes with 200 runs

    Other Settings:
    shanghai EvmVersion
    File 1 of 59 : IchiSwapXFarmStrategy.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
    import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
    import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
    import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
    import {StrategyBase} from "./base/StrategyBase.sol";
    import {LPStrategyBase} from "./base/LPStrategyBase.sol";
    import {FarmingStrategyBase} from "./base/FarmingStrategyBase.sol";
    import {StrategyLib} from "./libs/StrategyLib.sol";
    import {StrategyIdLib} from "./libs/StrategyIdLib.sol";
    import {FarmMechanicsLib} from "./libs/FarmMechanicsLib.sol";
    import {ISFLib} from "./libs/ISFLib.sol";
    import {IFactory} from "../interfaces/IFactory.sol";
    import {IAmmAdapter} from "../interfaces/IAmmAdapter.sol";
    import {ICAmmAdapter} from "../interfaces/ICAmmAdapter.sol";
    import {IStrategy} from "../interfaces/IStrategy.sol";
    import {IFarmingStrategy} from "../interfaces/IFarmingStrategy.sol";
    import {ILPStrategy} from "../interfaces/ILPStrategy.sol";
    import {IControllable} from "../interfaces/IControllable.sol";
    import {IPlatform} from "../interfaces/IPlatform.sol";
    import {VaultTypeLib} from "../core/libs/VaultTypeLib.sol";
    import {CommonLib} from "../core/libs/CommonLib.sol";
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 2 of 59 : IERC20.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC20 standard as defined in the EIP.
    */
    interface IERC20 {
    /**
    * @dev Emitted when `value` tokens are moved from one account (`from`) to
    * another (`to`).
    *
    * Note that `value` may be zero.
    */
    event Transfer(address indexed from, address indexed to, uint256 value);
    /**
    * @dev Emitted when the allowance of a `spender` for an `owner` is set by
    * a call to {approve}. `value` is the new allowance.
    */
    event Approval(address indexed owner, address indexed spender, uint256 value);
    /**
    * @dev Returns the value of tokens in existence.
    */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 3 of 59 : IERC20Metadata.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
    pragma solidity ^0.8.20;
    import {IERC20} from "../IERC20.sol";
    /**
    * @dev Interface for the optional metadata functions from the ERC20 standard.
    */
    interface IERC20Metadata is IERC20 {
    /**
    * @dev Returns the name of the token.
    */
    function name() external view returns (string memory);
    /**
    * @dev Returns the symbol of the token.
    */
    function symbol() external view returns (string memory);
    /**
    * @dev Returns the decimals places of the token.
    */
    function decimals() external view returns (uint8);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 4 of 59 : SafeERC20.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
    pragma solidity ^0.8.20;
    import {IERC20} from "../IERC20.sol";
    import {IERC20Permit} from "../extensions/IERC20Permit.sol";
    import {Address} from "../../../utils/Address.sol";
    /**
    * @title SafeERC20
    * @dev Wrappers around ERC20 operations that throw on failure (when the token
    * contract returns false). Tokens that return no value (and instead revert or
    * throw on failure) are also supported, non-reverting calls are assumed to be
    * successful.
    * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
    * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
    */
    library SafeERC20 {
    using Address for address;
    /**
    * @dev An operation with an ERC20 token failed.
    */
    error SafeERC20FailedOperation(address token);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 5 of 59 : SafeCast.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
    // This file was procedurally generated from scripts/generate/templates/SafeCast.js.
    pragma solidity ^0.8.20;
    /**
    * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
    * checks.
    *
    * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
    * easily result in undesired exploitation or bugs, since developers usually
    * assume that overflows raise errors. `SafeCast` restores this intuition by
    * reverting the transaction when such an operation overflows.
    *
    * Using this library instead of the unchecked operations eliminates an entire
    * class of bugs, so it's recommended to use it always.
    */
    library SafeCast {
    /**
    * @dev Value doesn't fit in an uint of `bits` size.
    */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
    /**
    * @dev An int value doesn't fit in an uint of `bits` size.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 6 of 59 : IERC165.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC165 standard, as defined in the
    * https://eips.ethereum.org/EIPS/eip-165[EIP].
    *
    * Implementers can declare support of contract interfaces, which can then be
    * queried by others ({ERC165Checker}).
    *
    * For an implementation, see {ERC165}.
    */
    interface IERC165 {
    /**
    * @dev Returns true if this contract implements the interface defined by
    * `interfaceId`. See the corresponding
    * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
    * to learn more about how these ids are created.
    *
    * This function call must use less than 30 000 gas.
    */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 7 of 59 : Math.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Standard math utilities missing in the Solidity language.
    */
    library Math {
    /**
    * @dev Muldiv operation overflow.
    */
    error MathOverflowedMulDiv();
    enum Rounding {
    Floor, // Toward negative infinity
    Ceil, // Toward positive infinity
    Trunc, // Toward zero
    Expand // Away from zero
    }
    /**
    * @dev Returns the addition of two unsigned integers, with an overflow flag.
    */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
    unchecked {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 8 of 59 : StrategyBase.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "../../core/base/Controllable.sol";
    import "../../core/libs/VaultTypeLib.sol";
    import "../libs/StrategyLib.sol";
    import "../../interfaces/IStrategy.sol";
    import "../../interfaces/IVault.sol";
    /// @dev Base universal strategy
    /// Changelog:
    /// 2.0.0: previewDepositAssetsWrite; use platform.getCustomVaultFee
    /// 1.1.0: autoCompoundingByUnderlyingProtocol(), virtual total()
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    abstract contract StrategyBase is Controllable, IStrategy {
    using SafeERC20 for IERC20;
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CONSTANTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    /// @dev Version of StrategyBase implementation
    string public constant VERSION_STRATEGY_BASE = "2.0.0";
    // keccak256(abi.encode(uint256(keccak256("erc7201:stability.StrategyBase")) - 1)) & ~bytes32(uint256(0xff));
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 9 of 59 : LPStrategyBase.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "./StrategyBase.sol";
    import "../libs/LPStrategyLib.sol";
    import "../../interfaces/ILPStrategy.sol";
    /// @dev Base liquidity providing strategy
    /// Changelog:
    /// 1.0.4: _swapForDepositProportion support all amm adapters
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    abstract contract LPStrategyBase is StrategyBase, ILPStrategy {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CONSTANTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    /// @dev Version of LPStrategyBase implementation
    string public constant VERSION_LP_STRATEGY_BASE = "1.0.4";
    // keccak256(abi.encode(uint256(keccak256("erc7201:stability.LPStrategyBase")) - 1)) & ~bytes32(uint256(0xff));
    bytes32 private constant LPSTRATEGYBASE_STORAGE_LOCATION =
    0xa6fdc931ca23c69f54119a0a2d6478619b5aa365084590a1fbc287668fbabe00;
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* INITIALIZATION */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 10 of 59 : FarmingStrategyBase.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "./StrategyBase.sol";
    import "../libs/StrategyLib.sol";
    import "../../interfaces/IStrategy.sol";
    import "../../interfaces/IFactory.sol";
    import "../../interfaces/IFarmingStrategy.sol";
    import "../../interfaces/ISwapper.sol";
    /// @title Base farming strategy
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    abstract contract FarmingStrategyBase is StrategyBase, IFarmingStrategy {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CONSTANTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    /// @dev Version of FarmingStrategyBase implementation
    string public constant VERSION_FARMING_STRATEGY_BASE = "1.2.0";
    // keccak256(abi.encode(uint256(keccak256("erc7201:stability.FarmingStrategyBase")) - 1)) & ~bytes32(uint256(0xff));
    bytes32 private constant FARMINGSTRATEGYBASE_STORAGE_LOCATION =
    0xe61f0a7b2953b9e28e48cc07562ad7979478dcaee972e68dcf3b10da2cba6000;
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 11 of 59 : StrategyLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    import "@openzeppelin/contracts/utils/math/Math.sol";
    import "../../core/libs/ConstantsLib.sol";
    import "../../core/libs/VaultTypeLib.sol";
    import "../../core/libs/CommonLib.sol";
    import "../../interfaces/IPlatform.sol";
    import "../../interfaces/IVault.sol";
    import "../../interfaces/IVaultManager.sol";
    import "../../interfaces/IStrategyLogic.sol";
    import "../../interfaces/IFactory.sol";
    import "../../interfaces/IPriceReader.sol";
    import "../../interfaces/ISwapper.sol";
    import "../../interfaces/ILPStrategy.sol";
    import "../../interfaces/IFarmingStrategy.sol";
    library StrategyLib {
    using SafeERC20 for IERC20;
    /// @dev Reward pools may have low liquidity and 1% fees
    uint internal constant SWAP_REWARDS_PRICE_IMPACT_TOLERANCE = 7_000;
    struct ExtractFeesVars {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 12 of 59 : StrategyIdLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    library StrategyIdLib {
    string internal constant DEV = "Dev Alpha DeepSpaceSwap Farm";
    string internal constant QUICKSWAPV3_STATIC_FARM = "QuickSwapV3 Static Farm";
    string internal constant GAMMA_QUICKSWAP_MERKL_FARM = "Gamma QuickSwap Merkl Farm";
    string internal constant GAMMA_RETRO_MERKL_FARM = "Gamma Retro Merkl Farm";
    string internal constant GAMMA_UNISWAPV3_MERKL_FARM = "Gamma UniswapV3 Merkl Farm";
    string internal constant COMPOUND_FARM = "Compound Farm";
    string internal constant DEFIEDGE_QUICKSWAP_MERKL_FARM = "DefiEdge QuickSwap Merkl Farm";
    string internal constant STEER_QUICKSWAP_MERKL_FARM = "Steer QuickSwap Merkl Farm";
    string internal constant ICHI_QUICKSWAP_MERKL_FARM = "Ichi QuickSwap Merkl Farm";
    string internal constant ICHI_RETRO_MERKL_FARM = "Ichi Retro Merkl Farm";
    string internal constant QUICKSWAP_STATIC_MERKL_FARM = "QuickSwap Static Merkl Farm";
    string internal constant CURVE_CONVEX_FARM = "Curve Convex Farm";
    string internal constant YEARN = "Yearn";
    string internal constant TRIDENT_PEARL_FARM = "Trident Pearl Farm";
    string internal constant BEETS_STABLE_FARM = "Beets Stable Farm";
    string internal constant BEETS_WEIGHTED_FARM = "Beets Weighted Farm";
    string internal constant EQUALIZER_FARM = "Equalizer Farm";
    string internal constant ICHI_SWAPX_FARM = "Ichi SwapX Farm";
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 13 of 59 : FarmMechanicsLib.sol
    1
    2
    3
    4
    5
    6
    7
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    library FarmMechanicsLib {
    string internal constant CLASSIC = "Classic";
    string internal constant MERKL = "Merkl";
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 14 of 59 : ISFLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import {IVolatilityOracle} from "../../integrations/algebrav4/IVolatilityOracle.sol";
    import {UniswapV3MathLib} from "./UniswapV3MathLib.sol";
    import {IAlgebraPool} from "../../integrations/algebrav4/IAlgebraPool.sol";
    import {IAlgebraPoolErrors} from "../../integrations/algebrav4/pool/IAlgebraPoolErrors.sol";
    library ISFLib {
    /// @notice Checks if the oracle is currently connected to the pool
    /// @param oracleAddress The address of oracle
    /// @param oracleAddress The address of the pool
    /// @return connected Whether or not the oracle is connected
    function isOracleConnectedToPool(
    address oracleAddress,
    address poolAddress
    ) internal view returns (bool connected) {
    if (oracleAddress == address(0)) {
    return false;
    }
    IAlgebraPool pool = IAlgebraPool(poolAddress);
    if (oracleAddress == pool.plugin()) {
    (,,, uint8 pluginConfig,,) = pool.globalState();
    connected = hasFlag(pluginConfig, BEFORE_SWAP_FLAG);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 15 of 59 : IFactory.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
    /// @notice Creating vaults, upgrading vaults and strategies, vault list, farms and strategy logics management
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    /// @author HCrypto7 (https://github.com/hcrypto7)
    interface IFactory {
    //region ----- Custom Errors -----
    error VaultImplementationIsNotAvailable();
    error VaultNotAllowedToDeploy();
    error StrategyImplementationIsNotAvailable();
    error StrategyLogicNotAllowedToDeploy();
    error YouDontHaveEnoughTokens(uint userBalance, uint requireBalance, address payToken);
    error SuchVaultAlreadyDeployed(bytes32 key);
    error NotActiveVault();
    error UpgradeDenied(bytes32 _hash);
    error AlreadyLastVersion(bytes32 _hash);
    error NotStrategy();
    error BoostDurationTooLow();
    error BoostAmountTooLow();
    error BoostAmountIsZero();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 16 of 59 : IAmmAdapter.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
    /// @dev Get price, swap, liquidity calculations. Used by strategies and swapper
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IAmmAdapter is IERC165 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CUSTOM ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error PriceIncreased();
    error WrongCallbackAmount();
    error NotSupportedByCAMM();
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* EVENTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    event SwapInPool(
    address pool,
    address tokenIn,
    address tokenOut,
    address recipient,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 17 of 59 : ICAmmAdapter.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.22;
    import "./IAmmAdapter.sol";
    /// @dev Adapter for interacting with Concentrated Automated Market Make
    /// based on liquidity pool of 2 tokens.
    /// @author Alien Deployer (https://github.com/a17)
    interface ICAmmAdapter is IAmmAdapter {
    /// @notice Price in pool at specified tick
    /// @param pool Address of a pool supported by the adapter
    /// @param tokenIn Token for sell
    /// @return Output amount of swap 1.0 tokenIn in pool without price impact
    function getPriceAtTick(address pool, address tokenIn, int24 tick) external view returns (uint);
    /// @notice Priced proportions of pool assets in specified range
    /// @param pool Address of a pool supported by the adapter
    /// @param ticks Tick boundaries. Lower and upper ticks for UniswapV3-like AMM position.
    /// @return Proportions with 5 decimals precision. Max is 100_000, min is 0.
    function getProportions(address pool, int24[] memory ticks) external view returns (uint[] memory);
    /// @notice Computes the maximum amount of liquidity received for given amounts of pool assets and the current
    /// pool prices and the prices at the tick boundaries
    /// @param pool Address of a pool supported by the adapter
    /// @param amounts Ampunts of pool assets
    /// @param ticks Tick boundaries. Lower and upper ticks for UniswapV3-like AMM position.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 18 of 59 : IStrategy.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
    /// @dev Core interface of strategy logic
    interface IStrategy is IERC165 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* EVENTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    event HardWork(
    uint apr, uint compoundApr, uint earned, uint tvl, uint duration, uint sharePrice, uint[] assetPrices
    );
    event ExtractFees(
    uint vaultManagerReceiverFee,
    uint strategyLogicReceiverFee,
    uint ecosystemRevenueReceiverFee,
    uint multisigReceiverFee
    );
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CUSTOM ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error NotReadyForHardWork();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 19 of 59 : IFarmingStrategy.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @dev Mostly this interface need for front-end and tests for interacting with farming strategies
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IFarmingStrategy {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* EVENTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    event RewardsClaimed(uint[] amounts);
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error BadFarm();
    error IncorrectStrategyId();
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* DATA TYPES */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    /// @custom:storage-location erc7201:stability.FarmingStrategyBase
    struct FarmingStrategyBaseStorage {
    /// @inheritdoc IFarmingStrategy
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 20 of 59 : ILPStrategy.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "../interfaces/IAmmAdapter.sol";
    /// @title Liquidity providing strategy
    /// @author Alien Deployer (https://github.com/a17)
    interface ILPStrategy {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* EVENTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    event FeesClaimed(uint[] fees);
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error ZeroAmmAdapter();
    error IncorrectAssetsLength();
    error IncorrectAssets();
    error IncorrectAmountsLength();
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* DATA TYPES */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 21 of 59 : IControllable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @dev Base core interface implemented by most platform contracts.
    /// Inherited contracts store an immutable Platform proxy address in the storage,
    /// which provides authorization capabilities and infrastructure contract addresses.
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IControllable {
    //region ----- Custom Errors -----
    error IncorrectZeroArgument();
    error IncorrectMsgSender();
    error NotGovernance();
    error NotMultisig();
    error NotGovernanceAndNotMultisig();
    error NotOperator();
    error NotFactory();
    error NotPlatform();
    error NotVault();
    error IncorrectArrayLength();
    error AlreadyExist();
    error NotExist();
    error NotTheOwner();
    error ETHTransferFailed();
    error IncorrectInitParams();
    //endregion -- Custom Errors -----
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 22 of 59 : IPlatform.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @notice Interface of the main contract and entry point to the platform.
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IPlatform {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CUSTOM ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error AlreadyAnnounced();
    error SameVersion();
    error NoNewVersion();
    error UpgradeTimerIsNotOver(uint TimerTimestamp);
    error IncorrectFee(uint minFee, uint maxFee);
    error NotEnoughAllowedBBToken();
    error TokenAlreadyExistsInSet(address token);
    error AggregatorNotExists(address dexAggRouter);
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* EVENTS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    event PlatformVersion(string version);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 23 of 59 : VaultTypeLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    library VaultTypeLib {
    string internal constant COMPOUNDING = "Compounding";
    string internal constant REWARDING = "Rewarding";
    string internal constant REWARDING_MANAGED = "Rewarding Managed";
    string internal constant SPLITTER_MANAGED = "Splitter Managed";
    string internal constant SPLITTER_AUTO = "Splitter Automatic";
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 24 of 59 : CommonLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
    import "@openzeppelin/contracts/utils/Strings.sol";
    import "./ConstantsLib.sol";
    library CommonLib {
    function filterAddresses(
    address[] memory addresses,
    address addressToRemove
    ) external pure returns (address[] memory filteredAddresses) {
    uint len = addresses.length;
    uint newLen;
    // nosemgrep
    for (uint i; i < len; ++i) {
    if (addresses[i] != addressToRemove) {
    ++newLen;
    }
    }
    filteredAddresses = new address[](newLen);
    uint k;
    // nosemgrep
    for (uint i; i < len; ++i) {
    if (addresses[i] != addressToRemove) {
    filteredAddresses[k] = addresses[i];
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 25 of 59 : AmmAdapterIdLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.21;
    library AmmAdapterIdLib {
    string public constant UNISWAPV3 = "UniswapV3";
    string public constant ALGEBRA = "Algebra";
    string public constant KYBER = "KyberSwap";
    string public constant CURVE = "Curve";
    string public constant SOLIDLY = "Solidly";
    string public constant BALANCER_COMPOSABLE_STABLE = "BalancerComposableStable";
    string public constant BALANCER_WEIGHTED = "BalancerWeighted";
    string public constant ALGEBRA_V4 = "AlgebraV4";
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 26 of 59 : IICHIVaultV4.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    interface IICHIVaultV4 {
    function ichiVaultFactory() external view returns (address);
    function pool() external view returns (address);
    function token0() external view returns (address);
    function allowToken0() external view returns (bool);
    function token1() external view returns (address);
    function allowToken1() external view returns (bool);
    function fee() external view returns (uint24);
    function tickSpacing() external view returns (int24);
    function affiliate() external view returns (address);
    function baseLower() external view returns (int24);
    function baseUpper() external view returns (int24);
    function limitLower() external view returns (int24);
    function limitUpper() external view returns (int24);
    function deposit0Max() external view returns (uint);
    function deposit1Max() external view returns (uint);
    function maxTotalSupply() external view returns (uint);
    function totalSupply() external view returns (uint);
    function hysteresis() external view returns (uint);
    function currentTick() external view returns (int24);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 27 of 59 : IGaugeV2_CL.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @dev https://sonicscan.org/address/0x413610103721df45c7e8333d5e34bb39975762f3#code
    interface IGaugeV2_CL {
    /// @notice deposit all TOKEN of msg.sender
    function depositAll() external;
    /// @notice deposit amount TOKEN
    function deposit(uint amount) external;
    /// @notice withdraw all token
    function withdrawAll() external;
    /// @notice withdraw a certain amount of TOKEN
    function withdraw(uint amount) external;
    /// @notice User harvest function called from distribution (voter allows harvest on multiple gauges)
    function getReward(address _user) external;
    /// @notice User harvest function
    function getReward() external;
    /// @dev Receive rewards from distribution
    function notifyRewardAmount(address token, uint reward) external;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 28 of 59 : IAlgebraPool.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    import "./pool/IAlgebraPoolImmutables.sol";
    import "./pool/IAlgebraPoolState.sol";
    import "./pool/IAlgebraPoolActions.sol";
    import "./pool/IAlgebraPoolPermissionedActions.sol";
    import "./pool/IAlgebraPoolEvents.sol";
    import "./pool/IAlgebraPoolErrors.sol";
    /// @title The interface for a Algebra Pool
    /// @dev The pool interface is broken up into many smaller pieces.
    /// This interface includes custom error definitions and cannot be used in older versions of Solidity.
    /// For older versions of Solidity use #IAlgebraPoolLegacy
    /// Credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPool is
    IAlgebraPoolImmutables,
    IAlgebraPoolState,
    IAlgebraPoolActions,
    IAlgebraPoolPermissionedActions,
    IAlgebraPoolEvents,
    IAlgebraPoolErrors
    {
    // used only for combining interfaces
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 29 of 59 : IVoterV3.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    interface IVoterV3 {
    /// @notice claim LP gauge rewards
    function claimRewards(address[] memory _gauges) external;
    /// @notice notify reward amount for gauge
    /// @dev the function is called by the minter each epoch. Anyway anyone can top up some extra rewards.
    /// @param amount amount to distribute
    function notifyRewardAmount(uint amount) external;
    /// @notice distribute reward onyl for given gauges
    /// @dev this function is used in case some distribution fails
    function distribute(address[] memory _gauges) external;
    function minter() external view returns (address);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 30 of 59 : IERC20Permit.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
    * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
    *
    * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
    * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
    * need to send a transaction, and thus is not required to hold Ether at all.
    *
    * ==== Security Considerations
    *
    * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
    * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
    * considered as an intention to spend the allowance in any specific way. The second is that because permits have
    * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
    * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
    * generally recommended is:
    *
    * ```solidity
    * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
    * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
    * doThing(..., value);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 31 of 59 : Address.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Collection of functions related to the address type
    */
    library Address {
    /**
    * @dev The ETH balance of the account is not enough to perform the operation.
    */
    error AddressInsufficientBalance(address account);
    /**
    * @dev There's no code at `target` (it is not a contract).
    */
    error AddressEmptyCode(address target);
    /**
    * @dev A call to an address target failed. The target may have reverted.
    */
    error FailedInnerCall();
    /**
    * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 32 of 59 : Controllable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
    import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
    import "../libs/SlotsLib.sol";
    import "../../interfaces/IControllable.sol";
    import "../../interfaces/IPlatform.sol";
    /// @dev Base core contract.
    /// It store an immutable platform proxy address in the storage and provides access control to inherited contracts.
    /// @author Alien Deployer (https://github.com/a17)
    /// @author 0xhokugava (https://github.com/0xhokugava)
    abstract contract Controllable is Initializable, IControllable, ERC165 {
    using SlotsLib for bytes32;
    string public constant CONTROLLABLE_VERSION = "1.0.0";
    bytes32 internal constant _PLATFORM_SLOT = bytes32(uint(keccak256("eip1967.controllable.platform")) - 1);
    bytes32 internal constant _CREATED_BLOCK_SLOT = bytes32(uint(keccak256("eip1967.controllable.created_block")) - 1);
    /// @dev Prevent implementation init
    constructor() {
    _disableInitializers();
    }
    /// @notice Initialize contract after setup it as proxy implementation
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 33 of 59 : IVault.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "./IStrategy.sol";
    /// @notice Vault core interface.
    /// Derived implementations can be effective for building tokenized vaults with single or multiple underlying liquidity mining position.
    /// Fungible, static non-fungible and actively re-balancing liquidity is supported, as well as single token liquidity provided to lending protocols.
    /// Vaults can be used for active concentrated liquidity management and market making.
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IVault is IERC165 {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CUSTOM ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error NotEnoughBalanceToPay();
    error FuseTrigger();
    error ExceedSlippage(uint mintToUser, uint minToMint);
    error ExceedSlippageExactAsset(address asset, uint mintToUser, uint minToMint);
    error ExceedMaxSupply(uint maxSupply);
    error NotEnoughAmountToInitSupply(uint mintAmount, uint initialShares);
    error WaitAFewBlocks();
    error StrategyZeroDeposit();
    error NotSupported();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 34 of 59 : LPStrategyLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
    import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
    import "../../core/libs/CommonLib.sol";
    import "../../core/libs/VaultTypeLib.sol";
    import "../../core/libs/ConstantsLib.sol";
    import "../../interfaces/ILPStrategy.sol";
    import "../../interfaces/IPlatform.sol";
    import "../../interfaces/IFactory.sol";
    import "../../interfaces/ISwapper.sol";
    import "../../interfaces/IRVault.sol";
    library LPStrategyLib {
    using SafeERC20 for IERC20;
    uint internal constant SWAP_ASSETS_PRICE_IMPACT_TOLERANCE = 4_000;
    struct ProcessRevenueVars {
    string vaultYpe;
    uint compoundRatio;
    address bbToken;
    uint bbAmountBefore;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 35 of 59 : ISwapper.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @notice On-chain price quoter and swapper by predefined routes
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    /// @author 0xhokugava (https://github.com/0xhokugava)
    interface ISwapper {
    event Swap(address indexed tokenIn, address indexed tokenOut, uint amount);
    event PoolAdded(PoolData poolData, bool assetAdded);
    event PoolRemoved(address token);
    event BlueChipAdded(PoolData poolData);
    event ThresholdChanged(address[] tokenIn, uint[] thresholdAmount);
    event BlueChipPoolRemoved(address tokenIn, address tokenOut);
    //region ----- Custom Errors -----
    error UnknownAMMAdapter();
    error LessThenThreshold(uint minimumAmount);
    error NoRouteFound();
    error NoRoutesForAssets();
    //endregion -- Custom Errors -----
    struct PoolData {
    address pool;
    address ammAdapter;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 36 of 59 : ERC20Upgradeable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
    pragma solidity ^0.8.20;
    import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
    import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
    import {ContextUpgradeable} from "../../utils/ContextUpgradeable.sol";
    import {IERC20Errors} from "@openzeppelin/contracts/interfaces/draft-IERC6093.sol";
    import {Initializable} from "../../proxy/utils/Initializable.sol";
    /**
    * @dev Implementation of the {IERC20} interface.
    *
    * This implementation is agnostic to the way tokens are created. This means
    * that a supply mechanism has to be added in a derived contract using {_mint}.
    *
    * TIP: For a detailed writeup see our guide
    * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
    * to implement supply mechanisms].
    *
    * The default value of {decimals} is 18. To change this, you should override
    * this function so it returns a different value.
    *
    * We have followed general OpenZeppelin Contracts guidelines: functions revert
    * instead returning `false` on failure. This behavior is nonetheless
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 37 of 59 : ConstantsLib.sol
    1
    2
    3
    4
    5
    6
    7
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    library ConstantsLib {
    uint internal constant DENOMINATOR = 100_000;
    address internal constant DEAD_ADDRESS = 0xdEad000000000000000000000000000000000000;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 38 of 59 : IVaultManager.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
    /// @notice The vaults are assembled at the factory by users through UI.
    /// Deployment rights of a vault are tokenized in VaultManager NFT.
    /// The holders of these tokens receive a share of the vault revenue and can manage vault if possible.
    /// @dev Rewards transfers to token owner or revenue receiver address managed by token owner.
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IVaultManager is IERC721Metadata {
    //region ----- Events -----
    event ChangeVaultParams(uint tokenId, address[] addresses, uint[] nums);
    event SetRevenueReceiver(uint tokenId, address receiver);
    //endregion -- Events -----
    struct VaultData {
    // vault
    uint tokenId;
    address vault;
    string vaultType;
    string name;
    string symbol;
    string[] assetsSymbols;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 39 of 59 : IStrategyLogic.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
    /// @dev Interface of developed strategy logic NFT
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IStrategyLogic is IERC721Metadata {
    //region ----- Events -----
    event SetRevenueReceiver(uint tokenId, address receiver);
    //endregion -- Events -----
    struct StrategyData {
    uint strategyTokenId;
    string strategyId;
    bytes32 strategyExtra;
    }
    /// @notice Minting of new developed strategy by the factory
    /// @dev Parameters from StrategyDeveloperLib, StrategyIdLib.
    /// Only factory can call it.
    /// @param to Strategy developer address
    /// @param strategyLogicId Strategy logic ID string
    /// @return tokenId Minted token ID
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 40 of 59 : IPriceReader.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @dev Combining oracle and DeX spot prices
    /// @author Alien Deployer (https://github.com/a17)
    /// @author Jude (https://github.com/iammrjude)
    /// @author JodsMigel (https://github.com/JodsMigel)
    interface IPriceReader {
    //region ----- Events -----
    event AdapterAdded(address adapter);
    event AdapterRemoved(address adapter);
    //endregion -- Events -----
    /// @notice Price of asset
    /// @dev Price of 1.0 amount of asset in USD
    /// @param asset Address of asset
    /// @return price USD price with 18 decimals
    /// @return trusted Price from oracle
    function getPrice(address asset) external view returns (uint price, bool trusted);
    /// @notice Get USD price of specified assets and amounts
    /// @param assets_ Addresses of assets
    /// @param amounts_ Amount of asset. Index of asset same as in previous parameter.
    /// @return total Total USD value with 18 decimals
    /// @return assetAmountPrice USD price of asset amount. Index of assetAmountPrice same as in assets_ parameters.
    /// @return assetPrice USD price of asset. Index of assetAmountPrice same as in assets_ parameters.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 41 of 59 : IVolatilityOracle.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @title The interface for the Algebra volatility oracle
    /// @dev This contract stores timepoints and calculates statistical averages
    interface IVolatilityOracle {
    /// @notice Returns data belonging to a certain timepoint
    /// @param index The index of timepoint in the array
    /// @dev There is more convenient function to fetch a timepoint: getTimepoints(). Which requires not an index but seconds
    /// @return initialized Whether the timepoint has been initialized and the values are safe to use
    /// @return blockTimestamp The timestamp of the timepoint
    /// @return tickCumulative The tick multiplied by seconds elapsed for the life of the pool as of the timepoint timestamp
    /// @return volatilityCumulative Cumulative standard deviation for the life of the pool as of the timepoint timestamp
    /// @return tick The tick at blockTimestamp
    /// @return averageTick Time-weighted average tick
    /// @return windowStartIndex Index of closest timepoint >= WINDOW seconds ago
    function timepoints(uint index)
    external
    view
    returns (
    bool initialized,
    uint32 blockTimestamp,
    int56 tickCumulative,
    uint88 volatilityCumulative,
    int24 tick,
    int24 averageTick,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 42 of 59 : UniswapV3MathLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    library UniswapV3MathLib {
    uint8 internal constant RESOLUTION = 96;
    uint internal constant Q96 = 0x1000000000000000000000000;
    uint internal constant TWO_96 = 2 ** 96;
    uint160 internal constant MIN_SQRT_RATIO = 4295128739 + 1;
    uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342 - 1;
    int24 internal constant MIN_TICK = -887272;
    int24 internal constant MAX_TICK = -MIN_TICK;
    struct ComputeFeesEarnedCommonParams {
    int24 tick;
    int24 lowerTick;
    int24 upperTick;
    uint128 liquidity;
    }
    function calcPriceOut(
    address tokenIn,
    address token0,
    uint160 sqrtPriceX96,
    uint tokenInDecimals,
    uint tokenOutDecimals,
    uint amount
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 43 of 59 : IAlgebraPoolErrors.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Errors emitted by a pool
    /// @notice Contains custom errors emitted by the pool
    /// @dev Custom errors are separated from the common pool interface for compatibility with older versions of Solidity
    interface IAlgebraPoolErrors {
    // #### pool errors ####
    /// @notice Emitted by the reentrancy guard
    error locked();
    /// @notice Emitted if arithmetic error occurred
    error arithmeticError();
    /// @notice Emitted if an attempt is made to initialize the pool twice
    error alreadyInitialized();
    /// @notice Emitted if an attempt is made to mint or swap in uninitialized pool
    error notInitialized();
    /// @notice Emitted if 0 is passed as amountRequired to swap function
    error zeroAmountRequired();
    /// @notice Emitted if invalid amount is passed as amountRequired to swap function
    error invalidAmountRequired();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 44 of 59 : EnumerableSet.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
    // This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
    pragma solidity ^0.8.20;
    /**
    * @dev Library for managing
    * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
    * types.
    *
    * Sets have the following properties:
    *
    * - Elements are added, removed, and checked for existence in constant time
    * (O(1)).
    * - Elements are enumerated in O(n). No guarantees are made on the ordering.
    *
    * ```solidity
    * contract Example {
    * // Add the library methods
    * using EnumerableSet for EnumerableSet.AddressSet;
    *
    * // Declare a set state variable
    * EnumerableSet.AddressSet private mySet;
    * }
    * ```
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 45 of 59 : Strings.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)
    pragma solidity ^0.8.20;
    import {Math} from "./math/Math.sol";
    import {SignedMath} from "./math/SignedMath.sol";
    /**
    * @dev String operations.
    */
    library Strings {
    bytes16 private constant HEX_DIGITS = "0123456789abcdef";
    uint8 private constant ADDRESS_LENGTH = 20;
    /**
    * @dev The `value` string doesn't fit in the specified `length`.
    */
    error StringsInsufficientHexLength(uint256 value, uint256 length);
    /**
    * @dev Converts a `uint256` to its ASCII `string` decimal representation.
    */
    function toString(uint256 value) internal pure returns (string memory) {
    unchecked {
    uint256 length = Math.log10(value) + 1;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 46 of 59 : IAlgebraPoolImmutables.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Pool state that never changes
    /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPoolImmutables {
    /// @notice The Algebra factory contract, which must adhere to the IAlgebraFactory interface
    /// @return The contract address
    function factory() external view returns (address);
    /// @notice The first of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token0() external view returns (address);
    /// @notice The second of the two tokens of the pool, sorted by address
    /// @return The token contract address
    function token1() external view returns (address);
    /// @notice The maximum amount of position liquidity that can use any tick in the range
    /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and
    /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool
    /// @return The max amount of liquidity per tick
    function maxLiquidityPerTick() external view returns (uint128);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 47 of 59 : IAlgebraPoolState.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Pool state that can change
    /// @dev Important security note: when using this data by external contracts, it is necessary to take into account the possibility
    /// of manipulation (including read-only reentrancy).
    /// This interface is based on the UniswapV3 interface, credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPoolState {
    /// @notice Safely get most important state values of Algebra Integral AMM
    /// @dev Several values exposed as a single method to save gas when accessed externally.
    /// **Important security note: this method checks reentrancy lock and should be preferred in most cases**.
    /// @return sqrtPrice The current price of the pool as a sqrt(dToken1/dToken0) Q64.96 value
    /// @return tick The current global tick of the pool. May not always be equal to SqrtTickMath.getTickAtSqrtRatio(price) if the price is on a tick
            boundary
    /// @return lastFee The current (last known) pool fee value in hundredths of a bip, i.e. 1e-6 (so '100' is '0.01%'). May be obsolete if using
            dynamic fee plugin
    /// @return pluginConfig The current plugin config as bitmap. Each bit is responsible for enabling/disabling the hooks, the last bit turns on/off
            dynamic fees logic
    /// @return activeLiquidity The currently in-range liquidity available to the pool
    /// @return nextTick The next initialized tick after current global tick
    /// @return previousTick The previous initialized tick before (or at) current global tick
    function safelyGetStateOfAMM()
    external
    view
    returns (
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 48 of 59 : IAlgebraPoolActions.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Permissionless pool actions
    /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPoolActions {
    /// @notice Sets the initial price for the pool
    /// @dev Price is represented as a sqrt(amountToken1/amountToken0) Q64.96 value
    /// @dev Initialization should be done in one transaction with pool creation to avoid front-running
    /// @param initialPrice The initial sqrt price of the pool as a Q64.96
    function initialize(uint160 initialPrice) external;
    /// @notice Adds liquidity for the given recipient/bottomTick/topTick position
    /// @dev The caller of this method receives a callback in the form of IAlgebraMintCallback#algebraMintCallback
    /// in which they must pay any token0 or token1 owed for the liquidity. The amount of token0/token1 due depends
    /// on bottomTick, topTick, the amount of liquidity, and the current price.
    /// @param leftoversRecipient The address which will receive potential surplus of paid tokens
    /// @param recipient The address for which the liquidity will be created
    /// @param bottomTick The lower tick of the position in which to add liquidity
    /// @param topTick The upper tick of the position in which to add liquidity
    /// @param liquidityDesired The desired amount of liquidity to mint
    /// @param data Any data that should be passed through to the callback
    /// @return amount0 The amount of token0 that was paid to mint the given amount of liquidity. Matches the value in the callback
    /// @return amount1 The amount of token1 that was paid to mint the given amount of liquidity. Matches the value in the callback
    /// @return liquidityActual The actual minted amount of liquidity
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 49 of 59 : IAlgebraPoolPermissionedActions.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Permissioned pool actions
    /// @notice Contains pool methods that may only be called by permissioned addresses
    /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPoolPermissionedActions {
    /// @notice Set the community's % share of the fees. Only factory owner or POOLS_ADMINISTRATOR_ROLE role
    /// @param newCommunityFee The new community fee percent in thousandths (1e-3)
    function setCommunityFee(uint16 newCommunityFee) external;
    /// @notice Set the new tick spacing values. Only factory owner or POOLS_ADMINISTRATOR_ROLE role
    /// @param newTickSpacing The new tick spacing value
    function setTickSpacing(int24 newTickSpacing) external;
    /// @notice Set the new plugin address. Only factory owner or POOLS_ADMINISTRATOR_ROLE role
    /// @param newPluginAddress The new plugin address
    function setPlugin(address newPluginAddress) external;
    /// @notice Set new plugin config. Only factory owner or POOLS_ADMINISTRATOR_ROLE role
    /// @param newConfig In the new configuration of the plugin,
    /// each bit of which is responsible for a particular hook.
    function setPluginConfig(uint8 newConfig) external;
    /// @notice Set new community fee vault address. Only factory owner or POOLS_ADMINISTRATOR_ROLE role
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 50 of 59 : IAlgebraPoolEvents.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: GPL-2.0-or-later
    pragma solidity ^0.8.23;
    /// @title Events emitted by a pool
    /// @dev Credit to Uniswap Labs under GPL-2.0-or-later license:
    /// https://github.com/Uniswap/v3-core/tree/main/contracts/interfaces
    interface IAlgebraPoolEvents {
    /// @notice Emitted exactly once by a pool when #initialize is first called on the pool
    /// @dev Mint/Burn/Swaps cannot be emitted by the pool before Initialize
    /// @param price The initial sqrt price of the pool, as a Q64.96
    /// @param tick The initial tick of the pool, i.e. log base 1.0001 of the starting price of the pool
    event Initialize(uint160 price, int24 tick);
    /// @notice Emitted when liquidity is minted for a given position
    /// @param sender The address that minted the liquidity
    /// @param owner The owner of the position and recipient of any minted liquidity
    /// @param bottomTick The lower tick of the position
    /// @param topTick The upper tick of the position
    /// @param liquidityAmount The amount of liquidity minted to the position range
    /// @param amount0 How much token0 was required for the minted liquidity
    /// @param amount1 How much token1 was required for the minted liquidity
    event Mint(
    address sender,
    address indexed owner,
    int24 indexed bottomTick,
    int24 indexed topTick,
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 51 of 59 : Initializable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
    * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
    * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
    * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
    *
    * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
    * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
    * case an upgrade adds a module that needs to be initialized.
    *
    * For example:
    *
    * [.hljs-theme-light.nopadding]
    * ```solidity
    * contract MyToken is ERC20Upgradeable {
    * function initialize() initializer public {
    * __ERC20_init("MyToken", "MTK");
    * }
    * }
    *
    * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 52 of 59 : ERC165.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
    pragma solidity ^0.8.20;
    import {IERC165} from "./IERC165.sol";
    /**
    * @dev Implementation of the {IERC165} interface.
    *
    * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
    * for the additional interface id that will be supported. For example:
    *
    * ```solidity
    * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
    * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
    * }
    * ```
    */
    abstract contract ERC165 is IERC165 {
    /**
    * @dev See {IERC165-supportsInterface}.
    */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
    return interfaceId == type(IERC165).interfaceId;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 53 of 59 : SlotsLib.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    /// @title Minimal library for setting / getting slot variables (used in upgradable proxy contracts)
    library SlotsLib {
    /// @dev Gets a slot as an address
    function getAddress(bytes32 slot) internal view returns (address result) {
    assembly {
    result := sload(slot)
    }
    }
    /// @dev Gets a slot as uint256
    function getUint(bytes32 slot) internal view returns (uint result) {
    assembly {
    result := sload(slot)
    }
    }
    /// @dev Sets a slot with address
    /// @notice Check address for 0 at the setter
    function set(bytes32 slot, address value) internal {
    assembly {
    sstore(slot, value)
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 54 of 59 : IRVault.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.23;
    import "./IVault.sol";
    /// @notice Interface of Rewarding Vault
    /// @author Alien Deployer (https://github.com/a17)
    /// @author JodsMigel (https://github.com/JodsMigel)
    /// @author 0xhokugava (https://github.com/0xhokugava)
    interface IRVault is IVault {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /* CUSTOM ERRORS */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/
    error NotAllowed();
    error Overflow(uint maxAmount);
    error RTNotFound();
    error NoBBToken();
    error NotAllowedBBToken();
    error IncorrectNums();
    error ZeroToken();
    error ZeroVestingDuration();
    error TooHighCompoundRation();
    error RewardIsTooSmall();
    // error RewardIsTooBig();
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 55 of 59 : ContextUpgradeable.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
    pragma solidity ^0.8.20;
    import {Initializable} from "../proxy/utils/Initializable.sol";
    /**
    * @dev Provides information about the current execution context, including the
    * sender of the transaction and its data. While these are generally available
    * via msg.sender and msg.data, they should not be accessed in such a direct
    * manner, since when dealing with meta-transactions the account sending and
    * paying for execution may not be the actual sender (as far as an application
    * is concerned).
    *
    * This contract is only required for intermediate, library-like contracts.
    */
    abstract contract ContextUpgradeable is Initializable {
    function __Context_init() internal onlyInitializing {
    }
    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
    return msg.sender;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 56 of 59 : draft-IERC6093.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Standard ERC20 Errors
    * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
    */
    interface IERC20Errors {
    /**
    * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
    * @param sender Address whose tokens are being transferred.
    * @param balance Current balance for the interacting account.
    * @param needed Minimum amount required to perform a transfer.
    */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
    /**
    * @dev Indicates a failure with the token `sender`. Used in transfers.
    * @param sender Address whose tokens are being transferred.
    */
    error ERC20InvalidSender(address sender);
    /**
    * @dev Indicates a failure with the token `receiver`. Used in transfers.
    * @param receiver Address to which tokens are being transferred.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 57 of 59 : IERC721Metadata.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)
    pragma solidity ^0.8.20;
    import {IERC721} from "../IERC721.sol";
    /**
    * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
    * @dev See https://eips.ethereum.org/EIPS/eip-721
    */
    interface IERC721Metadata is IERC721 {
    /**
    * @dev Returns the token collection name.
    */
    function name() external view returns (string memory);
    /**
    * @dev Returns the token collection symbol.
    */
    function symbol() external view returns (string memory);
    /**
    * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
    */
    function tokenURI(uint256 tokenId) external view returns (string memory);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 58 of 59 : SignedMath.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)
    pragma solidity ^0.8.20;
    /**
    * @dev Standard signed math utilities missing in the Solidity language.
    */
    library SignedMath {
    /**
    * @dev Returns the largest of two signed numbers.
    */
    function max(int256 a, int256 b) internal pure returns (int256) {
    return a > b ? a : b;
    }
    /**
    * @dev Returns the smallest of two signed numbers.
    */
    function min(int256 a, int256 b) internal pure returns (int256) {
    return a < b ? a : b;
    }
    /**
    * @dev Returns the average of two signed numbers without overflow.
    * The result is rounded towards zero.
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    File 59 of 59 : IERC721.sol
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
    pragma solidity ^0.8.20;
    import {IERC165} from "../../utils/introspection/IERC165.sol";
    /**
    * @dev Required interface of an ERC721 compliant contract.
    */
    interface IERC721 is IERC165 {
    /**
    * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
    */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    /**
    * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
    */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    /**
    * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
    */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Settings
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    {
    "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@solady/=lib/solady/src/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "solady/=lib/solady/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
    ],
    "optimizer": {
    "enabled": true,
    "runs": 200
    },
    "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
    },
    "outputSelection": {
    "*": {
    "*": [
    "evm.bytecode",
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Contract Security Audit

    Contract ABI

    API
    [{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyExist","type":"error"},{"inputs":[],"name":"BadFarm","type":"error"},{"inputs":[],"name":"ETHTransferFailed","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"IncorrectAmountsLength","type":"error"},{"inputs":[],"name":"IncorrectArrayLength","type":"error"},{"inputs":[],"name":"IncorrectAssets","type":"error"},{"inputs":[],"name":"IncorrectAssetsLength","type":"error"},{"inputs":[],"name":"IncorrectInitParams","type":"error"},{"inputs":[],"name":"IncorrectMsgSender","type":"error"},{"inputs":[],"name":"IncorrectStrategyId","type":"error"},{"inputs":[],"name":"IncorrectZeroArgument","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotExist","type":"error"},{"inputs":[],"name":"NotFactory","type":"error"},{"inputs":[],"name":"NotGovernance","type":"error"},{"inputs":[],"name":"NotGovernanceAndNotMultisig","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotMultisig","type":"error"},{"inputs":[],"name":"NotOperator","type":"error"},{"inputs":[],"name":"NotPlatform","type":"error"},{"inputs":[],"name":"NotReadyForHardWork","type":"error"},{"inputs":[],"name":"NotTheOwner","type":"error"},{"inputs":[],"name":"NotVault","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"ZeroAmmAdapter","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"uint256","name":"ts","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"block","type":"uint256"}],"name":"ContractInitialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultManagerReceiverFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strategyLogicReceiverFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ecosystemRevenueReceiverFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"multisigReceiverFee","type":"uint256"}],"name":"ExtractFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"fees","type":"uint256[]"}],"name":"FeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"apr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"compoundApr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"earned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tvl","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sharePrice","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"assetPrices","type":"uint256[]"}],"name":"HardWork","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"RewardsClaimed","type":"event"},{"inputs":[],"name":"CONTROLLABLE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_FARMING_STRATEGY_BASE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_LP_STRATEGY_BASE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION_STRATEGY_BASE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ammAdapter","outputs":[{"internalType":"contract IAmmAdapter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ammAdapterId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"assets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetsAmounts","outputs":[{"internalType":"address[]","name":"assets_","type":"address[]"},{"internalType":"uint256[]","name":"amounts_","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"autoCompoundingByUnderlyingProtocol","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canFarm","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createdBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"depositAssets","outputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositUnderlying","outputs":[{"internalType":"uint256[]","name":"amountsConsumed","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doHardWork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyStopInvesting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"extra","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"farmId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"farmMechanics","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"farmingAssets","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetsProportions","outputs":[{"internalType":"uint256[]","name":"proportions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRevenue","outputs":[{"internalType":"address[]","name":"__assets","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getSpecificName","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"platform_","type":"address"}],"name":"initVariants","outputs":[{"internalType":"string[]","name":"variants","type":"string[]"},{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"nums","type":"uint256[]"},{"internalType":"int24[]","name":"ticks","type":"int24[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"nums","type":"uint256[]"},{"internalType":"int24[]","name":"ticks","type":"int24[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isHardWorkOnDepositAllowed","outputs":[{"internalType":"bool","name":"allowed","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isReadyForHardWork","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastApr","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAprCompound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastHardWork","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platform","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets_","type":"address[]"},{"internalType":"uint256[]","name":"amountsMax","type":"uint256[]"}],"name":"previewDepositAssets","outputs":[{"internalType":"uint256[]","name":"amountsConsumed","type":"uint256[]"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets_","type":"address[]"},{"internalType":"uint256[]","name":"amountsMax","type":"uint256[]"}],"name":"previewDepositAssetsWrite","outputs":[{"internalType":"uint256[]","name":"amountsConsumed","type":"uint256[]"},{"internalType":"uint256","name":"value","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"refreshFarmingAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategyLogicId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"supportedVaultTypes","outputs":[{"internalType":"string[]","name":"types","type":"string[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"total","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"total_","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"transferAssets","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"underlying","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets_","type":"address[]"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdrawAssets","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"withdrawUnderlying","outputs":[],"stateMutability":"nonpayable","type":"function"}]

    608060405234801562000010575f80fd5b506200001b62000021565b620000d5565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000725760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d25780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b615c4e80620000e35f395ff3fe608060405234801561000f575f80fd5b5060043610610281575f3560e01c80636f307dc311610156578063aa47f4e1116100ca578063f2c33e2d11610084578063f2c33e2d14610579578063f815c4ff1461059d578063f985b0bc146105a5578063fbfa77cf146105b8578063fdff667c146105c0578063ffa1ad7414610499575f80fd5b8063aa47f4e11461051a578063aefb075114610522578063b600585a14610545578063b6c8cdef14610558578063b9f5be411461055e578063f1faf05014610571575f80fd5b80638a7f53601161011b5780638a7f536014610491578063936725ec146104995780639736374e146104bd57806399f428cf146104c45780639b3ff191146104d7578063a2b7722c14610507575f80fd5b80636f307dc31461045c57806371a97305146104645780637284e4161461047957806374bac4291461048157806380e7ac7c14610489575f80fd5b806341affeb8116101f857806350f4e419116101b257806350f4e419146103df57806359498ab7146103ff5780635b0f088a1461040757806367cf905a1461042b57806367fde573146104335780636d9894391461043b575f80fd5b806341affeb8146103835780634593144c146103965780634875c9681461039e57806348d7d9eb146103a65780634bde38c8146103cf5780634fa5d854146103d7575f80fd5b80631ec71e05116102495780631ec71e05146102f3578063278de000146103095780632a8ba2931461031d5780632d433b281461034e5780632ddbd13a14610371578063394f523214610379575f80fd5b806301ffc9a7146102855780630c56ae3b146102ad57806313e63180146102cd57806316f0115b146102e3578063190024e0146102eb575b5f80fd5b6102986102933660046147fe565b6105d5565b60405190151581526020015b60405180910390f35b6102b56105e5565b6040516001600160a01b0390911681526020016102a4565b6102d5610616565b6040519081526020016102a4565b6102b5610628565b6102d5610647565b6102fb6106e9565b6040516102a4929190614872565b5f80516020615bf9833981519152546102d5565b610341604051806040016040528060058152602001640312e322e360dc1b81525081565b6040516102a49190614895565b61036161035c3660046148bb565b6108b3565b6040516102a494939291906149a0565b6102d5610cac565b610381610cbe565b005b610381610391366004614b8f565b610d51565b6102d56110f3565b610341611126565b6103c1604080515f8082526020820190815281830190925291565b6040516102a4929190614c6d565b6102b561114f565b61038161117e565b6103f26103ed366004614c91565b61143b565b6040516102a49190614ce7565b6103c161145a565b610341604051806040016040528060058152602001640322e302e360dc1b81525081565b6103f26114ec565b6103816115d7565b61044e610449366004614cf9565b6115f3565b6040516102a4929190614d58565b6102b56116f8565b61046c611713565b6040516102a49190614d79565b61034161177c565b610298611899565b6102986118a9565b6103416118bb565b610341604051806040016040528060058152602001640312e302e360dc1b81525081565b6001610298565b6103816104d2366004614d8b565b6118de565b7fa6fdc931ca23c69f54119a0a2d6478619b5aa365084590a1fbc287668fbabe01546001600160a01b03166102b5565b6102d5610515366004614db9565b6118f4565b61046c61192e565b604080518082019091526007815266436c617373696360c81b6020820152610341565b61044e610553366004614cf9565b61199b565b5f610298565b6103f261056c366004614dea565b611a8d565b6102d5611aa0565b610341604051806040016040528060058152602001640c4b8c0b8d60da1b81525081565b6102d5611ab2565b6103f26105b3366004614e01565b611ac4565b6102b5611b6d565b6105c8611b76565b6040516102a49190614e2c565b5f6105df82611be8565b92915050565b5f806105ef611c0c565b9050806080015160018151811061060857610608614e3e565b602002602001015191505090565b5f61061f611c33565b60020154905090565b5f5f80516020615bd98339815191525b546001600160a01b0316919050565b6040805162965fff60e81b60208201525f6023820181905282516006818403018152602683019384905263bfe370d960e01b90935291734f76add676c04eca837130ceb58bc173de8799de9163bfe370d9916106a591602a01614895565b602060405180830381865af41580156106c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106e49190614e52565b905090565b60605f806106f5611c0c565b90505f81608001515f8151811061070e5761070e614e3e565b602002602001015190505f816001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610755573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107799190614e78565b6107e257816001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107dd9190614e9c565b610842565b816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108429190614e9c565b90505f816001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610880573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108a79190810190614f17565b965f9650945050505050565b6060806060805f856001600160a01b0316634254af1c6108d16118bb565b805190602001206040518263ffffffff1660e01b81526004016108f691815260200190565b5f60405180830381865afa158015610910573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109379190810190614f48565b602090810151604080515f80825281850181815282840180855263c45a015560e01b90529251919850919550919350916001600160a01b0389169163c45a0155916044808a019290818b030181865afa158015610996573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ba9190614e9c565b6001600160a01b031663871fd6826040518163ffffffff1660e01b81526004015f60405180830381865afa1580156109f4573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a1b91908101906151f3565b80519091505f805b82811015610af2575f848281518110610a3e57610a3e614e3e565b60200260200101519050805f01515f148015610ad85750734f76add676c04eca837130ceb58bc173de8799de6321a496428260400151610a7c611126565b6040518363ffffffff1660e01b8152600401610a9992919061529c565b602060405180830381865af4158015610ab4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad89190614e78565b15610ae957610ae6836152d4565b92505b50600101610a23565b50806001600160401b03811115610b0b57610b0b614a22565b604051908082528060200260200182016040528015610b3e57816020015b6060815260200190600190039081610b295790505b509750806001600160401b03811115610b5957610b59614a22565b604051908082528060200260200182016040528015610b82578160200160208202803683370190505b5095505f90505f5b82811015610ca0575f848281518110610ba557610ba5614e3e565b60200260200101519050805f01515f148015610c3f5750734f76add676c04eca837130ceb58bc173de8799de6321a496428260400151610be3611126565b6040518363ffffffff1660e01b8152600401610c0092919061529c565b602060405180830381865af4158015610c1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3f9190614e78565b15610c975781888481518110610c5757610c57614e3e565b602002602001018181525050610c6d8187611c57565b8a8481518110610c7f57610c7f614e3e565b602002602001018190525082610c94906152d4565b92505b50600101610b8a565b50505050509193509193565b5f610cb5611c33565b60010154905090565b610cc6611f42565b73e347a67358dd7cba1eb146b9a60172a10cb8abee63fede401f5f80516020615bf9833981519152610cf661114f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044015f6040518083038186803b158015610d39575f80fd5b505af4158015610d4b573d5f803e3d5ffd5b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610d955750825b90505f826001600160401b03166001148015610db05750303b155b905081158015610dbe575080155b15610ddc5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e0657845460ff60401b1916600160401b1785555b87516002141580610e1957508651600114155b80610e245750855115155b15610e42576040516363cf6b6160e01b815260040160405180910390fd5b5f610e7f895f81518110610e5857610e58614e3e565b6020026020010151895f81518110610e7257610e72614e3e565b6020026020010151611fd1565b90508060800151516002141580610e9a575060a08101515115155b80610ea9575060c08101515115155b15610ec7576040516325b769d160e11b815260040160405180910390fd5b610f956040518060a001604052806040518060400160405280600f81526020016e49636869205377617058204661726d60881b81525081526020018b5f81518110610f1457610f14614e3e565b60200260200101516001600160a01b031681526020018b600181518110610f3d57610f3d614e3e565b60200260200101516001600160a01b0316815260200183602001516001600160a01b0316815260200183608001515f81518110610f7c57610f7c614e3e565b60200260200101516001600160a01b03168152506120a7565b610fd1895f81518110610faa57610faa614e3e565b6020026020010151895f81518110610fc457610fc4614e3e565b6020026020010151612171565b5f610fda611713565b905061103182608001515f81518110610ff557610ff5614e3e565b60200260200101515f19835f8151811061101157611011614e3e565b60200260200101516001600160a01b03166121fd9092919063ffffffff16565b61106782608001515f8151811061104a5761104a614e3e565b60200260200101515f198360018151811061101157611011614e3e565b6110a1826080015160018151811061108157611081614e3e565b60200260200101515f1984608001515f8151811061101157611011614e3e565b505083156110e957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f6106e461112260017f812a673dfca07956350df10f8a654925f561d7a0da09bdbe79e653939a14d9f16152ec565b5490565b60408051808201909152600f81526e49636869205377617058204661726d60881b602082015290565b5f6106e461112260017faa116a42804728f23983458454b6eb9c6ddf3011db9f9addaf3cd7508d85b0d66152ec565b6111866122ba565b61118e6122eb565b5f611197611c33565b805460408051637299470360e11b815281519394506001600160a01b03909216925f92849263e5328e06926004808401938290030181865afa1580156111df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061120391906152ff565b5090508015611436575f61121561114f565b60088501549091505f808080611229612368565b93509350935093505f6112395f90565b61133d5761126185878151811061125257611252614e3e565b6020026020010151848461271f565b84878151811061127357611273614e3e565b602002602001018181516112879190615329565b915081815250505f73e347a67358dd7cba1eb146b9a60172a10cb8abee6356cd528e898c8e6007018a8a6040518663ffffffff1660e01b81526004016112d19594939291906153ed565b5f60405180830381865af41580156112eb573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611312919081019061543e565b90505f61131f87836127a3565b90508b600101549250801561133657611336612871565b50506113c1565b6040516336ac731760e11b81526001600160a01b038a1690636d58e62e9061136b9088908890600401614c6d565b5f604051808303815f87803b158015611382575f80fd5b505af1158015611394573d5f803e3d5ffd5b505050506113ad855f8151811061125257611252614e3e565b506113b885856127a3565b506113c1612871565b60405163640f244560e01b815273e347a67358dd7cba1eb146b9a60172a10cb8abee9063640f244590611402908d908b908a908a908f90899060040161546f565b5f6040518083038186803b158015611418575f80fd5b505af415801561142a573d5f803e3d5ffd5b50505050505050505050505b505050565b60606114456122ba565b61145084848461290a565b90505b9392505050565b606080611465612982565b604051633f8b51a560e21b8152919350915073e347a67358dd7cba1eb146b9a60172a10cb8abee9063fe2d4694906114a39085908590600401614c6d565b5f60405180830381865af41580156114bd573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114e491908101906154c0565b915091509091565b60605f6114f7611c33565b60068101546040805160028082526060820183529394506001600160a01b039092169290602083019080368337019050509250806001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611566573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061158a9190614e78565b156115bb57670de0b6b3a7640000835f815181106115aa576115aa614e3e565b602002602001018181525050505090565b670de0b6b3a7640000836001815181106115aa576115aa614e3e565b6115df612b57565b6115f06115ea610cac565b30612c72565b50565b60605f8351600114801561163f575061160a611c33565b6006015484516001600160a01b039091169085905f9061162c5761162c614e3e565b60200260200101516001600160a01b0316145b801561167657505f6001600160a01b0316845f8151811061166257611662614e3e565b60200260200101516001600160a01b031614155b156116e257825160011461169d57604051630ef9926760e21b815260040160405180910390fd5b825f815181106116af576116af614e3e565b602002602001015190506116db835f815181106116ce576116ce614e3e565b6020026020010151612e2f565b91506116f1565b6116ec8484612e3a565b915091505b9250929050565b5f611701611c33565b600601546001600160a01b0316919050565b606061171d611c33565b60050180548060200260200160405190810160405280929190818152602001828054801561177257602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611754575b5050505050905090565b60605f80516020615bf98339815191525f80516020615bd98339815191525f6117a361114f565b6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118029190614e9c565b835460405163538a85a160e01b81526001600160a01b03929092169163538a85a1916118349160040190815260200190565b5f60405180830381865afa15801561184e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526118759190810190615515565b60018301549091506118919082906001600160a01b0316611c57565b935050505090565b5f6118a2610cac565b1515919050565b5f806118b3611c0c565b511592915050565b604080518082019091526009815268105b19d9589c98558d60ba1b602082015290565b6118e66122ba565b6118f08282612e47565b5050565b5f6118fd6122ba565b5f611906611c33565b905080600201545f0361191a574260028201555b611925836001612f2f565b9150505b919050565b60605f80516020615bf983398151915260010180548060200260200160405190810160405280929190818152602001828054801561177257602002820191905f5260205f209081546001600160a01b03168152600190910190602001808311611754575050505050905090565b60605f835160011480156119e757506119b2611c33565b6006015484516001600160a01b039091169085905f906119d4576119d4614e3e565b60200260200101516001600160a01b0316145b8015611a1e57505f6001600160a01b0316845f81518110611a0a57611a0a614e3e565b60200260200101516001600160a01b031614155b15611a83578251600114611a4557604051630ef9926760e21b815260040160405180910390fd5b825f81518110611a5757611a57614e3e565b602002602001015190506116db835f81518110611a7657611a76614e3e565b60200260200101516130a2565b6116ec8484613218565b6060611a976122ba565b6105df82613292565b5f611aa9611c33565b60040154905090565b5f611abb611c33565b60030154905090565b6060611ace6122ba565b73e347a67358dd7cba1eb146b9a60172a10cb8abee6325567aef611af0611c33565b6040516001600160e01b031960e084901b168152600481019190915260248101879052604481018690526001600160a01b03851660648201526084015f60405180830381865af4158015611b46573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611450919081019061543e565b5f610638611c33565b604080516001808252818301909252606091816020015b6060815260200190600190039081611b8d5790505090506040518060400160405280600b81526020016a436f6d706f756e64696e6760a81b815250815f81518110611bda57611bda614e3e565b602002602001018190525090565b5f6001600160e01b031982166396cf43c560e01b14806105df57506105df8261334e565b611c1461474c565b6106e4611c1f61114f565b5f80516020615bf983398151915254611fd1565b7fb14b643f49bed6a2c6693bbd50f68dc950245db265c66acadbfa51ccc8c3ba0090565b6060734f76add676c04eca837130ceb58bc173de8799de631dfab928734f76add676c04eca837130ceb58bc173de8799de63fbcadbe986606001516040518263ffffffff1660e01b8152600401611cae9190614d79565b5f60405180830381865af4158015611cc8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611cef9190810190615546565b6040518263ffffffff1660e01b8152600401611d0b919061562d565b5f60405180830381865af4158015611d25573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611d4c9190810190614f17565b602084015160405163a912616960e01b81526001600160a01b039182166004820152734f76add676c04eca837130ceb58bc173de8799de91631dfab92891839163fbcadbe9919088169063a9126169906024015f60405180830381865afa158015611db9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611de09190810190615663565b6040518263ffffffff1660e01b8152600401611dfc9190614d79565b5f60405180830381865af4158015611e16573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e3d9190810190615546565b6040518263ffffffff1660e01b8152600401611e599190615694565b5f60405180830381865af4158015611e73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e9a9190810190614f17565b84608001515f81518110611eb057611eb0614e3e565b60200260200101516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611ef2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f199190810190614f17565b604051602001611f2b939291906156c9565b604051602081830303815290604052905092915050565b611f4a61114f565b6040516336b87bd760e11b81523360048201526001600160a01b039190911690636d70f7ae90602401602060405180830381865afa158015611f8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fb29190614e78565b611fcf57604051631f0853c160e21b815260040160405180910390fd5b565b611fd961474c565b826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612015573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120399190614e9c565b6001600160a01b031663538a85a1836040518263ffffffff1660e01b815260040161206691815260200190565b5f60405180830381865afa158015612080573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114539190810190615515565b6120af613372565b5f5f80516020615bd9833981519152905060605f73f732df3f82d1ce0234bf5ee6933fd370b8b30f2a638ff2a774848660200151876120ec6118bb565b6040518563ffffffff1660e01b815260040161210b949392919061575c565b5f60405180830381865af4158015612125573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261214c91908101906157d2565b8092508193505050610d4b8460200151855f01518660400151858860800151866133bb565b612179613372565b73e347a67358dd7cba1eb146b9a60172a10cb8abee634ab3b02f5f80516020615bf98339815191526121a9611c33565b60070185856040518563ffffffff1660e01b81526004016121cd9493929190615815565b5f6040518083038186803b1580156121e3575f80fd5b505af41580156121f5573d5f803e3d5ffd5b505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261224e848261345f565b610d4b576040516001600160a01b0384811660248301525f60448301526122b091869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613500565b610d4b8482613500565b6122c2611c33565b546001600160a01b03163314611fcf576040516362df054560e01b815260040160405180910390fd5b306001600160a01b03166374bac4296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612327573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061234b9190614e78565b611fcf576040516309ea311f60e11b815260040160405180910390fd5b606080606080612376611713565b935083516001600160401b0381111561239157612391614a22565b6040519080825280602002602001820160405280156123ba578160200160208202803683370190505b507fe61f0a7b2953b9e28e48cc07562ad7979478dcaee972e68dcf3b10da2cba60018054604080516020808402820181019092528281529396505f80516020615bf98339815191529392919083018282801561243d57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161241f575b505050505092505f73e347a67358dd7cba1eb146b9a60172a10cb8abee63e3d670d7855f8151811061247157612471614e3e565b60200260200101516040518263ffffffff1660e01b81526004016124a491906001600160a01b0391909116815260200190565b602060405180830381865af41580156124bf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124e39190614e52565b604080516001808252818301909252919250602080830190803683370190505092505f61250e611c0c565b90505f816080015160018151811061252857612528614e3e565b60200260200101516001600160a01b0316637c91e4eb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561256b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061258f9190614e9c565b6040805160018082528183019092529192505f91906020808301908036833701905050905082608001516001815181106125cb576125cb614e3e565b6020026020010151815f815181106125e5576125e5614e3e565b6001600160a01b03928316602091820292909201015260405163f9f031df60e01b81529083169063f9f031df90612620908490600401614d79565b5f604051808303815f87803b158015612637575f80fd5b505af1158015612649573d5f803e3d5ffd5b505050508373e347a67358dd7cba1eb146b9a60172a10cb8abee63e3d670d7895f8151811061267a5761267a614e3e565b60200260200101516040518263ffffffff1660e01b81526004016126ad91906001600160a01b0391909116815260200190565b602060405180830381865af41580156126c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ec9190614e52565b6126f691906152ec565b865f8151811061270857612708614e3e565b602002602001018181525050505050505090919293565b5f73e347a67358dd7cba1eb146b9a60172a10cb8abee6374e714c861274261114f565b8686866040518563ffffffff1660e01b81526004016127649493929190615849565b602060405180830381865af415801561277f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114509190614e52565b5f5f80516020615bd983398151915273f732df3f82d1ce0234bf5ee6933fd370b8b30f2a6372d46b086127d461114f565b6127dc611b6d565b60018501546001600160a01b03166127f2611c33565b6008015486546040516001600160e01b031960e088901b16815261282a95949392916001600160a01b0316908c908c90600401615891565b602060405180830381865af4158015612845573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128699190614e78565b949350505050565b5f61287a6114ec565b90505f61289f825f8151811061289257612892614e3e565b6020026020010151613566565b90506001815f815181106128b5576128b5614e3e565b602002602001015111806128e357506001816001815181106128d9576128d9614e3e565b6020026020010151115b156118f0575f6128f282613616565b9092509050600a81111561143657610d4b825f612f2f565b606073f732df3f82d1ce0234bf5ee6933fd370b8b30f2a639dfc419f8561292f611713565b6040518363ffffffff1660e01b815260040161294c9291906158f3565b5f6040518083038186803b158015612962575f80fd5b505af4158015612974573d5f803e3d5ffd5b505050506114508383612c72565b6060805f61298e611c33565b600581018054604080516020808402820181019092528281529394508301828280156129e157602002820191905f5260205f20905b81546001600160a01b031681526001909101906020018083116129c3575b505050506001830154600684015460408051636253bb0f60e11b8152815195985092946001600160a01b0390921693505f928392859263c4a7761e92600480820193918290030181865afa158015612a3b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a5f9190615917565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612aa0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ac49190614e52565b604080516002808252606082018352929350919060208301908036833701905050965080612af28685615939565b612afc9190615950565b875f81518110612b0e57612b0e614e3e565b602090810291909101015280612b248684615939565b612b2e9190615950565b87600181518110612b4157612b41614e3e565b6020026020010181815250505050505050509091565b5f612b6061114f565b9050336001600160a01b0316816001600160a01b0316635aa6e6756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ba8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bcc9190614e9c565b6001600160a01b031614158015612c545750336001600160a01b0316816001600160a01b0316634783c35b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c24573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c489190614e9c565b6001600160a01b031614155b156115f0576040516354299b6f60e01b815260040160405180910390fd5b60605f612c7d611c0c565b90508060800151600181518110612c9657612c96614e3e565b60200260200101516001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b8152600401612ccb91815260200190565b5f604051808303815f87803b158015612ce2575f80fd5b505af1158015612cf4573d5f803e3d5ffd5b5060029250612d01915050565b604051908082528060200260200182016040528015612d2a578160200160208202803683370190505b50915080608001515f81518110612d4357612d43614e3e565b60200260200101516001600160a01b031662f714ce85856040518363ffffffff1660e01b8152600401612d899291909182526001600160a01b0316602082015260400190565b60408051808303815f875af1158015612da4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612dc89190615917565b835f81518110612dda57612dda614e3e565b6020026020010184600181518110612df457612df4614e3e565b6020908102919091010191909152525f612e0c611c33565b905084816001015f828254612e2191906152ec565b909155509295945050505050565b60606105df826130a2565b60605f6116ec8484613218565b5f612e50611c0c565b90508060800151600181518110612e6957612e69614e3e565b60200260200101516001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b8152600401612e9e91815260200190565b5f604051808303815f87803b158015612eb5575f80fd5b505af1158015612ec7573d5f803e3d5ffd5b50505050612f06828483608001515f81518110612ee657612ee6614e3e565b60200260200101516001600160a01b0316613d409092919063ffffffff16565b5f612f0f611c33565b905083816001015f828254612f2491906152ec565b909155505050505050565b5f80612f39611c0c565b905080608001515f81518110612f5157612f51614e3e565b60200260200101516001600160a01b0316638dbdbe6d855f81518110612f7957612f79614e3e565b602002602001015186600181518110612f9457612f94614e3e565b60209081029190910101516040516001600160e01b031960e085901b168152600481019290925260248201523060448201526064016020604051808303815f875af1158015612fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130099190614e52565b9150806080015160018151811061302257613022614e3e565b60200260200101516001600160a01b031663b6b55f25836040518263ffffffff1660e01b815260040161305791815260200190565b5f604051808303815f87803b15801561306e575f80fd5b505af1158015613080573d5f803e3d5ffd5b505050505f61308d611c33565b905082816001015f828254612e219190615329565b60605f6130ad611c33565b600681015460408051636253bb0f60e11b815281519394506001600160a01b03909216925f928392859263c4a7761e9260048082019392918290030181865afa1580156130fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131209190615917565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613161573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131859190614e52565b6040805160028082526060820183529293509190602083019080368337019050509550806131b38885615939565b6131bd9190615950565b865f815181106131cf576131cf614e3e565b6020908102919091010152806131e58884615939565b6131ef9190615950565b8660018151811061320257613202614e3e565b6020026020010181815250505050505050919050565b60605f73f732df3f82d1ce0234bf5ee6933fd370b8b30f2a639d186c788561323e611713565b866040518463ffffffff1660e01b815260040161325d9392919061596f565b5f6040518083038186803b158015613273575f80fd5b505af4158015613285573d5f803e3d5ffd5b505050506116ec83613616565b60605f61329d611c0c565b905080608001516001815181106132b6576132b6614e3e565b60200260200101516001600160a01b031663b6b55f25846040518263ffffffff1660e01b81526004016132eb91815260200190565b5f604051808303815f87803b158015613302575f80fd5b505af1158015613314573d5f803e3d5ffd5b50505050613321836130a2565b91505f61332c611c33565b905083816001015f8282546133419190615329565b9091555092949350505050565b5f6001600160e01b031982166303d859d560e11b14806105df57506105df82613d71565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611fcf57604051631afcd79f60e31b815260040160405180910390fd5b6133c3613372565b6133cc86613d95565b5f6133d5611c33565b600881018390556006810180546001600160a01b0319166001600160a01b03861617905584519091508690869086908690869060078701905f908890829061342690600584019060208a0190614790565b5081546001600160a01b03808a166101009390930a928302920219161790555061345086826159f2565b50505050505050505050505050565b5f805f846001600160a01b03168460405161347a9190615aad565b5f604051808303815f865af19150503d805f81146134b3576040519150601f19603f3d011682016040523d82523d5f602084013e6134b8565b606091505b50915091508180156134e25750805115806134e25750808060200190518101906134e29190614e78565b80156134f757505f856001600160a01b03163b115b95945050505050565b5f6135146001600160a01b03841683613ef0565b905080515f141580156135385750808060200190518101906135369190614e78565b155b1561143657604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b60605f80516020615bd983398151915273f732df3f82d1ce0234bf5ee6933fd370b8b30f2a633f9406db61359861114f565b600184015484546001600160a01b0391821691166135b4611713565b886040518663ffffffff1660e01b81526004016135d5959493929190615ac8565b5f60405180830381865af41580156135ef573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611925919081019061543e565b60605f80613622611c33565b60068101546040805160028082526060820183529394506001600160a01b039092169290602083019080368337019050509350806001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613691573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b59190614e78565b156136f757845f815181106136cc576136cc614e3e565b6020026020010151845f815181106136e6576136e6614e3e565b602002602001018181525050613732565b8460018151811061370a5761370a614e3e565b60200260200101518460018151811061372557613725614e3e565b6020026020010181815250505b60408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152816001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137e29190614e9c565b8160e001906001600160a01b031690816001600160a01b031681525050816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561383b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061385f9190614e9c565b8161010001906001600160a01b031690816001600160a01b031681525050816001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138dd9190614e9c565b8161012001906001600160a01b031690816001600160a01b031681525050816001600160a01b031663f62073266040518163ffffffff1660e01b8152600401602060405180830381865afa158015613937573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061395b9190615b0d565b63ffffffff16815260408051630dfe168160e01b81529051613a9d916001600160a01b03851691630dfe1681916004808201926020929091908290030181865afa1580156139ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139cf9190614e9c565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a2f9190614e9c565b846001600160a01b031663065e53606040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a8f9190615b30565b670de0b6b3a7640000613efd565b604082015260e08101516101008201516101208301518351613aca93929190670de0b6b3a7640000613f12565b816060018181525050816001600160a01b03166391563d326040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b339190615b0d565b63ffffffff1660208201819052613b4e578060600151613b75565b613b758160e001518261010001518361012001518460200151670de0b6b3a7640000613f12565b8160800181815250505f80836001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa158015613bbb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bdf9190615917565b915091505f613c018460400151856060015186608001515f8860200151613fcd565b90505f670de0b6b3a7640000828a5f81518110613c2057613c20614e3e565b6020026020010151613c329190615939565b613c3c9190615950565b90508089600181518110613c5257613c52614e3e565b6020026020010151613c649190615329565b97505f866001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ca3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cc79190614e52565b90508015613d33575f613cee87604001518860600151896080015160018b60200151613fcd565b90505f670de0b6b3a7640000613d048389615939565b613d0e9190615950565b9050613d1a8682615329565b613d24848d615939565b613d2e9190615950565b9a5050505b5050505050505050915091565b6040516001600160a01b0383811660248301526044820183905261143691859182169063a9059cbb9060640161227e565b5f6001600160e01b031982166342c352d360e11b14806105df57506105df8261402d565b613d9d613372565b6001600160a01b0381161580613e2357505f6001600160a01b0316816001600160a01b0316634783c35b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613df4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e189190614e9c565b6001600160a01b0316145b15613e41576040516371c42ac360e01b815260040160405180910390fd5b613e74613e6f60017faa116a42804728f23983458454b6eb9c6ddf3011db9f9addaf3cd7508d85b0d66152ec565b829055565b613ea643613ea360017f812a673dfca07956350df10f8a654925f561d7a0da09bdbe79e653939a14d9f16152ec565b55565b604080516001600160a01b0383168152426020820152438183015290517f1a2dd071001ebf6e03174e3df5b305795a4ad5d41d8fdb9ba41dbbe2367134269181900360600190a150565b606061145383835f614061565b5f6134f783613f0b846140fa565b8787614131565b5f80613f1d876144e5565b604051638241348960e01b81526001600160a01b038216600482015263ffffffff861660248201529091505f9073e3c14573ccd72f95a739f297dcfa8d525aa330ac90638241348990604401602060405180830381865af4158015613f84573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fa89190615b30565b60020b9050613fc181613fba866140fa565b8989614131565b98975050505050505050565b5f82156140045763ffffffff821615613ffa57613ff3613fed8787614597565b85614597565b90506134f7565b613ff38686614597565b63ffffffff82161561402357613ff361401d87876145ac565b856145ac565b613ff386866145ac565b5f6001600160e01b03198216630f1ec81f60e41b14806105df57506301ffc9a760e01b6001600160e01b03198316146105df565b6060814710156140865760405163cd78605960e01b815230600482015260240161355d565b5f80856001600160a01b031684866040516140a19190615aad565b5f6040518083038185875af1925050503d805f81146140db576040519150601f19603f3d011682016040523d82523d5f602084013e6140e0565b606091505b50915091506140f08683836145ba565b9695505050505050565b5f6001600160801b0382111561412d576040516306dfcc6560e41b8152608060048201526024810183905260440161355d565b5090565b60405163986cfba360e01b8152600285900b60048201525f90819073bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063986cfba390602401602060405180830381865af4158015614186573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141aa9190614e9c565b90506001600160801b036001600160a01b03821611614315575f6141d76001600160a01b03831680615939565b9050836001600160a01b0316856001600160a01b0316106142825760405163554d048960e11b8152600160c01b60048201526001600160801b03871660248201526044810182905273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af4158015614259573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061427d9190614e52565b61430d565b60405163554d048960e11b8152600481018290526001600160801b0387166024820152600160c01b604482015273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af41580156142e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061430d9190614e52565b9250506144dc565b60405163554d048960e11b81526001600160a01b038216600482018190526024820152600160401b60448201525f9073bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af415801561437e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906143a29190614e52565b9050836001600160a01b0316856001600160a01b03161061444d5760405163554d048960e11b8152600160801b60048201526001600160801b03871660248201526044810182905273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af4158015614424573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144489190614e52565b6144d8565b60405163554d048960e11b8152600481018290526001600160801b0387166024820152600160801b604482015273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af41580156144b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144d89190614e52565b9250505b50949350505050565b5f816001600160a01b031663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614522573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145469190614e9c565b90506145528183614616565b6119295760405162461bcd60e51b815260206004820152601660248201527524ab1d103234b1b7b73732b1ba32b21038363ab3b4b760511b604482015260640161355d565b5f8183116145a55781611453565b5090919050565b5f8183106145a55781611453565b6060826145cf576145ca82614723565b611453565b81511580156145e657506001600160a01b0384163b155b1561460f57604051639996b31560e01b81526001600160a01b038516600482015260240161355d565b5080611453565b5f6001600160a01b03831661462c57505f6105df565b5f829050806001600160a01b031663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561466c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146909190614e9c565b6001600160a01b0316846001600160a01b03160361471c575f816001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa1580156146e5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906147099190615b5c565b505093505050506134f781600116151590565b5092915050565b8051156147335780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060e001604052805f81526020015f6001600160a01b0316815260200160608152602001606081526020016060815260200160608152602001606081525090565b828054828255905f5260205f209081019282156147e3579160200282015b828111156147e357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147ae565b5061412d9291505b8082111561412d575f81556001016147eb565b5f6020828403121561480e575f80fd5b81356001600160e01b031981168114611453575f80fd5b5f5b8381101561483f578181015183820152602001614827565b50505f910152565b5f815180845261485e816020860160208601614825565b601f01601f19169290920160200192915050565b604081525f6148846040830185614847565b905082151560208301529392505050565b602081525f6114536020830184614847565b6001600160a01b03811681146115f0575f80fd5b5f602082840312156148cb575f80fd5b8135611453816148a7565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561492157601f1986840301895261490f838351614847565b988401989250908301906001016148f3565b5090979650505050505050565b5f815180845260208085019450602084015f5b838110156149665781516001600160a01b031687529582019590820190600101614941565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561496657815187529582019590820190600101614984565b608081525f6149b260808301876148d6565b602083820360208501526149c6828861492e565b915083820360408501526149da8287614971565b8481036060860152855180825260208088019450909101905f5b81811015614a1357845160020b835293830193918301916001016149f4565b50909998505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b0381118282101715614a5857614a58614a22565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614a8657614a86614a22565b604052919050565b5f6001600160401b03821115614aa657614aa6614a22565b5060051b60200190565b5f82601f830112614abf575f80fd5b81356020614ad4614acf83614a8e565b614a5e565b8083825260208201915060208460051b870101935086841115614af5575f80fd5b602086015b84811015614b1a578035614b0d816148a7565b8352918301918301614afa565b509695505050505050565b5f82601f830112614b34575f80fd5b81356020614b44614acf83614a8e565b8083825260208201915060208460051b870101935086841115614b65575f80fd5b602086015b84811015614b1a5780358352918301918301614b6a565b8060020b81146115f0575f80fd5b5f805f60608486031215614ba1575f80fd5b83356001600160401b0380821115614bb7575f80fd5b614bc387838801614ab0565b9450602091508186013581811115614bd9575f80fd5b614be588828901614b25565b945050604086013581811115614bf9575f80fd5b86019050601f81018713614c0b575f80fd5b8035614c19614acf82614a8e565b81815260059190911b82018301908381019089831115614c37575f80fd5b928401925b82841015614c5e578335614c4f81614b81565b82529284019290840190614c3c565b80955050505050509250925092565b604081525f614c7f604083018561492e565b82810360208401526134f78185614971565b5f805f60608486031215614ca3575f80fd5b83356001600160401b03811115614cb8575f80fd5b614cc486828701614ab0565b935050602084013591506040840135614cdc816148a7565b809150509250925092565b602081525f6114536020830184614971565b5f8060408385031215614d0a575f80fd5b82356001600160401b0380821115614d20575f80fd5b614d2c86838701614ab0565b93506020850135915080821115614d41575f80fd5b50614d4e85828601614b25565b9150509250929050565b604081525f614d6a6040830185614971565b90508260208301529392505050565b602081525f611453602083018461492e565b5f8060408385031215614d9c575f80fd5b823591506020830135614dae816148a7565b809150509250929050565b5f60208284031215614dc9575f80fd5b81356001600160401b03811115614dde575f80fd5b61286984828501614b25565b5f60208284031215614dfa575f80fd5b5035919050565b5f805f60608486031215614e13575f80fd5b83359250602084013591506040840135614cdc816148a7565b602081525f61145360208301846148d6565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215614e62575f80fd5b5051919050565b80518015158114611929575f80fd5b5f60208284031215614e88575f80fd5b61145382614e69565b8051611929816148a7565b5f60208284031215614eac575f80fd5b8151611453816148a7565b5f82601f830112614ec6575f80fd5b81516001600160401b03811115614edf57614edf614a22565b614ef2601f8201601f1916602001614a5e565b818152846020838601011115614f06575f80fd5b612869826020830160208701614825565b5f60208284031215614f27575f80fd5b81516001600160401b03811115614f3c575f80fd5b61286984828501614eb7565b5f60208284031215614f58575f80fd5b81516001600160401b0380821115614f6e575f80fd5b9083019060408286031215614f81575f80fd5b604051604081018181108382111715614f9c57614f9c614a22565b604052825182811115614fad575f80fd5b614fb987828601614eb7565b82525060208301519250614fcc836148a7565b6020810192909252509392505050565b5f82601f830112614feb575f80fd5b81516020614ffb614acf83614a8e565b8083825260208201915060208460051b87010193508684111561501c575f80fd5b602086015b84811015614b1a578051615034816148a7565b8352918301918301615021565b5f82601f830112615050575f80fd5b81516020615060614acf83614a8e565b8083825260208201915060208460051b870101935086841115615081575f80fd5b602086015b84811015614b1a5780518352918301918301615086565b5f82601f8301126150ac575f80fd5b815160206150bc614acf83614a8e565b8083825260208201915060208460051b8701019350868411156150dd575f80fd5b602086015b84811015614b1a5780516150f581614b81565b83529183019183016150e2565b5f60e08284031215615112575f80fd5b61511a614a36565b90508151815261512c60208301614e91565b602082015260408201516001600160401b038082111561514a575f80fd5b61515685838601614eb7565b6040840152606084015191508082111561516e575f80fd5b61517a85838601614fdc565b60608401526080840151915080821115615192575f80fd5b61519e85838601614fdc565b608084015260a08401519150808211156151b6575f80fd5b6151c285838601615041565b60a084015260c08401519150808211156151da575f80fd5b506151e78482850161509d565b60c08301525092915050565b5f6020808385031215615204575f80fd5b82516001600160401b038082111561521a575f80fd5b818501915085601f83011261522d575f80fd5b815161523b614acf82614a8e565b81815260059190911b83018401908481019088831115615259575f80fd5b8585015b8381101561528f57805185811115615273575f80fd5b6152818b89838a0101615102565b84525091860191860161525d565b5098975050505050505050565b604081525f6152ae6040830185614847565b82810360208401526134f78185614847565b634e487b7160e01b5f52601160045260245ffd5b5f600182016152e5576152e56152c0565b5060010190565b818103818111156105df576105df6152c0565b5f8060408385031215615310575f80fd5b8251915061532060208401614e69565b90509250929050565b808201808211156105df576105df6152c0565b600181811c9082168061535057607f821691505b60208210810361536e57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f81546153808161533c565b80855260206001838116801561539d57600181146153b7576153e2565b60ff1985168884015283151560051b8801830195506153e2565b865f52825f205f5b858110156153da5781548a82018601529083019084016153bf565b890184019650505b505050505092915050565b6001600160a01b0386811682528516602082015260a0604082018190525f9061541890830186615374565b828103606084015261542a818661492e565b90508281036080840152613fc18185614971565b5f6020828403121561544e575f80fd5b81516001600160401b03811115615463575f80fd5b61286984828501615041565b8681526001600160a01b038616602082015260c0604082018190525f906154989083018761492e565b82810360608401526154aa8187614971565b6080840195909552505060a00152949350505050565b5f80604083850312156154d1575f80fd5b82516001600160401b03808211156154e7575f80fd5b6154f386838701614fdc565b93506020850151915080821115615508575f80fd5b50614d4e85828601615041565b5f60208284031215615525575f80fd5b81516001600160401b0381111561553a575f80fd5b61286984828501615102565b5f6020808385031215615557575f80fd5b82516001600160401b038082111561556d575f80fd5b818501915085601f830112615580575f80fd5b815161558e614acf82614a8e565b81815260059190911b830184019084810190888311156155ac575f80fd5b8585015b8381101561528f578051858111156155c6575f80fd5b6155d48b89838a0101614eb7565b8452509186019186016155b0565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561492157601f1986840301895261561b838351614847565b988401989250908301906001016155ff565b604081525f61563f60408301846155e2565b82810360208401526002815261016160f51b60208201526040810191505092915050565b5f60208284031215615673575f80fd5b81516001600160401b03811115615688575f80fd5b61286984828501614fdc565b604081525f6156a660408301846155e2565b828103602084015260018152602d60f81b60208201526040810191505092915050565b64022b0b937160dd1b81525f84516156e8816005850160208901614825565b7f20616e642066656573206f6e20537761705820706f6f6c200000000000000000600591840191820152845161572581601d840160208901614825565b68010313c9024b1b434960bd1b601d9290910191820152835161574f816026840160208801614825565b0160260195945050505050565b8481525f60018060a01b03808616602084015260806040840152845160a0608085015261578d610120850182614847565b90508160208701511660a08501528160408701511660c08501528160608701511660e0850152816080870151166101008501528381036060850152613fc18186614847565b5f80604083850312156157e3575f80fd5b82516001600160401b038111156157f8575f80fd5b61580485828601614fdc565b925050602083015190509250929050565b848152608060208201525f61582d6080830186615374565b6001600160a01b03949094166040830152506060015292915050565b6001600160a01b038581168252841660208201526080604082018190525f906158749083018561492e565b82810360608401526158868185614971565b979650505050505050565b6001600160a01b03888116825287811660208301528681166040830152606082018690528416608082015260e060a082018190525f906158d39083018561492e565b82810360c08401526158e58185614971565b9a9950505050505050505050565b604081525f615905604083018561492e565b82810360208401526134f7818561492e565b5f8060408385031215615928575f80fd5b505080516020909101519092909150565b80820281158282048414176105df576105df6152c0565b5f8261596a57634e487b7160e01b5f52601260045260245ffd5b500490565b606081525f615981606083018661492e565b8281036020840152615993818661492e565b905082810360408401526140f08185614971565b601f82111561143657805f5260205f20601f840160051c810160208510156159cc5750805b601f840160051c820191505b818110156159eb575f81556001016159d8565b5050505050565b81516001600160401b03811115615a0b57615a0b614a22565b615a1f81615a19845461533c565b846159a7565b602080601f831160018114615a52575f8415615a3b5750858301515b5f19600386901b1c1916600185901b1785556121f5565b5f85815260208120601f198616915b82811015615a8057888601518255948401946001909101908401615a61565b5085821015615a9d57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f8251615abe818460208701614825565b9190910192915050565b6001600160a01b03868116825285811660208301528416604082015260a0606082018190525f90615afb9083018561492e565b90508260808301529695505050505050565b5f60208284031215615b1d575f80fd5b815163ffffffff81168114611453575f80fd5b5f60208284031215615b40575f80fd5b815161145381614b81565b805161ffff81168114611929575f80fd5b5f805f805f8060c08789031215615b71575f80fd5b8651615b7c816148a7565b6020880151909650615b8d81614b81565b9450615b9b60408801615b4b565b9350606087015160ff81168114615bb0575f80fd5b9250615bbe60808801615b4b565b9150615bcc60a08801614e69565b9050929550929550929556fea6fdc931ca23c69f54119a0a2d6478619b5aa365084590a1fbc287668fbabe00e61f0a7b2953b9e28e48cc07562ad7979478dcaee972e68dcf3b10da2cba6000a2646970667358221220dfdb8d8f19ff02d80c686da25c0898194702e610f7c02b1f98a4981407dab07864736f6c63430008170033

    Deployed Bytecode

    0x608060405234801561000f575f80fd5b5060043610610281575f3560e01c80636f307dc311610156578063aa47f4e1116100ca578063f2c33e2d11610084578063f2c33e2d14610579578063f815c4ff1461059d578063f985b0bc146105a5578063fbfa77cf146105b8578063fdff667c146105c0578063ffa1ad7414610499575f80fd5b8063aa47f4e11461051a578063aefb075114610522578063b600585a14610545578063b6c8cdef14610558578063b9f5be411461055e578063f1faf05014610571575f80fd5b80638a7f53601161011b5780638a7f536014610491578063936725ec146104995780639736374e146104bd57806399f428cf146104c45780639b3ff191146104d7578063a2b7722c14610507575f80fd5b80636f307dc31461045c57806371a97305146104645780637284e4161461047957806374bac4291461048157806380e7ac7c14610489575f80fd5b806341affeb8116101f857806350f4e419116101b257806350f4e419146103df57806359498ab7146103ff5780635b0f088a1461040757806367cf905a1461042b57806367fde573146104335780636d9894391461043b575f80fd5b806341affeb8146103835780634593144c146103965780634875c9681461039e57806348d7d9eb146103a65780634bde38c8146103cf5780634fa5d854146103d7575f80fd5b80631ec71e05116102495780631ec71e05146102f3578063278de000146103095780632a8ba2931461031d5780632d433b281461034e5780632ddbd13a14610371578063394f523214610379575f80fd5b806301ffc9a7146102855780630c56ae3b146102ad57806313e63180146102cd57806316f0115b146102e3578063190024e0146102eb575b5f80fd5b6102986102933660046147fe565b6105d5565b60405190151581526020015b60405180910390f35b6102b56105e5565b6040516001600160a01b0390911681526020016102a4565b6102d5610616565b6040519081526020016102a4565b6102b5610628565b6102d5610647565b6102fb6106e9565b6040516102a4929190614872565b5f80516020615bf9833981519152546102d5565b610341604051806040016040528060058152602001640312e322e360dc1b81525081565b6040516102a49190614895565b61036161035c3660046148bb565b6108b3565b6040516102a494939291906149a0565b6102d5610cac565b610381610cbe565b005b610381610391366004614b8f565b610d51565b6102d56110f3565b610341611126565b6103c1604080515f8082526020820190815281830190925291565b6040516102a4929190614c6d565b6102b561114f565b61038161117e565b6103f26103ed366004614c91565b61143b565b6040516102a49190614ce7565b6103c161145a565b610341604051806040016040528060058152602001640322e302e360dc1b81525081565b6103f26114ec565b6103816115d7565b61044e610449366004614cf9565b6115f3565b6040516102a4929190614d58565b6102b56116f8565b61046c611713565b6040516102a49190614d79565b61034161177c565b610298611899565b6102986118a9565b6103416118bb565b610341604051806040016040528060058152602001640312e302e360dc1b81525081565b6001610298565b6103816104d2366004614d8b565b6118de565b7fa6fdc931ca23c69f54119a0a2d6478619b5aa365084590a1fbc287668fbabe01546001600160a01b03166102b5565b6102d5610515366004614db9565b6118f4565b61046c61192e565b604080518082019091526007815266436c617373696360c81b6020820152610341565b61044e610553366004614cf9565b61199b565b5f610298565b6103f261056c366004614dea565b611a8d565b6102d5611aa0565b610341604051806040016040528060058152602001640c4b8c0b8d60da1b81525081565b6102d5611ab2565b6103f26105b3366004614e01565b611ac4565b6102b5611b6d565b6105c8611b76565b6040516102a49190614e2c565b5f6105df82611be8565b92915050565b5f806105ef611c0c565b9050806080015160018151811061060857610608614e3e565b602002602001015191505090565b5f61061f611c33565b60020154905090565b5f5f80516020615bd98339815191525b546001600160a01b0316919050565b6040805162965fff60e81b60208201525f6023820181905282516006818403018152602683019384905263bfe370d960e01b90935291734f76add676c04eca837130ceb58bc173de8799de9163bfe370d9916106a591602a01614895565b602060405180830381865af41580156106c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106e49190614e52565b905090565b60605f806106f5611c0c565b90505f81608001515f8151811061070e5761070e614e3e565b602002602001015190505f816001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610755573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107799190614e78565b6107e257816001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107dd9190614e9c565b610842565b816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561081e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108429190614e9c565b90505f816001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015610880573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108a79190810190614f17565b965f9650945050505050565b6060806060805f856001600160a01b0316634254af1c6108d16118bb565b805190602001206040518263ffffffff1660e01b81526004016108f691815260200190565b5f60405180830381865afa158015610910573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526109379190810190614f48565b602090810151604080515f80825281850181815282840180855263c45a015560e01b90529251919850919550919350916001600160a01b0389169163c45a0155916044808a019290818b030181865afa158015610996573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ba9190614e9c565b6001600160a01b031663871fd6826040518163ffffffff1660e01b81526004015f60405180830381865afa1580156109f4573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a1b91908101906151f3565b80519091505f805b82811015610af2575f848281518110610a3e57610a3e614e3e565b60200260200101519050805f01515f148015610ad85750734f76add676c04eca837130ceb58bc173de8799de6321a496428260400151610a7c611126565b6040518363ffffffff1660e01b8152600401610a9992919061529c565b602060405180830381865af4158015610ab4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad89190614e78565b15610ae957610ae6836152d4565b92505b50600101610a23565b50806001600160401b03811115610b0b57610b0b614a22565b604051908082528060200260200182016040528015610b3e57816020015b6060815260200190600190039081610b295790505b509750806001600160401b03811115610b5957610b59614a22565b604051908082528060200260200182016040528015610b82578160200160208202803683370190505b5095505f90505f5b82811015610ca0575f848281518110610ba557610ba5614e3e565b60200260200101519050805f01515f148015610c3f5750734f76add676c04eca837130ceb58bc173de8799de6321a496428260400151610be3611126565b6040518363ffffffff1660e01b8152600401610c0092919061529c565b602060405180830381865af4158015610c1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c3f9190614e78565b15610c975781888481518110610c5757610c57614e3e565b602002602001018181525050610c6d8187611c57565b8a8481518110610c7f57610c7f614e3e565b602002602001018190525082610c94906152d4565b92505b50600101610b8a565b50505050509193509193565b5f610cb5611c33565b60010154905090565b610cc6611f42565b73e347a67358dd7cba1eb146b9a60172a10cb8abee63fede401f5f80516020615bf9833981519152610cf661114f565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044015f6040518083038186803b158015610d39575f80fd5b505af4158015610d4b573d5f803e3d5ffd5b50505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f81158015610d955750825b90505f826001600160401b03166001148015610db05750303b155b905081158015610dbe575080155b15610ddc5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610e0657845460ff60401b1916600160401b1785555b87516002141580610e1957508651600114155b80610e245750855115155b15610e42576040516363cf6b6160e01b815260040160405180910390fd5b5f610e7f895f81518110610e5857610e58614e3e565b6020026020010151895f81518110610e7257610e72614e3e565b6020026020010151611fd1565b90508060800151516002141580610e9a575060a08101515115155b80610ea9575060c08101515115155b15610ec7576040516325b769d160e11b815260040160405180910390fd5b610f956040518060a001604052806040518060400160405280600f81526020016e49636869205377617058204661726d60881b81525081526020018b5f81518110610f1457610f14614e3e565b60200260200101516001600160a01b031681526020018b600181518110610f3d57610f3d614e3e565b60200260200101516001600160a01b0316815260200183602001516001600160a01b0316815260200183608001515f81518110610f7c57610f7c614e3e565b60200260200101516001600160a01b03168152506120a7565b610fd1895f81518110610faa57610faa614e3e565b6020026020010151895f81518110610fc457610fc4614e3e565b6020026020010151612171565b5f610fda611713565b905061103182608001515f81518110610ff557610ff5614e3e565b60200260200101515f19835f8151811061101157611011614e3e565b60200260200101516001600160a01b03166121fd9092919063ffffffff16565b61106782608001515f8151811061104a5761104a614e3e565b60200260200101515f198360018151811061101157611011614e3e565b6110a1826080015160018151811061108157611081614e3e565b60200260200101515f1984608001515f8151811061101157611011614e3e565b505083156110e957845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f6106e461112260017f812a673dfca07956350df10f8a654925f561d7a0da09bdbe79e653939a14d9f16152ec565b5490565b60408051808201909152600f81526e49636869205377617058204661726d60881b602082015290565b5f6106e461112260017faa116a42804728f23983458454b6eb9c6ddf3011db9f9addaf3cd7508d85b0d66152ec565b6111866122ba565b61118e6122eb565b5f611197611c33565b805460408051637299470360e11b815281519394506001600160a01b03909216925f92849263e5328e06926004808401938290030181865afa1580156111df573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061120391906152ff565b5090508015611436575f61121561114f565b60088501549091505f808080611229612368565b93509350935093505f6112395f90565b61133d5761126185878151811061125257611252614e3e565b6020026020010151848461271f565b84878151811061127357611273614e3e565b602002602001018181516112879190615329565b915081815250505f73e347a67358dd7cba1eb146b9a60172a10cb8abee6356cd528e898c8e6007018a8a6040518663ffffffff1660e01b81526004016112d19594939291906153ed565b5f60405180830381865af41580156112eb573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611312919081019061543e565b90505f61131f87836127a3565b90508b600101549250801561133657611336612871565b50506113c1565b6040516336ac731760e11b81526001600160a01b038a1690636d58e62e9061136b9088908890600401614c6d565b5f604051808303815f87803b158015611382575f80fd5b505af1158015611394573d5f803e3d5ffd5b505050506113ad855f8151811061125257611252614e3e565b506113b885856127a3565b506113c1612871565b60405163640f244560e01b815273e347a67358dd7cba1eb146b9a60172a10cb8abee9063640f244590611402908d908b908a908a908f90899060040161546f565b5f6040518083038186803b158015611418575f80fd5b505af415801561142a573d5f803e3d5ffd5b50505050505050505050505b505050565b60606114456122ba565b61145084848461290a565b90505b9392505050565b606080611465612982565b604051633f8b51a560e21b8152919350915073e347a67358dd7cba1eb146b9a60172a10cb8abee9063fe2d4694906114a39085908590600401614c6d565b5f60405180830381865af41580156114bd573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114e491908101906154c0565b915091509091565b60605f6114f7611c33565b60068101546040805160028082526060820183529394506001600160a01b039092169290602083019080368337019050509250806001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611566573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061158a9190614e78565b156115bb57670de0b6b3a7640000835f815181106115aa576115aa614e3e565b602002602001018181525050505090565b670de0b6b3a7640000836001815181106115aa576115aa614e3e565b6115df612b57565b6115f06115ea610cac565b30612c72565b50565b60605f8351600114801561163f575061160a611c33565b6006015484516001600160a01b039091169085905f9061162c5761162c614e3e565b60200260200101516001600160a01b0316145b801561167657505f6001600160a01b0316845f8151811061166257611662614e3e565b60200260200101516001600160a01b031614155b156116e257825160011461169d57604051630ef9926760e21b815260040160405180910390fd5b825f815181106116af576116af614e3e565b602002602001015190506116db835f815181106116ce576116ce614e3e565b6020026020010151612e2f565b91506116f1565b6116ec8484612e3a565b915091505b9250929050565b5f611701611c33565b600601546001600160a01b0316919050565b606061171d611c33565b60050180548060200260200160405190810160405280929190818152602001828054801561177257602002820191905f5260205f20905b81546001600160a01b03168152600190910190602001808311611754575b5050505050905090565b60605f80516020615bf98339815191525f80516020615bd98339815191525f6117a361114f565b6001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117de573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118029190614e9c565b835460405163538a85a160e01b81526001600160a01b03929092169163538a85a1916118349160040190815260200190565b5f60405180830381865afa15801561184e573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526118759190810190615515565b60018301549091506118919082906001600160a01b0316611c57565b935050505090565b5f6118a2610cac565b1515919050565b5f806118b3611c0c565b511592915050565b604080518082019091526009815268105b19d9589c98558d60ba1b602082015290565b6118e66122ba565b6118f08282612e47565b5050565b5f6118fd6122ba565b5f611906611c33565b905080600201545f0361191a574260028201555b611925836001612f2f565b9150505b919050565b60605f80516020615bf983398151915260010180548060200260200160405190810160405280929190818152602001828054801561177257602002820191905f5260205f209081546001600160a01b03168152600190910190602001808311611754575050505050905090565b60605f835160011480156119e757506119b2611c33565b6006015484516001600160a01b039091169085905f906119d4576119d4614e3e565b60200260200101516001600160a01b0316145b8015611a1e57505f6001600160a01b0316845f81518110611a0a57611a0a614e3e565b60200260200101516001600160a01b031614155b15611a83578251600114611a4557604051630ef9926760e21b815260040160405180910390fd5b825f81518110611a5757611a57614e3e565b602002602001015190506116db835f81518110611a7657611a76614e3e565b60200260200101516130a2565b6116ec8484613218565b6060611a976122ba565b6105df82613292565b5f611aa9611c33565b60040154905090565b5f611abb611c33565b60030154905090565b6060611ace6122ba565b73e347a67358dd7cba1eb146b9a60172a10cb8abee6325567aef611af0611c33565b6040516001600160e01b031960e084901b168152600481019190915260248101879052604481018690526001600160a01b03851660648201526084015f60405180830381865af4158015611b46573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611450919081019061543e565b5f610638611c33565b604080516001808252818301909252606091816020015b6060815260200190600190039081611b8d5790505090506040518060400160405280600b81526020016a436f6d706f756e64696e6760a81b815250815f81518110611bda57611bda614e3e565b602002602001018190525090565b5f6001600160e01b031982166396cf43c560e01b14806105df57506105df8261334e565b611c1461474c565b6106e4611c1f61114f565b5f80516020615bf983398151915254611fd1565b7fb14b643f49bed6a2c6693bbd50f68dc950245db265c66acadbfa51ccc8c3ba0090565b6060734f76add676c04eca837130ceb58bc173de8799de631dfab928734f76add676c04eca837130ceb58bc173de8799de63fbcadbe986606001516040518263ffffffff1660e01b8152600401611cae9190614d79565b5f60405180830381865af4158015611cc8573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611cef9190810190615546565b6040518263ffffffff1660e01b8152600401611d0b919061562d565b5f60405180830381865af4158015611d25573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611d4c9190810190614f17565b602084015160405163a912616960e01b81526001600160a01b039182166004820152734f76add676c04eca837130ceb58bc173de8799de91631dfab92891839163fbcadbe9919088169063a9126169906024015f60405180830381865afa158015611db9573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611de09190810190615663565b6040518263ffffffff1660e01b8152600401611dfc9190614d79565b5f60405180830381865af4158015611e16573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e3d9190810190615546565b6040518263ffffffff1660e01b8152600401611e599190615694565b5f60405180830381865af4158015611e73573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611e9a9190810190614f17565b84608001515f81518110611eb057611eb0614e3e565b60200260200101516001600160a01b03166395d89b416040518163ffffffff1660e01b81526004015f60405180830381865afa158015611ef2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f199190810190614f17565b604051602001611f2b939291906156c9565b604051602081830303815290604052905092915050565b611f4a61114f565b6040516336b87bd760e11b81523360048201526001600160a01b039190911690636d70f7ae90602401602060405180830381865afa158015611f8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611fb29190614e78565b611fcf57604051631f0853c160e21b815260040160405180910390fd5b565b611fd961474c565b826001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015612015573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120399190614e9c565b6001600160a01b031663538a85a1836040518263ffffffff1660e01b815260040161206691815260200190565b5f60405180830381865afa158015612080573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526114539190810190615515565b6120af613372565b5f5f80516020615bd9833981519152905060605f73f732df3f82d1ce0234bf5ee6933fd370b8b30f2a638ff2a774848660200151876120ec6118bb565b6040518563ffffffff1660e01b815260040161210b949392919061575c565b5f60405180830381865af4158015612125573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261214c91908101906157d2565b8092508193505050610d4b8460200151855f01518660400151858860800151866133bb565b612179613372565b73e347a67358dd7cba1eb146b9a60172a10cb8abee634ab3b02f5f80516020615bf98339815191526121a9611c33565b60070185856040518563ffffffff1660e01b81526004016121cd9493929190615815565b5f6040518083038186803b1580156121e3575f80fd5b505af41580156121f5573d5f803e3d5ffd5b505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905261224e848261345f565b610d4b576040516001600160a01b0384811660248301525f60448301526122b091869182169063095ea7b3906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050613500565b610d4b8482613500565b6122c2611c33565b546001600160a01b03163314611fcf576040516362df054560e01b815260040160405180910390fd5b306001600160a01b03166374bac4296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612327573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061234b9190614e78565b611fcf576040516309ea311f60e11b815260040160405180910390fd5b606080606080612376611713565b935083516001600160401b0381111561239157612391614a22565b6040519080825280602002602001820160405280156123ba578160200160208202803683370190505b507fe61f0a7b2953b9e28e48cc07562ad7979478dcaee972e68dcf3b10da2cba60018054604080516020808402820181019092528281529396505f80516020615bf98339815191529392919083018282801561243d57602002820191905f5260205f20905b81546001600160a01b0316815260019091019060200180831161241f575b505050505092505f73e347a67358dd7cba1eb146b9a60172a10cb8abee63e3d670d7855f8151811061247157612471614e3e565b60200260200101516040518263ffffffff1660e01b81526004016124a491906001600160a01b0391909116815260200190565b602060405180830381865af41580156124bf573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124e39190614e52565b604080516001808252818301909252919250602080830190803683370190505092505f61250e611c0c565b90505f816080015160018151811061252857612528614e3e565b60200260200101516001600160a01b0316637c91e4eb6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561256b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061258f9190614e9c565b6040805160018082528183019092529192505f91906020808301908036833701905050905082608001516001815181106125cb576125cb614e3e565b6020026020010151815f815181106125e5576125e5614e3e565b6001600160a01b03928316602091820292909201015260405163f9f031df60e01b81529083169063f9f031df90612620908490600401614d79565b5f604051808303815f87803b158015612637575f80fd5b505af1158015612649573d5f803e3d5ffd5b505050508373e347a67358dd7cba1eb146b9a60172a10cb8abee63e3d670d7895f8151811061267a5761267a614e3e565b60200260200101516040518263ffffffff1660e01b81526004016126ad91906001600160a01b0391909116815260200190565b602060405180830381865af41580156126c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ec9190614e52565b6126f691906152ec565b865f8151811061270857612708614e3e565b602002602001018181525050505050505090919293565b5f73e347a67358dd7cba1eb146b9a60172a10cb8abee6374e714c861274261114f565b8686866040518563ffffffff1660e01b81526004016127649493929190615849565b602060405180830381865af415801561277f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114509190614e52565b5f5f80516020615bd983398151915273f732df3f82d1ce0234bf5ee6933fd370b8b30f2a6372d46b086127d461114f565b6127dc611b6d565b60018501546001600160a01b03166127f2611c33565b6008015486546040516001600160e01b031960e088901b16815261282a95949392916001600160a01b0316908c908c90600401615891565b602060405180830381865af4158015612845573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128699190614e78565b949350505050565b5f61287a6114ec565b90505f61289f825f8151811061289257612892614e3e565b6020026020010151613566565b90506001815f815181106128b5576128b5614e3e565b602002602001015111806128e357506001816001815181106128d9576128d9614e3e565b6020026020010151115b156118f0575f6128f282613616565b9092509050600a81111561143657610d4b825f612f2f565b606073f732df3f82d1ce0234bf5ee6933fd370b8b30f2a639dfc419f8561292f611713565b6040518363ffffffff1660e01b815260040161294c9291906158f3565b5f6040518083038186803b158015612962575f80fd5b505af4158015612974573d5f803e3d5ffd5b505050506114508383612c72565b6060805f61298e611c33565b600581018054604080516020808402820181019092528281529394508301828280156129e157602002820191905f5260205f20905b81546001600160a01b031681526001909101906020018083116129c3575b505050506001830154600684015460408051636253bb0f60e11b8152815195985092946001600160a01b0390921693505f928392859263c4a7761e92600480820193918290030181865afa158015612a3b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a5f9190615917565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612aa0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ac49190614e52565b604080516002808252606082018352929350919060208301908036833701905050965080612af28685615939565b612afc9190615950565b875f81518110612b0e57612b0e614e3e565b602090810291909101015280612b248684615939565b612b2e9190615950565b87600181518110612b4157612b41614e3e565b6020026020010181815250505050505050509091565b5f612b6061114f565b9050336001600160a01b0316816001600160a01b0316635aa6e6756040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ba8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612bcc9190614e9c565b6001600160a01b031614158015612c545750336001600160a01b0316816001600160a01b0316634783c35b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612c24573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612c489190614e9c565b6001600160a01b031614155b156115f0576040516354299b6f60e01b815260040160405180910390fd5b60605f612c7d611c0c565b90508060800151600181518110612c9657612c96614e3e565b60200260200101516001600160a01b0316632e1a7d4d856040518263ffffffff1660e01b8152600401612ccb91815260200190565b5f604051808303815f87803b158015612ce2575f80fd5b505af1158015612cf4573d5f803e3d5ffd5b5060029250612d01915050565b604051908082528060200260200182016040528015612d2a578160200160208202803683370190505b50915080608001515f81518110612d4357612d43614e3e565b60200260200101516001600160a01b031662f714ce85856040518363ffffffff1660e01b8152600401612d899291909182526001600160a01b0316602082015260400190565b60408051808303815f875af1158015612da4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612dc89190615917565b835f81518110612dda57612dda614e3e565b6020026020010184600181518110612df457612df4614e3e565b6020908102919091010191909152525f612e0c611c33565b905084816001015f828254612e2191906152ec565b909155509295945050505050565b60606105df826130a2565b60605f6116ec8484613218565b5f612e50611c0c565b90508060800151600181518110612e6957612e69614e3e565b60200260200101516001600160a01b0316632e1a7d4d846040518263ffffffff1660e01b8152600401612e9e91815260200190565b5f604051808303815f87803b158015612eb5575f80fd5b505af1158015612ec7573d5f803e3d5ffd5b50505050612f06828483608001515f81518110612ee657612ee6614e3e565b60200260200101516001600160a01b0316613d409092919063ffffffff16565b5f612f0f611c33565b905083816001015f828254612f2491906152ec565b909155505050505050565b5f80612f39611c0c565b905080608001515f81518110612f5157612f51614e3e565b60200260200101516001600160a01b0316638dbdbe6d855f81518110612f7957612f79614e3e565b602002602001015186600181518110612f9457612f94614e3e565b60209081029190910101516040516001600160e01b031960e085901b168152600481019290925260248201523060448201526064016020604051808303815f875af1158015612fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130099190614e52565b9150806080015160018151811061302257613022614e3e565b60200260200101516001600160a01b031663b6b55f25836040518263ffffffff1660e01b815260040161305791815260200190565b5f604051808303815f87803b15801561306e575f80fd5b505af1158015613080573d5f803e3d5ffd5b505050505f61308d611c33565b905082816001015f828254612e219190615329565b60605f6130ad611c33565b600681015460408051636253bb0f60e11b815281519394506001600160a01b03909216925f928392859263c4a7761e9260048082019392918290030181865afa1580156130fc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131209190615917565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613161573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131859190614e52565b6040805160028082526060820183529293509190602083019080368337019050509550806131b38885615939565b6131bd9190615950565b865f815181106131cf576131cf614e3e565b6020908102919091010152806131e58884615939565b6131ef9190615950565b8660018151811061320257613202614e3e565b6020026020010181815250505050505050919050565b60605f73f732df3f82d1ce0234bf5ee6933fd370b8b30f2a639d186c788561323e611713565b866040518463ffffffff1660e01b815260040161325d9392919061596f565b5f6040518083038186803b158015613273575f80fd5b505af4158015613285573d5f803e3d5ffd5b505050506116ec83613616565b60605f61329d611c0c565b905080608001516001815181106132b6576132b6614e3e565b60200260200101516001600160a01b031663b6b55f25846040518263ffffffff1660e01b81526004016132eb91815260200190565b5f604051808303815f87803b158015613302575f80fd5b505af1158015613314573d5f803e3d5ffd5b50505050613321836130a2565b91505f61332c611c33565b905083816001015f8282546133419190615329565b9091555092949350505050565b5f6001600160e01b031982166303d859d560e11b14806105df57506105df82613d71565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff16611fcf57604051631afcd79f60e31b815260040160405180910390fd5b6133c3613372565b6133cc86613d95565b5f6133d5611c33565b600881018390556006810180546001600160a01b0319166001600160a01b03861617905584519091508690869086908690869060078701905f908890829061342690600584019060208a0190614790565b5081546001600160a01b03808a166101009390930a928302920219161790555061345086826159f2565b50505050505050505050505050565b5f805f846001600160a01b03168460405161347a9190615aad565b5f604051808303815f865af19150503d805f81146134b3576040519150601f19603f3d011682016040523d82523d5f602084013e6134b8565b606091505b50915091508180156134e25750805115806134e25750808060200190518101906134e29190614e78565b80156134f757505f856001600160a01b03163b115b95945050505050565b5f6135146001600160a01b03841683613ef0565b905080515f141580156135385750808060200190518101906135369190614e78565b155b1561143657604051635274afe760e01b81526001600160a01b03841660048201526024015b60405180910390fd5b60605f80516020615bd983398151915273f732df3f82d1ce0234bf5ee6933fd370b8b30f2a633f9406db61359861114f565b600184015484546001600160a01b0391821691166135b4611713565b886040518663ffffffff1660e01b81526004016135d5959493929190615ac8565b5f60405180830381865af41580156135ef573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611925919081019061543e565b60605f80613622611c33565b60068101546040805160028082526060820183529394506001600160a01b039092169290602083019080368337019050509350806001600160a01b0316637f7a1eec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613691573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136b59190614e78565b156136f757845f815181106136cc576136cc614e3e565b6020026020010151845f815181106136e6576136e6614e3e565b602002602001018181525050613732565b8460018151811061370a5761370a614e3e565b60200260200101518460018151811061372557613725614e3e565b6020026020010181815250505b60408051610140810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810191909152816001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156137be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137e29190614e9c565b8160e001906001600160a01b031690816001600160a01b031681525050816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561383b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061385f9190614e9c565b8161010001906001600160a01b031690816001600160a01b031681525050816001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156138b9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138dd9190614e9c565b8161012001906001600160a01b031690816001600160a01b031681525050816001600160a01b031663f62073266040518163ffffffff1660e01b8152600401602060405180830381865afa158015613937573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061395b9190615b0d565b63ffffffff16815260408051630dfe168160e01b81529051613a9d916001600160a01b03851691630dfe1681916004808201926020929091908290030181865afa1580156139ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139cf9190614e9c565b836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a0b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a2f9190614e9c565b846001600160a01b031663065e53606040518163ffffffff1660e01b8152600401602060405180830381865afa158015613a6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613a8f9190615b30565b670de0b6b3a7640000613efd565b604082015260e08101516101008201516101208301518351613aca93929190670de0b6b3a7640000613f12565b816060018181525050816001600160a01b03166391563d326040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b339190615b0d565b63ffffffff1660208201819052613b4e578060600151613b75565b613b758160e001518261010001518361012001518460200151670de0b6b3a7640000613f12565b8160800181815250505f80836001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa158015613bbb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bdf9190615917565b915091505f613c018460400151856060015186608001515f8860200151613fcd565b90505f670de0b6b3a7640000828a5f81518110613c2057613c20614e3e565b6020026020010151613c329190615939565b613c3c9190615950565b90508089600181518110613c5257613c52614e3e565b6020026020010151613c649190615329565b97505f866001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613ca3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613cc79190614e52565b90508015613d33575f613cee87604001518860600151896080015160018b60200151613fcd565b90505f670de0b6b3a7640000613d048389615939565b613d0e9190615950565b9050613d1a8682615329565b613d24848d615939565b613d2e9190615950565b9a5050505b5050505050505050915091565b6040516001600160a01b0383811660248301526044820183905261143691859182169063a9059cbb9060640161227e565b5f6001600160e01b031982166342c352d360e11b14806105df57506105df8261402d565b613d9d613372565b6001600160a01b0381161580613e2357505f6001600160a01b0316816001600160a01b0316634783c35b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613df4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e189190614e9c565b6001600160a01b0316145b15613e41576040516371c42ac360e01b815260040160405180910390fd5b613e74613e6f60017faa116a42804728f23983458454b6eb9c6ddf3011db9f9addaf3cd7508d85b0d66152ec565b829055565b613ea643613ea360017f812a673dfca07956350df10f8a654925f561d7a0da09bdbe79e653939a14d9f16152ec565b55565b604080516001600160a01b0383168152426020820152438183015290517f1a2dd071001ebf6e03174e3df5b305795a4ad5d41d8fdb9ba41dbbe2367134269181900360600190a150565b606061145383835f614061565b5f6134f783613f0b846140fa565b8787614131565b5f80613f1d876144e5565b604051638241348960e01b81526001600160a01b038216600482015263ffffffff861660248201529091505f9073e3c14573ccd72f95a739f297dcfa8d525aa330ac90638241348990604401602060405180830381865af4158015613f84573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fa89190615b30565b60020b9050613fc181613fba866140fa565b8989614131565b98975050505050505050565b5f82156140045763ffffffff821615613ffa57613ff3613fed8787614597565b85614597565b90506134f7565b613ff38686614597565b63ffffffff82161561402357613ff361401d87876145ac565b856145ac565b613ff386866145ac565b5f6001600160e01b03198216630f1ec81f60e41b14806105df57506301ffc9a760e01b6001600160e01b03198316146105df565b6060814710156140865760405163cd78605960e01b815230600482015260240161355d565b5f80856001600160a01b031684866040516140a19190615aad565b5f6040518083038185875af1925050503d805f81146140db576040519150601f19603f3d011682016040523d82523d5f602084013e6140e0565b606091505b50915091506140f08683836145ba565b9695505050505050565b5f6001600160801b0382111561412d576040516306dfcc6560e41b8152608060048201526024810183905260440161355d565b5090565b60405163986cfba360e01b8152600285900b60048201525f90819073bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063986cfba390602401602060405180830381865af4158015614186573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906141aa9190614e9c565b90506001600160801b036001600160a01b03821611614315575f6141d76001600160a01b03831680615939565b9050836001600160a01b0316856001600160a01b0316106142825760405163554d048960e11b8152600160c01b60048201526001600160801b03871660248201526044810182905273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af4158015614259573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061427d9190614e52565b61430d565b60405163554d048960e11b8152600481018290526001600160801b0387166024820152600160c01b604482015273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af41580156142e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061430d9190614e52565b9250506144dc565b60405163554d048960e11b81526001600160a01b038216600482018190526024820152600160401b60448201525f9073bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af415801561437e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906143a29190614e52565b9050836001600160a01b0316856001600160a01b03161061444d5760405163554d048960e11b8152600160801b60048201526001600160801b03871660248201526044810182905273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af4158015614424573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144489190614e52565b6144d8565b60405163554d048960e11b8152600481018290526001600160801b0387166024820152600160801b604482015273bbc63ee4a06bf1f2432ccc4d70103e3d465fca399063aa9a091290606401602060405180830381865af41580156144b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144d89190614e52565b9250505b50949350505050565b5f816001600160a01b031663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015614522573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145469190614e9c565b90506145528183614616565b6119295760405162461bcd60e51b815260206004820152601660248201527524ab1d103234b1b7b73732b1ba32b21038363ab3b4b760511b604482015260640161355d565b5f8183116145a55781611453565b5090919050565b5f8183106145a55781611453565b6060826145cf576145ca82614723565b611453565b81511580156145e657506001600160a01b0384163b155b1561460f57604051639996b31560e01b81526001600160a01b038516600482015260240161355d565b5080611453565b5f6001600160a01b03831661462c57505f6105df565b5f829050806001600160a01b031663ef01df4f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561466c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146909190614e9c565b6001600160a01b0316846001600160a01b03160361471c575f816001600160a01b031663e76c01e46040518163ffffffff1660e01b815260040160c060405180830381865afa1580156146e5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906147099190615b5c565b505093505050506134f781600116151590565b5092915050565b8051156147335780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b6040518060e001604052805f81526020015f6001600160a01b0316815260200160608152602001606081526020016060815260200160608152602001606081525090565b828054828255905f5260205f209081019282156147e3579160200282015b828111156147e357825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147ae565b5061412d9291505b8082111561412d575f81556001016147eb565b5f6020828403121561480e575f80fd5b81356001600160e01b031981168114611453575f80fd5b5f5b8381101561483f578181015183820152602001614827565b50505f910152565b5f815180845261485e816020860160208601614825565b601f01601f19169290920160200192915050565b604081525f6148846040830185614847565b905082151560208301529392505050565b602081525f6114536020830184614847565b6001600160a01b03811681146115f0575f80fd5b5f602082840312156148cb575f80fd5b8135611453816148a7565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561492157601f1986840301895261490f838351614847565b988401989250908301906001016148f3565b5090979650505050505050565b5f815180845260208085019450602084015f5b838110156149665781516001600160a01b031687529582019590820190600101614941565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561496657815187529582019590820190600101614984565b608081525f6149b260808301876148d6565b602083820360208501526149c6828861492e565b915083820360408501526149da8287614971565b8481036060860152855180825260208088019450909101905f5b81811015614a1357845160020b835293830193918301916001016149f4565b50909998505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b0381118282101715614a5857614a58614a22565b60405290565b604051601f8201601f191681016001600160401b0381118282101715614a8657614a86614a22565b604052919050565b5f6001600160401b03821115614aa657614aa6614a22565b5060051b60200190565b5f82601f830112614abf575f80fd5b81356020614ad4614acf83614a8e565b614a5e565b8083825260208201915060208460051b870101935086841115614af5575f80fd5b602086015b84811015614b1a578035614b0d816148a7565b8352918301918301614afa565b509695505050505050565b5f82601f830112614b34575f80fd5b81356020614b44614acf83614a8e565b8083825260208201915060208460051b870101935086841115614b65575f80fd5b602086015b84811015614b1a5780358352918301918301614b6a565b8060020b81146115f0575f80fd5b5f805f60608486031215614ba1575f80fd5b83356001600160401b0380821115614bb7575f80fd5b614bc387838801614ab0565b9450602091508186013581811115614bd9575f80fd5b614be588828901614b25565b945050604086013581811115614bf9575f80fd5b86019050601f81018713614c0b575f80fd5b8035614c19614acf82614a8e565b81815260059190911b82018301908381019089831115614c37575f80fd5b928401925b82841015614c5e578335614c4f81614b81565b82529284019290840190614c3c565b80955050505050509250925092565b604081525f614c7f604083018561492e565b82810360208401526134f78185614971565b5f805f60608486031215614ca3575f80fd5b83356001600160401b03811115614cb8575f80fd5b614cc486828701614ab0565b935050602084013591506040840135614cdc816148a7565b809150509250925092565b602081525f6114536020830184614971565b5f8060408385031215614d0a575f80fd5b82356001600160401b0380821115614d20575f80fd5b614d2c86838701614ab0565b93506020850135915080821115614d41575f80fd5b50614d4e85828601614b25565b9150509250929050565b604081525f614d6a6040830185614971565b90508260208301529392505050565b602081525f611453602083018461492e565b5f8060408385031215614d9c575f80fd5b823591506020830135614dae816148a7565b809150509250929050565b5f60208284031215614dc9575f80fd5b81356001600160401b03811115614dde575f80fd5b61286984828501614b25565b5f60208284031215614dfa575f80fd5b5035919050565b5f805f60608486031215614e13575f80fd5b83359250602084013591506040840135614cdc816148a7565b602081525f61145360208301846148d6565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215614e62575f80fd5b5051919050565b80518015158114611929575f80fd5b5f60208284031215614e88575f80fd5b61145382614e69565b8051611929816148a7565b5f60208284031215614eac575f80fd5b8151611453816148a7565b5f82601f830112614ec6575f80fd5b81516001600160401b03811115614edf57614edf614a22565b614ef2601f8201601f1916602001614a5e565b818152846020838601011115614f06575f80fd5b612869826020830160208701614825565b5f60208284031215614f27575f80fd5b81516001600160401b03811115614f3c575f80fd5b61286984828501614eb7565b5f60208284031215614f58575f80fd5b81516001600160401b0380821115614f6e575f80fd5b9083019060408286031215614f81575f80fd5b604051604081018181108382111715614f9c57614f9c614a22565b604052825182811115614fad575f80fd5b614fb987828601614eb7565b82525060208301519250614fcc836148a7565b6020810192909252509392505050565b5f82601f830112614feb575f80fd5b81516020614ffb614acf83614a8e565b8083825260208201915060208460051b87010193508684111561501c575f80fd5b602086015b84811015614b1a578051615034816148a7565b8352918301918301615021565b5f82601f830112615050575f80fd5b81516020615060614acf83614a8e565b8083825260208201915060208460051b870101935086841115615081575f80fd5b602086015b84811015614b1a5780518352918301918301615086565b5f82601f8301126150ac575f80fd5b815160206150bc614acf83614a8e565b8083825260208201915060208460051b8701019350868411156150dd575f80fd5b602086015b84811015614b1a5780516150f581614b81565b83529183019183016150e2565b5f60e08284031215615112575f80fd5b61511a614a36565b90508151815261512c60208301614e91565b602082015260408201516001600160401b038082111561514a575f80fd5b61515685838601614eb7565b6040840152606084015191508082111561516e575f80fd5b61517a85838601614fdc565b60608401526080840151915080821115615192575f80fd5b61519e85838601614fdc565b608084015260a08401519150808211156151b6575f80fd5b6151c285838601615041565b60a084015260c08401519150808211156151da575f80fd5b506151e78482850161509d565b60c08301525092915050565b5f6020808385031215615204575f80fd5b82516001600160401b038082111561521a575f80fd5b818501915085601f83011261522d575f80fd5b815161523b614acf82614a8e565b81815260059190911b83018401908481019088831115615259575f80fd5b8585015b8381101561528f57805185811115615273575f80fd5b6152818b89838a0101615102565b84525091860191860161525d565b5098975050505050505050565b604081525f6152ae6040830185614847565b82810360208401526134f78185614847565b634e487b7160e01b5f52601160045260245ffd5b5f600182016152e5576152e56152c0565b5060010190565b818103818111156105df576105df6152c0565b5f8060408385031215615310575f80fd5b8251915061532060208401614e69565b90509250929050565b808201808211156105df576105df6152c0565b600181811c9082168061535057607f821691505b60208210810361536e57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f81546153808161533c565b80855260206001838116801561539d57600181146153b7576153e2565b60ff1985168884015283151560051b8801830195506153e2565b865f52825f205f5b858110156153da5781548a82018601529083019084016153bf565b890184019650505b505050505092915050565b6001600160a01b0386811682528516602082015260a0604082018190525f9061541890830186615374565b828103606084015261542a818661492e565b90508281036080840152613fc18185614971565b5f6020828403121561544e575f80fd5b81516001600160401b03811115615463575f80fd5b61286984828501615041565b8681526001600160a01b038616602082015260c0604082018190525f906154989083018761492e565b82810360608401526154aa8187614971565b6080840195909552505060a00152949350505050565b5f80604083850312156154d1575f80fd5b82516001600160401b03808211156154e7575f80fd5b6154f386838701614fdc565b93506020850151915080821115615508575f80fd5b50614d4e85828601615041565b5f60208284031215615525575f80fd5b81516001600160401b0381111561553a575f80fd5b61286984828501615102565b5f6020808385031215615557575f80fd5b82516001600160401b038082111561556d575f80fd5b818501915085601f830112615580575f80fd5b815161558e614acf82614a8e565b81815260059190911b830184019084810190888311156155ac575f80fd5b8585015b8381101561528f578051858111156155c6575f80fd5b6155d48b89838a0101614eb7565b8452509186019186016155b0565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561492157601f1986840301895261561b838351614847565b988401989250908301906001016155ff565b604081525f61563f60408301846155e2565b82810360208401526002815261016160f51b60208201526040810191505092915050565b5f60208284031215615673575f80fd5b81516001600160401b03811115615688575f80fd5b61286984828501614fdc565b604081525f6156a660408301846155e2565b828103602084015260018152602d60f81b60208201526040810191505092915050565b64022b0b937160dd1b81525f84516156e8816005850160208901614825565b7f20616e642066656573206f6e20537761705820706f6f6c200000000000000000600591840191820152845161572581601d840160208901614825565b68010313c9024b1b434960bd1b601d9290910191820152835161574f816026840160208801614825565b0160260195945050505050565b8481525f60018060a01b03808616602084015260806040840152845160a0608085015261578d610120850182614847565b90508160208701511660a08501528160408701511660c08501528160608701511660e0850152816080870151166101008501528381036060850152613fc18186614847565b5f80604083850312156157e3575f80fd5b82516001600160401b038111156157f8575f80fd5b61580485828601614fdc565b925050602083015190509250929050565b848152608060208201525f61582d6080830186615374565b6001600160a01b03949094166040830152506060015292915050565b6001600160a01b038581168252841660208201526080604082018190525f906158749083018561492e565b82810360608401526158868185614971565b979650505050505050565b6001600160a01b03888116825287811660208301528681166040830152606082018690528416608082015260e060a082018190525f906158d39083018561492e565b82810360c08401526158e58185614971565b9a9950505050505050505050565b604081525f615905604083018561492e565b82810360208401526134f7818561492e565b5f8060408385031215615928575f80fd5b505080516020909101519092909150565b80820281158282048414176105df576105df6152c0565b5f8261596a57634e487b7160e01b5f52601260045260245ffd5b500490565b606081525f615981606083018661492e565b8281036020840152615993818661492e565b905082810360408401526140f08185614971565b601f82111561143657805f5260205f20601f840160051c810160208510156159cc5750805b601f840160051c820191505b818110156159eb575f81556001016159d8565b5050505050565b81516001600160401b03811115615a0b57615a0b614a22565b615a1f81615a19845461533c565b846159a7565b602080601f831160018114615a52575f8415615a3b5750858301515b5f19600386901b1c1916600185901b1785556121f5565b5f85815260208120601f198616915b82811015615a8057888601518255948401946001909101908401615a61565b5085821015615a9d57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f8251615abe818460208701614825565b9190910192915050565b6001600160a01b03868116825285811660208301528416604082015260a0606082018190525f90615afb9083018561492e565b90508260808301529695505050505050565b5f60208284031215615b1d575f80fd5b815163ffffffff81168114611453575f80fd5b5f60208284031215615b40575f80fd5b815161145381614b81565b805161ffff81168114611929575f80fd5b5f805f805f8060c08789031215615b71575f80fd5b8651615b7c816148a7565b6020880151909650615b8d81614b81565b9450615b9b60408801615b4b565b9350606087015160ff81168114615bb0575f80fd5b9250615bbe60808801615b4b565b9150615bcc60a08801614e69565b9050929550929550929556fea6fdc931ca23c69f54119a0a2d6478619b5aa365084590a1fbc287668fbabe00e61f0a7b2953b9e28e48cc07562ad7979478dcaee972e68dcf3b10da2cba6000a2646970667358221220dfdb8d8f19ff02d80c686da25c0898194702e610f7c02b1f98a4981407dab07864736f6c63430008170033

    Block Age Transaction Gas Used Reward
    view all blocks ##produced##

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

    Validator Index Block Age Amount
    View All Withdrawals

    Transaction Hash Block Age Value Eth2 PubKey Valid
    View All Deposits

    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.