# AccountantWithRateProviders

[Git Source](https://github.com/Ion-Protocol/nucleus-boring-vault/blob/cc0b494b83e17b9b169a73b96050d2810b690477/src/base/Roles/AccountantWithRateProviders.sol)

**Inherits:** Auth, IRateProvider

## State Variables

### accountantState

Store the accountant state in 3 packed slots.

```solidity
AccountantState public accountantState;
```

### rateProviderData

Maps ERC20s to their RateProviderData.

```solidity
mapping(ERC20 => RateProviderData) public rateProviderData;
```

### base

The base asset rates are provided in.

```solidity
ERC20 public immutable base;
```

### decimals

The decimals rates are provided in.

```solidity
uint8 public immutable decimals;
```

### vault

The BoringVault this accountant is working with. Used to determine share supply for fee calculation.

```solidity
BoringVault public immutable vault;
```

### ONE\_SHARE

One share of the BoringVault.

```solidity
uint256 internal immutable ONE_SHARE;
```

## Functions

### constructor

```solidity
constructor(
    address _owner,
    address _vault,
    address payoutAddress,
    uint96 startingExchangeRate,
    address _base,
    uint16 allowedExchangeRateChangeUpper,
    uint16 allowedExchangeRateChangeLower,
    uint32 minimumUpdateDelayInSeconds,
    uint16 managementFee
)
    Auth(_owner, Authority(address(0)));
```

### pause

Pause this contract, which prevents future calls to `updateExchangeRate`, and any safe rate calls will revert.

*Callable by MULTISIG\_ROLE.*

```solidity
function pause() external requiresAuth;
```

### unpause

Unpause this contract, which allows future calls to `updateExchangeRate`, and any safe rate calls will stop reverting.

*Callable by MULTISIG\_ROLE.*

```solidity
function unpause() external requiresAuth;
```

### updateDelay

Update the minimum time delay between `updateExchangeRate` calls.

*There are no input requirements, as it is possible the admin would want the exchange rate updated as frequently as needed.*

*Callable by OWNER\_ROLE.*

```solidity
function updateDelay(uint32 minimumUpdateDelayInSeconds) external requiresAuth;
```

### updateUpper

Update the allowed upper bound change of exchange rate between `updateExchangeRateCalls`.

*Callable by OWNER\_ROLE.*

```solidity
function updateUpper(uint16 allowedExchangeRateChangeUpper) external requiresAuth;
```

### updateLower

Update the allowed lower bound change of exchange rate between `updateExchangeRateCalls`.

*Callable by OWNER\_ROLE.*

```solidity
function updateLower(uint16 allowedExchangeRateChangeLower) external requiresAuth;
```

### updateManagementFee

Update the management fee to a new value.

*Callable by OWNER\_ROLE.*

```solidity
function updateManagementFee(uint16 managementFee) external requiresAuth;
```

### updatePayoutAddress

Update the payout address fees are sent to.

*Callable by OWNER\_ROLE.*

```solidity
function updatePayoutAddress(address payoutAddress) external requiresAuth;
```

### setRateProviderData

Update the rate provider data for a specific `asset`.

*Rate providers must return rates in terms of `base` or an asset pegged to base and they must use the same decimals as `asset`.*

*Callable by OWNER\_ROLE.*

```solidity
function setRateProviderData(ERC20 asset, bool isPeggedToBase, address rateProvider) external requiresAuth;
```

### updateExchangeRate

Updates this contract exchangeRate.

*If new exchange rate is outside of accepted bounds, or if not enough time has passed, this will pause the contract, and this function will NOT calculate fees owed.*

*Callable by UPDATE\_EXCHANGE\_RATE\_ROLE.*

```solidity
function updateExchangeRate(uint96 newExchangeRate) external requiresAuth;
```

### claimFees

Claim pending fees.

*This function must be called by the BoringVault.*

*This function will lose precision if the exchange rate decimals is greater than the feeAsset's decimals.*

```solidity
function claimFees(ERC20 feeAsset) external;
```

### getRate

Get this BoringVault's current rate in the base.

```solidity
function getRate() public view returns (uint256 rate);
```

### getRateSafe

Get this BoringVault's current rate in the base.

*Revert if paused.*

```solidity
function getRateSafe() external view returns (uint256 rate);
```

### getRateInQuote

Get this BoringVault's current rate in the provided quote.

*`quote` must have its RateProviderData set, else this will revert.*

*This function will lose precision if the exchange rate decimals is greater than the quote's decimals.*

```solidity
function getRateInQuote(ERC20 quote) public view returns (uint256 rateInQuote);
```

### getRateInQuoteSafe

Get this BoringVault's current rate in the provided quote.

*`quote` must have its RateProviderData set, else this will revert.*

*Revert if paused.*

```solidity
function getRateInQuoteSafe(ERC20 quote) external view returns (uint256 rateInQuote);
```

### changeDecimals

Used to change the decimals of precision used for an amount.

```solidity
function changeDecimals(uint256 amount, uint8 fromDecimals, uint8 toDecimals) internal pure returns (uint256);
```

## Events

### Paused

```solidity
event Paused();
```

### Unpaused

```solidity
event Unpaused();
```

### DelayInSecondsUpdated

```solidity
event DelayInSecondsUpdated(uint32 oldDelay, uint32 newDelay);
```

### UpperBoundUpdated

```solidity
event UpperBoundUpdated(uint16 oldBound, uint16 newBound);
```

### LowerBoundUpdated

```solidity
event LowerBoundUpdated(uint16 oldBound, uint16 newBound);
```

### ManagementFeeUpdated

```solidity
event ManagementFeeUpdated(uint16 oldFee, uint16 newFee);
```

### PayoutAddressUpdated

```solidity
event PayoutAddressUpdated(address oldPayout, address newPayout);
```

### RateProviderUpdated

```solidity
event RateProviderUpdated(address asset, bool isPegged, address rateProvider);
```

### ExchangeRateUpdated

```solidity
event ExchangeRateUpdated(uint96 oldRate, uint96 newRate, uint64 currentTime);
```

### FeesClaimed

```solidity
event FeesClaimed(address indexed feeAsset, uint256 amount);
```

## Errors

### AccountantWithRateProviders\_\_UpperBoundTooSmall

```solidity
error AccountantWithRateProviders__UpperBoundTooSmall();
```

### AccountantWithRateProviders\_\_LowerBoundTooLarge

```solidity
error AccountantWithRateProviders__LowerBoundTooLarge();
```

### AccountantWithRateProviders\_\_ManagementFeeTooLarge

```solidity
error AccountantWithRateProviders__ManagementFeeTooLarge();
```

### AccountantWithRateProviders\_\_Paused

```solidity
error AccountantWithRateProviders__Paused();
```

### AccountantWithRateProviders\_\_ZeroFeesOwed

```solidity
error AccountantWithRateProviders__ZeroFeesOwed();
```

### AccountantWithRateProviders\_\_OnlyCallableByBoringVault

```solidity
error AccountantWithRateProviders__OnlyCallableByBoringVault();
```

### AccountantWithRateProviders\_\_UpdateDelayTooLarge

```solidity
error AccountantWithRateProviders__UpdateDelayTooLarge();
```

## Structs

### AccountantState

```solidity
struct AccountantState {
    address payoutAddress;
    uint128 feesOwedInBase;
    uint128 totalSharesLastUpdate;
    uint96 exchangeRate;
    uint16 allowedExchangeRateChangeUpper;
    uint16 allowedExchangeRateChangeLower;
    uint64 lastUpdateTimestamp;
    bool isPaused;
    uint32 minimumUpdateDelayInSeconds;
    uint16 managementFee;
}
```

**Properties**

| Name                             | Type      | Description                                                                                                                           |
| -------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `payoutAddress`                  | `address` | the address `claimFees` sends fees to                                                                                                 |
| `feesOwedInBase`                 | `uint128` | total pending fees owed in terms of base                                                                                              |
| `totalSharesLastUpdate`          | `uint128` | total amount of shares the last exchange rate update                                                                                  |
| `exchangeRate`                   | `uint96`  | the current exchange rate in terms of base                                                                                            |
| `allowedExchangeRateChangeUpper` | `uint16`  | the max allowed change to exchange rate from an update                                                                                |
| `allowedExchangeRateChangeLower` | `uint16`  | the min allowed change to exchange rate from an update                                                                                |
| `lastUpdateTimestamp`            | `uint64`  | the block timestamp of the last exchange rate update                                                                                  |
| `isPaused`                       | `bool`    | whether or not this contract is paused                                                                                                |
| `minimumUpdateDelayInSeconds`    | `uint32`  | the minimum amount of time that must pass between exchange rate updates, such that the update won't trigger the contract to be paused |
| `managementFee`                  | `uint16`  | the management fee                                                                                                                    |

### RateProviderData

```solidity
struct RateProviderData {
    bool isPeggedToBase;
    IRateProvider rateProvider;
}
```

**Properties**

| Name             | Type            | Description                                                   |
| ---------------- | --------------- | ------------------------------------------------------------- |
| `isPeggedToBase` | `bool`          | whether or not the asset is 1:1 with the base asset           |
| `rateProvider`   | `IRateProvider` | the rate provider for this asset if `isPeggedToBase` is false |
