# Vault

## Vault

* Responsible for following actions on USDs:
  * Mint USDs token
  * Redeem USDs token
  * Carry out rebase for USDs token
  * Allocate collateral to strategies
  * Withdraw collateral from strategies

## Contract documentation

[Git Source](https://github.com/Sperax/USDs-v2/blob/ff71faf9d7e40d2b2764e5e8f2acc631f31489aa/contracts/vault/VaultCore.sol)

**Inherits:** Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable

**Author:** Sperax Foundation

This contract enables users to mint and redeem USDs with allowed collaterals.

It also allocates collateral to strategies based on the Collateral Manager contract.

### **State Variables**

#### **feeVault**

```solidity
address public feeVault;

```

#### **yieldReceiver**

```solidity
address public yieldReceiver;

```

#### **collateralManager**

```solidity
address public collateralManager;

```

#### **feeCalculator**

```solidity
address public feeCalculator;

```

#### **oracle**

```solidity
address public oracle;

```

#### **rebaseManager**

```solidity
address public rebaseManager;

```

### **Functions**

#### **constructor**

```solidity
constructor();

```

#### **initialize**

```solidity
function initialize() external initializer;

```

#### **updateFeeVault**

Updates the address receiving fee.

```solidity
function updateFeeVault(address _feeVault) external onlyOwner;

```

**Parameters**

| Name       | Type    | Description                     |
| ---------- | ------- | ------------------------------- |
| \_feeVault | address | New desired SPABuyback address. |

#### **updateYieldReceiver**

Updates the address receiving yields from strategies.

```solidity
function updateYieldReceiver(address _yieldReceiver) external onlyOwner;

```

**Parameters**

| Name            | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| \_yieldReceiver | address | New desired yield receiver address. |

#### **updateCollateralManager**

Updates the address having the configuration for collaterals.

```solidity
function updateCollateralManager(address _collateralManager) external onlyOwner;

```

**Parameters**

| Name                | Type    | Description                             |
| ------------------- | ------- | --------------------------------------- |
| \_collateralManager | address | New desired collateral manager address. |

#### **updateRebaseManager**

Updates the address having the configuration for rebases.

```solidity
function updateRebaseManager(address _rebaseManager) external onlyOwner;

```

**Parameters**

| Name            | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| \_rebaseManager | address | New desired rebase manager address. |

#### **updateFeeCalculator**

Updates the fee calculator library.

```solidity
function updateFeeCalculator(address _feeCalculator) external onlyOwner;

```

**Parameters**

| Name            | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| \_feeCalculator | address | New desired fee calculator address. |

#### **updateOracle**

Updates the price oracle address.

```solidity
function updateOracle(address _oracle) external onlyOwner;

```

**Parameters**

| Name     | Type    | Description                 |
| -------- | ------- | --------------------------- |
| \_oracle | address | New desired oracle address. |

#### **allocate**

Allocates `_amount` of `_collateral` to `_strategy`.

```solidity
function allocate(address _collateral, address _strategy, uint256 _amount) external nonReentrant;

```

**Parameters**

| Name         | Type    | Description                           |
| ------------ | ------- | ------------------------------------- |
| \_collateral | address | Address of the desired collateral.    |
| \_strategy   | address | Address of the desired strategy.      |
| \_amount     | uint256 | Amount of collateral to be allocated. |

#### **mint**

Mint USDs by depositing collateral.

```solidity
function mint(address _collateral, uint256 _collateralAmt, uint256 _minUSDSAmt, uint256 _deadline)
    external
    nonReentrant;

```

**Parameters**

| Name            | Type    | Description                                   |
| --------------- | ------- | --------------------------------------------- |
| \_collateral    | address | Address of the collateral.                    |
| \_collateralAmt | uint256 | Amount of collateral to mint USDs with.       |
| \_minUSDSAmt    | uint256 | Minimum expected amount of USDs to be minted. |
| \_deadline      | uint256 | Expiry time of the transaction.               |

#### **mintBySpecifyingCollateralAmt**

Mint USDs by depositing collateral (backward compatibility).

*This function is for backward compatibility.*

```solidity
function mintBySpecifyingCollateralAmt(
    address _collateral,
    uint256 _collateralAmt,
    uint256 _minUSDSAmt,
    uint256,
    uint256 _deadline
) external nonReentrant;

```

**Parameters**

| Name            | Type    | Description                                   |
| --------------- | ------- | --------------------------------------------- |
| \_collateral    | address | Address of the collateral.                    |
| \_collateralAmt | uint256 | Amount of collateral to mint USDs with.       |
| \_minUSDSAmt    | uint256 | Minimum expected amount of USDs to be minted. |
|                 | uint256 |                                               |
| \_deadline      | uint256 | Expiry time of the transaction.               |

#### **redeem**

Redeem USDs for `_collateral`.

*In case where there is not sufficient collateral available in the vault, the collateral is withdrawn from the default strategy configured for the collateral.*

```solidity
function redeem(address _collateral, uint256 _usdsAmt, uint256 _minCollAmt, uint256 _deadline) external nonReentrant;

```

**Parameters**

| Name         | Type    | Description                                           |
| ------------ | ------- | ----------------------------------------------------- |
| \_collateral | address | Address of the collateral.                            |
| \_usdsAmt    | uint256 | Amount of USDs to be redeemed.                        |
| \_minCollAmt | uint256 | Minimum expected amount of collateral to be received. |
| \_deadline   | uint256 | Expiry time of the transaction.                       |

#### **redeem**

Redeem USDs for `_collateral` from a specific strategy.

```solidity
function redeem(address _collateral, uint256 _usdsAmt, uint256 _minCollAmt, uint256 _deadline, address _strategy)
    external
    nonReentrant;

```

**Parameters**

| Name         | Type    | Description                                                 |
| ------------ | ------- | ----------------------------------------------------------- |
| \_collateral | address | Address of the collateral.                                  |
| \_usdsAmt    | uint256 | Amount of USDs to be redeemed.                              |
| \_minCollAmt | uint256 | Minimum expected amount of collateral to be received.       |
| \_deadline   | uint256 | Expiry time of the transaction.                             |
| \_strategy   | address | Address of the strategy to withdraw excess collateral from. |

#### **redeemView**

Get the expected redeem result.

```solidity
function redeemView(address _collateral, uint256 _usdsAmt)
    external
    view
    returns (
        uint256 calculatedCollateralAmt,
        uint256 usdsBurnAmt,
        uint256 feeAmt,
        uint256 vaultAmt,
        uint256 strategyAmt
    );

```

**Parameters**

| Name         | Type    | Description                    |
| ------------ | ------- | ------------------------------ |
| \_collateral | address | Desired collateral address.    |
| \_usdsAmt    | uint256 | Amount of USDs to be redeemed. |

**Returns**

| Name                    | Type    | Description                                                                  |
| ----------------------- | ------- | ---------------------------------------------------------------------------- |
| calculatedCollateralAmt | uint256 | Expected amount of collateral to be released based on the price calculation. |
| usdsBurnAmt             | uint256 | Expected amount of USDs to be burnt in the process.                          |
| feeAmt                  | uint256 | Amount of USDs collected as fee for redemption.                              |
| vaultAmt                | uint256 | Amount of collateral released from Vault.                                    |
| strategyAmt             | uint256 | Amount of collateral to withdraw from the strategy.                          |

#### **redeemView**

Get the expected redeem result from a specific strategy.

```solidity
function redeemView(address _collateral, uint256 _usdsAmt, address _strategyAddr)
    external
    view
    returns (
        uint256 calculatedCollateralAmt,
        uint256 usdsBurnAmt,
        uint256 feeAmt,
        uint256 vaultAmt,
        uint256 strategyAmt
    );

```

**Parameters**

| Name           | Type    | Description                         |
| -------------- | ------- | ----------------------------------- |
| \_collateral   | address | Desired collateral address.         |
| \_usdsAmt      | uint256 | Amount of USDs to be redeemed.      |
| \_strategyAddr | address | Address of strategy to redeem from. |

**Returns**

| Name                    | Type    | Description                                                                  |
| ----------------------- | ------- | ---------------------------------------------------------------------------- |
| calculatedCollateralAmt | uint256 | Expected amount of collateral to be released based on the price calculation. |
| usdsBurnAmt             | uint256 | Expected amount of USDs to be burnt in the process.                          |
| feeAmt                  | uint256 | Amount of USDs collected as fee for redemption.                              |
| vaultAmt                | uint256 | Amount of collateral released from Vault.                                    |
| strategyAmt             | uint256 | Amount of collateral to withdraw from the strategy.                          |

#### **rebase**

Rebase USDs to share earned yield with the USDs holders.

*If Rebase manager returns a non-zero value, it calls the rebase function on the USDs contract.*

```solidity
function rebase() public;

```

#### **mintView**

Get the expected mint result (USDs amount, fee).

```solidity
function mintView(address _collateral, uint256 _collateralAmt) public view returns (uint256, uint256);

```

**Parameters**

| Name            | Type    | Description            |
| --------------- | ------- | ---------------------- |
| \_collateral    | address | Address of collateral. |
| \_collateralAmt | uint256 | Amount of collateral.  |

**Returns**

| Name | Type    | Description                                                |
| ---- | ------- | ---------------------------------------------------------- |
|      | uint256 | Returns the expected USDs mint amount and fee for minting. |
|      | uint256 |                                                            |

#### **\_mint**

Mint USDs by depositing collateral.

*Mints USDs by locking collateral based on user input, ensuring a minimum expected minted amount is met.*

*If the minimum expected amount is not met, the transaction will revert.*

*Fee is collected, and collateral is transferred accordingly.*

*A rebase operation is triggered after minting.*

```solidity
function _mint(address _collateral, uint256 _collateralAmt, uint256 _minUSDSAmt, uint256 _deadline) private;

```

**Parameters**

| Name            | Type    | Description                                   |
| --------------- | ------- | --------------------------------------------- |
| \_collateral    | address | Address of the collateral.                    |
| \_collateralAmt | uint256 | Amount of collateral to deposit.              |
| \_minUSDSAmt    | uint256 | Minimum expected amount of USDs to be minted. |
| \_deadline      | uint256 | Deadline timestamp for executing mint.        |

#### **\_redeem**

Redeem USDs for collateral.

*Redeems USDs for collateral, ensuring a minimum expected collateral amount is met.*

*If the minimum expected collateral amount is not met, the transaction will revert.*

*Fee is collected, collateral is transferred, and a rebase operation is triggered.*

```solidity
function _redeem(
    address _collateral,
    uint256 _usdsAmt,
    uint256 _minCollateralAmt,
    uint256 _deadline,
    address _strategyAddr
) private;

```

**Parameters**

| Name               | Type    | Description                                        |
| ------------------ | ------- | -------------------------------------------------- |
| \_collateral       | address | Address of the collateral to receive.              |
| \_usdsAmt          | uint256 | Amount of USDs to redeem.                          |
| \_minCollateralAmt | uint256 | Minimum expected collateral amount to be received. |
| \_deadline         | uint256 | Deadline timestamp for executing the redemption.   |
| \_strategyAddr     | address | Address of the strategy to withdraw from.          |

#### **\_redeemView**

Get the expected redeem result.

*Calculates the expected results of a redemption, including collateral amount, fees, and strategy-specific details.*

*Ensures that the redemption is allowed for the specified collateral.*

*Calculates fees, burn amounts, and collateral amounts based on prices and conversion factors.*

*Determines if collateral needs to be withdrawn from a strategy, and if so, checks the availability of collateral in the strategy.*

```solidity
function _redeemView(address _collateral, uint256 _usdsAmt, address _strategyAddr)
    private
    view
    returns (
        uint256 calculatedCollateralAmt,
        uint256 usdsBurnAmt,
        uint256 feeAmt,
        uint256 vaultAmt,
        uint256 strategyAmt,
        IStrategy strategy
    );

```

**Parameters**

| Name           | Type    | Description                             |
| -------------- | ------- | --------------------------------------- |
| \_collateral   | address | Desired collateral address.             |
| \_usdsAmt      | uint256 | Amount of USDs to be redeemed.          |
| \_strategyAddr | address | Address of the strategy to redeem from. |

**Returns**

| Name                    | Type      | Description                                                                  |
| ----------------------- | --------- | ---------------------------------------------------------------------------- |
| calculatedCollateralAmt | uint256   | Expected amount of collateral to be released based on the price calculation. |
| usdsBurnAmt             | uint256   | Expected amount of USDs to be burnt in the process.                          |
| feeAmt                  | uint256   | Amount of USDs collected as a fee for redemption.                            |
| vaultAmt                | uint256   | Amount of collateral released from Vault.                                    |
| strategyAmt             | uint256   | Amount of collateral to withdraw from the strategy.                          |
| strategy                | IStrategy | Strategy contract to withdraw collateral from.                               |

### **Events**

#### **FeeVaultUpdated**

```solidity
event FeeVaultUpdated(address newFeeVault);

```

#### **YieldReceiverUpdated**

```solidity
event YieldReceiverUpdated(address newYieldReceiver);

```

#### **CollateralManagerUpdated**

```solidity
event CollateralManagerUpdated(address newCollateralManager);

```

#### **FeeCalculatorUpdated**

```solidity
event FeeCalculatorUpdated(address newFeeCalculator);

```

#### **RebaseManagerUpdated**

```solidity
event RebaseManagerUpdated(address newRebaseManager);

```

#### **OracleUpdated**

```solidity
event OracleUpdated(address newOracle);

```

#### **Minted**

```solidity
event Minted(
    address indexed wallet, address indexed collateralAddr, uint256 usdsAmt, uint256 collateralAmt, uint256 feeAmt
);

```

#### **Redeemed**

```solidity
event Redeemed(
    address indexed wallet, address indexed collateralAddr, uint256 usdsAmt, uint256 collateralAmt, uint256 feeAmt
);

```

#### **RebasedUSDs**

```solidity
event RebasedUSDs(uint256 rebaseAmt);

```

#### **Allocated**

```solidity
event Allocated(address indexed collateral, address indexed strategy, uint256 amount);

```

### **Errors**

#### **AllocationNotAllowed**

```solidity
error AllocationNotAllowed(address collateral, address strategy, uint256 amount);

```

#### **RedemptionPausedForCollateral**

```solidity
error RedemptionPausedForCollateral(address collateral);

```

#### **InsufficientCollateral**

```solidity
error InsufficientCollateral(address collateral, address strategy, uint256 amount, uint256 availableAmount);

```

#### **InvalidStrategy**

```solidity
error InvalidStrategy(address _collateral, address _strategyAddr);

```

#### **MintFailed**

```solidity
error MintFailed();
```
