# MultiDepositorVault

**Inherits:** IMultiDepositorVault, ERC20, FeeVault

A vault that allows users to deposit and withdraw multiple tokens. This contract just mints and burns unit tokens and all logic and validation is handled by the provisioner

## State Variables

### beforeTransferHook

Hooks contract called before unit transfers/mints/burns

```solidity
IBeforeTransferHook public beforeTransferHook;
```

### provisioner

Role that can mint/burn vault units

```solidity
address public provisioner;
```

## Functions

### onlyProvisioner

Ensures caller is the provisioner

```solidity
modifier onlyProvisioner();
```

### constructor

```solidity
constructor()
    ERC20(IMultiDepositorVaultFactory(msg.sender).getERC20Name(), IMultiDepositorVaultFactory(msg.sender).getERC20Symbol())
    FeeVault();
```

### enter

Deposit tokens into the vault and mint units

```solidity
function enter(address sender, IERC20 token, uint256 tokenAmount, uint256 unitsAmount, address recipient)
    external
    whenNotPaused
    onlyProvisioner;
```

**Parameters**

| Name          | Type      | Description                    |
| ------------- | --------- | ------------------------------ |
| `sender`      | `address` | The sender of the tokens       |
| `token`       | `IERC20`  | The token to deposit           |
| `tokenAmount` | `uint256` | The amount of token to deposit |
| `unitsAmount` | `uint256` | The amount of units to mint    |
| `recipient`   | `address` | The recipient of the units     |

### exit

Withdraw tokens from the vault and burn units

```solidity
function exit(address sender, IERC20 token, uint256 tokenAmount, uint256 unitsAmount, address recipient)
    external
    whenNotPaused
    onlyProvisioner;
```

**Parameters**

| Name          | Type      | Description                     |
| ------------- | --------- | ------------------------------- |
| `sender`      | `address` | The sender of the units         |
| `token`       | `IERC20`  | The token to withdraw           |
| `tokenAmount` | `uint256` | The amount of token to withdraw |
| `unitsAmount` | `uint256` | The amount of units to burn     |
| `recipient`   | `address` | The recipient of the tokens     |

### setProvisioner

Sets the provisioner address

```solidity
function setProvisioner(address provisioner_) external requiresAuth;
```

**Parameters**

| Name           | Type      | Description                 |
| -------------- | --------- | --------------------------- |
| `provisioner_` | `address` | The new provisioner address |

### setBeforeTransferHook

Set the before transfer hooks

```solidity
function setBeforeTransferHook(IBeforeTransferHook hook) external requiresAuth;
```

**Parameters**

| Name   | Type                  | Description |
| ------ | --------------------- | ----------- |
| `hook` | `IBeforeTransferHook` |             |

### \_update

Internal function to update token balances with transfer hook checks

*Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding this function. Emits a {Transfer} event.*

```solidity
function _update(address from, address to, uint256 amount) internal override;
```

**Parameters**

| Name     | Type      | Description                             |
| -------- | --------- | --------------------------------------- |
| `from`   | `address` | The address tokens are transferred from |
| `to`     | `address` | The address tokens are transferred to   |
| `amount` | `uint256` | The amount of tokens to transfer        |

### \_setBeforeTransferHook

Set the transfer hook

```solidity
function _setBeforeTransferHook(IBeforeTransferHook hook_) internal;
```

**Parameters**

| Name    | Type                  | Description               |
| ------- | --------------------- | ------------------------- |
| `hook_` | `IBeforeTransferHook` | The transfer hook address |

### \_setProvisioner

Set the provisioner

```solidity
function _setProvisioner(address provisioner_) internal;
```

**Parameters**

| Name           | Type      | Description             |
| -------------- | --------- | ----------------------- |
| `provisioner_` | `address` | The provisioner address |


---

# 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.aera.finance/the-protocol/core/multidepositorvault.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.
