编译器
0.8.14+commit.80d49f37
文件 1 的 11:Address.sol
pragma solidity ^0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 11:AggregatorV3Interface.sol
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
);
}
文件 3 的 11:BaseMath.sol
pragma solidity ^0.8.14;
abstract contract BaseMath {
uint256 public constant DECIMAL_PRECISION = 1 ether;
}
文件 4 的 11:CheckContract.sol
pragma solidity ^0.8.14;
contract CheckContract {
function checkContract(address _account) internal view {
require(_account != address(0), "Account cannot be zero address");
uint256 size;
assembly {
size := extcodesize(_account)
}
require(size > 0, "Account code size cannot be zero");
}
}
文件 5 的 11:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 6 的 11:DfrancMath.sol
pragma solidity ^0.8.14;
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
library DfrancMath {
using SafeMath for uint256;
uint256 internal constant DECIMAL_PRECISION = 1 ether;
uint256 internal constant NICR_PRECISION = 1e20;
function _min(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a < _b) ? _a : _b;
}
function _max(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? _a : _b;
}
function decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) {
uint256 prod_xy = x.mul(y);
decProd = prod_xy.add(DECIMAL_PRECISION / 2).div(DECIMAL_PRECISION);
}
function _decPow(uint256 _base, uint256 _minutes) internal pure returns (uint256) {
if (_minutes > 525600000) {
_minutes = 525600000;
}
if (_minutes == 0) {
return DECIMAL_PRECISION;
}
uint256 y = DECIMAL_PRECISION;
uint256 x = _base;
uint256 n = _minutes;
while (n > 1) {
if (n % 2 == 0) {
x = decMul(x, x);
n = n.div(2);
} else {
y = decMul(x, y);
x = decMul(x, x);
n = (n.sub(1)).div(2);
}
}
return decMul(x, y);
}
function _getAbsoluteDifference(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? _a.sub(_b) : _b.sub(_a);
}
function _computeNominalCR(uint256 _coll, uint256 _debt) internal pure returns (uint256) {
if (_debt > 0) {
return _coll.mul(NICR_PRECISION).div(_debt);
}
else {
return 2**256 - 1;
}
}
function _computeCR(
uint256 _coll,
uint256 _debt,
uint256 _price
) internal pure returns (uint256) {
if (_debt > 0) {
return _coll.mul(_price).div(_debt);
}
else {
return type(uint256).max;
}
}
}
文件 7 的 11:IPriceFeed.sol
import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
pragma solidity ^0.8.14;
interface IPriceFeed {
struct ChainlinkResponse {
uint80 roundId;
int256 answer;
uint256 timestamp;
bool success;
uint8 decimals;
}
struct RegisterOracle {
AggregatorV3Interface chainLinkOracle;
AggregatorV3Interface chainLinkIndex;
bool isRegistered;
}
enum Status {
chainlinkWorking,
chainlinkUntrusted
}
event PriceFeedStatusChanged(Status newStatus);
event LastGoodPriceUpdated(address indexed token, uint256 _lastGoodPrice);
event LastGoodIndexUpdated(address indexed token, uint256 _lastGoodIndex);
event RegisteredNewOracle(
address token,
address chainLinkAggregator,
address chianLinkIndex
);
function addOracle(
address _token,
address _chainlinkOracle,
address _chainlinkIndexOracle
) external;
function fetchPrice(address _token) external returns (uint256);
function getDirectPrice(address _asset) external returns (uint256);
}
文件 8 的 11:Initializable.sol
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/utils/Address.sol";
abstract contract Initializable {
uint8 private _initialized;
bool private _initializing;
event Initialized(uint8 version);
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
文件 9 的 11:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
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);
}
}
文件 10 的 11:PriceFeed.sol
pragma solidity ^0.8.14;
import "./Interfaces/IPriceFeed.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./Dependencies/CheckContract.sol";
import "./Dependencies/BaseMath.sol";
import "./Dependencies/DfrancMath.sol";
import "./Dependencies/Initializable.sol";
contract PriceFeed is Ownable, CheckContract, BaseMath, Initializable, IPriceFeed {
using SafeMath for uint256;
string public constant NAME = "PriceFeed";
uint256 public constant TARGET_DIGITS = 18;
uint256 public constant TIMEOUT = 4 hours;
uint256 public constant MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND = 5e17;
uint256 public constant MAX_PRICE_DIFFERENCE_BETWEEN_ORACLES = 5e16;
bool public isInitialized;
address public adminContract;
IPriceFeed.Status public status;
mapping(address => RegisterOracle) public registeredOracles;
mapping(address => uint256) public lastGoodPrice;
mapping(address => uint256) public lastGoodIndex;
modifier isController() {
require(msg.sender == owner() || msg.sender == adminContract, "Invalid Permission");
_;
}
function setAddresses(address _adminContract) external initializer onlyOwner {
require(!isInitialized, "Already initialized");
checkContract(_adminContract);
isInitialized = true;
adminContract = _adminContract;
status = Status.chainlinkWorking;
}
function setAdminContract(address _admin) external onlyOwner {
require(_admin != address(0), "Admin address is zero");
checkContract(_admin);
adminContract = _admin;
}
function addOracle(
address _token,
address _chainlinkOracle,
address _chainlinkIndexOracle
) external override isController {
AggregatorV3Interface priceOracle = AggregatorV3Interface(_chainlinkOracle);
AggregatorV3Interface indexOracle = AggregatorV3Interface(_chainlinkIndexOracle);
registeredOracles[_token] = RegisterOracle(priceOracle, indexOracle, true);
(
ChainlinkResponse memory chainlinkResponse,
ChainlinkResponse memory prevChainlinkResponse,
ChainlinkResponse memory chainlinkIndexResponse,
ChainlinkResponse memory prevChainlinkIndexResponse
) = _getChainlinkResponses(priceOracle, indexOracle);
require(
!_chainlinkIsBroken(chainlinkResponse, prevChainlinkResponse) &&
!_chainlinkIsFrozen(chainlinkResponse),
"PriceFeed: Chainlink must be working and current"
);
require(
!_chainlinkIsBroken(chainlinkIndexResponse, prevChainlinkIndexResponse),
"PriceFeed: Chainlink must be working and current"
);
_storeChainlinkPrice(_token, chainlinkResponse);
_storeChainlinkIndex(_token, chainlinkIndexResponse);
emit RegisteredNewOracle(_token, _chainlinkOracle, _chainlinkIndexOracle);
}
function getDirectPrice(address _asset) public view returns (uint256 _priceAssetInDCHF) {
RegisterOracle memory oracle = registeredOracles[_asset];
(
ChainlinkResponse memory chainlinkResponse,
,
ChainlinkResponse memory chainlinkIndexResponse,
) = _getChainlinkResponses(oracle.chainLinkOracle, oracle.chainLinkIndex);
uint256 scaledChainlinkPrice = _scaleChainlinkPriceByDigits(
uint256(chainlinkResponse.answer),
chainlinkResponse.decimals
);
uint256 scaledChainlinkIndexPrice = _scaleChainlinkPriceByDigits(
uint256(chainlinkIndexResponse.answer),
chainlinkIndexResponse.decimals
);
_priceAssetInDCHF = scaledChainlinkPrice.mul(1 ether).div(scaledChainlinkIndexPrice);
}
function fetchPrice(address _token) external override returns (uint256) {
RegisterOracle storage oracle = registeredOracles[_token];
require(oracle.isRegistered, "Oracle is not registered!");
(
ChainlinkResponse memory chainlinkResponse,
ChainlinkResponse memory prevChainlinkResponse,
ChainlinkResponse memory chainlinkIndexResponse,
ChainlinkResponse memory prevChainlinkIndexResponse
) = _getChainlinkResponses(oracle.chainLinkOracle, oracle.chainLinkIndex);
uint256 lastTokenGoodPrice = lastGoodPrice[_token];
uint256 lastTokenGoodIndex = lastGoodIndex[_token];
bool isChainlinkOracleBroken = _chainlinkIsBroken(
chainlinkResponse,
prevChainlinkResponse
) || _chainlinkIsFrozen(chainlinkResponse);
bool isChainlinkIndexBroken = _chainlinkIsBroken(
chainlinkIndexResponse,
prevChainlinkIndexResponse
);
if (status == Status.chainlinkWorking) {
if (isChainlinkOracleBroken || isChainlinkIndexBroken) {
if (!isChainlinkOracleBroken) {
lastTokenGoodPrice = _storeChainlinkPrice(_token, chainlinkResponse);
}
if (!isChainlinkIndexBroken) {
lastTokenGoodIndex = _storeChainlinkIndex(_token, chainlinkIndexResponse);
}
_changeStatus(Status.chainlinkUntrusted);
return _getIndexedPrice(lastTokenGoodPrice, lastTokenGoodIndex);
}
if (_chainlinkPriceChangeAboveMax(chainlinkResponse, prevChainlinkResponse)) {
return _getIndexedPrice(lastTokenGoodPrice, lastTokenGoodIndex);
}
lastTokenGoodPrice = _storeChainlinkPrice(_token, chainlinkResponse);
lastTokenGoodIndex = _storeChainlinkIndex(_token, chainlinkIndexResponse);
return _getIndexedPrice(lastTokenGoodPrice, lastTokenGoodIndex);
}
if (status == Status.chainlinkUntrusted) {
if (!isChainlinkOracleBroken && !isChainlinkIndexBroken) {
_changeStatus(Status.chainlinkWorking);
}
if (!isChainlinkOracleBroken) {
lastTokenGoodPrice = _storeChainlinkPrice(_token, chainlinkResponse);
}
if (!isChainlinkIndexBroken) {
lastTokenGoodIndex = _storeChainlinkIndex(_token, chainlinkIndexResponse);
}
return _getIndexedPrice(lastTokenGoodPrice, lastTokenGoodIndex);
}
return _getIndexedPrice(lastTokenGoodPrice, lastTokenGoodIndex);
}
function _getIndexedPrice(uint256 _price, uint256 _index) internal pure returns (uint256) {
return _price.mul(1 ether).div(_index);
}
function _getChainlinkResponses(
AggregatorV3Interface _chainLinkOracle,
AggregatorV3Interface _chainLinkIndexOracle
)
internal
view
returns (
ChainlinkResponse memory currentChainlink,
ChainlinkResponse memory prevChainLink,
ChainlinkResponse memory currentChainlinkIndex,
ChainlinkResponse memory prevChainLinkIndex
)
{
currentChainlink = _getCurrentChainlinkResponse(_chainLinkOracle);
prevChainLink = _getPrevChainlinkResponse(
_chainLinkOracle,
currentChainlink.roundId,
currentChainlink.decimals
);
if (address(_chainLinkIndexOracle) != address(0)) {
currentChainlinkIndex = _getCurrentChainlinkResponse(_chainLinkIndexOracle);
prevChainLinkIndex = _getPrevChainlinkResponse(
_chainLinkIndexOracle,
currentChainlinkIndex.roundId,
currentChainlinkIndex.decimals
);
} else {
currentChainlinkIndex = ChainlinkResponse(1, 1 ether, block.timestamp, true, 18);
prevChainLinkIndex = currentChainlinkIndex;
}
return (currentChainlink, prevChainLink, currentChainlinkIndex, prevChainLinkIndex);
}
function _chainlinkIsBroken(
ChainlinkResponse memory _currentResponse,
ChainlinkResponse memory _prevResponse
) internal view returns (bool) {
return _badChainlinkResponse(_currentResponse) || _badChainlinkResponse(_prevResponse);
}
function _badChainlinkResponse(ChainlinkResponse memory _response)
internal
view
returns (bool)
{
if (!_response.success) {
return true;
}
if (_response.roundId == 0) {
return true;
}
if (_response.timestamp == 0 || _response.timestamp > block.timestamp) {
return true;
}
if (_response.answer <= 0) {
return true;
}
return false;
}
function _chainlinkIsFrozen(ChainlinkResponse memory _response)
internal
view
returns (bool)
{
return block.timestamp.sub(_response.timestamp) > TIMEOUT;
}
function _chainlinkPriceChangeAboveMax(
ChainlinkResponse memory _currentResponse,
ChainlinkResponse memory _prevResponse
) internal pure returns (bool) {
uint256 currentScaledPrice = _scaleChainlinkPriceByDigits(
uint256(_currentResponse.answer),
_currentResponse.decimals
);
uint256 prevScaledPrice = _scaleChainlinkPriceByDigits(
uint256(_prevResponse.answer),
_prevResponse.decimals
);
uint256 minPrice = DfrancMath._min(currentScaledPrice, prevScaledPrice);
uint256 maxPrice = DfrancMath._max(currentScaledPrice, prevScaledPrice);
uint256 percentDeviation = maxPrice.sub(minPrice).mul(DECIMAL_PRECISION).div(maxPrice);
return percentDeviation > MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND;
}
function _scaleChainlinkPriceByDigits(uint256 _price, uint256 _answerDigits)
internal
pure
returns (uint256)
{
uint256 price;
if (_answerDigits >= TARGET_DIGITS) {
price = _price.div(10**(_answerDigits - TARGET_DIGITS));
} else if (_answerDigits < TARGET_DIGITS) {
price = _price.mul(10**(TARGET_DIGITS - _answerDigits));
}
return price;
}
function _changeStatus(Status _status) internal {
status = _status;
emit PriceFeedStatusChanged(_status);
}
function _storeChainlinkIndex(
address _token,
ChainlinkResponse memory _chainlinkIndexResponse
) internal returns (uint256) {
uint256 scaledChainlinkIndex = _scaleChainlinkPriceByDigits(
uint256(_chainlinkIndexResponse.answer),
_chainlinkIndexResponse.decimals
);
_storeIndex(_token, scaledChainlinkIndex);
return scaledChainlinkIndex;
}
function _storeChainlinkPrice(address _token, ChainlinkResponse memory _chainlinkResponse)
internal
returns (uint256)
{
uint256 scaledChainlinkPrice = _scaleChainlinkPriceByDigits(
uint256(_chainlinkResponse.answer),
_chainlinkResponse.decimals
);
_storePrice(_token, scaledChainlinkPrice);
return scaledChainlinkPrice;
}
function _storePrice(address _token, uint256 _currentPrice) internal {
lastGoodPrice[_token] = _currentPrice;
emit LastGoodPriceUpdated(_token, _currentPrice);
}
function _storeIndex(address _token, uint256 _currentIndex) internal {
lastGoodIndex[_token] = _currentIndex;
emit LastGoodIndexUpdated(_token, _currentIndex);
}
function _getCurrentChainlinkResponse(AggregatorV3Interface _priceAggregator)
internal
view
returns (ChainlinkResponse memory chainlinkResponse)
{
try _priceAggregator.decimals() returns (uint8 decimals) {
chainlinkResponse.decimals = decimals;
} catch {
return chainlinkResponse;
}
try _priceAggregator.latestRoundData() returns (
uint80 roundId,
int256 answer,
uint256,
uint256 timestamp,
uint80
) {
chainlinkResponse.roundId = roundId;
chainlinkResponse.answer = answer;
chainlinkResponse.timestamp = timestamp;
chainlinkResponse.success = true;
return chainlinkResponse;
} catch {
return chainlinkResponse;
}
}
function _getPrevChainlinkResponse(
AggregatorV3Interface _priceAggregator,
uint80 _currentRoundId,
uint8 _currentDecimals
) internal view returns (ChainlinkResponse memory prevChainlinkResponse) {
if (_currentRoundId == 0) {
return prevChainlinkResponse;
}
unchecked {
try _priceAggregator.getRoundData(_currentRoundId - 1) returns (
uint80 roundId,
int256 answer,
uint256,
uint256 timestamp,
uint80
) {
prevChainlinkResponse.roundId = roundId;
prevChainlinkResponse.answer = answer;
prevChainlinkResponse.timestamp = timestamp;
prevChainlinkResponse.decimals = _currentDecimals;
prevChainlinkResponse.success = true;
return prevChainlinkResponse;
} catch {
return prevChainlinkResponse;
}
}
}
}
文件 11 的 11:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
{
"compilationTarget": {
"contracts/PriceFeed.sol": "PriceFeed"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_lastGoodIndex","type":"uint256"}],"name":"LastGoodIndexUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_lastGoodPrice","type":"uint256"}],"name":"LastGoodPriceUpdated","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":false,"internalType":"enum IPriceFeed.Status","name":"newStatus","type":"uint8"}],"name":"PriceFeedStatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"chainLinkAggregator","type":"address"},{"indexed":false,"internalType":"address","name":"chianLinkIndex","type":"address"}],"name":"RegisteredNewOracle","type":"event"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRICE_DEVIATION_FROM_PREVIOUS_ROUND","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRICE_DIFFERENCE_BETWEEN_ORACLES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NAME","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TARGET_DIGITS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TIMEOUT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_chainlinkOracle","type":"address"},{"internalType":"address","name":"_chainlinkIndexOracle","type":"address"}],"name":"addOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"fetchPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getDirectPrice","outputs":[{"internalType":"uint256","name":"_priceAssetInDCHF","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastGoodIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastGoodPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"registeredOracles","outputs":[{"internalType":"contract AggregatorV3Interface","name":"chainLinkOracle","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"chainLinkIndex","type":"address"},{"internalType":"bool","name":"isRegistered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adminContract","type":"address"}],"name":"setAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"setAdminContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"status","outputs":[{"internalType":"enum IPriceFeed.Status","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]