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