Mumbai Testnet

Contract

0x96B76aB42289688b68882CDcCd071B2C39b0165E
Transaction Hash
Method
Block
From
To
Value
Set Price Proxy400517812023-09-12 23:05:16198 days ago1694559916IN
0x96B76aB4...C39b0165E
0 MATIC0.000077292.50000001
Set Price Proxy400517812023-09-12 23:05:16198 days ago1694559916IN
0x96B76aB4...C39b0165E
0 MATIC0.000093432.99999999
Set Price Proxy347516772023-04-24 2:08:59340 days ago1682302139IN
0x96B76aB4...C39b0165E
0 MATIC0.000031141.00000001
Set Price Proxy347513762023-04-24 1:58:21340 days ago1682301501IN
0x96B76aB4...C39b0165E
0 MATIC0.000030911.00000001
Add Exchange Con...340563892023-04-06 23:42:25357 days ago1680824545IN
0x96B76aB4...C39b0165E
0 MATIC0.0001892.50000001
Set Price Proxy318617862023-02-08 23:53:31414 days ago1675900411IN
0x96B76aB4...C39b0165E
0 MATIC0.0048245100
Set Price Proxy318617832023-02-08 23:53:19414 days ago1675900399IN
0x96B76aB4...C39b0165E
0 MATIC0.01688575350
Set Price Proxy318617832023-02-08 23:53:19414 days ago1675900399IN
0x96B76aB4...C39b0165E
0 MATIC0.01688155350
Set Price Proxy318617832023-02-08 23:53:19414 days ago1675900399IN
0x96B76aB4...C39b0165E
0 MATIC0.000072021.50000001
Set Price Proxy318617792023-02-08 23:53:03414 days ago1675900383IN
0x96B76aB4...C39b0165E
0 MATIC0.0048245100.00000002
Add Exchange Con...318616052023-02-08 23:44:49414 days ago1675899889IN
0x96B76aB4...C39b0165E
0 MATIC0.0082595889.10012375
0x60806040318611172023-02-08 23:21:27414 days ago1675898487IN
 Contract Creation
0 MATIC0.00235861.50000001

Parent Txn Hash Block From To Value
View All Internal Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x598221b8...430Ed397f
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
PriceOracle

Compiler Version
v0.8.2+commit.661d1103

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

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"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101215760003560e01c8063862efd4b116100ad578063e70f330311610071578063e70f330314610254578063f2e0b6a514610267578063f2fde38b1461027a578063f4fe5e6f1461028d578063fed5a0191461029557610121565b8063862efd4b146101fe5780638da5cb5b14610207578063ab44048414610161578063d86faec714610218578063de03d10d1461024157610121565b806331f7d964116100f457806331f7d964146101875780634205d68f146101a75780636fbd0657146101d0578063715018a6146101e357806385c44376146101eb57610121565b806304c9554414610126578063092307da1461013b57806316fac92a146101615780631d4a7b2114610174575b600080fd5b610139610134366004611576565b6102a8565b005b61014e6101493660046115ed565b6102e7565b6040519081526020015b60405180910390f35b61014e61016f366004611688565b6103be565b610139610182366004611670565b610494565b61018f600181565b6040516001600160a01b039091168152602001610158565b61018f6101b5366004611576565b6001602052600090815260409020546001600160a01b031681565b60055461018f906001600160a01b031681565b6101396104c7565b6101396101f93660046115b5565b6104f3565b61014e60045481565b6000546001600160a01b031661018f565b61018f610226366004611576565b6002602052600090815260409020546001600160a01b031681565b61013961024f366004611670565b61059c565b61018f610262366004611670565b6106b5565b6101396102753660046115b5565b6106df565b610139610288366004611576565b610869565b60035461014e565b61014e6102a3366004611688565b610901565b6000546001600160a01b031633146102db5760405162461bcd60e51b81526004016102d290611784565b60405180910390fd5b6102e481610acd565b50565b6000826001600160a01b0381166103105760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b0381166103375760405162461bcd60e51b81526004016102d29061174d565b60008061034689898989610b51565b90925090506001821515146103b25760405162461bcd60e51b815260206004820152602c60248201527f50726963654f7261636c653a205061697220646f6573206e6f7420657869737460448201526b206f6e2065786368616e676560a01b60648201526084016102d2565b98975050505050505050565b6000826001600160a01b0381166103e75760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b03811661040e5760405162461bcd60e51b81526004016102d29061174d565b600061041d8989898989610e30565b50945090506001811515146104885760405162461bcd60e51b815260206004820152602b60248201527f50726963654f7261636c653a206f7261636c65206e6f74206578697374206f7260448201526a20757020746f206461746560a81b60648201526084016102d2565b50505095945050505050565b6000546001600160a01b031633146104be5760405162461bcd60e51b81526004016102d290611784565b6102e4816112f8565b6000546001600160a01b031633146104f15760405162461bcd60e51b81526004016102d290611784565b565b816001600160a01b03811661051a5760405162461bcd60e51b81526004016102d29061174d565b6000546001600160a01b031633146105445760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0383811660008181526001602052604080822080546001600160a01b0319169487169485179055517f7a94f0ad15b775c1f9cbf924619ec6379ccf1230a329c8bb3243b48f495d88449190a3505050565b6000546001600160a01b031633146105c65760405162461bcd60e51b81526004016102d290611784565b60035481106106225760405162461bcd60e51b815260206004820152602260248201527f50726963654f7261636c653a20496e646578206973206f7574206f6620626f756044820152611b9960f21b60648201526084016102d2565b60006003828154811061064557634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b0316905061066582611389565b6001600160a01b03811660008181526002602052604080822080546001600160a01b0319169055517fd4c309ca8e170bf136bae67942030e0ac2e3992e9ea36936196c38be6d67a47d9190a25050565b600381815481106106c557600080fd5b6000918252602090912001546001600160a01b0316905081565b816001600160a01b0381166107065760405162461bcd60e51b81526004016102d29061174d565b816001600160a01b03811661072d5760405162461bcd60e51b81526004016102d29061174d565b6000546001600160a01b031633146107575760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0384811660009081526002602052604090205416156107d35760405162461bcd60e51b815260206004820152602b60248201527f50726963654f7261636c653a2065786368616e676520726f7574657220616c7260448201526a656164792065786973747360a81b60648201526084016102d2565b60038054600181019091557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b038087166001600160a01b03199283168117909355600083815260026020526040808220805493891693909416831790935591519092917f19dd93282347163d78a1e91a8278207144203887305da5724821079ffcc138ad91a350505050565b6000546001600160a01b031633146108935760405162461bcd60e51b81526004016102d290611784565b6001600160a01b0381166108f85760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016102d2565b6102e481611463565b6000826001600160a01b03811661092a5760405162461bcd60e51b81526004016102d29061174d565b826001600160a01b0381166109515760405162461bcd60e51b81526004016102d29061174d565b60008060006109638b8b8b8b8b610e30565b9194509250905060018315151480156109a1575060045461099e610986426114b3565b61098f846114b3565b610999919061191b565b611525565b11155b156109b057509350610ac29050565b600080600185151514156109c5575082905060015b60005b600354811015610a4f57610a13600382815481106109f657634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03168f8d8d610b51565b909650945060018615151415610a3d57610a2e8260016117b9565b9150610a3a85846117b9565b92505b80610a4781611971565b9150506109c8565b5060008111610ab05760405162461bcd60e51b815260206004820152602760248201527f50726963654f7261636c653a206e6f207072696365206665656420697320617660448201526661696c61626c6560c81b60648201526084016102d2565b610aba81836117d1565b975050505050505b505095945050505050565b806001600160a01b038116610af45760405162461bcd60e51b81526004016102d29061174d565b6005546040516001600160a01b038085169216907f4a6beeb37b9f482406bcaf6e918424d6a3d27c6e726f2934b56e75e086bd0a7990600090a350600580546001600160a01b0319166001600160a01b0392909216919091179055565b6000806001600160a01b03841660011415610c99576001600160a01b0380871660009081526002602090815260408083205481516317fcb39b60e01b81529151939416926317fcb39b92600480840193919291829003018186803b158015610bb857600080fd5b505afa158015610bcc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf09190611599565b6001600160a01b038881166000908152600260205260409081902054905163df71d7f360e01b8152600481018a905283831660248201528783166044820152929350169063df71d7f3906064015b604080518083038186803b158015610c5557600080fd5b505afa158015610c69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8d919061163f565b9093509150610e279050565b6001600160a01b03831660011415610d87576001600160a01b0380871660009081526002602090815260408083205481516317fcb39b60e01b81529151939416926317fcb39b92600480840193919291829003018186803b158015610cfd57600080fd5b505afa158015610d11573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d359190611599565b6001600160a01b038881166000908152600260205260409081902054905163df71d7f360e01b8152600481018a905288831660248201528383166044820152929350169063df71d7f390606401610c3e565b6001600160a01b038681166000908152600260205260409081902054905163df71d7f360e01b8152600481018890528683166024820152858316604482015291169063df71d7f390606401604080518083038186803b158015610de957600080fd5b505afa158015610dfd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e21919061163f565b90925090505b94509492505050565b60008080808080806001600160a01b03891660011415610e59576005546001600160a01b031698505b6001600160a01b03881660011415610e7a576005546001600160a01b031697505b6001600160a01b038981166000908152600160205260409020541615801590610ebc57506001600160a01b038881166000908152600160205260409020541615155b156112dd57610ec961153e565b6001600160a01b03808b1660009081526001602052604090819020548151633fabe5a360e21b8152915192169163feaf968c9160048082019260a092909190829003018186803b158015610f1c57600080fd5b505afa158015610f30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f5491906116dd565b508452509350839050610fb95760405162461bcd60e51b815260206004820152602760248201527f50726963654f7261636c653a207a65726f20707269636520666f7220696e70756044820152663a103a37b5b2b760c91b60648201526084016102d2565b6001600160a01b03808b1660009081526001602090815260409182902054825163313ce56760e01b8152925193169263313ce567926004808201939291829003018186803b15801561100a57600080fd5b505afa15801561101e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611042919061172c565b6001600160a01b03808b1660009081526001602052604090819020548151633fabe5a360e21b8152915160ff9490941698509091169163feaf968c9160048082019260a092909190829003018186803b15801561109e57600080fd5b505afa1580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d691906116dd565b50602085015250925082905061113f5760405162461bcd60e51b815260206004820152602860248201527f50726963654f7261636c653a207a65726f20707269636520666f72206f7574706044820152673aba103a37b5b2b760c11b60648201526084016102d2565b6001600160a01b03808a1660009081526001602090815260409182902054825163313ce56760e01b8152925193169263313ce567926004808201939291829003018186803b15801561119057600080fd5b505afa1580156111a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111c8919061172c565b60ff1693506111d88b60016117b9565b6111e390600a61182e565b8d6111ef86600a61182e565b6111f990866118fc565b61120391906118fc565b61120d91906118fc565b965061121a85600a61182e565b61122490836118fc565b61122f8d60016117b9565b61123a90600a61182e565b61124491906118fc565b61124e90886117d1565b6004549097506112716112688360005b60200201516114b3565b61098f426114b3565b11156112925760008782825b602002015197509750975050505050506112ed565b6004546112a361126883600161125e565b11156112b45760008782600161127d565b60208101518151116112c75780516112cd565b60208101515b95506001975050505050506112ed565b6000806000965096509650505050505b955095509592505050565b60045460408051918252602082018390527f61fcc6fa9ba5b3ab5f72b919bc6324527ede6b5d73e12c63bbc4d4e0352e7002910160405180910390a1600081116113845760405162461bcd60e51b815260206004820152601860248201527f50726963654f7261636c653a207a65726f20616d6f756e74000000000000000060448201526064016102d2565b600455565b600380546113999060019061195a565b815481106113b757634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600380546001600160a01b0390921691839081106113f157634e487b7160e01b600052603260045260246000fd5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600380548061143e57634e487b7160e01b600052603160045260246000fd5b600082815260209020810160001990810180546001600160a01b031916905501905550565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600160ff1b0382111561151d5760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b60648201526084016102d2565b50805b919050565b60008082121561151d576115388261198c565b92915050565b60405180604001604052806002906020820280368337509192915050565b805169ffffffffffffffffffff8116811461152057600080fd5b600060208284031215611587578081fd5b8135611592816119bc565b9392505050565b6000602082840312156115aa578081fd5b8151611592816119bc565b600080604083850312156115c7578081fd5b82356115d2816119bc565b915060208301356115e2816119bc565b809150509250929050565b60008060008060808587031215611602578182fd5b843561160d816119bc565b9350602085013592506040850135611624816119bc565b91506060850135611634816119bc565b939692955090935050565b60008060408385031215611651578182fd5b82518015158114611660578283fd5b6020939093015192949293505050565b600060208284031215611681578081fd5b5035919050565b600080600080600060a0868803121561169f578081fd5b85359450602086013593506040860135925060608601356116bf816119bc565b915060808601356116cf816119bc565b809150509295509295909350565b600080600080600060a086880312156116f4578081fd5b6116fd8661155c565b94506020860151935060408601519250606086015191506117206080870161155c565b90509295509295909350565b60006020828403121561173d578081fd5b815160ff81168114611592578182fd5b60208082526019908201527f50726963654f7261636c653a207a65726f206164647265737300000000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082198211156117cc576117cc6119a6565b500190565b6000826117ec57634e487b7160e01b81526012600452602481fd5b500490565b80825b60018086116118035750610e27565b818704821115611815576118156119a6565b8086161561182257918102915b9490941c9380026117f4565b6000611592600019848460008261184757506001611592565b8161185457506000611592565b816001811461186a5760028114611874576118a1565b6001915050611592565b60ff841115611885576118856119a6565b6001841b91508482111561189b5761189b6119a6565b50611592565b5060208310610133831016604e8410600b84101617156118d4575081810a838111156118cf576118cf6119a6565b611592565b6118e184848460016117f1565b8086048211156118f3576118f36119a6565b02949350505050565b6000816000190483118215151615611916576119166119a6565b500290565b60008083128015600160ff1b850184121615611939576119396119a6565b6001600160ff1b0384018313811615611954576119546119a6565b50500390565b60008282101561196c5761196c6119a6565b500390565b6000600019821415611985576119856119a6565b5060010190565b6000600160ff1b8214156119a2576119a26119a6565b0390565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b03811681146102e457600080fdfea2646970667358221220e331187a6f947dbbc792a3af44f9645ec3733b750880bc55b5618b37c26bee5264736f6c63430008020033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

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