Comment on page
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.
The OracleManager contract is a smart contract that is used to store and manage various oracle implementations. The contract uses the
IBasePriceOracleinterface to define the oracle implementations that it supports. It also uses the
Ownablecontract to restrict access to certain functions to the contract owner.
The contract has an array of oracle implementations called
oracles, and a variable called
numOracleswhich holds the number of active oracle implementations. It also has a variable called
quoteAssetwhich 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
quoteAssetvariable to this value. It also has a
getPricefunction 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
oraclesarray, and calls the
IBasePriceOracle.getPricefunction on each oracle implementation if it supports the asset. If no oracle supports the asset, the function reverts.
The contract also has a
setOraclesfunction which allows the contract owner to set the oracle implementations in the contract. This function takes an array of
IBasePriceOracleimplementations as a parameter, and first zeroes out the
oraclesarray in storage. It then copies the elements from the
_oraclesarray into the
oraclesarray, and updates the
numOraclesvariable. This function can only be called by the contract owner.
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.
To set the oracles, the contract first zeroes out the
oraclesarray in storage. It then copies elements from the
_oraclesarray passed as a parameter and updates the
numOraclesvariable 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
getPricefunction to get the price of an asset. The
getPricefunction iterates through the
oraclesarray 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.