forked from aave-dao/aave-v3-origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAaveOracle.sol
146 lines (130 loc) · 4.94 KB
/
AaveOracle.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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
import {AggregatorInterface} from '../dependencies/chainlink/AggregatorInterface.sol';
import {Errors} from '../protocol/libraries/helpers/Errors.sol';
import {IACLManager} from '../interfaces/IACLManager.sol';
import {IPoolAddressesProvider} from '../interfaces/IPoolAddressesProvider.sol';
import {IPriceOracleGetter} from '../interfaces/IPriceOracleGetter.sol';
import {IAaveOracle} from '../interfaces/IAaveOracle.sol';
/**
* @title AaveOracle
* @author Aave
* @notice Contract to get asset prices, manage price sources and update the fallback oracle
* - Use of Chainlink Aggregators as first source of price
* - If the returned price by a Chainlink aggregator is <= 0, the call is forwarded to a fallback oracle
* - Owned by the Aave governance
*/
contract AaveOracle is IAaveOracle {
IPoolAddressesProvider public immutable ADDRESSES_PROVIDER;
// Map of asset price sources (asset => priceSource)
mapping(address => AggregatorInterface) private assetsSources;
IPriceOracleGetter private _fallbackOracle;
address public immutable override BASE_CURRENCY;
uint256 public immutable override BASE_CURRENCY_UNIT;
/**
* @dev Only asset listing or pool admin can call functions marked by this modifier.
*/
modifier onlyAssetListingOrPoolAdmins() {
_onlyAssetListingOrPoolAdmins();
_;
}
/**
* @notice Constructor
* @param provider The address of the new PoolAddressesProvider
* @param assets The addresses of the assets
* @param sources The address of the source of each asset
* @param fallbackOracle The address of the fallback oracle to use if the data of an
* aggregator is not consistent
* @param baseCurrency The base currency used for the price quotes. If USD is used, base currency is 0x0
* @param baseCurrencyUnit The unit of the base currency
*/
constructor(
IPoolAddressesProvider provider,
address[] memory assets,
address[] memory sources,
address fallbackOracle,
address baseCurrency,
uint256 baseCurrencyUnit
) {
ADDRESSES_PROVIDER = provider;
_setFallbackOracle(fallbackOracle);
_setAssetsSources(assets, sources);
BASE_CURRENCY = baseCurrency;
BASE_CURRENCY_UNIT = baseCurrencyUnit;
emit BaseCurrencySet(baseCurrency, baseCurrencyUnit);
}
/// @inheritdoc IAaveOracle
function setAssetSources(
address[] calldata assets,
address[] calldata sources
) external override onlyAssetListingOrPoolAdmins {
_setAssetsSources(assets, sources);
}
/// @inheritdoc IAaveOracle
function setFallbackOracle(
address fallbackOracle
) external override onlyAssetListingOrPoolAdmins {
_setFallbackOracle(fallbackOracle);
}
/**
* @notice Internal function to set the sources for each asset
* @param assets The addresses of the assets
* @param sources The address of the source of each asset
*/
function _setAssetsSources(address[] memory assets, address[] memory sources) internal {
require(assets.length == sources.length, Errors.INCONSISTENT_PARAMS_LENGTH);
for (uint256 i = 0; i < assets.length; i++) {
assetsSources[assets[i]] = AggregatorInterface(sources[i]);
emit AssetSourceUpdated(assets[i], sources[i]);
}
}
/**
* @notice Internal function to set the fallback oracle
* @param fallbackOracle The address of the fallback oracle
*/
function _setFallbackOracle(address fallbackOracle) internal {
_fallbackOracle = IPriceOracleGetter(fallbackOracle);
emit FallbackOracleUpdated(fallbackOracle);
}
/// @inheritdoc IPriceOracleGetter
function getAssetPrice(address asset) public view override returns (uint256) {
AggregatorInterface source = assetsSources[asset];
if (asset == BASE_CURRENCY) {
return BASE_CURRENCY_UNIT;
} else if (address(source) == address(0)) {
return _fallbackOracle.getAssetPrice(asset);
} else {
int256 price = source.latestAnswer();
if (price > 0) {
return uint256(price);
} else {
return _fallbackOracle.getAssetPrice(asset);
}
}
}
/// @inheritdoc IAaveOracle
function getAssetsPrices(
address[] calldata assets
) external view override returns (uint256[] memory) {
uint256[] memory prices = new uint256[](assets.length);
for (uint256 i = 0; i < assets.length; i++) {
prices[i] = getAssetPrice(assets[i]);
}
return prices;
}
/// @inheritdoc IAaveOracle
function getSourceOfAsset(address asset) external view override returns (address) {
return address(assetsSources[asset]);
}
/// @inheritdoc IAaveOracle
function getFallbackOracle() external view returns (address) {
return address(_fallbackOracle);
}
function _onlyAssetListingOrPoolAdmins() internal view {
IACLManager aclManager = IACLManager(ADDRESSES_PROVIDER.getACLManager());
require(
aclManager.isAssetListingAdmin(msg.sender) || aclManager.isPoolAdmin(msg.sender),
Errors.CALLER_NOT_ASSET_LISTING_OR_POOL_ADMIN
);
}
}