S Price: $0.511674 (+1.42%)

Contract

0xBAe5dc9B19004883d0377419FeF3c2C8832d7d7B

Overview

S Balance

Sonic LogoSonic LogoSonic Logo0 S

S Value

$0.00

Multichain Info

No addresses found
Amount:Between 1-100k
Reset Filter

Transaction Hash
Method
Block
From
To

There are no matching entries

Update your filters to view other transactions

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

Contract Source Code Verified (Exact Match)

Contract Name:
PriceGetterBackwardsCompatible

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 14 : PriceGetterBackwardsCompatible.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.16;

import "./PriceGetter.sol";

/**
VERSION: 3.0

DISCLAIMER: 
This smart contract is provided for user interface purposes only and is not intended to be used for smart contract logic. 
Any attempt to rely on this code for the execution of a smart contract may result in unexpected behavior, 
errors, or other issues that could lead to financial loss or other damages. 
The user assumes all responsibility and risk for proper usage. 
The developer and associated parties make no warranties and are not liable for any damages incurred.
*/

contract PriceGetterBackwardsCompatible is PriceGetter {
    // ========== Get Token Prices ==========

    /**
     * @dev Returns the price of a token from a specific factory based on the protocol.
     * @param token The address of the token for which the price is requested.
     * @param protocol The protocol version to use for the price retrieval.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @return price The price of the token in USD.
     */
    function getPriceFromFactory(
        address token,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly
    ) public view returns (uint256 price) {
        return _getPriceFromFactory(token, protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, address(0));
    }

    /**
     * @dev Returns the price of a token from a specific factory based on the protocol.
     * @param token The address of the token for which the price is requested.
     * @param protocol The protocol version to use for the price retrieval.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @param factoryXFAI The address of the XFAI factory.
     * @return price The price of the token in USD.
     */
    function getPriceFromFactory(
        address token,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) public view returns (uint256 price) {
        return _getPriceFromFactory(token, protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, factoryXFAI);
    }

    function _getPriceFromFactory(
        address token,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) internal view returns (uint256 price) {
        if (protocol == Protocol.___) {
            uint256 priceV2 = getTokenPrice(token, Protocol.UniV2, factoryV2);
            uint256 priceV3 = getTokenPrice(token, Protocol.UniV3, factoryV3);
            return (priceV2 + priceV3) / 2;
        } else if (protocol == Protocol.UniV2) {
            return getTokenPrice(token, protocol, factoryV2);
        } else if (protocol == Protocol.UniV3) {
            return getTokenPrice(token, protocol, factoryV3);
        } else if (protocol == Protocol.Algebra) {
            return getTokenPrice(token, protocol, factoryAlgebra);
        } else if (protocol == Protocol.Solidly) {
            return getTokenPrice(token, protocol, factorySolidly);
        } else if (protocol == Protocol.Xfai) {
            return getTokenPrice(token, protocol, factoryXFAI);
        } else if (protocol == Protocol.Curve) {
            return getTokenPrice(token, protocol, factoryV2);
        } else {
            revert("Invalid");
        }
    }

    // ========== Get LP Prices ==========

    /**
     * @dev Returns the price of an LP token from a specific protocol and factory.
     * @param lp The address of the LP token for which the price is requested.
     * @param protocol The protocol version to use.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @return lpPrice The current price of the LP token.
     */
    function getLPPriceFromFactory(
        address lp,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly
    ) public view returns (uint256 lpPrice) {
        return _getLPPriceFromFactory(lp, protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, address(0));
    }

    /**
     * @dev Returns the price of an LP token from a specific protocol and factory.
     * @param lp The address of the LP token for which the price is requested.
     * @param protocol The protocol version to use.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @param factoryXFAI The address of the XFAI factory.
     * @return lpPrice The current price of the LP token.
     */
    function getLPPriceFromFactory(
        address lp,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) public view returns (uint256 lpPrice) {
        return _getLPPriceFromFactory(lp, protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, factoryXFAI);
    }

    function _getLPPriceFromFactory(
        address lp,
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) internal view returns (uint256 lpPrice) {
        if (protocol == Protocol.___) {
            revert("LP can't be both");
        } else if (protocol == Protocol.UniV2) {
            return getLPPrice(lp, protocol, factoryV2);
        } else if (protocol == Protocol.UniV3) {
            return getLPPrice(lp, protocol, factoryV3);
        } else if (protocol == Protocol.Algebra) {
            return getLPPrice(lp, protocol, factoryAlgebra);
        } else if (protocol == Protocol.Solidly) {
            return getLPPrice(lp, protocol, factorySolidly);
        } else if (protocol == Protocol.Xfai) {
            return getLPPrice(lp, protocol, factoryXFAI);
        } else if (protocol == Protocol.Curve) {
            return getLPPrice(lp, protocol, factoryV2);
        } else if (protocol == Protocol._Gamma) {
            //This does not make sense, it's just for backwards compatibility. Gamma was used for all Algebra wrappers
            return getWrappedLPPrice(lp, Protocol.Algebra, factoryAlgebra, Wrappers.Gamma);
        } else if (protocol == Protocol._Steer) {
            //This does not make sense, it's just for backwards compatibility. Steer was used for all UniV3 wrappers
            return getWrappedLPPrice(lp, Protocol.UniV3, factoryV3, Wrappers.Gamma);
        } else if (protocol == Protocol.Curve) {
            return getLPPrice(lp, protocol, factoryV2);
        } else {
            revert("Invalid");
        }
    }

    // ========== Get Native Prices ==========

    /**
     * @dev Returns the current price of wNative in USD based on the given protocol and time delta.
     * @param protocol The protocol version to use.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @return nativePrice The current price of wNative in USD.
     */
    function getNativePriceFromFactory(
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly
    ) public view returns (uint256 nativePrice) {
        return _getNativePriceFromFactory(protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, address(0));
    }

    /**
     * @dev Returns the current price of wNative in USD based on the given protocol and time delta.
     * This function is an extension of the original `getNativePriceFromFactory` to include support for XFAI protocol.
     * @param protocol The protocol version to use.
     * @param factoryV2 The address of the V2 factory.
     * @param factoryV3 The address of the V3 factory.
     * @param factoryAlgebra The address of the Algebra factory.
     * @param factorySolidly The address of the Solidly factory.
     * @param factoryXFAI The address of the XFAI factory.
     * @return nativePrice The current price of wNative in USD.
     */
    function getNativePriceFromFactory(
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) public view returns (uint256 nativePrice) {
        return _getNativePriceFromFactory(protocol, factoryV2, factoryV3, factoryAlgebra, factorySolidly, factoryXFAI);
    }

    function _getNativePriceFromFactory(
        Protocol protocol,
        address factoryV2,
        address factoryV3,
        address factoryAlgebra,
        address factorySolidly,
        address factoryXFAI
    ) internal view returns (uint256 nativePrice) {
        if (protocol == Protocol.UniV2) {
            return getNativePrice(protocol, factoryV2);
        } else if (protocol == Protocol.UniV3) {
            return getNativePrice(protocol, factoryV3);
        } else if (protocol == Protocol.Algebra) {
            return getNativePrice(protocol, factoryAlgebra);
        } else if (protocol == Protocol.Solidly) {
            return getNativePrice(protocol, factorySolidly);
        } else if (protocol == Protocol.Xfai) {
            return getNativePrice(protocol, factoryXFAI);
        } else if (protocol == Protocol.Curve) {
            return getNativePrice(protocol, factoryV2);
        } else {
            revert("Invalid");
        }
    }
}

File 2 of 14 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface AggregatorV3Interface {
  function decimals() external view returns (uint8);

  function description() external view returns (string memory);

  function version() external view returns (uint256);

  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}

File 3 of 14 : OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal onlyInitializing {
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal onlyInitializing {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[49] private __gap;
}

File 4 of 14 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

import "../../utils/AddressUpgradeable.sol";

/**
 * @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]
 * ```
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original
     * initialization step. This is essential to configure modules that are added through upgrades and that require
     * initialization.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized < type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }
}

File 5 of 14 : AddressUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

pragma solidity ^0.8.0;
import "../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;
    }

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

    /**
     * @dev This empty reserved space is put in place to allow future versions to add new
     * variables without shifting down storage in the inheritance chain.
     * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
     */
    uint256[50] private __gap;
}

File 7 of 14 : ChainlinkOracle.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity ^0.8.0;

import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";

abstract contract ChainlinkOracle {
    /// @notice Returns the price of the token in decimals of oracle
    function _getChainlinkPriceRaw(address oracleAddress) internal view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(oracleAddress);
        (, int256 price, , , ) = priceFeed.latestRoundData();
        return uint256(price);
    }

    /// @notice Returns the price of the token in wei with 18 decimals
    function _getChainlinkPriceNormalized(address oracleAddress) internal view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(oracleAddress);
        (, int256 price, , , ) = AggregatorV3Interface(oracleAddress).latestRoundData();
        uint8 decimals = priceFeed.decimals();
        return (uint256(price) * 10 ** 18) / 10 ** decimals;
    }
}

File 8 of 14 : IPriceGetterProtocol.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.16;

import "../IPriceGetter.sol";

interface IPriceGetterProtocol {
    struct PriceGetterParams {
        IPriceGetter mainPriceGetter;
        IPriceGetter.TokenAndDecimals wrappedNative;
        IPriceGetter.TokenAndDecimals[] stableUsdTokens;
        uint256 nativeLiquidityThreshold;
    }

    /**
     * @dev Returns the price of a token.
     * @param token The address of the token to get the price for.
     * @return price The current price of the token.
     */
    function getTokenPrice(
        address token,
        address factory,
        PriceGetterParams memory params
    ) external view returns (uint256 price);

    /**
     * @dev Returns the price of an LP token.
     * @param lp The address of the LP token to get the price for.
     * @return price The current price of the LP token.
     */
    function getLPPrice(
        address lp,
        address factory,
        PriceGetterParams memory params
    ) external view returns (uint256 price);

    /**
     * @dev Returns the current price of the native token in USD.
     * @return nativePrice The current price of the native token in USD.
     */
    function getNativePrice(
        address factory,
        PriceGetterParams memory params
    ) external view returns (uint256 nativePrice);
}

File 9 of 14 : IGammaHypervisor.sol
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.16;

import "../token-lib/IERC20.sol";

interface Hypervisor is IERC20 {
    function token0() external view returns (IERC20);

    function token1() external view returns (IERC20);

    function whitelistedAddress() external view returns (address);

    function withdraw(
        uint256 shares,
        address to,
        address from,
        uint256[4] memory minAmounts
    ) external returns (uint256 amount0, uint256 amount1);

    function getTotalAmounts() external view returns (uint256 total0, uint256 total1);
}

File 10 of 14 : IICHIVault.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.6.6;

interface IICHIVault {
    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 (uint256);
    function deposit1Max() external view returns (uint256);
    function maxTotalSupply() external view returns (uint256);
    function hysteresis() external view returns (uint256);

    function getTotalAmounts() external view returns (uint256, uint256);

    function deposit(uint256, uint256, address) external returns (uint256);

    function withdraw(uint256, address) external returns (uint256, uint256);

    function rebalance(
        int24 _baseLower,
        int24 _baseUpper,
        int24 _limitLower,
        int24 _limitUpper,
        int256 swapQuantity
    ) external;

    function setDepositMax(uint256 _deposit0Max, uint256 _deposit1Max) external;

    function setAffiliate(address _affiliate) external;

    event DeployICHIVault(
        address indexed sender,
        address indexed pool,
        bool allowToken0,
        bool allowToken1,
        address owner,
        uint256 twapPeriod
    );

    event SetTwapPeriod(address sender, uint32 newTwapPeriod);

    event Deposit(address indexed sender, address indexed to, uint256 shares, uint256 amount0, uint256 amount1);

    event Withdraw(address indexed sender, address indexed to, uint256 shares, uint256 amount0, uint256 amount1);

    event Rebalance(
        int24 tick,
        uint256 totalAmount0,
        uint256 totalAmount1,
        uint256 feeAmount0,
        uint256 feeAmount1,
        uint256 totalSupply
    );

    event MaxTotalSupply(address indexed sender, uint256 maxTotalSupply);

    event Hysteresis(address indexed sender, uint256 hysteresis);

    event DepositMax(address indexed sender, uint256 deposit0Max, uint256 deposit1Max);

    event Affiliate(address indexed sender, address affiliate);
}

File 11 of 14 : IPriceGetter.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.16;

interface IPriceGetter {
    enum Protocol {
        __,
        ___,
        UniV2,
        UniV3,
        Algebra,
        _Gamma, // outdated
        _Steer, // outdated
        Solidly,
        Xfai,
        Curve,
        AlgebraIntegral
    }

    enum Wrappers {
        Gamma,
        Ichi,
        Steer
    }

    struct TokenAndDecimals {
        address tokenAddress;
        uint8 decimals;
    }

    function getTokenPrice(address token, Protocol protocol, address factory) external view returns (uint256 price);
    function getLPPrice(address lp, Protocol protocol, address factory) external view returns (uint256 price);
    function getWrappedLPPrice(
        address lp,
        Protocol protocol,
        address factory,
        IPriceGetter.Wrappers wrapper
    ) external view returns (uint256 price);
    function getNativePrice(Protocol protocol, address factory) external view returns (uint256 nativePrice);
    function getOraclePriceNormalized(address token) external view returns (uint256 price);
}

File 12 of 14 : UtilityLibrary.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.16;

import "../token-lib/IERC20.sol";

library UtilityLibrary {
    function _isSorted(address tokenA, address tokenB) internal pure returns (bool isSorted) {
        //  (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        isSorted = tokenA < tokenB ? true : false;
    }

    function _getTokenDecimals(address token) internal view returns (uint8 decimals) {
        try IERC20(token).decimals() returns (uint8 dec) {
            decimals = dec;
        } catch {
            decimals = 18;
        }
    }

    /// @notice Normalize the amount of a token to wei or 1e18
    function _normalizeToken(uint256 amount, address token) internal view returns (uint256) {
        return _normalize(amount, _getTokenDecimals(token));
    }

    /// @notice Normalize the amount of a token to wei or 1e18
    function _normalizeToken112(uint112 amount, address token) internal view returns (uint112) {
        return _normalize112(amount, _getTokenDecimals(token));
    }

    /// @notice Normalize the amount passed to wei or 1e18 decimals
    function _normalize(uint256 amount, uint8 decimals) internal pure returns (uint256) {
        if (decimals == 18) return amount;
        return (amount * (10 ** 18)) / (10 ** decimals);
    }

    /// @notice Normalize the amount passed to wei or 1e18 decimals
    function _normalize112(uint112 amount, uint8 decimals) internal pure returns (uint112) {
        if (decimals == 18) {
            return amount;
        } else if (decimals > 18) {
            return uint112(amount / (10 ** (decimals - 18)));
        } else {
            return uint112(amount * (10 ** (18 - decimals)));
        }
    }
}

File 13 of 14 : PriceGetter.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.16;

import "./IPriceGetter.sol";
import "./chainlink/ChainlinkOracle.sol";
import "./extensions/IPriceGetterProtocol.sol";
import "./lib/UtilityLibrary.sol";

import {Hypervisor} from "./interfaces/IGammaHypervisor.sol";
import {IICHIVault} from "./interfaces/IICHIVault.sol";

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

/**
VERSION: 3.0

DISCLAIMER: 
This smart contract is provided for user interface purposes only and is not intended to be used for smart contract logic. 
Any attempt to rely on this code for the execution of a smart contract may result in unexpected behavior, 
errors, or other issues that could lead to financial loss or other damages. 
The user assumes all responsibility and risk for proper usage. 
The developer and associated parties make no warranties and are not liable for any damages incurred.
*/

contract PriceGetter is IPriceGetter, ChainlinkOracle, Initializable, OwnableUpgradeable {
    enum OracleType {
        NONE,
        CHAIN_LINK
    }

    struct OracleInfo {
        OracleType oracleType;
        address oracleAddress;
        uint8 oracleDecimals;
    }

    mapping(Protocol => IPriceGetterProtocol) public protocolPriceGetter;
    mapping(address => OracleInfo) public tokenOracles;
    TokenAndDecimals private wrappedNative;
    TokenAndDecimals[] public stableUsdTokens;
    uint256 public nativeLiquidityThreshold;

    // Reserved storage space to allow for layout changes in the future.
    uint256[50] private __gap;

    /**
     * @dev This contract constructor takes in several parameters which includes the wrapped native token address,
     * an array of addresses for stable USD tokens, an array of addresses for oracle tokens, and an array of addresses
     * for oracles.
     *
     * @param _wNative Address of the wrapped native token
     * @param _nativeLiquidityThreshold The native liquidity threshold
     * @param _stableUsdTokens Array of stable USD token addresses
     * @param _oracleTokens Array of oracle token addresses
     * @param _oracles Array of oracle addresses
     */
    function initialize(
        address _wNative,
        uint256 _nativeLiquidityThreshold,
        address[] calldata _stableUsdTokens,
        address[] calldata _oracleTokens,
        address[] calldata _oracles
    ) public initializer {
        __Ownable_init();
        nativeLiquidityThreshold = _nativeLiquidityThreshold;
        // Check if the lengths of the oracleTokens and oracles arrays match
        require(_oracleTokens.length == _oracles.length, "Oracle length mismatch");

        // Loop through the oracleTokens array and set the oracle address for each oracle token using the _setTokenOracle() internal helper function
        for (uint256 i = 0; i < _oracleTokens.length; i++) {
            /// @dev Assumes OracleType.CHAIN_LINK
            _setTokenOracle(_oracleTokens[i], _oracles[i], OracleType.CHAIN_LINK);
        }

        // Add the stable USD tokens to the stableCoins array using the addStableUsdTokens() internal helper function
        addStableUsdTokens(_stableUsdTokens);

        // Set the wrapped native token (wrappedNative) address
        wrappedNative = TokenAndDecimals(_wNative, UtilityLibrary._getTokenDecimals(_wNative));
    }

    /** SETTERS */

    /**
     * @dev Adds new stable USD tokens to the list of supported stable USD tokens.
     * @param newStableUsdTokens An array of addresses representing the new stable USD tokens to add.
     */
    function addStableUsdTokens(address[] calldata newStableUsdTokens) public onlyOwner {
        for (uint256 i = 0; i < newStableUsdTokens.length; i++) {
            address stableUsdToken = newStableUsdTokens[i];
            bool exists = false;

            for (uint256 j = 0; j < stableUsdTokens.length; j++) {
                if (stableUsdTokens[j].tokenAddress == stableUsdToken) {
                    exists = true;
                    break;
                }
            }

            if (!exists) {
                TokenAndDecimals memory newStableToken = TokenAndDecimals(
                    stableUsdToken,
                    UtilityLibrary._getTokenDecimals(stableUsdToken)
                );
                stableUsdTokens.push(newStableToken);
            }
        }
    }

    /**
     * @dev Removes the stable address.
     * @param tokens An array of token addresses to remove the stable address for.
     */
    function removeStableUsdTokens(address[] calldata tokens) external onlyOwner {
        for (uint256 i = 0; i < tokens.length; i++) {
            address token = tokens[i];
            uint256 length = stableUsdTokens.length;
            for (uint256 j = 0; j < length; j++) {
                if (stableUsdTokens[j].tokenAddress == token) {
                    stableUsdTokens[j] = stableUsdTokens[length - 1];
                    stableUsdTokens.pop();
                    break;
                }
            }
        }
    }

    /**
     * @dev Sets the oracle address and type for a specified token.
     * @param token The address of the token to set the oracle for.
     * @param oracleAddress The address of the oracle contract.
     * @param oracleType The type of the oracle (e.g. Chainlink, Uniswap).
     */
    function setTokenOracle(address token, address oracleAddress, OracleType oracleType) public onlyOwner {
        _setTokenOracle(token, oracleAddress, oracleType);
    }

    /**
     * @dev Removes the oracle address for a specified token.
     * @param token The address of the token to set the oracle for.
     */
    function removeTokenOracle(address token) public onlyOwner {
        delete tokenOracles[token];
    }

    /**
     * @dev Sets the oracle address and type for a specified token.
     * @param token The address of the token to set the oracle for.
     * @param oracleAddress The address of the oracle contract.
     * @param oracleType The type of the oracle (e.g. Chainlink, Uniswap).
     */
    function _setTokenOracle(address token, address oracleAddress, OracleType oracleType) internal {
        uint8 oracleDecimals = 18;
        try IERC20(oracleAddress).decimals() returns (uint8 dec) {
            oracleDecimals = dec;
        } catch {}

        tokenOracles[token] = OracleInfo({
            oracleType: oracleType,
            oracleAddress: oracleAddress,
            oracleDecimals: oracleDecimals
        });
    }

    function setNativeLiquidityThreshold(uint256 _nativeLiquidityThreshold) public onlyOwner {
        nativeLiquidityThreshold = _nativeLiquidityThreshold;
    }

    function setPriceGetterProtocol(Protocol protocol, address extension) public onlyOwner {
        protocolPriceGetter[protocol] = IPriceGetterProtocol(extension);
    }

    /**
     * @dev Sets the price getter protocols for multiple protocols at once.
     * @param protocols The protocols for which to set the price getter.
     * @param extensions The addresses of the price getter extensions for each protocol.
     */
    function setPriceGetterProtocols(Protocol[] memory protocols, address[] memory extensions) public onlyOwner {
        require(protocols.length == extensions.length, "Number of protocols must match number of extensions");
        for (uint256 i; i < protocols.length; i++) {
            setPriceGetterProtocol(protocols[i], extensions[i]);
        }
    }

    /** GETTERS */
    // ========== Get Token Prices ==========

    /**
     * @dev Returns the current price of the given token based on the specified protocol and time interval.
     * If protocol is set to 'Both', the price is calculated as a weighted average of the V2 and V3 prices,
     * where the weights are the respective liquidity pools. If protocol is set to 'V2' or 'V3', the price
     * is calculated based on the respective liquidity pool.
     * @param token Address of the token for which the price is requested.
     * @param protocol The liquidity protocol used to calculate the price.
     * @param factory The address of the factory used to calculate the price.
     * @return tokenPrice The price of the token in USD.
     */
    function getTokenPrice(address token, Protocol protocol, address factory) public view returns (uint256 tokenPrice) {
        if (token == wrappedNative.tokenAddress) {
            return getNativePrice(protocol, factory);
        }

        /// @dev Short circuit if oracle price is found
        uint256 oraclePrice = getOraclePriceNormalized(token);
        if (oraclePrice > 0) {
            return oraclePrice;
        }

        IPriceGetterProtocol extension = getPriceGetterProtocol(protocol);
        tokenPrice = extension.getTokenPrice(token, factory, getParams());
    }

    function getTokenPrices(
        address[] calldata tokens,
        Protocol protocol,
        address factory
    ) public view returns (uint256[] memory tokenPrices) {
        uint256 tokenLength = tokens.length;
        tokenPrices = new uint256[](tokenLength);

        for (uint256 i; i < tokenLength; i++) {
            address token = tokens[i];
            tokenPrices[i] = getTokenPrice(token, protocol, factory);
        }
    }

    // ========== Get LP Prices ==========

    /**
     * @dev Returns the prices of LP token from a specic protocol an factory.
     * @param lp The address of the LP token
     * @param protocol The protocol version to use
     * @param factory The address of the factory used to calculate the price.
     * @return price The current price of LP.
     * @dev Protocol V3 and Algebra not yet supported in here because functions token 2 tokens instead of 1 and for V3 also a fee.
     * Use the dedicated functions for these protocols
     */
    function getLPPrice(address lp, Protocol protocol, address factory) public view returns (uint256 price) {
        if (protocol == Protocol._Gamma || protocol == Protocol._Steer) {
            revert("This protocol needs to use getWrappedLPPrice() instead");
        }
        IPriceGetterProtocol extension = getPriceGetterProtocol(protocol);
        price = extension.getLPPrice(lp, factory, getParams());
    }

    function getLPPrices(
        address[] calldata lps,
        Protocol protocol,
        address factory
    ) public view returns (uint256[] memory prices) {
        uint256 lpLength = lps.length;
        prices = new uint256[](lpLength);

        for (uint256 i; i < lpLength; i++) {
            prices[i] = getLPPrice(lps[i], protocol, factory);
        }
    }

    function getWrappedLPPrice(
        address lp,
        Protocol protocol,
        address factory,
        Wrappers wrapper
    ) public view override returns (uint256 price) {
        if (protocol != Protocol.UniV3 && protocol != Protocol.Algebra && protocol != Protocol.AlgebraIntegral) {
            revert("Protocol does not have wrappers");
        }

        if (protocol == Protocol._Gamma || protocol == Protocol._Steer) {
            revert("You are confusing protocol and wrapper");
        }

        address token0;
        address token1;
        uint256 total0;
        uint256 total1;

        if (wrapper == IPriceGetter.Wrappers.Gamma) {
            token0 = address(Hypervisor(lp).token0());
            token1 = address(Hypervisor(lp).token1());
        } else if (wrapper == IPriceGetter.Wrappers.Ichi) {
            token0 = IICHIVault(lp).token0();
            token1 = IICHIVault(lp).token1();
        } else {
            //As backup just try token0() and token1() which is default interface usually
            token0 = address(Hypervisor(lp).token0());
            token1 = address(Hypervisor(lp).token1());
        }

        uint256 priceToken0 = getTokenPrice(token0, protocol, factory);
        uint256 priceToken1 = getTokenPrice(token1, protocol, factory);

        if (wrapper == IPriceGetter.Wrappers.Gamma) {
            (total0, total1) = Hypervisor(lp).getTotalAmounts();
        } else if (wrapper == IPriceGetter.Wrappers.Ichi) {
            (total0, total1) = IICHIVault(lp).getTotalAmounts();
        } else {
            //as backup just try gamma which is has pretty generic interface
            (total0, total1) = Hypervisor(lp).getTotalAmounts();
        }

        price =
            (priceToken0 *
                UtilityLibrary._normalizeToken(total0, token0) +
                priceToken1 *
                UtilityLibrary._normalizeToken(total1, token1)) /
            IERC20(lp).totalSupply();
    }

    // ========== Get Native Prices ==========

    /**
     * @dev Returns the current price of wrappedNative in USD based on the given protocol.
     * @param protocol The protocol version to use
     * @param factory The address of the factory used to calculate the price.
     * @return nativePrice The current price of wrappedNative in USD.
     */
    function getNativePrice(Protocol protocol, address factory) public view returns (uint256 nativePrice) {
        /// @dev Short circuit if oracle price is found
        uint256 oraclePrice = getOraclePriceNormalized(wrappedNative.tokenAddress);
        if (oraclePrice > 0) {
            return oraclePrice;
        }

        IPriceGetterProtocol extension = getPriceGetterProtocol(protocol);
        nativePrice = extension.getNativePrice(factory, getParams());
    }

    /**
     * @dev Retrieves the normalized USD price of a token from its oracle.
     * @param token Address of the token to retrieve the price for.
     * @return price The normalized USD price of the token from its oracle.
     */
    function getOraclePriceNormalized(address token) public view returns (uint256 price) {
        OracleInfo memory oracleInfo = tokenOracles[token];
        if (oracleInfo.oracleType == OracleType.CHAIN_LINK) {
            uint256 tokenUSDPrice = _getChainlinkPriceRaw(oracleInfo.oracleAddress);
            return UtilityLibrary._normalize(tokenUSDPrice, oracleInfo.oracleDecimals);
        }
        /// @dev Additional oracle types can be implemented here.
        // else if (oracleInfo.oracleType == OracleType.<NEW_ORACLE>) { }
        return 0;
    }

    function getPriceGetterProtocol(Protocol protocol) public view returns (IPriceGetterProtocol extension) {
        extension = protocolPriceGetter[protocol];
        if (address(extension) == address(0)) {
            revert("Invalid extension");
        }
    }

    /** VIEW FUNCTIONS */

    function getParams() public view returns (IPriceGetterProtocol.PriceGetterParams memory params) {
        params = IPriceGetterProtocol.PriceGetterParams(this, wrappedNative, stableUsdTokens, nativeLiquidityThreshold);
    }
}

File 14 of 14 : IERC20.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >=0.5.0;

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint);

    function balanceOf(address owner) external view returns (uint);

    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);

    function transfer(address to, uint value) external returns (bool);

    function transferFrom(address from, address to, uint value) external returns (bool);
}

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

Contract Security Audit

Contract ABI

API
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address[]","name":"newStableUsdTokens","type":"address[]"}],"name":"addStableUsdTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lp","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"}],"name":"getLPPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lp","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"}],"name":"getLPPriceFromFactory","outputs":[{"internalType":"uint256","name":"lpPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lp","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"},{"internalType":"address","name":"factoryXFAI","type":"address"}],"name":"getLPPriceFromFactory","outputs":[{"internalType":"uint256","name":"lpPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"lps","type":"address[]"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"}],"name":"getLPPrices","outputs":[{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"}],"name":"getNativePrice","outputs":[{"internalType":"uint256","name":"nativePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"}],"name":"getNativePriceFromFactory","outputs":[{"internalType":"uint256","name":"nativePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"},{"internalType":"address","name":"factoryXFAI","type":"address"}],"name":"getNativePriceFromFactory","outputs":[{"internalType":"uint256","name":"nativePrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getOraclePriceNormalized","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getParams","outputs":[{"components":[{"internalType":"contract IPriceGetter","name":"mainPriceGetter","type":"address"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"internalType":"struct IPriceGetter.TokenAndDecimals","name":"wrappedNative","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"internalType":"struct IPriceGetter.TokenAndDecimals[]","name":"stableUsdTokens","type":"tuple[]"},{"internalType":"uint256","name":"nativeLiquidityThreshold","type":"uint256"}],"internalType":"struct IPriceGetterProtocol.PriceGetterParams","name":"params","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"},{"internalType":"address","name":"factoryXFAI","type":"address"}],"name":"getPriceFromFactory","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factoryV2","type":"address"},{"internalType":"address","name":"factoryV3","type":"address"},{"internalType":"address","name":"factoryAlgebra","type":"address"},{"internalType":"address","name":"factorySolidly","type":"address"}],"name":"getPriceFromFactory","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"}],"name":"getPriceGetterProtocol","outputs":[{"internalType":"contract IPriceGetterProtocol","name":"extension","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"}],"name":"getTokenPrice","outputs":[{"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"}],"name":"getTokenPrices","outputs":[{"internalType":"uint256[]","name":"tokenPrices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lp","type":"address"},{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"factory","type":"address"},{"internalType":"enum IPriceGetter.Wrappers","name":"wrapper","type":"uint8"}],"name":"getWrappedLPPrice","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wNative","type":"address"},{"internalType":"uint256","name":"_nativeLiquidityThreshold","type":"uint256"},{"internalType":"address[]","name":"_stableUsdTokens","type":"address[]"},{"internalType":"address[]","name":"_oracleTokens","type":"address[]"},{"internalType":"address[]","name":"_oracles","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nativeLiquidityThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"","type":"uint8"}],"name":"protocolPriceGetter","outputs":[{"internalType":"contract IPriceGetterProtocol","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"removeStableUsdTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"removeTokenOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nativeLiquidityThreshold","type":"uint256"}],"name":"setNativeLiquidityThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol","name":"protocol","type":"uint8"},{"internalType":"address","name":"extension","type":"address"}],"name":"setPriceGetterProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum IPriceGetter.Protocol[]","name":"protocols","type":"uint8[]"},{"internalType":"address[]","name":"extensions","type":"address[]"}],"name":"setPriceGetterProtocols","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"enum PriceGetter.OracleType","name":"oracleType","type":"uint8"}],"name":"setTokenOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"stableUsdTokens","outputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint8","name":"decimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenOracles","outputs":[{"internalType":"enum PriceGetter.OracleType","name":"oracleType","type":"uint8"},{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"uint8","name":"oracleDecimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50612ae5806100206000396000f3fe608060405234801561001057600080fd5b50600436106101d95760003560e01c80639b788f0b11610104578063c4740b6f116100a2578063f2fde38b11610071578063f2fde38b1461043d578063fcd9c2f014610450578063fefa834214610463578063ff72def21461049757600080fd5b8063c4740b6f146103f1578063cdcb58b814610404578063d135babe14610417578063ed0f171b1461042a57600080fd5b8063b0af1970116100de578063b0af197014610355578063b71c7ed61461037e578063bcf3913314610391578063bd492432146103a457600080fd5b80639b788f0b14610326578063a9828f8a14610339578063abacdeab1461034257600080fd5b806369605acc1161017c57806384fac4ce1161014b57806384fac4ce146102c857806388e32fc2146102db5780638c6ae341146102ee5780638da5cb5b1461030157600080fd5b806369605acc146102875780636a4daf8f1461029a578063715018a6146102ad5780637d60227b146102b557600080fd5b80632c5c0144116101b85780632c5c01441461023757806352b4fdbe1461024a5780635e615a6b1461025f5780636888b4401461027457600080fd5b806214f61c146101de5780631d6de7c5146102045780631e2fa68d14610217575b600080fd5b6101f16101ec366004611faf565b6104aa565b6040519081526020015b60405180910390f35b6101f161021236600461202f565b6104c9565b61022a6102253660046120ea565b6104da565b6040516101fb9190612151565b6101f1610245366004612195565b61059d565b61025d6102583660046122c7565b610ae6565b005b610267610bba565b6040516101fb919061243a565b6101f161028236600461244d565b610c7a565b6101f1610295366004612496565b610da7565b61022a6102a83660046120ea565b610dc6565b61025d610e79565b6101f16102c336600461244d565b610e8d565b6101f16102d636600461252a565b610f62565b61025d6102e936600461252a565b611024565b6101f16102fc366004611faf565b611053565b6033546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b61030e610334366004612547565b611065565b6101f160695481565b61025d610350366004612562565b6110f0565b61030e610363366004612547565b6065602052600090815260409020546001600160a01b031681565b61025d61038c3660046125a6565b611103565b6101f161039f366004612496565b611250565b6103e26103b236600461252a565b60666020526000908152604090205460ff808216916001600160a01b0361010082041691600160a81b9091041683565b6040516101fb939291906125fe565b61025d6103ff366004612640565b611261565b6101f16104123660046126f6565b6114a5565b61025d610425366004612728565b6114b5565b61025d6104383660046125a6565b6114c2565b61025d61044b36600461252a565b61162d565b61025d61045e366004612741565b6116a6565b610476610471366004612728565b61170c565b604080516001600160a01b03909316835260ff9091166020830152016101fb565b6101f16104a5366004612741565b611741565b60006104bc87878787878760006117f8565b90505b9695505050505050565b60006104bf868686868660006119d1565b6060838067ffffffffffffffff8111156104f6576104f66121e8565b60405190808252806020026020018201604052801561051f578160200160208202803683370190505b50915060005b8181101561059357600087878381811061054157610541612778565b9050602002016020810190610556919061252a565b9050610563818787610e8d565b84838151811061057557610575612778565b6020908102919091010152508061058b816127a4565b915050610525565b5050949350505050565b6000600384600a8111156105b3576105b36125e8565b141580156105d35750600484600a8111156105d0576105d06125e8565b14155b80156105f15750600a84600a8111156105ee576105ee6125e8565b14155b156106435760405162461bcd60e51b815260206004820152601f60248201527f50726f746f636f6c20646f6573206e6f7420686176652077726170706572730060448201526064015b60405180910390fd5b600584600a811115610657576106576125e8565b14806106745750600684600a811115610672576106726125e8565b145b156106d05760405162461bcd60e51b815260206004820152602660248201527f596f752061726520636f6e667573696e672070726f746f636f6c20616e6420776044820152653930b83832b960d11b606482015260840161063a565b6000808080808660028111156106e8576106e86125e8565b036107ba57886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f91906127bd565b9350886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561078f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b391906127bd565b92506108da565b60018660028111156107ce576107ce6125e8565b0361081157886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087391906127bd565b9350886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d791906127bd565b92505b60006108e7858a8a610e8d565b905060006108f6858b8b610e8d565b9050600088600281111561090c5761090c6125e8565b0361097c578a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097291906127da565b9094509250610a39565b6001886002811115610990576109906125e8565b036109d2578a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa15801561094e573d6000803e3d6000fd5b8a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3391906127da565b90945092505b8a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b91906127fe565b610aa58487611aac565b610aaf9083612817565b610ab98689611aac565b610ac39085612817565b610acd9190612836565b610ad79190612849565b9b9a5050505050505050505050565b610aee611ac0565b8051825114610b5b5760405162461bcd60e51b815260206004820152603360248201527f4e756d626572206f662070726f746f636f6c73206d757374206d61746368206e604482015272756d626572206f6620657874656e73696f6e7360681b606482015260840161063a565b60005b8251811015610bb557610ba3838281518110610b7c57610b7c612778565b6020026020010151838381518110610b9657610b96612778565b60200260200101516116a6565b80610bad816127a4565b915050610b5e565b505050565b610bc2611f33565b60408051608081018252308152815180830183526067546001600160a01b0381168252600160a01b900460ff166020808301919091528083019190915260688054845181840281018401865281815293948501939260009084015b82821015610c6657600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101610c1d565b505050508152602001606954815250905090565b6000600583600a811115610c9057610c906125e8565b1480610cad5750600683600a811115610cab57610cab6125e8565b145b15610d195760405162461bcd60e51b815260206004820152603660248201527f546869732070726f746f636f6c206e6565647320746f20757365206765745772604482015275185c1c19591314141c9a58d94a0a481a5b9cdd19585960521b606482015260840161063a565b6000610d2484611065565b9050806001600160a01b0316635a51a2a08685610d3f610bba565b6040518463ffffffff1660e01b8152600401610d5d9392919061286b565b602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9e91906127fe565b95945050505050565b6000610db888888888888888611b1a565b90505b979650505050505050565b6060838067ffffffffffffffff811115610de257610de26121e8565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50915060005b8181101561059357610e4a878783818110610e2e57610e2e612778565b9050602002016020810190610e43919061252a565b8686610c7a565b838281518110610e5c57610e5c612778565b602090810291909101015280610e71816127a4565b915050610e11565b610e81611ac0565b610e8b6000611c4c565b565b6067546000906001600160a01b0390811690851603610eb757610eb08383611741565b9050610f5b565b6000610ec285610f62565b90508015610ed1579050610f5b565b6000610edc85611065565b9050806001600160a01b0316639bbcae168786610ef7610bba565b6040518463ffffffff1660e01b8152600401610f159392919061286b565b602060405180830381865afa158015610f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5691906127fe565b925050505b9392505050565b6001600160a01b038116600090815260666020526040808220815160608101909252805483929190829060ff166001811115610fa057610fa06125e8565b6001811115610fb157610fb16125e8565b8152905461010081046001600160a01b03166020830152600160a81b900460ff166040909101529050600181516001811115610fef57610fef6125e8565b0361101b5760006110038260200151611c9e565b9050611013818360400151611d15565b949350505050565b50600092915050565b61102c611ac0565b6001600160a01b0316600090815260666020526040902080546001600160b01b0319169055565b60006104bc8787878787876000611b1a565b60006065600083600a81111561107d5761107d6125e8565b600a81111561108e5761108e6125e8565b81526020810191909152604001600020546001600160a01b03169050806110eb5760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b21032bc3a32b739b4b7b760791b604482015260640161063a565b919050565b6110f8611ac0565b610bb5838383611d50565b61110b611ac0565b60005b81811015610bb557600083838381811061112a5761112a612778565b905060200201602081019061113f919061252a565b90506000805b6068548110156111a157826001600160a01b03166068828154811061116c5761116c612778565b6000918252602090912001546001600160a01b03160361118f57600191506111a1565b80611199816127a4565b915050611145565b508061123b5760006040518060400160405280846001600160a01b031681526020016111cc85611e71565b60ff9081169091526068805460018101825560009190915282517fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977539091018054602090940151909216600160a01b026001600160a81b03199093166001600160a01b0390911617919091179055505b50508080611248906127a4565b91505061110e565b6000610db8888888888888886117f8565b600054610100900460ff16158080156112815750600054600160ff909116105b8061129b5750303b15801561129b575060005460ff166001145b6112fe5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161063a565b6000805460ff191660011790558015611321576000805461ff0019166101001790555b611329611ed9565b60698890558382146113765760405162461bcd60e51b815260206004820152601660248201527509ee4c2c6d8ca40d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640161063a565b60005b848110156113eb576113d986868381811061139657611396612778565b90506020020160208101906113ab919061252a565b8585848181106113bd576113bd612778565b90506020020160208101906113d2919061252a565b6001611d50565b806113e3816127a4565b915050611379565b506113f68787611103565b60405180604001604052808a6001600160a01b031681526020016114198b611e71565b60ff908116909152815160678054602090940151909216600160a01b026001600160a81b03199093166001600160a01b0390911617919091179055801561149a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b60006104bc8787878787876119d1565b6114bd611ac0565b606955565b6114ca611ac0565b60005b81811015610bb55760008383838181106114e9576114e9612778565b90506020020160208101906114fe919061252a565b60685490915060005b8181101561161757826001600160a01b03166068828154811061152c5761152c612778565b6000918252602090912001546001600160a01b031603611605576068611553600184612897565b8154811061156357611563612778565b906000526020600020016068828154811061158057611580612778565b600091825260209091208254910180546001600160a01b039092166001600160a01b031983168117825592546001600160a81b0319909216909217600160a01b9182900460ff1690910217905560688054806115de576115de6128aa565b600082815260209020810160001990810180546001600160a81b0319169055019055611617565b8061160f816127a4565b915050611507565b5050508080611625906127a4565b9150506114cd565b611635611ac0565b6001600160a01b03811661169a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161063a565b6116a381611c4c565b50565b6116ae611ac0565b806065600084600a8111156116c5576116c56125e8565b600a8111156116d6576116d66125e8565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6068818154811061171c57600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b900460ff1682565b606754600090819061175b906001600160a01b0316610f62565b9050801561176a5790506117f2565b600061177585611065565b9050806001600160a01b031663e98765648561178f610bba565b6040518363ffffffff1660e01b81526004016117ac9291906128c0565b602060405180830381865afa1580156117c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ed91906127fe565b925050505b92915050565b6000600187600a81111561180e5761180e6125e8565b0361184e5760405162461bcd60e51b815260206004820152601060248201526f098a040c6c2dc4ee840c4ca40c4dee8d60831b604482015260640161063a565b600287600a811115611862576118626125e8565b0361187957611872888888610c7a565b9050610dbb565b600387600a81111561188d5761188d6125e8565b0361189d57611872888887610c7a565b600487600a8111156118b1576118b16125e8565b036118c157611872888886610c7a565b600787600a8111156118d5576118d56125e8565b036118e557611872888885610c7a565b600887600a8111156118f9576118f96125e8565b0361190957611872888884610c7a565b600987600a81111561191d5761191d6125e8565b0361192d57611872888888610c7a565b600587600a811115611941576119416125e8565b036119545761187288600486600061059d565b600687600a811115611968576119686125e8565b0361197b5761187288600387600061059d565b600987600a81111561198f5761198f6125e8565b0361199f57611872888888610c7a565b60405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161063a565b6000600287600a8111156119e7576119e76125e8565b036119fd576119f68787611741565b90506104bf565b600387600a811115611a1157611a116125e8565b03611a20576119f68786611741565b600487600a811115611a3457611a346125e8565b03611a43576119f68785611741565b600787600a811115611a5757611a576125e8565b03611a66576119f68784611741565b600887600a811115611a7a57611a7a6125e8565b03611a89576119f68783611741565b600987600a811115611a9d57611a9d6125e8565b0361199f576119f68787611741565b6000610f5b83611abb84611e71565b611d15565b6033546001600160a01b03163314610e8b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161063a565b6000600187600a811115611b3057611b306125e8565b03611b74576000611b4389600289610e8d565b90506000611b538a600389610e8d565b90506002611b618284612836565b611b6b9190612849565b92505050610dbb565b600287600a811115611b8857611b886125e8565b03611b9857611872888888610e8d565b600387600a811115611bac57611bac6125e8565b03611bbc57611872888887610e8d565b600487600a811115611bd057611bd06125e8565b03611be057611872888886610e8d565b600787600a811115611bf457611bf46125e8565b03611c0457611872888885610e8d565b600887600a811115611c1857611c186125e8565b03611c2857611872888884610e8d565b600987600a811115611c3c57611c3c6125e8565b0361199f57611872888888610e8d565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000808290506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0891906128fe565b5091979650505050505050565b60008160ff16601203611d295750816117f2565b611d3482600a612a32565b611d4684670de0b6b3a7640000612817565b610f5b9190612849565b600060129050826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611db0575060408051601f3d908101601f19168201909252611dad91810190612a41565b60015b15611db85790505b6040518060600160405280836001811115611dd557611dd56125e8565b81526001600160a01b0380861660208084019190915260ff8516604093840152908716600090815260669091522081518154829060ff191660018381811115611e2057611e206125e8565b02179055506020820151815460409093015160ff16600160a81b0260ff60a81b196001600160a01b039092166101000291909116610100600160b01b03199093169290921791909117905550505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611ecd575060408051601f3d908101601f19168201909252611eca91810190612a41565b60015b6117f257506012919050565b600054610100900460ff16611f005760405162461bcd60e51b815260040161063a90612a64565b610e8b600054610100900460ff16611f2a5760405162461bcd60e51b815260040161063a90612a64565b610e8b33611c4c565b604051806080016040528060006001600160a01b03168152602001611f77604051806040016040528060006001600160a01b03168152602001600060ff1681525090565b815260200160608152602001600081525090565b6001600160a01b03811681146116a357600080fd5b8035600b81106110eb57600080fd5b60008060008060008060c08789031215611fc857600080fd5b8635611fd381611f8b565b9550611fe160208801611fa0565b94506040870135611ff181611f8b565b9350606087013561200181611f8b565b9250608087013561201181611f8b565b915060a087013561202181611f8b565b809150509295509295509295565b600080600080600060a0868803121561204757600080fd5b61205086611fa0565b9450602086013561206081611f8b565b9350604086013561207081611f8b565b9250606086013561208081611f8b565b9150608086013561209081611f8b565b809150509295509295909350565b60008083601f8401126120b057600080fd5b50813567ffffffffffffffff8111156120c857600080fd5b6020830191508360208260051b85010111156120e357600080fd5b9250929050565b6000806000806060858703121561210057600080fd5b843567ffffffffffffffff81111561211757600080fd5b6121238782880161209e565b9095509350612136905060208601611fa0565b9150604085013561214681611f8b565b939692955090935050565b6020808252825182820181905260009190848201906040850190845b818110156121895783518352928401929184019160010161216d565b50909695505050505050565b600080600080608085870312156121ab57600080fd5b84356121b681611f8b565b93506121c460208601611fa0565b925060408501356121d481611f8b565b915060608501356003811061214657600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612227576122276121e8565b604052919050565b600067ffffffffffffffff821115612249576122496121e8565b5060051b60200190565b600082601f83011261226457600080fd5b813560206122796122748361222f565b6121fe565b82815260059290921b8401810191818101908684111561229857600080fd5b8286015b848110156122bc5780356122af81611f8b565b835291830191830161229c565b509695505050505050565b600080604083850312156122da57600080fd5b823567ffffffffffffffff808211156122f257600080fd5b818501915085601f83011261230657600080fd5b813560206123166122748361222f565b82815260059290921b8401810191818101908984111561233557600080fd5b948201945b8386101561235a5761234b86611fa0565b8252948201949082019061233a565b9650508601359250508082111561237057600080fd5b5061237d85828601612253565b9150509250929050565b80516001600160a01b0316825260208082015160009160a08501916123c48287018280516001600160a01b0316825260209081015160ff16910152565b5060408481015160a0606088015280519384905282019260009060c08801905b808310156124215761240d82875180516001600160a01b0316825260209081015160ff16910152565b9484019460019290920191908301906123e4565b5060608701516080890152809550505050505092915050565b602081526000610f5b6020830184612387565b60008060006060848603121561246257600080fd5b833561246d81611f8b565b925061247b60208501611fa0565b9150604084013561248b81611f8b565b809150509250925092565b600080600080600080600060e0888a0312156124b157600080fd5b87356124bc81611f8b565b96506124ca60208901611fa0565b955060408801356124da81611f8b565b945060608801356124ea81611f8b565b935060808801356124fa81611f8b565b925060a088013561250a81611f8b565b915060c088013561251a81611f8b565b8091505092959891949750929550565b60006020828403121561253c57600080fd5b8135610f5b81611f8b565b60006020828403121561255957600080fd5b610f5b82611fa0565b60008060006060848603121561257757600080fd5b833561258281611f8b565b9250602084013561259281611f8b565b915060408401356002811061248b57600080fd5b600080602083850312156125b957600080fd5b823567ffffffffffffffff8111156125d057600080fd5b6125dc8582860161209e565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b606081016002851061262057634e487b7160e01b600052602160045260246000fd5b9381526001600160a01b0392909216602083015260ff1660409091015290565b60008060008060008060008060a0898b03121561265c57600080fd5b883561266781611f8b565b975060208901359650604089013567ffffffffffffffff8082111561268b57600080fd5b6126978c838d0161209e565b909850965060608b01359150808211156126b057600080fd5b6126bc8c838d0161209e565b909650945060808b01359150808211156126d557600080fd5b506126e28b828c0161209e565b999c989b5096995094979396929594505050565b60008060008060008060c0878903121561270f57600080fd5b61271887611fa0565b95506020870135611fe181611f8b565b60006020828403121561273a57600080fd5b5035919050565b6000806040838503121561275457600080fd5b61275d83611fa0565b9150602083013561276d81611f8b565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016127b6576127b661278e565b5060010190565b6000602082840312156127cf57600080fd5b8151610f5b81611f8b565b600080604083850312156127ed57600080fd5b505080516020909101519092909150565b60006020828403121561281057600080fd5b5051919050565b60008160001904831182151516156128315761283161278e565b500290565b808201808211156117f2576117f261278e565b60008261286657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03848116825283166020820152606060408201819052600090610d9e90830184612387565b818103818111156117f2576117f261278e565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b038316815260406020820181905260009061101390830184612387565b805169ffffffffffffffffffff811681146110eb57600080fd5b600080600080600060a0868803121561291657600080fd5b61291f866128e4565b9450602086015193506040860151925060608601519150612942608087016128e4565b90509295509295909350565b600181815b8085111561298957816000190482111561296f5761296f61278e565b8085161561297c57918102915b93841c9390800290612953565b509250929050565b6000826129a0575060016117f2565b816129ad575060006117f2565b81600181146129c357600281146129cd576129e9565b60019150506117f2565b60ff8411156129de576129de61278e565b50506001821b6117f2565b5060208310610133831016604e8410600b8410161715612a0c575081810a6117f2565b612a16838361294e565b8060001904821115612a2a57612a2a61278e565b029392505050565b6000610f5b60ff841683612991565b600060208284031215612a5357600080fd5b815160ff81168114610f5b57600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220480bcbef361c6387d3d47feb28b0ff578125cbc8e8c54d8ffb8ab32da12811e964736f6c63430008100033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101d95760003560e01c80639b788f0b11610104578063c4740b6f116100a2578063f2fde38b11610071578063f2fde38b1461043d578063fcd9c2f014610450578063fefa834214610463578063ff72def21461049757600080fd5b8063c4740b6f146103f1578063cdcb58b814610404578063d135babe14610417578063ed0f171b1461042a57600080fd5b8063b0af1970116100de578063b0af197014610355578063b71c7ed61461037e578063bcf3913314610391578063bd492432146103a457600080fd5b80639b788f0b14610326578063a9828f8a14610339578063abacdeab1461034257600080fd5b806369605acc1161017c57806384fac4ce1161014b57806384fac4ce146102c857806388e32fc2146102db5780638c6ae341146102ee5780638da5cb5b1461030157600080fd5b806369605acc146102875780636a4daf8f1461029a578063715018a6146102ad5780637d60227b146102b557600080fd5b80632c5c0144116101b85780632c5c01441461023757806352b4fdbe1461024a5780635e615a6b1461025f5780636888b4401461027457600080fd5b806214f61c146101de5780631d6de7c5146102045780631e2fa68d14610217575b600080fd5b6101f16101ec366004611faf565b6104aa565b6040519081526020015b60405180910390f35b6101f161021236600461202f565b6104c9565b61022a6102253660046120ea565b6104da565b6040516101fb9190612151565b6101f1610245366004612195565b61059d565b61025d6102583660046122c7565b610ae6565b005b610267610bba565b6040516101fb919061243a565b6101f161028236600461244d565b610c7a565b6101f1610295366004612496565b610da7565b61022a6102a83660046120ea565b610dc6565b61025d610e79565b6101f16102c336600461244d565b610e8d565b6101f16102d636600461252a565b610f62565b61025d6102e936600461252a565b611024565b6101f16102fc366004611faf565b611053565b6033546001600160a01b03165b6040516001600160a01b0390911681526020016101fb565b61030e610334366004612547565b611065565b6101f160695481565b61025d610350366004612562565b6110f0565b61030e610363366004612547565b6065602052600090815260409020546001600160a01b031681565b61025d61038c3660046125a6565b611103565b6101f161039f366004612496565b611250565b6103e26103b236600461252a565b60666020526000908152604090205460ff808216916001600160a01b0361010082041691600160a81b9091041683565b6040516101fb939291906125fe565b61025d6103ff366004612640565b611261565b6101f16104123660046126f6565b6114a5565b61025d610425366004612728565b6114b5565b61025d6104383660046125a6565b6114c2565b61025d61044b36600461252a565b61162d565b61025d61045e366004612741565b6116a6565b610476610471366004612728565b61170c565b604080516001600160a01b03909316835260ff9091166020830152016101fb565b6101f16104a5366004612741565b611741565b60006104bc87878787878760006117f8565b90505b9695505050505050565b60006104bf868686868660006119d1565b6060838067ffffffffffffffff8111156104f6576104f66121e8565b60405190808252806020026020018201604052801561051f578160200160208202803683370190505b50915060005b8181101561059357600087878381811061054157610541612778565b9050602002016020810190610556919061252a565b9050610563818787610e8d565b84838151811061057557610575612778565b6020908102919091010152508061058b816127a4565b915050610525565b5050949350505050565b6000600384600a8111156105b3576105b36125e8565b141580156105d35750600484600a8111156105d0576105d06125e8565b14155b80156105f15750600a84600a8111156105ee576105ee6125e8565b14155b156106435760405162461bcd60e51b815260206004820152601f60248201527f50726f746f636f6c20646f6573206e6f7420686176652077726170706572730060448201526064015b60405180910390fd5b600584600a811115610657576106576125e8565b14806106745750600684600a811115610672576106726125e8565b145b156106d05760405162461bcd60e51b815260206004820152602660248201527f596f752061726520636f6e667573696e672070726f746f636f6c20616e6420776044820152653930b83832b960d11b606482015260840161063a565b6000808080808660028111156106e8576106e86125e8565b036107ba57886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074f91906127bd565b9350886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561078f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b391906127bd565b92506108da565b60018660028111156107ce576107ce6125e8565b0361081157886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561072b573d6000803e3d6000fd5b886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061087391906127bd565b9350886001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d791906127bd565b92505b60006108e7858a8a610e8d565b905060006108f6858b8b610e8d565b9050600088600281111561090c5761090c6125e8565b0361097c578a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa15801561094e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097291906127da565b9094509250610a39565b6001886002811115610990576109906125e8565b036109d2578a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa15801561094e573d6000803e3d6000fd5b8a6001600160a01b031663c4a7761e6040518163ffffffff1660e01b81526004016040805180830381865afa158015610a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3391906127da565b90945092505b8a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9b91906127fe565b610aa58487611aac565b610aaf9083612817565b610ab98689611aac565b610ac39085612817565b610acd9190612836565b610ad79190612849565b9b9a5050505050505050505050565b610aee611ac0565b8051825114610b5b5760405162461bcd60e51b815260206004820152603360248201527f4e756d626572206f662070726f746f636f6c73206d757374206d61746368206e604482015272756d626572206f6620657874656e73696f6e7360681b606482015260840161063a565b60005b8251811015610bb557610ba3838281518110610b7c57610b7c612778565b6020026020010151838381518110610b9657610b96612778565b60200260200101516116a6565b80610bad816127a4565b915050610b5e565b505050565b610bc2611f33565b60408051608081018252308152815180830183526067546001600160a01b0381168252600160a01b900460ff166020808301919091528083019190915260688054845181840281018401865281815293948501939260009084015b82821015610c6657600084815260209081902060408051808201909152908401546001600160a01b0381168252600160a01b900460ff1681830152825260019092019101610c1d565b505050508152602001606954815250905090565b6000600583600a811115610c9057610c906125e8565b1480610cad5750600683600a811115610cab57610cab6125e8565b145b15610d195760405162461bcd60e51b815260206004820152603660248201527f546869732070726f746f636f6c206e6565647320746f20757365206765745772604482015275185c1c19591314141c9a58d94a0a481a5b9cdd19585960521b606482015260840161063a565b6000610d2484611065565b9050806001600160a01b0316635a51a2a08685610d3f610bba565b6040518463ffffffff1660e01b8152600401610d5d9392919061286b565b602060405180830381865afa158015610d7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d9e91906127fe565b95945050505050565b6000610db888888888888888611b1a565b90505b979650505050505050565b6060838067ffffffffffffffff811115610de257610de26121e8565b604051908082528060200260200182016040528015610e0b578160200160208202803683370190505b50915060005b8181101561059357610e4a878783818110610e2e57610e2e612778565b9050602002016020810190610e43919061252a565b8686610c7a565b838281518110610e5c57610e5c612778565b602090810291909101015280610e71816127a4565b915050610e11565b610e81611ac0565b610e8b6000611c4c565b565b6067546000906001600160a01b0390811690851603610eb757610eb08383611741565b9050610f5b565b6000610ec285610f62565b90508015610ed1579050610f5b565b6000610edc85611065565b9050806001600160a01b0316639bbcae168786610ef7610bba565b6040518463ffffffff1660e01b8152600401610f159392919061286b565b602060405180830381865afa158015610f32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5691906127fe565b925050505b9392505050565b6001600160a01b038116600090815260666020526040808220815160608101909252805483929190829060ff166001811115610fa057610fa06125e8565b6001811115610fb157610fb16125e8565b8152905461010081046001600160a01b03166020830152600160a81b900460ff166040909101529050600181516001811115610fef57610fef6125e8565b0361101b5760006110038260200151611c9e565b9050611013818360400151611d15565b949350505050565b50600092915050565b61102c611ac0565b6001600160a01b0316600090815260666020526040902080546001600160b01b0319169055565b60006104bc8787878787876000611b1a565b60006065600083600a81111561107d5761107d6125e8565b600a81111561108e5761108e6125e8565b81526020810191909152604001600020546001600160a01b03169050806110eb5760405162461bcd60e51b815260206004820152601160248201527024b73b30b634b21032bc3a32b739b4b7b760791b604482015260640161063a565b919050565b6110f8611ac0565b610bb5838383611d50565b61110b611ac0565b60005b81811015610bb557600083838381811061112a5761112a612778565b905060200201602081019061113f919061252a565b90506000805b6068548110156111a157826001600160a01b03166068828154811061116c5761116c612778565b6000918252602090912001546001600160a01b03160361118f57600191506111a1565b80611199816127a4565b915050611145565b508061123b5760006040518060400160405280846001600160a01b031681526020016111cc85611e71565b60ff9081169091526068805460018101825560009190915282517fa2153420d844928b4421650203c77babc8b33d7f2e7b450e2966db0c220977539091018054602090940151909216600160a01b026001600160a81b03199093166001600160a01b0390911617919091179055505b50508080611248906127a4565b91505061110e565b6000610db8888888888888886117f8565b600054610100900460ff16158080156112815750600054600160ff909116105b8061129b5750303b15801561129b575060005460ff166001145b6112fe5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840161063a565b6000805460ff191660011790558015611321576000805461ff0019166101001790555b611329611ed9565b60698890558382146113765760405162461bcd60e51b815260206004820152601660248201527509ee4c2c6d8ca40d8cadccee8d040dad2e6dac2e8c6d60531b604482015260640161063a565b60005b848110156113eb576113d986868381811061139657611396612778565b90506020020160208101906113ab919061252a565b8585848181106113bd576113bd612778565b90506020020160208101906113d2919061252a565b6001611d50565b806113e3816127a4565b915050611379565b506113f68787611103565b60405180604001604052808a6001600160a01b031681526020016114198b611e71565b60ff908116909152815160678054602090940151909216600160a01b026001600160a81b03199093166001600160a01b0390911617919091179055801561149a576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050505050565b60006104bc8787878787876119d1565b6114bd611ac0565b606955565b6114ca611ac0565b60005b81811015610bb55760008383838181106114e9576114e9612778565b90506020020160208101906114fe919061252a565b60685490915060005b8181101561161757826001600160a01b03166068828154811061152c5761152c612778565b6000918252602090912001546001600160a01b031603611605576068611553600184612897565b8154811061156357611563612778565b906000526020600020016068828154811061158057611580612778565b600091825260209091208254910180546001600160a01b039092166001600160a01b031983168117825592546001600160a81b0319909216909217600160a01b9182900460ff1690910217905560688054806115de576115de6128aa565b600082815260209020810160001990810180546001600160a81b0319169055019055611617565b8061160f816127a4565b915050611507565b5050508080611625906127a4565b9150506114cd565b611635611ac0565b6001600160a01b03811661169a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161063a565b6116a381611c4c565b50565b6116ae611ac0565b806065600084600a8111156116c5576116c56125e8565b600a8111156116d6576116d66125e8565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6068818154811061171c57600080fd5b6000918252602090912001546001600160a01b0381169150600160a01b900460ff1682565b606754600090819061175b906001600160a01b0316610f62565b9050801561176a5790506117f2565b600061177585611065565b9050806001600160a01b031663e98765648561178f610bba565b6040518363ffffffff1660e01b81526004016117ac9291906128c0565b602060405180830381865afa1580156117c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ed91906127fe565b925050505b92915050565b6000600187600a81111561180e5761180e6125e8565b0361184e5760405162461bcd60e51b815260206004820152601060248201526f098a040c6c2dc4ee840c4ca40c4dee8d60831b604482015260640161063a565b600287600a811115611862576118626125e8565b0361187957611872888888610c7a565b9050610dbb565b600387600a81111561188d5761188d6125e8565b0361189d57611872888887610c7a565b600487600a8111156118b1576118b16125e8565b036118c157611872888886610c7a565b600787600a8111156118d5576118d56125e8565b036118e557611872888885610c7a565b600887600a8111156118f9576118f96125e8565b0361190957611872888884610c7a565b600987600a81111561191d5761191d6125e8565b0361192d57611872888888610c7a565b600587600a811115611941576119416125e8565b036119545761187288600486600061059d565b600687600a811115611968576119686125e8565b0361197b5761187288600387600061059d565b600987600a81111561198f5761198f6125e8565b0361199f57611872888888610c7a565b60405162461bcd60e51b8152602060048201526007602482015266125b9d985b1a5960ca1b604482015260640161063a565b6000600287600a8111156119e7576119e76125e8565b036119fd576119f68787611741565b90506104bf565b600387600a811115611a1157611a116125e8565b03611a20576119f68786611741565b600487600a811115611a3457611a346125e8565b03611a43576119f68785611741565b600787600a811115611a5757611a576125e8565b03611a66576119f68784611741565b600887600a811115611a7a57611a7a6125e8565b03611a89576119f68783611741565b600987600a811115611a9d57611a9d6125e8565b0361199f576119f68787611741565b6000610f5b83611abb84611e71565b611d15565b6033546001600160a01b03163314610e8b5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161063a565b6000600187600a811115611b3057611b306125e8565b03611b74576000611b4389600289610e8d565b90506000611b538a600389610e8d565b90506002611b618284612836565b611b6b9190612849565b92505050610dbb565b600287600a811115611b8857611b886125e8565b03611b9857611872888888610e8d565b600387600a811115611bac57611bac6125e8565b03611bbc57611872888887610e8d565b600487600a811115611bd057611bd06125e8565b03611be057611872888886610e8d565b600787600a811115611bf457611bf46125e8565b03611c0457611872888885610e8d565b600887600a811115611c1857611c186125e8565b03611c2857611872888884610e8d565b600987600a811115611c3c57611c3c6125e8565b0361199f57611872888888610e8d565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000808290506000816001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015611ce4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d0891906128fe565b5091979650505050505050565b60008160ff16601203611d295750816117f2565b611d3482600a612a32565b611d4684670de0b6b3a7640000612817565b610f5b9190612849565b600060129050826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611db0575060408051601f3d908101601f19168201909252611dad91810190612a41565b60015b15611db85790505b6040518060600160405280836001811115611dd557611dd56125e8565b81526001600160a01b0380861660208084019190915260ff8516604093840152908716600090815260669091522081518154829060ff191660018381811115611e2057611e206125e8565b02179055506020820151815460409093015160ff16600160a81b0260ff60a81b196001600160a01b039092166101000291909116610100600160b01b03199093169290921791909117905550505050565b6000816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015611ecd575060408051601f3d908101601f19168201909252611eca91810190612a41565b60015b6117f257506012919050565b600054610100900460ff16611f005760405162461bcd60e51b815260040161063a90612a64565b610e8b600054610100900460ff16611f2a5760405162461bcd60e51b815260040161063a90612a64565b610e8b33611c4c565b604051806080016040528060006001600160a01b03168152602001611f77604051806040016040528060006001600160a01b03168152602001600060ff1681525090565b815260200160608152602001600081525090565b6001600160a01b03811681146116a357600080fd5b8035600b81106110eb57600080fd5b60008060008060008060c08789031215611fc857600080fd5b8635611fd381611f8b565b9550611fe160208801611fa0565b94506040870135611ff181611f8b565b9350606087013561200181611f8b565b9250608087013561201181611f8b565b915060a087013561202181611f8b565b809150509295509295509295565b600080600080600060a0868803121561204757600080fd5b61205086611fa0565b9450602086013561206081611f8b565b9350604086013561207081611f8b565b9250606086013561208081611f8b565b9150608086013561209081611f8b565b809150509295509295909350565b60008083601f8401126120b057600080fd5b50813567ffffffffffffffff8111156120c857600080fd5b6020830191508360208260051b85010111156120e357600080fd5b9250929050565b6000806000806060858703121561210057600080fd5b843567ffffffffffffffff81111561211757600080fd5b6121238782880161209e565b9095509350612136905060208601611fa0565b9150604085013561214681611f8b565b939692955090935050565b6020808252825182820181905260009190848201906040850190845b818110156121895783518352928401929184019160010161216d565b50909695505050505050565b600080600080608085870312156121ab57600080fd5b84356121b681611f8b565b93506121c460208601611fa0565b925060408501356121d481611f8b565b915060608501356003811061214657600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612227576122276121e8565b604052919050565b600067ffffffffffffffff821115612249576122496121e8565b5060051b60200190565b600082601f83011261226457600080fd5b813560206122796122748361222f565b6121fe565b82815260059290921b8401810191818101908684111561229857600080fd5b8286015b848110156122bc5780356122af81611f8b565b835291830191830161229c565b509695505050505050565b600080604083850312156122da57600080fd5b823567ffffffffffffffff808211156122f257600080fd5b818501915085601f83011261230657600080fd5b813560206123166122748361222f565b82815260059290921b8401810191818101908984111561233557600080fd5b948201945b8386101561235a5761234b86611fa0565b8252948201949082019061233a565b9650508601359250508082111561237057600080fd5b5061237d85828601612253565b9150509250929050565b80516001600160a01b0316825260208082015160009160a08501916123c48287018280516001600160a01b0316825260209081015160ff16910152565b5060408481015160a0606088015280519384905282019260009060c08801905b808310156124215761240d82875180516001600160a01b0316825260209081015160ff16910152565b9484019460019290920191908301906123e4565b5060608701516080890152809550505050505092915050565b602081526000610f5b6020830184612387565b60008060006060848603121561246257600080fd5b833561246d81611f8b565b925061247b60208501611fa0565b9150604084013561248b81611f8b565b809150509250925092565b600080600080600080600060e0888a0312156124b157600080fd5b87356124bc81611f8b565b96506124ca60208901611fa0565b955060408801356124da81611f8b565b945060608801356124ea81611f8b565b935060808801356124fa81611f8b565b925060a088013561250a81611f8b565b915060c088013561251a81611f8b565b8091505092959891949750929550565b60006020828403121561253c57600080fd5b8135610f5b81611f8b565b60006020828403121561255957600080fd5b610f5b82611fa0565b60008060006060848603121561257757600080fd5b833561258281611f8b565b9250602084013561259281611f8b565b915060408401356002811061248b57600080fd5b600080602083850312156125b957600080fd5b823567ffffffffffffffff8111156125d057600080fd5b6125dc8582860161209e565b90969095509350505050565b634e487b7160e01b600052602160045260246000fd5b606081016002851061262057634e487b7160e01b600052602160045260246000fd5b9381526001600160a01b0392909216602083015260ff1660409091015290565b60008060008060008060008060a0898b03121561265c57600080fd5b883561266781611f8b565b975060208901359650604089013567ffffffffffffffff8082111561268b57600080fd5b6126978c838d0161209e565b909850965060608b01359150808211156126b057600080fd5b6126bc8c838d0161209e565b909650945060808b01359150808211156126d557600080fd5b506126e28b828c0161209e565b999c989b5096995094979396929594505050565b60008060008060008060c0878903121561270f57600080fd5b61271887611fa0565b95506020870135611fe181611f8b565b60006020828403121561273a57600080fd5b5035919050565b6000806040838503121561275457600080fd5b61275d83611fa0565b9150602083013561276d81611f8b565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016127b6576127b661278e565b5060010190565b6000602082840312156127cf57600080fd5b8151610f5b81611f8b565b600080604083850312156127ed57600080fd5b505080516020909101519092909150565b60006020828403121561281057600080fd5b5051919050565b60008160001904831182151516156128315761283161278e565b500290565b808201808211156117f2576117f261278e565b60008261286657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160a01b03848116825283166020820152606060408201819052600090610d9e90830184612387565b818103818111156117f2576117f261278e565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b038316815260406020820181905260009061101390830184612387565b805169ffffffffffffffffffff811681146110eb57600080fd5b600080600080600060a0868803121561291657600080fd5b61291f866128e4565b9450602086015193506040860151925060608601519150612942608087016128e4565b90509295509295909350565b600181815b8085111561298957816000190482111561296f5761296f61278e565b8085161561297c57918102915b93841c9390800290612953565b509250929050565b6000826129a0575060016117f2565b816129ad575060006117f2565b81600181146129c357600281146129cd576129e9565b60019150506117f2565b60ff8411156129de576129de61278e565b50506001821b6117f2565b5060208310610133831016604e8410600b8410161715612a0c575081810a6117f2565b612a16838361294e565b8060001904821115612a2a57612a2a61278e565b029392505050565b6000610f5b60ff841683612991565b600060208284031215612a5357600080fd5b815160ff81168114610f5b57600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220480bcbef361c6387d3d47feb28b0ff578125cbc8e8c54d8ffb8ab32da12811e964736f6c63430008100033

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

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits

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.