# 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 |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nucleusearn.io/nucleus-architecture/smart-contracts/contracts/base/roles/accountantwithrateproviders.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
