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