Contract 0x598221b864f773010F9f20bc2018a92430Ed397f

Contract Overview

Balance:
0 MATIC
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x34c9903b3476de1cf446d48750b525d869a68fab8c2f48f2b5e713b73bea29d3Set Price Proxy314751532023-01-27 15:29:51128 days 22 hrs ago0x1de72a1935df9b4e02315bda3c3cdbdf2a640583 IN  0x598221b864f773010f9f20bc2018a92430ed397f0 MATIC0.000083522422 1.731644783
0x8e707e43f522bf47386151b0eda53494774e8ac86a0662ec889ab8896c2f6a77Set Price Proxy314751512023-01-27 15:29:45128 days 22 hrs ago0x1de72a1935df9b4e02315bda3c3cdbdf2a640583 IN  0x598221b864f773010f9f20bc2018a92430ed397f0 MATIC0.001056374 22
0x421fdb5a973b76bf8107b8d87f11322c194afa8985b1d21f4b8ed0b8d70ccc1fSet Price Proxy314751492023-01-27 15:29:41128 days 22 hrs ago0x1de72a1935df9b4e02315bda3c3cdbdf2a640583 IN  0x598221b864f773010f9f20bc2018a92430ed397f0 MATIC0.0000723675 1.500000016
0xdb347298a5eb966d9378c3f602c93768da9b75dbf742dfc8fd465d0fc85b36f0Add Exchange Con...314750582023-01-27 15:26:29128 days 22 hrs ago0x1de72a1935df9b4e02315bda3c3cdbdf2a640583 IN  0x598221b864f773010f9f20bc2018a92430ed397f0 MATIC0.0016686 18
0x5daa5ae0296c67f726425f9118ad88bf7dc0b4802c2f231fc109090d13880f540x60806040314702992023-01-27 12:37:31129 days 53 mins ago0x1de72a1935df9b4e02315bda3c3cdbdf2a640583 IN  Create: PriceOracle0 MATIC0.003813077301 2.425000017
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PriceOracle

Compiler Version
v0.8.2+commit.661d1103

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 7 : PriceOracle.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.8.4;

import "./interfaces/IPriceOracle.sol";
import "../connectors/interfaces/IExchangeConnector.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";


contract PriceOracle is IPriceOracle, Ownable {

    using SafeCast for uint;

    modifier nonZeroAddress(address _address) {
        require(_address != address(0), "PriceOracle: zero address");
        _;
    }

    // Public variables
    mapping (address => address) public override ChainlinkPriceProxy; // Given two token addresses returns related Chainlink price proxy
    mapping(address => address) public override exchangeConnector; // Mapping from exchange router to exchange connector
    address[] public override exchangeRoutersList; // List of available exchange routers
    uint public override acceptableDelay;
    address public constant NATIVE_TOKEN = address(1); // ONE_ADDRESS is used for getting price of blockchain native token 
    address public override oracleNativeToken;

    /// @notice                         This contract is used to get relative price of two assets from Chainlink and available exchanges 
    /// @param _acceptableDelay         Maximum acceptable delay for data given from Chainlink
    /// @param _oracleNativeToken       The address of the chainlink oracle for the native token
    constructor(uint _acceptableDelay,address _oracleNativeToken) {
        _setAcceptableDelay(_acceptableDelay);
        _setOracleNativeToken(_oracleNativeToken);
    }

    function renounceOwnership() public virtual override onlyOwner {}

    /// @notice                 Getter for the length of exchange router list
    function getExchangeRoutersListLength() public view override returns (uint) {
        return exchangeRoutersList.length;
    }

    /// @notice                         Finds amount of output token that has same value as the input amount of the input token
    /// @dev                            First we try to get the output amount from Chain Link
    ///                                 Only if the price is not available or out-of-date we will 
    ///                                 reach to exchange routers
    /// @param _inputAmount             Amount of the input token
    /// @param _inputDecimals           Number of input token decimals
    /// @param _outputDecimals          Number of output token decimals
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return                         Amount of the output token
    function equivalentOutputAmountByAverage(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view nonZeroAddress(_inputToken) nonZeroAddress(_outputToken) override returns (uint) {
        // Gets output amount from oracle
        (bool result, uint outputAmount, uint timestamp) = _equivalentOutputAmountFromOracle(
            _inputAmount,
            _inputDecimals,
            _outputDecimals,
            _inputToken,
            _outputToken
        );

        // Checks timestamp of the oracle result
        if (result == true && _abs(timestamp.toInt256() - block.timestamp.toInt256()) <= acceptableDelay) {
            return outputAmount;
        } else {
            uint _totalAmount;
            uint _totalNumber;

            // If Chainlink price is available but out-of-date, we still use it
            if (result == true) {
                _totalAmount = outputAmount;
                _totalNumber = 1;
            }

            // Gets output amounts from exchange routers
            // note: we assume that the decimal of exchange returned result is _outputDecimals.
            for (uint i = 0; i < getExchangeRoutersListLength(); i++) {
                (result, outputAmount) = _equivalentOutputAmountFromExchange(
                    exchangeRoutersList[i],
                    _inputAmount,
                    _inputToken,
                    _outputToken
                );

                if (result == true) {
                    _totalNumber = _totalNumber + 1;
                    _totalAmount = _totalAmount + outputAmount;
                }
            }

            require(_totalNumber > 0, "PriceOracle: no price feed is available");

            // Returns average of results from different sources
            return _totalAmount/_totalNumber;
        }
    }

    /// @notice                         Finds amount of output token that has equal value
    ///                                 as the input amount of the input token
    /// @dev                            The oracle is ChainLink
    /// @param _inputAmount             Amount of the input token
    /// @param _inputDecimals           Number of input token decimals
    /// @param _outputDecimals          Number of output token decimals
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return _outputAmount           Amount of the output token
    function equivalentOutputAmount(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view nonZeroAddress(_inputToken) nonZeroAddress(_outputToken) override returns (uint _outputAmount) {
        bool result;
        (result, _outputAmount, /*timestamp*/) = _equivalentOutputAmountFromOracle(
            _inputAmount,
            _inputDecimals,
            _outputDecimals,
            _inputToken,
            _outputToken
        );
        require(result == true, "PriceOracle: oracle not exist or up to date");
    }

    /// @notice                         Finds amount of output token that has equal value
    ///                                 as the input amount of the input token
    /// @dev                            The oracle is ChainLink
    /// @param _inputAmount             Amount of the input token
    /// @param _inputDecimals           Number of input token decimals
    /// @param _outputDecimals          Number of output token decimals
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return _outputAmount           Amount of the output token
    function equivalentOutputAmountFromOracle(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view nonZeroAddress(_inputToken) nonZeroAddress(_outputToken) override returns (uint _outputAmount) {
        bool result;
        (result, _outputAmount, /*timestamp*/) = _equivalentOutputAmountFromOracle(
            _inputAmount,
            _inputDecimals,
            _outputDecimals,
            _inputToken,
            _outputToken
        );
        require(result == true, "PriceOracle: oracle not exist or up to date");
    }

    /// @notice                         Finds amount of output token that has same value 
    ///                                 as the input amount of the input token
    /// @dev                            Input amount should have the same decimal as input token
    ///                                 Output amount has the same decimal as output token
    /// @param _exchangeRouter          Address of the exchange router we are reading the price from
    /// @param _inputAmount             Amount of the input token
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return                         Amount of the output token
    function equivalentOutputAmountFromExchange(
        address _exchangeRouter,
        uint _inputAmount,
        address _inputToken,
        address _outputToken
    ) external view nonZeroAddress(_inputToken) nonZeroAddress(_outputToken) override returns (uint) {
        (bool result, uint outputAmount) = _equivalentOutputAmountFromExchange(
            _exchangeRouter,
            _inputAmount,
            _inputToken,
            _outputToken
        );
        require(result == true, "PriceOracle: Pair does not exist on exchange");
        return outputAmount;
    }

    /// @notice                    Adds an exchange connector
    /// @dev                       Only owner can call this
    /// @param _exchangeRouter     Exchange router contract address
    /// @param _exchangeConnector  New exchange connector contract address
    function addExchangeConnector(
        address _exchangeRouter, 
        address _exchangeConnector
    ) external nonZeroAddress(_exchangeRouter) nonZeroAddress(_exchangeConnector) override onlyOwner {
        require(exchangeConnector[_exchangeRouter] == address(0), "PriceOracle: exchange router already exists");
        exchangeRoutersList.push(_exchangeRouter);
        exchangeConnector[_exchangeRouter] = _exchangeConnector;
        emit ExchangeConnectorAdded(_exchangeRouter, _exchangeConnector);
    }

    /// @notice                       Removes an exchange connector
    /// @dev                          Only owner can call this
    /// @param _exchangeRouterIndex   The exchange router index in the list
    function removeExchangeConnector(uint _exchangeRouterIndex) external override onlyOwner {
        require(_exchangeRouterIndex < exchangeRoutersList.length, "PriceOracle: Index is out of bound");
        address exchangeRouterAddress = exchangeRoutersList[_exchangeRouterIndex];
        _removeElementFromExchangeRoutersList(_exchangeRouterIndex);
        exchangeConnector[exchangeRouterAddress] = address(0);
        emit ExchangeConnectorRemoved(exchangeRouterAddress);
    }

    /// @notice                     Sets a USD price proxy for a token
    /// @dev                        Only owner can call this
    ///                             This price proxy gives exchange rate of _token/USD
    ///                             Setting price proxy address to zero means that we remove it
    /// @param _token               Address of the token
    /// @param _priceProxyAddress   The address of the proxy price
    function setPriceProxy(
        address _token, 
        address _priceProxyAddress
    ) external nonZeroAddress(_token) override onlyOwner {
        ChainlinkPriceProxy[_token] = _priceProxyAddress;
        emit SetPriceProxy(_token, _priceProxyAddress);
    }

    /// @notice                     Sets acceptable delay for oracle responses
    /// @dev                        If oracle data has not been updated for a while, 
    ///                             we will get data from exchange routers
    /// @param _acceptableDelay     Maximum acceptable delay (in seconds)
    function setAcceptableDelay(uint _acceptableDelay) external override onlyOwner {
        _setAcceptableDelay(_acceptableDelay);
    }

    /// @notice                     Sets oracle native token address
    function setOracleNativeToken(address _oracleNativeToken) external override onlyOwner {
       _setOracleNativeToken(_oracleNativeToken);
    }

    /// @notice                     Internal setter for acceptable delay for oracle responses
    /// @dev                        If oracle data has not been updated for a while, 
    ///                             we will get data from exchange routers
    /// @param _acceptableDelay     Maximum acceptable delay (in seconds)
    function _setAcceptableDelay(uint _acceptableDelay) private {
        emit NewAcceptableDelay(acceptableDelay, _acceptableDelay);
        require(
            _acceptableDelay > 0,
            "PriceOracle: zero amount"
        );
        acceptableDelay = _acceptableDelay;
    }

    /// @notice                     Internal setter for oracle native token address
    function _setOracleNativeToken(address _oracleNativeToken) private nonZeroAddress(_oracleNativeToken) {
        emit NewOracleNativeToken(oracleNativeToken, _oracleNativeToken);
        oracleNativeToken = _oracleNativeToken;
    }

    /// @notice                         Finds amount of output token that has same value 
    ///                                 as the input amount of the input token
    /// @param _exchangeRouter          Address of the exchange we are reading the price from
    /// @param _inputAmount             Amount of the input token
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return _result                 True if getting amount was successful
    /// @return _outputAmount           Amount of the output token
    function _equivalentOutputAmountFromExchange(
        address _exchangeRouter,
        uint _inputAmount,
        address _inputToken,
        address _outputToken
    ) private view returns (bool _result, uint _outputAmount) {
        if (_inputToken == NATIVE_TOKEN) {
            // note: different exchanges may use different wrapped native token versions
            address wrappedNativeToken = IExchangeConnector(exchangeConnector[_exchangeRouter]).wrappedNativeToken();

            (_result, _outputAmount) = IExchangeConnector(exchangeConnector[_exchangeRouter]).getOutputAmount(
                _inputAmount,
                wrappedNativeToken,
                _outputToken
            );
        } else if (_outputToken == NATIVE_TOKEN) {
            // note: different exchanges may use different wrapped native token versions
            address wrappedNativeToken = IExchangeConnector(exchangeConnector[_exchangeRouter]).wrappedNativeToken();

            (_result, _outputAmount) = IExchangeConnector(exchangeConnector[_exchangeRouter]).getOutputAmount(
                _inputAmount,
                _inputToken,
                wrappedNativeToken
            );
        } else {
            (_result, _outputAmount) = IExchangeConnector(exchangeConnector[_exchangeRouter]).getOutputAmount(
                _inputAmount,
                _inputToken,
                _outputToken
            );
        }

    }

    /// @notice                         Finds amount of output token that is equal as the input amount of the input token
    /// @dev                            The oracle is ChainLink
    /// @param _inputAmount             Amount of the input token
    /// @param _inputDecimals           Number of input token decimals
    /// @param _outputDecimals          Number of output token decimals
    /// @param _inputToken              Address of the input token
    /// @param _outputToken             Address of output token
    /// @return _result                 True if getting amount was successful
    /// @return _outputAmount           Amount of the output token
    /// @return _timestamp              Timestamp of the result
    function _equivalentOutputAmountFromOracle(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) private view returns (bool, uint _outputAmount, uint _timestamp) {
        uint decimals0;
        uint decimals1;
        int price0;
        int price1;

        if (_inputToken == NATIVE_TOKEN) {
            _inputToken = oracleNativeToken;
        }

        if (_outputToken == NATIVE_TOKEN) {
            _outputToken = oracleNativeToken;
        }

        if (ChainlinkPriceProxy[_inputToken] != address(0) && ChainlinkPriceProxy[_outputToken] != address(0)) {
            uint[2] memory _timestamps;

            // Gets price of _inputToken/USD
            (
            /*uint80 roundID*/,
            price0,
            /*uint startedAt*/,
            _timestamps[0],
            /*uint80 answeredInRound*/
            ) = AggregatorV3Interface(ChainlinkPriceProxy[_inputToken]).latestRoundData();

            require(price0 != 0, "PriceOracle: zero price for input token");

            // Gets number of decimals
            decimals0 = AggregatorV3Interface(ChainlinkPriceProxy[_inputToken]).decimals();


            // Gets price of _outputToken/USD
            (
            /*uint80 roundID*/,
            price1,
            /*uint startedAt*/,
            _timestamps[1],
            /*uint80 answeredInRound*/
            ) = AggregatorV3Interface(ChainlinkPriceProxy[_outputToken]).latestRoundData();

            require(price1 != 0, "PriceOracle: zero price for output token");

            // Gets number of decimals
            decimals1 = AggregatorV3Interface(ChainlinkPriceProxy[_outputToken]).decimals();

            // uint price = (uint(price0) * 10**(decimals1)) / (uint(price1) * 10**(decimals0));

            // // note: to make inside of power parentheses greater than zero, we add them with one
            // _outputAmount = price*_inputAmount*(10**(_outputDecimals + 1))/(10**(_inputDecimals + 1));

            // convert the above calculation to the below one to eliminate precision loss
            _outputAmount = (uint(price0) * 10**(decimals1))*_inputAmount*(10**(_outputDecimals + 1));
            _outputAmount = _outputAmount/((10**(_inputDecimals + 1))*(uint(price1) * 10**(decimals0)));

            if (_abs(block.timestamp.toInt256() - _timestamps[0].toInt256()) > acceptableDelay) {
                return (false, _outputAmount, _timestamps[0]);
            }

            if (_abs(block.timestamp.toInt256() - _timestamps[1].toInt256()) > acceptableDelay) {
                return (false, _outputAmount, _timestamps[1]);
            }

            _timestamp = _timestamps[0] > _timestamps[1] ? _timestamps[1] : _timestamps[0];

            return (true, _outputAmount, _timestamp);
            
        } else {
            return (false, 0, 0);
        }
    }

    /// @notice             Removes an element of excahngeRouterList
    /// @dev                Deletes and shifts the array
    /// @param _index       Index of the element that will be deleted
    function _removeElementFromExchangeRoutersList(uint _index) private {
        exchangeRoutersList[_index] = exchangeRoutersList[exchangeRoutersList.length - 1];
        exchangeRoutersList.pop();
    }

    /// @notice             Returns absolute value
    function _abs(int _value) private pure returns (uint) {
        return _value >= 0 ? uint(_value) : uint(-_value);
    }

}

File 2 of 7 : IPriceOracle.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.8.4;

interface IPriceOracle {

    /// @notice                     Emits when new exchange router is added
    /// @param exchangeRouter       Address of new exchange router
    /// @param exchangeConnector    Address of exchange connector
    event ExchangeConnectorAdded(address indexed exchangeRouter, address indexed exchangeConnector);

    /// @notice                     Emits when an exchange router is removed
    /// @param exchangeRouter       Address of removed exchange router
    event ExchangeConnectorRemoved(address indexed exchangeRouter);

    /// @notice                     Emits when a price proxy is set
    /// @param _token               Address of the token
    /// @param _priceProxyAddress   Address of price proxy contract
    event SetPriceProxy(address indexed _token, address indexed _priceProxyAddress);

    /// @notice                     Emits when changes made to acceptable delay
	event NewAcceptableDelay(uint oldAcceptableDelay, uint newAcceptableDelay);

    /// @notice                     Emits when changes made to oracle native token
	event NewOracleNativeToken(address indexed oldOracleNativeToken, address indexed newOracleNativeToken);

    // Read-only functions
    
    /// @notice                     Gives USD price proxy address for a token
    /// @param _token          Address of the token
    /// @return                     Address of price proxy contract
    function ChainlinkPriceProxy(address _token) external view returns (address);

    /// @notice                     Gives exchange connector address for an exchange router
    /// @param _exchangeRouter      Address of exchange router
    /// @return                     Address of exchange connector
    function exchangeConnector(address _exchangeRouter) external view returns (address);

    /// @notice                     Gives address of an exchange router from exchange routers list
    /// @param _index               Index of exchange router
    /// @return                     Address of exchange router
    function exchangeRoutersList(uint _index) external view returns (address);

    function getExchangeRoutersListLength() external view returns (uint);

    function acceptableDelay() external view returns (uint);

    function oracleNativeToken() external view returns (address);

    function equivalentOutputAmountByAverage(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view returns (uint);

    function equivalentOutputAmount(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view returns (uint);

    function equivalentOutputAmountFromOracle(
        uint _inputAmount,
        uint _inputDecimals,
        uint _outputDecimals,
        address _inputToken,
        address _outputToken
    ) external view returns (uint);

    function equivalentOutputAmountFromExchange(
        address _exchangeRouter,
        uint _inputAmount,
        address _inputToken,
        address _outputToken
    ) external view returns (uint);
    
    // State-changing functions
    
    function addExchangeConnector(address _exchangeRouter, address _exchangeConnector) external;

    function removeExchangeConnector(uint _exchangeRouterIndex) external;

    function setPriceProxy(address _token, address _priceProxyAddress) external;

    function setAcceptableDelay(uint _acceptableDelay) external;

    function setOracleNativeToken(address _oracleNativeToken) external;
}

File 3 of 7 : IExchangeConnector.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0 <0.8.4;

interface IExchangeConnector {

    // Events
    
    event Swap(address[] path, uint[] amounts, address receiver);

    // Read-only functions

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

    function exchangeRouter() external view returns (address);

    function liquidityPoolFactory() external view returns (address);

    function wrappedNativeToken() external view returns (address);

    function getInputAmount(
        uint _outputAmount,
        address _inputToken,
        address _outputToken
    ) external view returns (bool, uint);

    function getOutputAmount(
        uint _inputAmount,
        address _inputToken,
        address _outputToken
    ) external view returns (bool, uint);

    // State-changing functions

    function setExchangeRouter(address _exchangeRouter) external;

    function setLiquidityPoolFactory() external;

    function setWrappedNativeToken() external;

    function swap(
        uint256 _inputAmount,
        uint256 _outputAmount,
        address[] memory _path,
        address _to,
        uint256 _deadline,
        bool _isFixedToken
    ) external returns (bool, uint[] memory);

    function isPathValid(address[] memory _path) external view returns(bool);
}

File 4 of 7 : 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 5 of 7 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 6 of 7 : SafeCast.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

File 7 of 7 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

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

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_acceptableDelay","type":"uint256"},{"internalType":"address","name":"_oracleNativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"exchangeRouter","type":"address"},{"indexed":true,"internalType":"address","name":"exchangeConnector","type":"address"}],"name":"ExchangeConnectorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"exchangeRouter","type":"address"}],"name":"ExchangeConnectorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldAcceptableDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newAcceptableDelay","type":"uint256"}],"name":"NewAcceptableDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOracleNativeToken","type":"address"},{"indexed":true,"internalType":"address","name":"newOracleNativeToken","type":"address"}],"name":"NewOracleNativeToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":true,"internalType":"address","name":"_priceProxyAddress","type":"address"}],"name":"SetPriceProxy","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ChainlinkPriceProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptableDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_exchangeRouter","type":"address"},{"internalType":"address","name":"_exchangeConnector","type":"address"}],"name":"addExchangeConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_inputDecimals","type":"uint256"},{"internalType":"uint256","name":"_outputDecimals","type":"uint256"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"address","name":"_outputToken","type":"address"}],"name":"equivalentOutputAmount","outputs":[{"internalType":"uint256","name":"_outputAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_inputDecimals","type":"uint256"},{"internalType":"uint256","name":"_outputDecimals","type":"uint256"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"address","name":"_outputToken","type":"address"}],"name":"equivalentOutputAmountByAverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_exchangeRouter","type":"address"},{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"address","name":"_outputToken","type":"address"}],"name":"equivalentOutputAmountFromExchange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_inputAmount","type":"uint256"},{"internalType":"uint256","name":"_inputDecimals","type":"uint256"},{"internalType":"uint256","name":"_outputDecimals","type":"uint256"},{"internalType":"address","name":"_inputToken","type":"address"},{"internalType":"address","name":"_outputToken","type":"address"}],"name":"equivalentOutputAmountFromOracle","outputs":[{"internalType":"uint256","name":"_outputAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"exchangeConnector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"exchangeRoutersList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchangeRoutersListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleNativeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_exchangeRouterIndex","type":"uint256"}],"name":"removeExchangeConnector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_acceptableDelay","type":"uint256"}],"name":"setAcceptableDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracleNativeToken","type":"address"}],"name":"setOracleNativeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_priceProxyAddress","type":"address"}],"name":"setPriceProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162001c4e38038062001c4e8339810160408190526200003491620001fa565b6200003f336200005d565b6200004a82620000ad565b620000558162000144565b505062000237565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60045460408051918252602082018390527f61fcc6fa9ba5b3ab5f72b919bc6324527ede6b5d73e12c63bbc4d4e0352e7002910160405180910390a1600081116200013f5760405162461bcd60e51b815260206004820152601860248201527f50726963654f7261636c653a207a65726f20616d6f756e74000000000000000060448201526064015b60405180910390fd5b600455565b806001600160a01b0381166200019d5760405162461bcd60e51b815260206004820152601960248201527f50726963654f7261636c653a207a65726f206164647265737300000000000000604482015260640162000136565b6005546040516001600160a01b038085169216907f4a6beeb37b9f482406bcaf6e918424d6a3d27c6e726f2934b56e75e086bd0a7990600090a350600580546001600160a01b0319166001600160a01b0392909216919091179055565b600080604083850312156200020d578182fd5b825160208401519092506001600160a01b03811681146200022c578182fd5b809150509250929050565b611a0780620002476000396000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c8063862efd4b116100ad578063e70f330311610071578063e70f330314610254578063f2e0b6a514610267578063f2fde38b1461027a578063f4fe5e6f1461028d578063fed5a0191461029557610121565b8063862efd4b146101fe5780638da5cb5b14610207578063ab44048414610161578063d86faec714610218578063de03d10d1461024157610121565b806331f7d964116100f457806331f7d964146101875780634205d68f146101a75780636fbd0657146101d0578063715018a6146101e357806385c44376146101eb57610121565b806304c9554414610126578063092307da1461013b57806316fac92a146101615780631d4a7b2114610174575b600080fd5b610139610134366004611576565b6102a8565b005b61014e6101493660046115ed565b6102e7565b6040519081526020015b60405180910390f35b61014e61016f366004611688565b6103be565b610139610182366004611670565b610494565b61018f600181565b6040516001600160a01b039091168152602001610158565b61018f6101b5366004611576565b6001602052600090815260409020546001600160a01b031681565b60055461018f906001600160a01b031681565b6101396104c7565b6101396101f93660046115b5565b6104f3565b61014e60045481565b6000546001600160a01b031661018f565b61018f610226366004611576565b6002602052600090815260409020546001600160a01b031681565b61013961024f366004611670565b61059c565b61018f610262366004611670565b6106b5565b6101396102753660046115b5565b6106df565b610139610288366004611576565b610869565b60035461014e565b61014e6102a3366004611688565b610901565b6000546001600160a01b031633146102db5760405162461bcd60e51b81526004016102d290611784565b60405180910390fd5b6102e481610acd565b50565b6000826001600160a01b0381166103105760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b0381166103375760405162461bcd60e51b81526004016102d29061174d565b60008061034689898989610b51565b90925090506001821515146103b25760405162461bcd60e51b815260206004820152602c60248201527f50726963654f7261636c653a205061697220646f6573206e6f7420657869737460448201526b206f6e2065786368616e676560a01b60648201526084016102d2565b98975050505050505050565b6000826001600160a01b0381166103e75760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b03811661040e5760405162461bcd60e51b81526004016102d29061174d565b600061041d8989898989610e30565b50945090506001811515146104885760405162461bcd60e51b815260206004820152602b60248201527f50726963654f7261636c653a206f7261636c65206e6f74206578697374206f7260448201526a20757020746f206461746560a81b60648201526084016102d2565b50505095945050505050565b6000546001600160a01b031633146104be5760405162461bcd60e51b81526004016102d290611784565b6102e4816112f8565b6000546001600160a01b031633146104f15760405162461bcd60e51b81526004016102d290611784565b565b816001600160a01b03811661051a5760405162461bcd60e51b81526004016102d29061174d565b6000546001600160a01b031633146105445760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0383811660008181526001602052604080822080546001600160a01b0319169487169485179055517f7a94f0ad15b775c1f9cbf924619ec6379ccf1230a329c8bb3243b48f495d88449190a3505050565b6000546001600160a01b031633146105c65760405162461bcd60e51b81526004016102d290611784565b60035481106106225760405162461bcd60e51b815260206004820152602260248201527f50726963654f7261636c653a20496e646578206973206f7574206f6620626f756044820152611b9960f21b60648201526084016102d2565b60006003828154811061064557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061066582611389565b6001600160a01b03811660008181526002602052604080822080546001600160a01b0319169055517fd4c309ca8e170bf136bae67942030e0ac2e3992e9ea36936196c38be6d67a47d9190a25050565b600381815481106106c557600080fd5b6000918252602090912001546001600160a01b0316905081565b816001600160a01b0381166107065760405162461bcd60e51b81526004016102d29061174d565b816001600160a01b03811661072d5760405162461bcd60e51b81526004016102d29061174d565b6000546001600160a01b031633146107575760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0384811660009081526002602052604090205416156107d35760405162461bcd60e51b815260206004820152602b60248201527f50726963654f7261636c653a2065786368616e676520726f7574657220616c7260448201526a656164792065786973747360a81b60648201526084016102d2565b60038054600181019091557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b038087166001600160a01b03199283168117909355600083815260026020526040808220805493891693909416831790935591519092917f19dd93282347163d78a1e91a8278207144203887305da5724821079ffcc138ad91a350505050565b6000546001600160a01b031633146108935760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0381166108f85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102d2565b6102e481611463565b6000826001600160a01b03811661092a5760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b0381166109515760405162461bcd60e51b81526004016102d29061174d565b60008060006109638b8b8b8b8b610e30565b9194509250905060018315151480156109a1575060045461099e610986426114b3565b61098f846114b3565b610999919061191b565b611525565b11155b156109b057509350610ac29050565b600080600185151514156109c5575082905060015b60005b600354811015610a4f57610a13600382815481106109f657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03168f8d8d610b51565b909650945060018615151415610a3d57610a2e8260016117b9565b9150610a3a85846117b9565b92505b80610a4781611971565b9150506109c8565b5060008111610ab05760405162461bcd60e51b815260206004820152602760248201527f50726963654f7261636c653a206e6f207072696365206665656420697320617660448201526661696c61626c6560c81b60648201526084016102d2565b610aba81836117d1565b975050505050505b505095945050505050565b806001600160a01b038116610af45760405162461bcd60e51b81526004016102d29061174d565b6005546040516001600160a01b038085169216907f4a6beeb37b9f482406bcaf6e918424d6a3d27c6e726f2934b56e75e086bd0a7990600090a350600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000806001600160a01b03841660011415610c99576001600160a01b0380871660009081526002602090815260408083205481516317fcb39b60e01b81529151939416926317fcb39b92600480840193919291829003018186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611599565b6001600160a01b038881166000908152600260205260409081902054905163df71d7f360e01b8152600481018a905283831660248201528783166044820152929350169063df71d7f3906064015b604080518083038186803b158015610c5557600080fd5b505afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d919061163f565b9093509150610e279050565b6001600160a01b03831660011415610d87576001600160a01b0380871660009081526002602090815260408083205481516317fcb39b60e01b81529151939416926317fcb39b92600480840193919291829003018186803b158015610cfd57600080fd5b505afa158015610d11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d359190611599565b6001600160a01b038881166000908152600260205260409081902054905163df71d7f360e01b8152600481018a905288831660248201528383166044820152929350169063df71d7f390606401610c3e565b6001600160a01b038681166000908152600260205260409081902054905163df71d7f360e01b8152600481018890528683166024820152858316604482015291169063df71d7f390606401604080518083038186803b158015610de957600080fd5b505afa158015610dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e21919061163f565b90925090505b94509492505050565b60008080808080806001600160a01b03891660011415610e59576005546001600160a01b031698505b6001600160a01b03881660011415610e7a576005546001600160a01b031697505b6001600160a01b038981166000908152600160205260409020541615801590610ebc57506001600160a01b038881166000908152600160205260409020541615155b156112dd57610ec961153e565b6001600160a01b03808b1660009081526001602052604090819020548151633fabe5a360e21b8152915192169163feaf968c9160048082019260a092909190829003018186803b158015610f1c57600080fd5b505afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5491906116dd565b508452509350839050610fb95760405162461bcd60e51b815260206004820152602760248201527f50726963654f7261636c653a207a65726f20707269636520666f7220696e70756044820152663a103a37b5b2b760c91b60648201526084016102d2565b6001600160a01b03808b1660009081526001602090815260409182902054825163313ce56760e01b8152925193169263313ce567926004808201939291829003018186803b15801561100a57600080fd5b505afa15801561101e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611042919061172c565b6001600160a01b03808b1660009081526001602052604090819020548151633fabe5a360e21b8152915160ff9490941698509091169163feaf968c9160048082019260a092909190829003018186803b15801561109e57600080fd5b505afa1580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d691906116dd565b50602085015250925082905061113f5760405162461bcd60e51b815260206004820152602860248201527f50726963654f7261636c653a207a65726f20707269636520666f72206f7574706044820152673aba103a37b5b2b760c11b60648201526084016102d2565b6001600160a01b03808a1660009081526001602090815260409182902054825163313ce56760e01b8152925193169263313ce567926004808201939291829003018186803b15801561119057600080fd5b505afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c8919061172c565b60ff1693506111d88b60016117b9565b6111e390600a61182e565b8d6111ef86600a61182e565b6111f990866118fc565b61120391906118fc565b61120d91906118fc565b965061121a85600a61182e565b61122490836118fc565b61122f8d60016117b9565b61123a90600a61182e565b61124491906118fc565b61124e90886117d1565b6004549097506112716112688360005b60200201516114b3565b61098f426114b3565b11156112925760008782825b602002015197509750975050505050506112ed565b6004546112a361126883600161125e565b11156112b45760008782600161127d565b60208101518151116112c75780516112cd565b60208101515b95506001975050505050506112ed565b6000806000965096509650505050505b955095509592505050565b60045460408051918252602082018390527f61fcc6fa9ba5b3ab5f72b919bc6324527ede6b5d73e12c63bbc4d4e0352e7002910160405180910390a1600081116113845760405162461bcd60e51b815260206004820152601860248201527f50726963654f7261636c653a207a65726f20616d6f756e74000000000000000060448201526064016102d2565b600455565b600380546113999060019061195a565b815481106113b757634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600380546001600160a01b0390921691839081106113f157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600380548061143e57634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b031916905501905550565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600160ff1b0382111561151d5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016102d2565b50805b919050565b60008082121561151d576115388261198c565b92915050565b60405180604001604052806002906020820280368337509192915050565b805169ffffffffffffffffffff8116811461152057600080fd5b600060208284031215611587578081fd5b8135611592816119bc565b9392505050565b6000602082840312156115aa578081fd5b8151611592816119bc565b600080604083850312156115c7578081fd5b82356115d2816119bc565b915060208301356115e2816119bc565b809150509250929050565b60008060008060808587031215611602578182fd5b843561160d816119bc565b9350602085013592506040850135611624816119bc565b91506060850135611634816119bc565b939692955090935050565b60008060408385031215611651578182fd5b82518015158114611660578283fd5b6020939093015192949293505050565b600060208284031215611681578081fd5b5035919050565b600080600080600060a0868803121561169f578081fd5b85359450602086013593506040860135925060608601356116bf816119bc565b915060808601356116cf816119bc565b809150509295509295909350565b600080600080600060a086880312156116f4578081fd5b6116fd8661155c565b94506020860151935060408601519250606086015191506117206080870161155c565b90509295509295909350565b60006020828403121561173d578081fd5b815160ff81168114611592578182fd5b60208082526019908201527f50726963654f7261636c653a207a65726f206164647265737300000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156117cc576117cc6119a6565b500190565b6000826117ec57634e487b7160e01b81526012600452602481fd5b500490565b80825b60018086116118035750610e27565b818704821115611815576118156119a6565b8086161561182257918102915b9490941c9380026117f4565b6000611592600019848460008261184757506001611592565b8161185457506000611592565b816001811461186a5760028114611874576118a1565b6001915050611592565b60ff841115611885576118856119a6565b6001841b91508482111561189b5761189b6119a6565b50611592565b5060208310610133831016604e8410600b84101617156118d4575081810a838111156118cf576118cf6119a6565b611592565b6118e184848460016117f1565b8086048211156118f3576118f36119a6565b02949350505050565b6000816000190483118215151615611916576119166119a6565b500290565b60008083128015600160ff1b850184121615611939576119396119a6565b6001600160ff1b0384018313811615611954576119546119a6565b50500390565b60008282101561196c5761196c6119a6565b500390565b6000600019821415611985576119856119a6565b5060010190565b6000600160ff1b8214156119a2576119a26119a6565b0390565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146102e457600080fdfea2646970667358221220e331187a6f947dbbc792a3af44f9645ec3733b750880bc55b5618b37c26bee5264736f6c6343000802003300000000000000000000000000000000000000000000000000000000000003840000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb032889

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

00000000000000000000000000000000000000000000000000000000000003840000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb032889

-----Decoded View---------------
Arg [0] : _acceptableDelay (uint256): 900
Arg [1] : _oracleNativeToken (address): 0x9c3c9283d3e44854697cd22d3faa240cfb032889

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000384
Arg [1] : 0000000000000000000000009c3c9283d3e44854697cd22d3faa240cfb032889


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading