# YieldOracle

[Git Source](https://github.com/Ion-Protocol/ion-protocol/blob/88cc595825f1dc2eb738fb93e172a3e8ab7a5c43/src/YieldOracle.sol)

**Inherits:** IYieldOracle, Ownable2Step

An on-chain oracle that provides the APY for each collateral type.

*This contract stores a history of the exchange rates of each collateral for the past `LOOK_BACK` days. Every time that `updateAll()` is called, it will update the value at `currentIndex` in the `historicalExchangeRates` with the current exchange rate and it will also calculate the APY for each collateral type based on the data currently in the buffer. The APY is calculated by taking the difference between the new element being added and the element being replaced. This provides a growth amount of `LOOK_BACK` days. This value is then projected out to a year. Similar to the `InterestRate` module, as the amount of collaterals added to the market increases, storage reads during interest accrual can become prohibitively expensive. Therefore, this contract is heavily optimized at the unfortunate cost of code-complexity.*

### [State Variables](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#state-variables" id="state-variables"></a>

#### [apys](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#apys" id="apys"></a>

```
uint32[ILK_COUNT] public apys;
```

#### [historicalExchangeRates](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#historicalexchangerates" id="historicalexchangerates"></a>

```
uint64[ILK_COUNT][LOOK_BACK] public historicalExchangeRates;
```

#### [ADDRESS0](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#address0" id="address0"></a>

```
address public immutable ADDRESS0;
```

#### [ADDRESS1](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#address1" id="address1"></a>

```
address public immutable ADDRESS1;
```

#### [ADDRESS2](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#address2" id="address2"></a>

```
address public immutable ADDRESS2;
```

#### [ionPool](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#ionpool" id="ionpool"></a>

```
IonPool public ionPool;
```

#### [currentIndex](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#currentindex" id="currentindex"></a>

```
uint32 public currentIndex;
```

#### [lastUpdated](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#lastupdated" id="lastupdated"></a>

```
uint48 public lastUpdated;
```

### [Functions](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#functions" id="functions"></a>

#### [constructor](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#constructor" id="constructor"></a>

Creates a new `YieldOracle` instance.

```
constructor(
    uint64[ILK_COUNT][LOOK_BACK] memory _historicalExchangeRates,
    address _weEth,
    address _stader,
    address _swell,
    address owner
)
    Ownable(owner);
```

**Parameters**

| Name                       | Type                           | Description                                                        |
| -------------------------- | ------------------------------ | ------------------------------------------------------------------ |
| `_historicalExchangeRates` | `uint64[ILK_COUNT][LOOK_BACK]` | An initial set of values for the historical exchange rates matrix. |
| `_weEth`                   | `address`                      | Address of the weETH contract.                                     |
| `_stader`                  | `address`                      | Address of the Stader deposit contract.                            |
| `_swell`                   | `address`                      | Address of the Swell Eth contract.                                 |
| `owner`                    | `address`                      | Admin address.                                                     |

#### [updateIonPool](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#updateionpool" id="updateionpool"></a>

Updates the `IonPool` reference.

```
function updateIonPool(IonPool _ionPool) external onlyOwner;
```

**Parameters**

| Name       | Type      | Description   |
| ---------- | --------- | ------------- |
| `_ionPool` | `IonPool` | pool instance |

#### [updateAll](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#updateall" id="updateall"></a>

Every update should also accrue interest on `IonPool`. This is because an update to the apy changes interest rates which means the previous interest rate must be accrued, or else its effect will be lost. NOTE: This contract should continue to function as normal even if `IonPool` is paused.

```
function updateAll() external;
```

#### [\_updateAll](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#updateall" id="updateall"></a>

Handles the logic for updating the APYs and the historical exchange rates matrix. If the last update was less than `UPDATE_LOCK_LENGTH` seconds ago, then this function will revert. If APY is ever negative, then it will simply be set to 0.

```
function _updateAll() internal;
```

#### [\_getExchangeRate](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#getexchangerate" id="getexchangerate"></a>

Returns the exchange rate for a given collateral.

```
function _getExchangeRate(uint256 ilkIndex) internal view returns (uint64 exchangeRate);
```

**Parameters**

| Name       | Type      | Description                  |
| ---------- | --------- | ---------------------------- |
| `ilkIndex` | `uint256` | The index of the collateral. |

**Returns**

| Name           | Type     | Description  |
| -------------- | -------- | ------------ |
| `exchangeRate` | `uint64` | exchangeRate |

### [Events](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#events" id="events"></a>

#### [ApyUpdate](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#apyupdate" id="apyupdate"></a>

```
event ApyUpdate(uint256 indexed ilkIndex, uint256 newApy);
```

### [Errors](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#errors" id="errors"></a>

#### [InvalidExchangeRate](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#invalidexchangerate" id="invalidexchangerate"></a>

```
error InvalidExchangeRate(uint256 ilkIndex);
```

#### [InvalidIlkIndex](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#invalidilkindex" id="invalidilkindex"></a>

```
error InvalidIlkIndex(uint256 ilkIndex);
```

#### [AlreadyUpdated](https://docs.ionprotocol.io/devs/smart-contract-architecture/broken-reference) <a href="#alreadyupdated" id="alreadyupdated"></a>

```
error AlreadyUpdated();
```
