# AeraVaultV2

## AeraVaultV2

**Inherits:** IVault, ERC165, Ownable2Step, Pausable, ReentrancyGuard

Aera Vault V2 Vault contract.

### State Variables

#### \_MAX\_FEE

Largest possible fee earned proportion per one second.

*0.0000001% per second, i.e. 3.1536% per year. 0.0000001% \* (365 \* 24 \* 60 \* 60) = 3.1536% or 3.16224% per year in leap years.*

```solidity
uint256 private constant _MAX_FEE = 10 ** 9;
```

#### \_feeTokenDecimals

Number of decimals for fee token.

```solidity
uint256 private immutable _feeTokenDecimals;
```

#### \_numeraireTokenDecimals

Number of decimals for numeraire token.

```solidity
uint256 private immutable _numeraireTokenDecimals;
```

#### \_feeToken

Fee token used by asset registry.

```solidity
IERC20 private immutable _feeToken;
```

#### fee

Fee per second in 18 decimal fixed point format.

```solidity
uint256 public immutable fee;
```

#### assetRegistry

Asset registry address.

```solidity
IAssetRegistry public immutable assetRegistry;
```

#### wrappedNativeToken

The address of wrapped native token.

```solidity
address public immutable wrappedNativeToken;
```

#### hooks

STORAGE ///

Hooks module address.

```solidity
IHooks public hooks;
```

#### guardian

Guardian address.

```solidity
address public guardian;
```

#### feeRecipient

Fee recipient address.

```solidity
address public feeRecipient;
```

#### finalized

True if vault has been finalized.

```solidity
bool public finalized;
```

#### lastValue

Last measured value of assets in vault.

```solidity
uint256 public lastValue;
```

#### lastFeeTokenPrice

Last spot price of fee token.

```solidity
uint256 public lastFeeTokenPrice;
```

#### fees

Fee earned amount for each prior fee recipient.

```solidity
mapping(address => uint256) public fees;
```

#### feeTotal

Total fee earned and unclaimed amount by all fee recipients.

```solidity
uint256 public feeTotal;
```

#### lastFeeCheckpoint

Last timestamp when fee index was reserved.

```solidity
uint256 public lastFeeCheckpoint;
```

### Functions

#### onlyOwnerOrGuardian

MODIFIERS ///

*Throws if called by any account other than the owner or guardian.*

```solidity
modifier onlyOwnerOrGuardian();
```

#### onlyGuardian

*Throws if called by any account other than the guardian.*

```solidity
modifier onlyGuardian();
```

#### whenNotFinalized

*Throws if called after the vault is finalized.*

```solidity
modifier whenNotFinalized();
```

#### whenHooksSet

*Throws if hooks is not set*

```solidity
modifier whenHooksSet();
```

#### reserveFees

*Calculate current guardian fees.*

```solidity
modifier reserveFees();
```

#### checkReservedFees

*Check insolvency of fee token was not made worse.*

```solidity
modifier checkReservedFees();
```

#### constructor

FUNCTIONS ///

```solidity
constructor() Ownable ReentrancyGuard;
```

#### deposit

FUNCTIONS ///

*MUST revert if not called by owner.*

```solidity
function deposit(AssetValue[] calldata amounts)
    external
    override
    nonReentrant
    onlyOwner
    whenHooksSet
    whenNotFinalized
    reserveFees;
```

**Parameters**

| Name      | Type           | Description                    |
| --------- | -------------- | ------------------------------ |
| `amounts` | `AssetValue[]` | Assets and amounts to deposit. |

#### withdraw

Withdraw assets.

*MUST revert if not called by owner.*

```solidity
function withdraw(AssetValue[] calldata amounts)
    external
    override
    nonReentrant
    onlyOwner
    whenHooksSet
    whenNotFinalized
    reserveFees;
```

**Parameters**

| Name      | Type           | Description                     |
| --------- | -------------- | ------------------------------- |
| `amounts` | `AssetValue[]` | Assets and amounts to withdraw. |

#### setGuardianAndFeeRecipient

Set current guardian and fee recipient.

*MUST revert if not called by owner.*

```solidity
function setGuardianAndFeeRecipient(
    address newGuardian,
    address newFeeRecipient
) external override onlyOwner whenNotFinalized reserveFees;
```

**Parameters**

| Name              | Type      | Description |
| ----------------- | --------- | ----------- |
| `newGuardian`     | `address` |             |
| `newFeeRecipient` | `address` |             |

#### setHooks

Sets the current hooks module.

*MUST revert if not called by owner.*

```solidity
function setHooks(address newHooks)
    external
    override
    nonReentrant
    onlyOwner
    whenNotFinalized
    reserveFees;
```

**Parameters**

| Name       | Type      | Description |
| ---------- | --------- | ----------- |
| `newHooks` | `address` |             |

#### execute

Execute a transaction via the vault.

*reserveFees modifier is not used to avoid reverts.*

```solidity
function execute(Operation calldata operation)
    external
    override
    nonReentrant
    onlyOwner;
```

**Parameters**

| Name        | Type        | Description                                        |
| ----------- | ----------- | -------------------------------------------------- |
| `operation` | `Operation` | Struct details for target and calldata to execute. |

#### finalize

Terminate the vault and return all funds to owner.

*MUST revert if not called by owner.*

```solidity
function finalize()
    external
    override
    nonReentrant
    onlyOwner
    whenHooksSet
    whenNotFinalized
    reserveFees;
```

#### pause

Stops the guardian from submission and halts fee accrual.

*MUST revert if not called by owner or guardian.*

```solidity
function pause()
    external
    override
    nonReentrant
    onlyOwnerOrGuardian
    whenNotFinalized
    reserveFees;
```

#### resume

Resume fee accrual and guardian submissions.

*MUST revert if not called by owner.*

```solidity
function resume() external override onlyOwner whenHooksSet whenNotFinalized;
```

#### submit

Submit a series of transactions for execution via the vault.

*MUST revert if not called by guardian.*

```solidity
function submit(Operation[] calldata operations)
    external
    override
    nonReentrant
    onlyGuardian
    whenHooksSet
    whenNotFinalized
    whenNotPaused
    reserveFees
    checkReservedFees;
```

**Parameters**

| Name         | Type          | Description                        |
| ------------ | ------------- | ---------------------------------- |
| `operations` | `Operation[]` | Sequence of operations to execute. |

#### claim

Claim fees on behalf of a current or previous fee recipient.

```solidity
function claim() external override nonReentrant reserveFees;
```

#### holdings

Get current balances of all assets.

```solidity
function holdings() external view override returns (AssetValue[] memory);
```

**Returns**

| Name     | Type           | Description                                |
| -------- | -------------- | ------------------------------------------ |
| `<none>` | `AssetValue[]` | assetAmounts Amounts of registered assets. |

#### value

Get current total value of assets in vault.

```solidity
function value() external view override returns (uint256 vaultValue);
```

**Returns**

| Name         | Type      | Description                |
| ------------ | --------- | -------------------------- |
| `vaultValue` | `uint256` | value Current total value. |

#### supportsInterface

*Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    override
    returns (bool);
```

#### renounceOwnership

*Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.*

```solidity
function renounceOwnership() public view override onlyOwner;
```

#### transferOwnership

*Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. Can only be called by the current owner.*

```solidity
function transferOwnership(address newOwner) public override onlyOwner;
```

#### receive

Only accept native token from the wrapped native token contract when burning wrapped native tokens.

```solidity
receive() external payable;
```

#### \_getFeeIndex

INTERNAL FUNCTIONS ///

Calculate guardian fee index.

```solidity
function _getFeeIndex() internal view returns (uint256 feeIndex);
```

**Returns**

| Name       | Type      | Description         |
| ---------- | --------- | ------------------- |
| `feeIndex` | `uint256` | Guardian fee index. |

#### \_reserveFees

Calculate current guardian fees.

```solidity
function _reserveFees() internal;
```

#### \_value

Get current total value of assets in vault and price of fee token.

*It calculates the value in Numeraire token decimals.*

```solidity
function _value(IAssetRegistry.AssetPriceReading[] memory erc20SpotPrices)
    internal
    view
    returns (uint256 vaultValue, uint256 feeTokenPrice);
```

**Parameters**

| Name              | Type                                 | Description                  |
| ----------------- | ------------------------------------ | ---------------------------- |
| `erc20SpotPrices` | `IAssetRegistry.AssetPriceReading[]` | Spot prices of ERC20 assets. |

**Returns**

| Name            | Type      | Description          |
| --------------- | --------- | -------------------- |
| `vaultValue`    | `uint256` | Current total value. |
| `feeTokenPrice` | `uint256` | Fee token price.     |

#### \_checkAmountsSorted

Check that assets in provided amounts are sorted and unique.

```solidity
function _checkAmountsSorted(AssetValue[] memory amounts) internal pure;
```

**Parameters**

| Name      | Type           | Description                                        |
| --------- | -------------- | -------------------------------------------------- |
| `amounts` | `AssetValue[]` | Struct details for assets and amounts to withdraw. |

#### \_checkWithdrawRequest

Check request to withdraw.

```solidity
function _checkWithdrawRequest(
    IAssetRegistry.AssetInformation[] memory assets,
    AssetValue[] memory amounts
) internal view;
```

**Parameters**

| Name      | Type                                | Description                                               |
| --------- | ----------------------------------- | --------------------------------------------------------- |
| `assets`  | `IAssetRegistry.AssetInformation[]` | Struct details for asset information from asset registry. |
| `amounts` | `AssetValue[]`                      | Struct details for assets and amounts to withdraw.        |

#### \_getSpotPricesAndUnits

Get spot prices and units of requested assets.

*Spot prices are scaled to 18 decimals.*

```solidity
function _getSpotPricesAndUnits(
    IAssetRegistry.AssetInformation[] memory assets,
    IAssetRegistry.AssetPriceReading[] memory erc20SpotPrices
)
    internal
    view
    returns (uint256[] memory spotPrices, uint256[] memory assetUnits);
```

**Parameters**

| Name              | Type                                 | Description                                                |
| ----------------- | ------------------------------------ | ---------------------------------------------------------- |
| `assets`          | `IAssetRegistry.AssetInformation[]`  | Registered assets in asset registry and their information. |
| `erc20SpotPrices` | `IAssetRegistry.AssetPriceReading[]` | Struct details for spot prices of ERC20 assets.            |

**Returns**

| Name         | Type        | Description            |
| ------------ | ----------- | ---------------------- |
| `spotPrices` | `uint256[]` | Spot prices of assets. |
| `assetUnits` | `uint256[]` | Units of assets.       |

#### \_getHoldings

Get total amount of assets in vault.

```solidity
function _getHoldings(IAssetRegistry.AssetInformation[] memory assets)
    internal
    view
    returns (AssetValue[] memory assetAmounts);
```

**Parameters**

| Name     | Type                                | Description                                             |
| -------- | ----------------------------------- | ------------------------------------------------------- |
| `assets` | `IAssetRegistry.AssetInformation[]` | Struct details for registered assets in asset registry. |

**Returns**

| Name           | Type           | Description       |
| -------------- | -------------- | ----------------- |
| `assetAmounts` | `AssetValue[]` | Amount of assets. |

#### \_checkReservedFees

Check if balance of fee becomes insolvent or becomes more insolvent.

```solidity
function _checkReservedFees(uint256 prevFeeTokenBalance) internal view;
```

**Parameters**

| Name                  | Type      | Description                         |
| --------------------- | --------- | ----------------------------------- |
| `prevFeeTokenBalance` | `uint256` | Balance of fee token before action. |

#### \_checkGuardianAddress

Check if the address can be a guardian.

```solidity
function _checkGuardianAddress(
    address newGuardian,
    address owner_
) internal pure;
```

**Parameters**

| Name          | Type      | Description       |
| ------------- | --------- | ----------------- |
| `newGuardian` | `address` | Address to check. |
| `owner_`      | `address` | Owner address.    |

#### \_checkFeeRecipientAddress

Check if the address can be a fee recipient.

```solidity
function _checkFeeRecipientAddress(
    address newFeeRecipient,
    address owner_
) internal pure;
```

**Parameters**

| Name              | Type      | Description       |
| ----------------- | --------- | ----------------- |
| `newFeeRecipient` | `address` | Address to check. |
| `owner_`          | `address` | Owner address.    |

#### \_checkAssetRegistryAddress

Check if the address can be an asset registry.

```solidity
function _checkAssetRegistryAddress(address newAssetRegistry) internal view;
```

**Parameters**

| Name               | Type      | Description       |
| ------------------ | --------- | ----------------- |
| `newAssetRegistry` | `address` | Address to check. |

#### \_checkHooksAddress

Check if the address can be a hooks contract.

```solidity
function _checkHooksAddress(address newHooks) internal view;
```

**Parameters**

| Name       | Type      | Description       |
| ---------- | --------- | ----------------- |
| `newHooks` | `address` | Address to check. |

#### \_isAssetRegistered

Check whether asset is registered to asset registry or not.

```solidity
function _isAssetRegistered(
    IERC20 asset,
    IAssetRegistry.AssetInformation[] memory registeredAssets
) internal pure returns (bool isRegistered, uint256 index);
```

**Parameters**

| Name               | Type                                | Description                 |
| ------------------ | ----------------------------------- | --------------------------- |
| `asset`            | `IERC20`                            | Asset to check.             |
| `registeredAssets` | `IAssetRegistry.AssetInformation[]` | Array of registered assets. |

**Returns**

| Name           | Type      | Description                       |
| -------------- | --------- | --------------------------------- |
| `isRegistered` | `bool`    | True if asset is registered.      |
| `index`        | `uint256` | Index of asset in asset registry. |
