Abstract Oracle
High-Level Overview
The AbstractOracle contract is inherited by the ClassicalOracle. It is not meant to be deployed on its own and is designed to safely be inherited by upgradable contracts, and upgradable contracts only.
Contract Summary
The shared logic contained in AbstractOracle includes:
Converting the price of the oracle of arbitrary decimals into wad (18 decimals)
Computing a quote (USD value) for a given token and amount of tokens
Making sure stablecoins haven’t depegged
Allowing the admin to set the maximum allowed price variation for stablecoins
The inheriting contracts are responsible for initializing the tokenToOracleInfo
mapping as well as implementing _latestRoundData
to handle the specific interaction for the corresponding oracle.
Inherited Contracts
IOracle: Common interface used by other contracts and external service (e.g. the dApp) to interact with UsualOracle and ClassicalOracle. Ensures function signatures are the ones expected by these external actors.
Initializable: Allows to handle contract setup and upgrades.
Functionality Breakdown
The main functionality of this contract is to get the price a given token by its address with getPrice
. The AbstractOracle contract calls the virtual function _latestRoundData
. It then converts the returned amount to 18 decimals. Finally, it runs the anti-depeg check for stablecoins.
The getQuote
function calls getPrice
internally, and then applies a cross-product to the amount given as parameter, yielding the final quote.
Functions Description
Public/External Functions
getMaxDepegThreshold(): Returns the current maximum allowed price variation for stablecoins in basis points (e.g. with a value of 500,
getPrice
andgetQuote
will revert if the price of a stablecoin is outside the range $0.95-$1.05). View function.setMaxDepegThreshold(uint256 maxAuthorizedDepegPrice): Updates the maximum allowed price variation and emits a
SetMaxDepegThreshold
event. Nonpayable function. Reserved for admin use only.getPrice(address token): Returns the price of the given token scaled to 18 decimals (e.g. a return value of 3e18 means the token price is $3). Reverts if the token is a stablecoin and it’s outside of the allowed price variation range. View function.
getQuote(address token): Returns the USD value equivalent to the given amount of the given token (e.g. if the token price is $3, calling with 1e6 will return 3e6, no matter the number of decimals of the token). Reverts if the token is a stablecoin and it’s outside of the allowed price variation range. View function.
Remediation Strategies
Off-chain data sources: We do not rely on on-chain oracles, such as Uniswap or Curve. These protocols could more easily be vulnerable to sandwich and/or flashloan attacks, enabling price manipulation.
Dual-oracle cross-verification: Not live yet, will require a future upgrade. Drawing inspiration from Liquity’s PriceFeed, we could add a secondary oracle and compare prices between the two. This would reduce the impact of one of the two oracles getting hacked or freezing. We had implemented such a system, but didn’t find any other reliable price feed for USDC, USDT, nor USYC.
Last updated