Oracle Manager
The OracleManager contract aggregates answers by oracle systems such as Chainlink. Fetching a price involves querying oracles one-by-one until a satisfactory answer is obtained.
Overview
The OracleManager contract is a smart contract that is used to store and manage various oracle implementations. The contract uses the IBasePriceOracle
interface to define the oracle implementations that it supports. It also uses the Ownable
contract to restrict access to certain functions to the contract owner.
The contract has an array of oracle implementations called oracles
, and a variable called numOracles
which holds the number of active oracle implementations. It also has a variable called quoteAsset
which holds the address of the ERC20 token in which the price is quoted.
The contract has a constructor which takes the address of the quote asset as a parameter and sets the quoteAsset
variable to this value. It also has a getPrice
function which takes the address of the asset to be quoted as a parameter, and returns the price of the asset in terms of the base asset. This function iterates through the oracles
array, and calls the IBasePriceOracle.getPrice
function on each oracle implementation if it supports the asset. If no oracle supports the asset, the function reverts.
The contract also has a setOracles
function which allows the contract owner to set the oracle implementations in the contract. This function takes an array of IBasePriceOracle
implementations as a parameter, and first zeroes out the oracles
array in storage. It then copies the elements from the _oracles
array into the oracles
array, and updates the numOracles
variable. This function can only be called by the contract owner.
Getting the price
The getPrice function is a public view function in the OracleManager contract that allows external contracts to query the price of an asset. It accepts a single argument, the address of the asset to be quoted, and returns the price of the asset in wad.
The function first checks if the asset is the same as the quote asset specified in the contract constructor. If this is the case, it returns a price of 1e18 (1 with 18 zeros after it) as the price of the asset in wad.
If the asset is not the same as the quote asset, the function iterates through the array of oracle implementations stored in the contract in order of priority. For each oracle, it checks if the oracle supports the asset by calling the supportsAsset function on the oracle. If the oracle supports the asset, it calls the getPrice function on the oracle to get the price of the asset in wad. If the oracle successfully returns the price, the function returns it.
If none of the oracles in the contract support the asset, the function reverts with the error message "OracleManager::not supported".
The getPrice function is a view function, so it does not modify the contract state and can be called by external contracts without any gas costs.
Setting the oracles
To set the oracles, the contract first zeroes out the oracles
array in storage. It then copies elements from the _oracles
array passed as a parameter and updates the numOracles
variable to reflect the number of oracles that have been set. This can only be done by the owner of the contract.
The contract requires that the number of oracles is between 1 and 10, inclusive. If the number of oracles is outside of this range, the transaction will revert with an error message.
Once the oracles have been set, external contracts can call the getPrice
function to get the price of an asset. The getPrice
function iterates through the oracles
array in order and calls the IBasePriceOracle.getPrice()
function on each oracle if the oracle supports the asset. If no oracle supports the asset, the transaction will revert with an error message.
Last updated