# IProvisioner

Interface for the contract that can mint and burn vault units in exchange for tokens

## Functions

### deposit

Deposit tokens directly into the vault

*MUST revert if tokensIn is 0, minUnitsOut is 0, or sync deposits are disabled*

```solidity
function deposit(IERC20 token, uint256 tokensIn, uint256 minUnitsOut) external returns (uint256 unitsOut);
```

**Parameters**

| Name          | Type      | Description                          |
| ------------- | --------- | ------------------------------------ |
| `token`       | `IERC20`  | The token to deposit                 |
| `tokensIn`    | `uint256` | The amount of tokens to deposit      |
| `minUnitsOut` | `uint256` | The minimum amount of units expected |

**Returns**

| Name       | Type      | Description                                 |
| ---------- | --------- | ------------------------------------------- |
| `unitsOut` | `uint256` | The amount of shares minted to the receiver |

### mint

Mint exact amount of units by depositing required tokens

```solidity
function mint(IERC20 token, uint256 unitsOut, uint256 maxTokensIn) external returns (uint256 tokensIn);
```

**Parameters**

| Name          | Type      | Description                                 |
| ------------- | --------- | ------------------------------------------- |
| `token`       | `IERC20`  | The token to deposit                        |
| `unitsOut`    | `uint256` | The exact amount of units to mint           |
| `maxTokensIn` | `uint256` | Maximum amount of tokens willing to deposit |

**Returns**

| Name       | Type      | Description                                            |
| ---------- | --------- | ------------------------------------------------------ |
| `tokensIn` | `uint256` | The amount of tokens used to mint the requested shares |

### refundDeposit

Refund a deposit within the refund period

*Only callable by authorized addresses*

```solidity
function refundDeposit(address sender, IERC20 token, uint256 tokenAmount, uint256 unitsAmount, uint256 refundableUntil)
    external;
```

**Parameters**

| Name              | Type      | Description                              |
| ----------------- | --------- | ---------------------------------------- |
| `sender`          | `address` | The original depositor                   |
| `token`           | `IERC20`  | The deposited token                      |
| `tokenAmount`     | `uint256` | The amount of tokens deposited           |
| `unitsAmount`     | `uint256` | The amount of units minted               |
| `refundableUntil` | `uint256` | Timestamp until which refund is possible |

### refundRequest

Refund an expired deposit or redeem request

*Can only be called after request deadline has passed*

```solidity
function refundRequest(IERC20 token, Request calldata request) external;
```

**Parameters**

| Name      | Type      | Description                       |
| --------- | --------- | --------------------------------- |
| `token`   | `IERC20`  | The token involved in the request |
| `request` | `Request` | The request to refund             |

### requestDeposit

Create a new deposit request to be solved by solvers

```solidity
function requestDeposit(
    IERC20 token,
    uint256 tokensIn,
    uint256 minUnitsOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice
) external;
```

**Parameters**

| Name           | Type      | Description                                        |
| -------------- | --------- | -------------------------------------------------- |
| `token`        | `IERC20`  | The token to deposit                               |
| `tokensIn`     | `uint256` | The amount of tokens to deposit                    |
| `minUnitsOut`  | `uint256` | The minimum amount of units expected               |
| `solverTip`    | `uint256` | The tip offered to the solver                      |
| `deadline`     | `uint256` | Duration in seconds for which the request is valid |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use      |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request       |

### requestRedeem

Create a new redeem request to be solved by solvers

```solidity
function requestRedeem(
    IERC20 token,
    uint256 unitsIn,
    uint256 minTokensOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice
) external;
```

**Parameters**

| Name           | Type      | Description                                        |
| -------------- | --------- | -------------------------------------------------- |
| `token`        | `IERC20`  | The token to receive                               |
| `unitsIn`      | `uint256` | The amount of units to redeem                      |
| `minTokensOut` | `uint256` | The minimum amount of tokens expected              |
| `solverTip`    | `uint256` | The tip offered to the solver                      |
| `deadline`     | `uint256` | Duration in seconds for which the request is valid |
| `maxPriceAge`  | `uint256` | Maximum age of price data that solver can use      |
| `isFixedPrice` | `bool`    | Whether the request is a fixed price request       |

### solveRequestsVault

Solve multiple requests using vault's liquidity

*Only callable by authorized addresses*

```solidity
function solveRequestsVault(IERC20 token, Request[] calldata requests) external;
```

**Parameters**

| Name       | Type        | Description                           |
| ---------- | ----------- | ------------------------------------- |
| `token`    | `IERC20`    | The token for which to solve requests |
| `requests` | `Request[]` | Array of requests to solve            |

### solveRequestsDirect

Solve multiple requests using solver's own liquidity

```solidity
function solveRequestsDirect(IERC20 token, Request[] calldata requests) external;
```

**Parameters**

| Name       | Type        | Description                           |
| ---------- | ----------- | ------------------------------------- |
| `token`    | `IERC20`    | The token for which to solve requests |
| `requests` | `Request[]` | Array of requests to solve            |

### setTokenDetails

Update token parameters

```solidity
function setTokenDetails(IERC20 token, TokenDetails calldata tokensDetails) external;
```

**Parameters**

| Name            | Type           | Description           |
| --------------- | -------------- | --------------------- |
| `token`         | `IERC20`       | The token to update   |
| `tokensDetails` | `TokenDetails` | The new token details |

### removeToken

Removes token from provisioner

```solidity
function removeToken(IERC20 token) external;
```

**Parameters**

| Name    | Type     | Description             |
| ------- | -------- | ----------------------- |
| `token` | `IERC20` | The token to be removed |

### setDepositDetails

Update deposit parameters

```solidity
function setDepositDetails(uint256 depositCap_, uint256 depositRefundTimeout_) external;
```

**Parameters**

| Name                    | Type      | Description                                   |
| ----------------------- | --------- | --------------------------------------------- |
| `depositCap_`           | `uint256` | New maximum total value that can be deposited |
| `depositRefundTimeout_` | `uint256` | New time window for deposit refunds           |

### maxDeposit

Return maximum amount that can still be deposited

```solidity
function maxDeposit() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                          |
| -------- | --------- | ------------------------------------ |
| `<none>` | `uint256` | Amount of deposit capacity remaining |

### areUserUnitsLocked

Check if a user's units are currently locked

```solidity
function areUserUnitsLocked(address user) external view returns (bool);
```

**Parameters**

| Name   | Type      | Description          |
| ------ | --------- | -------------------- |
| `user` | `address` | The address to check |

**Returns**

| Name     | Type   | Description                                      |
| -------- | ------ | ------------------------------------------------ |
| `<none>` | `bool` | True if user's units are locked, false otherwise |

### getDepositHash

Computes the hash for a sync deposit

```solidity
function getDepositHash(address user, IERC20 token, uint256 tokenAmount, uint256 unitsAmount, uint256 refundableUntil)
    external
    pure
    returns (bytes32);
```

**Parameters**

| Name              | Type      | Description                                         |
| ----------------- | --------- | --------------------------------------------------- |
| `user`            | `address` | The address making the deposit                      |
| `token`           | `IERC20`  | The token being deposited                           |
| `tokenAmount`     | `uint256` | The amount of tokens to deposit                     |
| `unitsAmount`     | `uint256` | Minimum amount of units to receive                  |
| `refundableUntil` | `uint256` | The timestamp until which the deposit is refundable |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the deposit |

### getRequestHash

Computes the hash for a generic request

```solidity
function getRequestHash(IERC20 token, Request calldata request) external pure returns (bytes32);
```

**Parameters**

| Name      | Type      | Description                       |
| --------- | --------- | --------------------------------- |
| `token`   | `IERC20`  | The token involved in the request |
| `request` | `Request` | The request struct                |

**Returns**

| Name     | Type      | Description             |
| -------- | --------- | ----------------------- |
| `<none>` | `bytes32` | The hash of the request |

## Events

### Deposited

Emitted when a user deposits tokens directly into the vault

```solidity
event Deposited(address indexed user, IERC20 indexed token, uint256 tokensIn, uint256 unitsOut, bytes32 depositHash);
```

**Parameters**

| Name          | Type      | Description                        |
| ------------- | --------- | ---------------------------------- |
| `user`        | `address` | The address of the depositor       |
| `token`       | `IERC20`  | The token being deposited          |
| `tokensIn`    | `uint256` | The amount of tokens deposited     |
| `unitsOut`    | `uint256` | The amount of units minted         |
| `depositHash` | `bytes32` | Unique identifier for this deposit |

### DepositRefunded

Emitted when a deposit is refunded

```solidity
event DepositRefunded(bytes32 indexed depositHash);
```

**Parameters**

| Name          | Type      | Description                            |
| ------------- | --------- | -------------------------------------- |
| `depositHash` | `bytes32` | The hash of the deposit being refunded |

### DirectDepositRefunded

Emitted when a direct (sync) deposit is refunded

```solidity
event DirectDepositRefunded(bytes32 indexed depositHash);
```

**Parameters**

| Name          | Type      | Description                            |
| ------------- | --------- | -------------------------------------- |
| `depositHash` | `bytes32` | The hash of the deposit being refunded |

### DepositRequested

Emitted when a user creates a deposit request

```solidity
event DepositRequested(
    address indexed user,
    IERC20 indexed token,
    uint256 tokensIn,
    uint256 minUnitsOut,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    bytes32 depositRequestHash
);
```

**Parameters**

| Name                 | Type      | Description                                          |
| -------------------- | --------- | ---------------------------------------------------- |
| `user`               | `address` | The address requesting the deposit                   |
| `token`              | `IERC20`  | The token being deposited                            |
| `tokensIn`           | `uint256` | The amount of tokens to deposit                      |
| `minUnitsOut`        | `uint256` | The minimum amount of units expected                 |
| `solverTip`          | `uint256` | The tip offered to the solver in deposit token terms |
| `deadline`           | `uint256` | Timestamp until which the request is valid           |
| `maxPriceAge`        | `uint256` | Maximum age of price data that solver can use        |
| `isFixedPrice`       | `bool`    | Whether the request is a fixed price request         |
| `depositRequestHash` | `bytes32` | The hash of the deposit request                      |

### RedeemRequested

Emitted when a user creates a redeem request

```solidity
event RedeemRequested(
    address indexed user,
    IERC20 indexed token,
    uint256 minTokensOut,
    uint256 unitsIn,
    uint256 solverTip,
    uint256 deadline,
    uint256 maxPriceAge,
    bool isFixedPrice,
    bytes32 redeemRequestHash
);
```

**Parameters**

| Name                | Type      | Description                                              |
| ------------------- | --------- | -------------------------------------------------------- |
| `user`              | `address` | The address requesting the redemption                    |
| `token`             | `IERC20`  | The token requested in return for units                  |
| `minTokensOut`      | `uint256` | The minimum amount of tokens the user expects to receive |
| `unitsIn`           | `uint256` | The amount of units being redeemed                       |
| `solverTip`         | `uint256` | The tip offered to the solver in redeem token terms      |
| `deadline`          | `uint256` | The timestamp until which this request is valid          |
| `maxPriceAge`       | `uint256` | Maximum age of price data that solver can use            |
| `isFixedPrice`      | `bool`    | Whether the request is a fixed price request             |
| `redeemRequestHash` | `bytes32` | The hash of the redeem request                           |

### DepositSolved

Emitted when a deposit request is solved successfully

```solidity
event DepositSolved(bytes32 indexed depositHash);
```

**Parameters**

| Name          | Type      | Description                                                  |
| ------------- | --------- | ------------------------------------------------------------ |
| `depositHash` | `bytes32` | The unique identifier of the deposit request that was solved |

### RedeemSolved

Emitted when a redeem request is solved successfully

```solidity
event RedeemSolved(bytes32 indexed redeemHash);
```

**Parameters**

| Name         | Type      | Description                                                 |
| ------------ | --------- | ----------------------------------------------------------- |
| `redeemHash` | `bytes32` | The unique identifier of the redeem request that was solved |

### InvalidRequestHash

Emitted when an unrecognized async deposit hash is used

```solidity
event InvalidRequestHash(bytes32 indexed depositHash);
```

**Parameters**

| Name          | Type      | Description                                          |
| ------------- | --------- | ---------------------------------------------------- |
| `depositHash` | `bytes32` | The deposit hash that was not found in async records |

### AsyncDepositDisabled

Emitted when async deposits are disabled and a deposit request cannot be processed

```solidity
event AsyncDepositDisabled(uint256 indexed index);
```

**Parameters**

| Name    | Type      | Description                                        |
| ------- | --------- | -------------------------------------------------- |
| `index` | `uint256` | The index of the deposit request that was rejected |

### AsyncRedeemDisabled

Emitted when async redeems are disabled and a redeem request cannot be processed

```solidity
event AsyncRedeemDisabled(uint256 indexed index);
```

**Parameters**

| Name    | Type      | Description                                       |
| ------- | --------- | ------------------------------------------------- |
| `index` | `uint256` | The index of the redeem request that was rejected |

### PriceAgeExceeded

Emitted when the price age exceeds the maximum allowed for a request

```solidity
event PriceAgeExceeded(uint256 indexed index);
```

**Parameters**

| Name    | Type      | Description                                |
| ------- | --------- | ------------------------------------------ |
| `index` | `uint256` | The index of the request that was rejected |

### DepositCapExceeded

Emitted when a deposit exceeds the vault's configured deposit cap

```solidity
event DepositCapExceeded(uint256 indexed index);
```

**Parameters**

| Name    | Type      | Description                                |
| ------- | --------- | ------------------------------------------ |
| `index` | `uint256` | The index of the request that was rejected |

### InsufficientTokensForTip

Emitted when there are not enough tokens to cover the required solver tip

```solidity
event InsufficientTokensForTip(uint256 indexed index);
```

**Parameters**

| Name    | Type      | Description                                |
| ------- | --------- | ------------------------------------------ |
| `index` | `uint256` | The index of the request that was rejected |

### AmountBoundExceeded

Emitted when the output units are less than the amount requested

```solidity
event AmountBoundExceeded(uint256 indexed index, uint256 amount, uint256 bound);
```

**Parameters**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `index`  | `uint256` | The index of the request that was rejected |
| `amount` | `uint256` | The actual amount                          |
| `bound`  | `uint256` | The minimum amount                         |

### RedeemRefunded

Emitted when a redeem request is refunded due to expiration or cancellation

```solidity
event RedeemRefunded(bytes32 indexed redeemHash);
```

**Parameters**

| Name         | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `redeemHash` | `bytes32` | The unique identifier of the redeem request that was refunded |

### DepositDetailsUpdated

Emitted when the vault's deposit limits are updated

```solidity
event DepositDetailsUpdated(uint256 depositCap, uint256 depositRefundTimeout);
```

**Parameters**

| Name                   | Type      | Description                                                      |
| ---------------------- | --------- | ---------------------------------------------------------------- |
| `depositCap`           | `uint256` | The new maximum total value that can be deposited into the vault |
| `depositRefundTimeout` | `uint256` | The new time window during which deposits can be refunded        |

### TokenDetailsSet

Emitted when a token's deposit/withdrawal settings are updated

```solidity
event TokenDetailsSet(IERC20 indexed token, TokenDetails tokensDetails);
```

**Parameters**

| Name            | Type           | Description                                |
| --------------- | -------------- | ------------------------------------------ |
| `token`         | `IERC20`       | The token whose settings are being updated |
| `tokensDetails` | `TokenDetails` | The new token details                      |

### TokenRemoved

Emitted when a token is removed from the provisioner

```solidity
event TokenRemoved(IERC20 indexed token);
```

**Parameters**

| Name    | Type     | Description                |
| ------- | -------- | -------------------------- |
| `token` | `IERC20` | The token that was removed |

## Errors

### Aera\_\_SyncDepositDisabled

```solidity
error Aera__SyncDepositDisabled();
```

### Aera\_\_AsyncDepositDisabled

```solidity
error Aera__AsyncDepositDisabled();
```

### Aera\_\_AsyncRedeemDisabled

```solidity
error Aera__AsyncRedeemDisabled();
```

### Aera\_\_DepositCapExceeded

```solidity
error Aera__DepositCapExceeded();
```

### Aera\_\_MinUnitsOutNotMet

```solidity
error Aera__MinUnitsOutNotMet();
```

### Aera\_\_TokensInZero

```solidity
error Aera__TokensInZero();
```

### Aera\_\_UnitsInZero

```solidity
error Aera__UnitsInZero();
```

### Aera\_\_UnitsOutZero

```solidity
error Aera__UnitsOutZero();
```

### Aera\_\_MinUnitsOutZero

```solidity
error Aera__MinUnitsOutZero();
```

### Aera\_\_MaxTokensInZero

```solidity
error Aera__MaxTokensInZero();
```

### Aera\_\_MaxTokensInExceeded

```solidity
error Aera__MaxTokensInExceeded();
```

### Aera\_\_MaxDepositRefundTimeoutExceeded

```solidity
error Aera__MaxDepositRefundTimeoutExceeded();
```

### Aera\_\_DepositHashNotFound

```solidity
error Aera__DepositHashNotFound();
```

### Aera\_\_HashNotFound

```solidity
error Aera__HashNotFound();
```

### Aera\_\_RefundPeriodExpired

```solidity
error Aera__RefundPeriodExpired();
```

### Aera\_\_DeadlineInPast

```solidity
error Aera__DeadlineInPast();
```

### Aera\_\_DeadlineTooFarInFuture

```solidity
error Aera__DeadlineTooFarInFuture();
```

### Aera\_\_DeadlineInFutureAndUnauthorized

```solidity
error Aera__DeadlineInFutureAndUnauthorized();
```

### Aera\_\_MinTokenOutZero

```solidity
error Aera__MinTokenOutZero();
```

### Aera\_\_HashCollision

```solidity
error Aera__HashCollision();
```

### Aera\_\_ZeroAddressPriceAndFeeCalculator

```solidity
error Aera__ZeroAddressPriceAndFeeCalculator();
```

### Aera\_\_ZeroAddressMultiDepositorVault

```solidity
error Aera__ZeroAddressMultiDepositorVault();
```

### Aera\_\_DepositMultiplierTooLow

```solidity
error Aera__DepositMultiplierTooLow();
```

### Aera\_\_DepositMultiplierTooHigh

```solidity
error Aera__DepositMultiplierTooHigh();
```

### Aera\_\_RedeemMultiplierTooLow

```solidity
error Aera__RedeemMultiplierTooLow();
```

### Aera\_\_RedeemMultiplierTooHigh

```solidity
error Aera__RedeemMultiplierTooHigh();
```

### Aera\_\_DepositCapZero

```solidity
error Aera__DepositCapZero();
```

### Aera\_\_PriceAndFeeCalculatorVaultPaused

```solidity
error Aera__PriceAndFeeCalculatorVaultPaused();
```

### Aera\_\_AutoPriceSolveNotAllowed

```solidity
error Aera__AutoPriceSolveNotAllowed();
```

### Aera\_\_FixedPriceSolverTipNotAllowed

```solidity
error Aera__FixedPriceSolverTipNotAllowed();
```

### Aera\_\_TokenCantBePriced

```solidity
error Aera__TokenCantBePriced();
```

### Aera\_\_CallerIsVault

```solidity
error Aera__CallerIsVault();
```

### Aera\_\_InvalidToken

```solidity
error Aera__InvalidToken();
```
