# ETH0 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 the 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` and `getQuote` 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](https://github.com/liquity/dev/blob/main/packages/contracts/contracts/PriceFeed.sol), 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.
