# BaseStrategy

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

**Inherits:** Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable

**Author:** Sperax Foundation

*Contract acts as a single interface for implementing specific yield-earning strategies.*

## **State Variables**

### **vault**

```solidity
address public vault;

```

### **withdrawSlippage**

```solidity
uint16 public withdrawSlippage;

```

### **depositSlippage**

```solidity
uint16 public depositSlippage;

```

### **harvestIncentiveRate**

```solidity
uint16 public harvestIncentiveRate;

```

### **assetsMapped**

```solidity
address[] internal assetsMapped;

```

### **rewardTokenAddress**

```solidity
address[] public rewardTokenAddress;

```

### **assetToPToken**

```solidity
mapping(address => address) public assetToPToken;

```

### **gap**

```solidity
uint256[40] private __gap__;

```

## **Functions**

### **onlyVault**

```solidity
modifier onlyVault();

```

### **onlyVaultOrOwner**

```solidity
modifier onlyVaultOrOwner();

```

### **constructor**

```solidity
constructor();

```

### **updateVault**

Update the linked vault contract.

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

```

**Parameters**

| Name       | Type    | Description               |
| ---------- | ------- | ------------------------- |
| \_newVault | address | Address of the new Vault. |

### **updateHarvestIncentiveRate**

Updates the HarvestIncentive rate for the user.

```solidity
function updateHarvestIncentiveRate(uint16 _newRate) external onlyOwner;

```

**Parameters**

| Name      | Type   | Description       |
| --------- | ------ | ----------------- |
| \_newRate | uint16 | new Desired rate. |

### **recoverERC20**

A function to recover any erc20 token sent to this strategy mistakenly.

*Only callable by owner.*

*reverts if amount > balance.*

```solidity
function recoverERC20(address token, address receiver, uint256 amount) external onlyOwner;

```

**Parameters**

| Name     | Type    | Description             |
| -------- | ------- | ----------------------- |
| token    | address | Address of the token.   |
| receiver | address | Receiver of the token.  |
| amount   | uint256 | Amount to be recovered. |

### **deposit**

*Deposit an amount of asset into the platform.*

```solidity
function deposit(address _asset, uint256 _amount) external virtual;

```

**Parameters**

| Name     | Type    | Description                |
| -------- | ------- | -------------------------- |
| \_asset  | address | Address for the asset.     |
| \_amount | uint256 | Units of asset to deposit. |

### **withdraw**

*Withdraw an amount of asset from the platform.*

```solidity
function withdraw(address _recipient, address _asset, uint256 _amount)
    external
    virtual
    returns (uint256 amountReceived);

```

**Parameters**

| Name        | Type    | Description                                |
| ----------- | ------- | ------------------------------------------ |
| \_recipient | address | Address to which the asset should be sent. |
| \_asset     | address | Address of the asset.                      |
| \_amount    | uint256 | Units of asset to withdraw.                |

**Returns**

| Name           | Type    | Description                 |
| -------------- | ------- | --------------------------- |
| amountReceived | uint256 | The actual amount received. |

### **withdrawToVault**

*Withdraw an amount of asset from the platform to vault.*

```solidity
function withdrawToVault(address _asset, uint256 _amount) external virtual returns (uint256 amount);

```

**Parameters**

| Name     | Type    | Description                 |
| -------- | ------- | --------------------------- |
| \_asset  | address | Address of the asset.       |
| \_amount | uint256 | Units of asset to withdraw. |

### **collectInterest**

Withdraw the interest earned of asset from the platform.

```solidity
function collectInterest(address _asset) external virtual;

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

### **collectReward**

Collect accumulated reward token and send to Vault.

```solidity
function collectReward() external virtual;

```

### **checkBalance**

Get the amount of a specific asset held in the strategy, excluding the interest.

*Curve: assuming balanced withdrawal.*

```solidity
function checkBalance(address _asset) external view virtual returns (uint256);

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

**Returns**

| Name | Type    | Description                                 |
| ---- | ------- | ------------------------------------------- |
|      | uint256 | uint256 Balance of \_asset in the strategy. |

### **checkAvailableBalance**

Get the amount of a specific asset held in the strategy, excluding the interest and any locked liquidity that is not available for instant withdrawal.

*Curve: assuming balanced withdrawal.*

```solidity
function checkAvailableBalance(address _asset) external view virtual returns (uint256);

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

**Returns**

| Name | Type    | Description                                                |
| ---- | ------- | ---------------------------------------------------------- |
|      | uint256 | uint256 Available balance inside the strategy for \_asset. |

### **checkInterestEarned**

AAVE: Get the interest earned on a specific asset. Curve: Get the total interest earned.

*Curve: to avoid double-counting, \_asset has to be of index 'entryTokenIndex'.*

```solidity
function checkInterestEarned(address _asset) external view virtual returns (uint256);

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

**Returns**

| Name | Type    | Description                        |
| ---- | ------- | ---------------------------------- |
|      | uint256 | uint256 Amount of interest earned. |

### **checkRewardEarned**

Get the amount of claimable reward.

```solidity
function checkRewardEarned() external view virtual returns (RewardData[] memory);

```

**Returns**

| Name | Type          | Description                                                      |
| ---- | ------------- | ---------------------------------------------------------------- |
|      | RewardData\[] | struct array of type RewardData (address token, uint256 amount). |

### **checkLPTokenBalance**

Get the total LP token balance for a asset.

```solidity
function checkLPTokenBalance(address _asset) external view virtual returns (uint256);

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

### **supportsCollateral**

Check if an asset/collateral is supported.

```solidity
function supportsCollateral(address _asset) external view virtual returns (bool);

```

**Parameters**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| \_asset | address | Address of the asset. |

**Returns**

| Name | Type | Description                      |
| ---- | ---- | -------------------------------- |
|      | bool | bool Whether asset is supported. |

### **updateSlippage**

Change to a new depositSlippage & withdrawSlippage.

```solidity
function updateSlippage(uint16 _depositSlippage, uint16 _withdrawSlippage) public onlyOwner;

```

**Parameters**

| Name               | Type   | Description                        |
| ------------------ | ------ | ---------------------------------- |
| \_depositSlippage  | uint16 | Slippage tolerance for allocation. |
| \_withdrawSlippage | uint16 | Slippage tolerance for withdrawal. |

### **\_initialize**

Initialize the base properties of the strategy.

```solidity
function _initialize(address _vault, uint16 _depositSlippage, uint16 _withdrawSlippage) internal;

```

**Parameters**

| Name               | Type    | Description                        |
| ------------------ | ------- | ---------------------------------- |
| \_vault            | address | Address of the USDs Vault.         |
| \_depositSlippage  | uint16  | Allowed max slippage for Deposit.  |
| \_withdrawSlippage | uint16  | Allowed max slippage for withdraw. |

### **\_setPTokenAddress**

Provide support for asset by passing its pToken address. Add to internal mappings and execute the platform specific, abstract method `_abstractSetPToken`.

```solidity
function _setPTokenAddress(address _asset, address _pToken) internal;

```

**Parameters**

| Name     | Type    | Description                                   |
| -------- | ------- | --------------------------------------------- |
| \_asset  | address | Address for the asset.                        |
| \_pToken | address | Address for the corresponding platform token. |

### **\_removePTokenAddress**

Remove a supported asset by passing its index. This method can only be called by the system owner.

```solidity
function _removePTokenAddress(uint256 _assetIndex) internal returns (address asset);

```

**Parameters**

| Name         | Type    | Description                       |
| ------------ | ------- | --------------------------------- |
| \_assetIndex | uint256 | Index of the asset to be removed. |

**Returns**

| Name  | Type    | Description               |
| ----- | ------- | ------------------------- |
| asset | address | address which is removed. |

### **\_splitAndSendReward**

Splits and sends the accumulated rewards to harvestor and yield receiver.

*Sends the amount to harvestor as per `harvestIncentiveRate` and sends the rest to yield receiver.*

```solidity
function _splitAndSendReward(address _token, address _yieldReceiver, address _harvestor, uint256 _amount)
    internal
    returns (uint256);

```

**Parameters**

| Name            | Type    | Description                    |
| --------------- | ------- | ------------------------------ |
| \_token         | address | Address of the reward token.   |
| \_yieldReceiver | address | Address of the yield receiver. |
| \_harvestor     | address | Address of the harvestor.      |
| \_amount        | uint256 | to be split and sent.          |

**Returns**

| Name | Type    | Description                                      |
| ---- | ------- | ------------------------------------------------ |
|      | uint256 | uint256 Harvested amount sent to yield receiver. |

### **\_abstractSetPToken**

Call the necessary approvals for the underlying strategy.

```solidity
function _abstractSetPToken(address _asset, address _pToken) internal virtual;

```

**Parameters**

| Name     | Type    | Description                                 |
| -------- | ------- | ------------------------------------------- |
| \_asset  | address | Address of the asset.                       |
| \_pToken | address | Address of the corresponding receipt token. |

## **Events**

### **VaultUpdated**

```solidity
event VaultUpdated(address newVaultAddr);

```

### **YieldReceiverUpdated**

```solidity
event YieldReceiverUpdated(address newYieldReceiver);

```

### **PTokenAdded**

```solidity
event PTokenAdded(address indexed asset, address pToken);

```

### **PTokenRemoved**

```solidity
event PTokenRemoved(address indexed asset, address pToken);

```

### **Deposit**

```solidity
event Deposit(address indexed asset, uint256 amount);

```

### **Withdrawal**

```solidity
event Withdrawal(address indexed asset, uint256 amount);

```

### **SlippageUpdated**

```solidity
event SlippageUpdated(uint16 depositSlippage, uint16 withdrawSlippage);

```

### **HarvestIncentiveCollected**

```solidity
event HarvestIncentiveCollected(address indexed token, address indexed harvestor, uint256 amount);

```

### **HarvestIncentiveRateUpdated**

```solidity
event HarvestIncentiveRateUpdated(uint16 newRate);

```

### **InterestCollected**

```solidity
event InterestCollected(address indexed asset, address indexed recipient, uint256 amount);

```

### **RewardTokenCollected**

```solidity
event RewardTokenCollected(address indexed rwdToken, address indexed recipient, uint256 amount);

```

## **Errors**

### **CallerNotVault**

```solidity
error CallerNotVault(address caller);

```

### **CallerNotVaultOrOwner**

```solidity
error CallerNotVaultOrOwner(address caller);

```

### **PTokenAlreadySet**

```solidity
error PTokenAlreadySet(address collateral, address pToken);

```

### **InvalidIndex**

```solidity
error InvalidIndex();

```

### **CollateralNotSupported**

```solidity
error CollateralNotSupported(address asset);

```

### **InvalidAssetLpPair**

```solidity
error InvalidAssetLpPair(address asset, address lpToken);

```

### **CollateralAllocated**

```solidity
error CollateralAllocated(address asset);

```

## **Structs**

### **RewardData**

```solidity
struct RewardData {
    address token;
    uint256 amount;
}
```
