-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPriceFeed.sol
68 lines (56 loc) · 2.75 KB
/
PriceFeed.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPDX-License-Identifier: MIT
pragma solidity 0.6.11;
import "./Interfaces/IPriceFeed.sol";
import "./Dependencies/CheckContract.sol";
import "./PriceFeedStorage.sol";
/// @title The system price feed adapter
/// @notice The PriceFeed relies upon a main oracle and a secondary as a fallback in case of error
contract PriceFeed is PriceFeedStorage, IPriceFeed {
event LastGoodPriceUpdated(uint256 _lastGoodPrice);
event PriceFeedBroken(uint8 index, address priceFeedAddress);
event PriceFeedUpdated(uint8 index, address newPriceFeedAddress);
// --- Dependency setters ---
function setAddresses(address _mainPriceFeed, address _backupPriceFeed) external onlyOwner {
uint256 latestPrice = setAddress(0, _mainPriceFeed);
setAddress(1, _backupPriceFeed);
_storePrice(latestPrice);
}
// --- Functions ---
/// @notice Returns the latest price obtained from the Oracle. Called by Zero functions that require a current price.
/// It uses the main price feed and fallback to the backup one in case of an error. If both fail return the last
/// good price seen. Function will rever if got false success flag from the medianizer contract.
/// @dev It's also callable by anyone externally
/// @return The price
function fetchPrice() external override returns (uint256) {
for (uint8 index = 0; index < 2; index++) {
(uint256 price, bool success) = priceFeeds[index].latestAnswer();
if (success) {
_storePrice(price);
return price;
} else {
emit PriceFeedBroken(index, address(priceFeeds[index]));
}
}
revert("PriceFeed: Price feed price is stale");
}
/// @notice Allows users to setup the main and the backup price feeds
/// @param _index the oracle to be configured
/// @param _newPriceFeed address where an IExternalPriceFeed implementation is located
/// @return price the latest price of the inserted price feed
function setAddress(uint8 _index, address _newPriceFeed) public onlyOwner returns (uint256) {
require(_index < priceFeeds.length, "Out of bounds when setting the price feed");
checkContract(_newPriceFeed);
priceFeeds[_index] = IExternalPriceFeed(_newPriceFeed);
(uint256 price, bool _) = priceFeeds[_index].latestAnswer();
emit PriceFeedUpdated(_index, _newPriceFeed);
return price;
}
// --- Helper functions ---
function _storePrice(uint256 _currentPrice) internal {
lastGoodPrice = _currentPrice;
emit LastGoodPriceUpdated(_currentPrice);
}
function getPriceFeedAtIndex(uint8 _index) external view returns(address) {
return address(priceFeeds[_index]);
}
}