Contract Overview
Balance:
0 MATIC
My Name Tag:
Not Available
[ Download CSV Export ]
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)
// 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); } }
// 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; }
// 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); }
// 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 ); }
// 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); } }
// 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); } }
// 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; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"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"}]
Contract Creation Code
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
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|