# Yield Reserve

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

**Inherits:** ReentrancyGuard, Ownable

**Author:** Sperax Foundation

This contract allows users to swap supported stable-coins for yield earned by the USDs protocol. It sends USDs to the Dripper contract for rebase and to the Buyback Contract for buyback.

## **State Variables**

### **vault**

```solidity
address public vault;

```

### **oracle**

```solidity
address public oracle;

```

### **buyback**

```solidity
address public buyback;

```

### **dripper**

```solidity
address public dripper;

```

### **buybackPercentage**

```solidity
uint256 public buybackPercentage;

```

### **tokenData**

```solidity
mapping(address => TokenData) public tokenData;

```

## **Functions**

### **constructor**

Constructor of the YieldReserve contract.

```solidity
constructor(address _buyback, address _vault, address _oracle, address _dripper);

```

**Parameters**

| Name      | Type    | Description                      |
| --------- | ------- | -------------------------------- |
| \_buyback | address | Address of the Buyback contract. |
| \_vault   | address | Address of the Vault.            |
| \_oracle  | address | Address of the Oracle.           |
| \_dripper | address | Address of the Dripper contract. |

### **swap**

Swap function to be called by frontend users.

```solidity
function swap(address _srcToken, address _dstToken, uint256 _amountIn, uint256 _minAmountOut) external;

```

**Parameters**

| Name           | Type    | Description                     |
| -------------- | ------- | ------------------------------- |
| \_srcToken     | address | Source/Input token.             |
| \_dstToken     | address | Destination/Output token.       |
| \_amountIn     | uint256 | Input token amount.             |
| \_minAmountOut | uint256 | Minimum output tokens expected. |

### **toggleSrcTokenPermission**

Allow or disallow a specific `token` for use as a source/input token.

```solidity
function toggleSrcTokenPermission(address _token, bool _isAllowed) external onlyOwner;

```

**Parameters**

| Name        | Type    | Description                                                                                          |
| ----------- | ------- | ---------------------------------------------------------------------------------------------------- |
| \_token     | address | Address of the token to be allowed or disallowed.                                                    |
| \_isAllowed | bool    | If set to true, the token will be allowed as a source/input token; otherwise, it will be disallowed. |

### **toggleDstTokenPermission**

Allow or disallow a specific `token` for use as a destination/output token.

*Reverts if caller is not owner.*

```solidity
function toggleDstTokenPermission(address _token, bool _isAllowed) external onlyOwner;

```

**Parameters**

| Name        | Type    | Description                                                                                                |
| ----------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| \_token     | address | Address of the token to be allowed or disallowed.                                                          |
| \_isAllowed | bool    | If set to true, the token will be allowed as a destination/output token; otherwise, it will be disallowed. |

### **withdraw**

Emergency withdrawal function for unexpected situations.

```solidity
function withdraw(address _token, address _receiver, uint256 _amount) external onlyOwner;

```

**Parameters**

| Name       | Type    | Description                           |
| ---------- | ------- | ------------------------------------- |
| \_token    | address | Address of the asset to be withdrawn. |
| \_receiver | address | Address of the receiver of tokens.    |
| \_amount   | uint256 | Amount of tokens to be withdrawn.     |

### **updateBuybackPercentage**

Set the percentage of newly minted USDs to be sent to the Buyback contract.

*Reverts if caller is not owner.*

*The remaining USDs are sent to VaultCore for rebase.*

```solidity
function updateBuybackPercentage(uint256 _toBuyback) public onlyOwner;

```

**Parameters**

| Name        | Type    | Description                                                  |
| ----------- | ------- | ------------------------------------------------------------ |
| \_toBuyback | uint256 | The percentage of USDs sent to Buyback (e.g., 3000 for 30%). |

### **updateBuyback**

Update the address of the Buyback contract.

*Reverts if caller is not owner.*

```solidity
function updateBuyback(address _newBuyBack) public onlyOwner;

```

**Parameters**

| Name         | Type    | Description                          |
| ------------ | ------- | ------------------------------------ |
| \_newBuyBack | address | New address of the Buyback contract. |

### **updateOracle**

Update the address of the Oracle contract.

*Reverts if caller is not owner.*

```solidity
function updateOracle(address _newOracle) public onlyOwner;

```

**Parameters**

| Name        | Type    | Description                         |
| ----------- | ------- | ----------------------------------- |
| \_newOracle | address | New address of the Oracle contract. |

### **updateDripper**

Update the address of the Dripper contract.

*Reverts if caller is not owner.*

```solidity
function updateDripper(address _newDripper) public onlyOwner;

```

**Parameters**

| Name         | Type    | Description                          |
| ------------ | ------- | ------------------------------------ |
| \_newDripper | address | New address of the Dripper contract. |

### **updateVault**

Update the address of the VaultCore contract.

*Reverts if caller is not owner.*

```solidity
function updateVault(address _newVault) public onlyOwner;

```

**Parameters**

| Name       | Type    | Description                            |
| ---------- | ------- | -------------------------------------- |
| \_newVault | address | New address of the VaultCore contract. |

### **swap**

Swap allowed source token for allowed destination token.

```solidity
function swap(address _srcToken, address _dstToken, uint256 _amountIn, uint256 _minAmountOut, address _receiver)
    public
    nonReentrant;

```

**Parameters**

| Name           | Type    | Description                     |
| -------------- | ------- | ------------------------------- |
| \_srcToken     | address | Source/Input token.             |
| \_dstToken     | address | Destination/Output token.       |
| \_amountIn     | uint256 | Input token amount.             |
| \_minAmountOut | uint256 | Minimum output tokens expected. |
| \_receiver     | address | Receiver of the tokens.         |

### **mintUSDs**

Mints USDs directly with the allowed collaterals for USDs.

*Only collaterals configured in USDs vault are allowed to be used for minting.*

```solidity
function mintUSDs(address _token) public nonReentrant;

```

**Parameters**

| Name    | Type    | Description                        |
| ------- | ------- | ---------------------------------- |
| \_token | address | Address of token to mint USDs with |

### **getTokenBForTokenA**

Get an estimate of the output token amount for a given input token amount.

```solidity
function getTokenBForTokenA(address _srcToken, address _dstToken, uint256 _amountIn) public view returns (uint256);

```

**Parameters**

| Name       | Type    | Description                 |
| ---------- | ------- | --------------------------- |
| \_srcToken | address | Input token address.        |
| \_dstToken | address | Output token address.       |
| \_amountIn | uint256 | Input amount of \_srcToken. |

**Returns**

| Name | Type    | Description                    |
| ---- | ------- | ------------------------------ |
|      | uint256 | Estimated output token amount. |

### **\_sendUSDs**

Distributes USDs to the Buyback and Dripper contracts based on buybackPercentage.

*Sends a portion of the USDs balance to the Buyback contract and the remaining to the Dripper contract for rebase.*

```solidity
function _sendUSDs() private;

```

## **Events**

### **Swapped**

```solidity
event Swapped(
    address indexed srcToken, address indexed dstToken, address indexed dstReceiver, uint256 amountIn, uint256 amountOut
);

```

### **USDsMintedViaSwapper**

```solidity
event USDsMintedViaSwapper(address indexed collateralAddr, uint256 usdsMinted);

```

### **Withdrawn**

```solidity
event Withdrawn(address indexed token, address indexed receiver, uint256 amount);

```

### **BuybackPercentageUpdated**

```solidity
event BuybackPercentageUpdated(uint256 toBuyback);

```

### **BuybackUpdated**

```solidity
event BuybackUpdated(address newBuyback);

```

### **OracleUpdated**

```solidity
event OracleUpdated(address newOracle);

```

### **VaultUpdated**

```solidity
event VaultUpdated(address newVault);

```

### **DripperUpdated**

```solidity
event DripperUpdated(address newDripper);

```

### **USDsSent**

```solidity
event USDsSent(uint256 toBuyback, uint256 toDripper);

```

### **SrcTokenPermissionUpdated**

```solidity
event SrcTokenPermissionUpdated(address indexed token, bool isAllowed);

```

### **DstTokenPermissionUpdated**

```solidity
event DstTokenPermissionUpdated(address indexed token, bool isAllowed);

```

## **Errors**

### **InvalidSourceToken**

```solidity
error InvalidSourceToken();

```

### **InvalidDestinationToken**

```solidity
error InvalidDestinationToken();

```

### **AlreadyInDesiredState**

```solidity
error AlreadyInDesiredState();

```

### **TokenPriceFeedMissing**

```solidity
error TokenPriceFeedMissing();

```

## **Structs**

### **TokenData**

```solidity
struct TokenData {
    bool srcAllowed;
    bool dstAllowed;
    uint160 conversionFactor;
}
```
