# Espresso Strategy

`EspressoStrategy` is a staking strategy that manages multiple `EspressoVault` contracts by tracking the balance of each and moving tokens in and out of them.

## View Functions

### token

Returns the address of the staking token (ESP).

```solidity
function token() public view returns (address)
```

#### Return Values

| Name  | Type    | Description       |
| ----- | ------- | ----------------- |
| token | address | ESP token address |

### stakingPool

Returns the address of the staking pool that controls this strategy.

```solidity
function stakingPool() public view returns (address)
```

#### Return Values

| Name        | Type    | Description          |
| ----------- | ------- | -------------------- |
| stakingPool | address | Staking pool address |

### espressoStaking

Returns the address of the Espresso delegation contract.

```solidity
function espressoStaking() public view returns (address)
```

#### Return Values

| Name            | Type    | Description                          |
| --------------- | ------- | ------------------------------------ |
| espressoStaking | address | Espresso delegation contract address |

### espressoRewards

Returns the address of the Espresso rewards contract.

```solidity
function espressoRewards() public view returns (address)
```

#### Return Values

| Name            | Type    | Description                       |
| --------------- | ------- | --------------------------------- |
| espressoRewards | address | Espresso rewards contract address |

### fundFlowController

Returns the address of the fund flow controller contract.

```solidity
function fundFlowController() public view returns (address)
```

#### Return Values

| Name               | Type    | Description                  |
| ------------------ | ------- | ---------------------------- |
| fundFlowController | address | Fund flow controller address |

### rewardsOracle

Returns the address of the rewards oracle.

```solidity
function rewardsOracle() public view returns (address)
```

#### Return Values

| Name          | Type    | Description            |
| ------------- | ------- | ---------------------- |
| rewardsOracle | address | Rewards oracle address |

### maxRewardChangeBPS

Returns the max reward change allowed per update in basis points.

```solidity
function maxRewardChangeBPS() public view returns (uint256)
```

#### Return Values

| Name               | Type    | Description                        |
| ------------------ | ------- | ---------------------------------- |
| maxRewardChangeBPS | uint256 | Max reward change per update (bps) |

### vaultImplementation

Returns the address of the vault implementation contract.

```solidity
function vaultImplementation() public view returns (address)
```

#### Return Values

| Name                | Type    | Description                  |
| ------------------- | ------- | ---------------------------- |
| vaultImplementation | address | Vault implementation address |

### totalQueued

Returns the total number of tokens queued for deposit into vaults.

```solidity
function totalQueued() public view returns (uint256)
```

#### Return Values

| Name        | Type    | Description         |
| ----------- | ------- | ------------------- |
| totalQueued | uint256 | Total queued tokens |

### numVaultsUnbonding

Returns the total number of vaults currently unbonding.

```solidity
function numVaultsUnbonding() public view returns (uint256)
```

#### Return Values

| Name               | Type    | Description                |
| ------------------ | ------- | -------------------------- |
| numVaultsUnbonding | uint256 | Number of vaults unbonding |

### vaultWithdrawalIndex

Returns the index of vault to withdraw from on next withdrawal.

```solidity
function vaultWithdrawalIndex() public view returns (uint256)
```

#### Return Values

| Name                 | Type    | Description            |
| -------------------- | ------- | ---------------------- |
| vaultWithdrawalIndex | uint256 | Vault withdrawal index |

### canDeposit

Returns the available deposit room for this strategy.

```solidity
function canDeposit() public view returns (uint256)
```

#### Return Values

| Name       | Type    | Description            |
| ---------- | ------- | ---------------------- |
| canDeposit | uint256 | Available deposit room |

### canWithdraw

Returns the available withdrawal room for this strategy.

```solidity
function canWithdraw() public view returns (uint256)
```

#### Return Values

| Name        | Type    | Description               |
| ----------- | ------- | ------------------------- |
| canWithdraw | uint256 | Available withdrawal room |

### getTotalDeposits

Returns the total amount of deposits in this strategy.

```solidity
function getTotalDeposits() public view returns (uint256)
```

#### Return Values

| Name          | Type    | Description    |
| ------------- | ------- | -------------- |
| totalDeposits | uint256 | Total deposits |

### getMaxDeposits

Returns the maximum that can be deposited into this strategy.

```solidity
function getMaxDeposits() public view returns (uint256)
```

#### Return Values

| Name        | Type    | Description      |
| ----------- | ------- | ---------------- |
| maxDeposits | uint256 | Maximum deposits |

### getMinDeposits

Returns the minimum that must remain in this strategy.

```solidity
function getMinDeposits() public view returns (uint256)
```

#### Return Values

| Name        | Type    | Description      |
| ----------- | ------- | ---------------- |
| minDeposits | uint256 | Minimum deposits |

### getVaults

Returns a list of all vaults controlled by this contract.

```solidity
function getVaults() external view returns (IEspressoVault[] memory)
```

#### Return Values

| Name   | Type              | Description    |
| ------ | ----------------- | -------------- |
| vaults | IEspressoVault\[] | List of vaults |

### getDepositChange

Returns the deposit change since deposits were last updated.

```solidity
function getDepositChange() public view returns (int)
```

#### Return Values

| Name          | Type | Description              |
| ------------- | ---- | ------------------------ |
| depositChange | int  | Change in total deposits |

### getFees

Returns a list of all fees and fee receivers.

```solidity
function getFees() external view returns (Fee[] memory)
```

#### Return Values

| Name | Type   | Description  |
| ---- | ------ | ------------ |
| fees | Fee\[] | List of fees |

## Write Functions

### deposit

Deposits tokens from the staking pool into this strategy.

```solidity
function deposit(uint256 _amount, bytes calldata) external
```

#### Parameters

| Name     | Type    | Description       |
| -------- | ------- | ----------------- |
| \_amount | uint256 | Amount to deposit |

### withdraw

Withdraws tokens from this strategy and sends them to staking pool.

```solidity
function withdraw(uint256 _amount, bytes calldata) external
```

#### Parameters

| Name     | Type    | Description        |
| -------- | ------- | ------------------ |
| \_amount | uint256 | Amount to withdraw |

### depositQueuedTokens

Deposits queued tokens into vaults.

```solidity
function depositQueuedTokens(uint256[] calldata _vaultIds, uint256[] calldata _amounts) external
```

#### Parameters

| Name       | Type       | Description                  |
| ---------- | ---------- | ---------------------------- |
| \_vaultIds | uint256\[] | List of vault IDs            |
| \_amounts  | uint256\[] | Amounts to deposit per vault |

### unbond

Unbonds token deposits in vaults.

```solidity
function unbond(uint256 _toUnbond) external
```

#### Parameters

| Name       | Type    | Description      |
| ---------- | ------- | ---------------- |
| \_toUnbond | uint256 | Amount to unbond |

### forceUnbond

Unbonds token deposits in vaults (used to rebalance between vaults).

```solidity
function forceUnbond(uint256[] calldata _vaultIds, uint256[] calldata _amounts) external
```

#### Parameters

| Name       | Type       | Description                 |
| ---------- | ---------- | --------------------------- |
| \_vaultIds | uint256\[] | List of vault IDs           |
| \_amounts  | uint256\[] | Amounts to unbond per vault |

### claimUnbond

Claims and withdraws tokens from vaults that are unbonded.

```solidity
function claimUnbond(uint256[] calldata _vaultIds) external
```

#### Parameters

| Name       | Type       | Description       |
| ---------- | ---------- | ----------------- |
| \_vaultIds | uint256\[] | List of vault IDs |

### updateDeposits

Updates deposit accounting and calculates fees on newly earned rewards.

```solidity
function updateDeposits(bytes calldata) external returns (int256 depositChange, address[] memory receivers, uint256[] memory amounts)
```

#### Return Values

| Name          | Type       | Description                          |
| ------------- | ---------- | ------------------------------------ |
| depositChange | int256     | Change in deposits since last update |
| receivers     | address\[] | List of fee receivers                |
| amounts       | uint256\[] | List of fee amounts                  |

### restakeRewards

Restakes rewards in the Espresso staking contract for given vaults.

```solidity
function restakeRewards(uint256[] calldata _vaultIds, uint256[] calldata _lifetimeRewards, bytes[] calldata _authData) external
```

#### Parameters

| Name              | Type       | Description                            |
| ----------------- | ---------- | -------------------------------------- |
| \_vaultIds        | uint256\[] | List of vault IDs                      |
| \_lifetimeRewards | uint256\[] | Lifetime rewards values for each vault |
| \_authData        | bytes\[]   | Authorization data for each vault      |

### withdrawRewards

Withdraws rewards from the Espresso staking contract for given vaults.

```solidity
function withdrawRewards(uint256[] calldata _vaultIds, uint256[] calldata _lifetimeRewards, bytes[] calldata _authData) external
```

#### Parameters

| Name              | Type       | Description                            |
| ----------------- | ---------- | -------------------------------------- |
| \_vaultIds        | uint256\[] | List of vault IDs                      |
| \_lifetimeRewards | uint256\[] | Lifetime rewards values for each vault |
| \_authData        | bytes\[]   | Authorization data for each vault      |

### updateLifetimeRewards

Updates lifetime rewards tracking for specified vaults. Used to sync lifetime rewards which is fetched off chain.

```solidity
function updateLifetimeRewards(uint256[] calldata _vaultIds, uint256[] calldata _lifetimeRewards) external
```

#### Parameters

| Name              | Type       | Description                            |
| ----------------- | ---------- | -------------------------------------- |
| \_vaultIds        | uint256\[] | List of vault IDs                      |
| \_lifetimeRewards | uint256\[] | Lifetime rewards values for each vault |

### claimValidatorExits

Claims validator exits for specified vaults.

```solidity
function claimValidatorExits(uint256[] calldata _vaultIds) external
```

#### Parameters

| Name       | Type       | Description       |
| ---------- | ---------- | ----------------- |
| \_vaultIds | uint256\[] | List of vault IDs |

### addVault

Adds a new vault for a validator.

```solidity
function addVault(address _validator) external
```

#### Parameters

| Name        | Type    | Description       |
| ----------- | ------- | ----------------- |
| \_validator | address | Validator address |

### removeVaults

Removes vaults. Withdraws any remaining principal deposits so vault must be empty or any unbonding periods must have elapsed for remaining deposits. Will not claim rewards so rewards must be claimed before removing a vault.

```solidity
function removeVaults(uint256[] calldata _vaultIdxs) external
```

#### Parameters

| Name        | Type       | Description                                     |
| ----------- | ---------- | ----------------------------------------------- |
| \_vaultIdxs | uint256\[] | List of vault indices (must be ascending order) |

### upgradeVaults

Upgrades vaults to a new implementation contract.

```solidity
function upgradeVaults(address[] calldata _vaults, bytes[] memory _data) external
```

#### Parameters

| Name     | Type       | Description                      |
| -------- | ---------- | -------------------------------- |
| \_vaults | address\[] | List of vault addresses          |
| \_data   | bytes\[]   | Encoded function calls per vault |

### addFee

Adds a new fee.

```solidity
function addFee(address _receiver, uint256 _feeBasisPoints) external
```

#### Parameters

| Name             | Type    | Description          |
| ---------------- | ------- | -------------------- |
| \_receiver       | address | Fee receiver address |
| \_feeBasisPoints | uint256 | Fee in basis points  |

### updateFee

Updates an existing fee. Set `_feeBasisPoints` to 0 to remove the fee.

```solidity
function updateFee(uint256 _index, address _receiver, uint256 _feeBasisPoints) external
```

#### Parameters

| Name             | Type    | Description          |
| ---------------- | ------- | -------------------- |
| \_index          | uint256 | Fee index            |
| \_receiver       | address | Fee receiver address |
| \_feeBasisPoints | uint256 | Fee in basis points  |

### setVaultImplementation

Sets a new vault implementation contract to be used when deploying/upgrading vaults.

```solidity
function setVaultImplementation(address _vaultImplementation) external
```

#### Parameters

| Name                  | Type    | Description                  |
| --------------------- | ------- | ---------------------------- |
| \_vaultImplementation | address | Vault implementation address |

### setFundFlowController

Sets the fund flow controller.

```solidity
function setFundFlowController(address _fundFlowController) external
```

#### Parameters

| Name                 | Type    | Description                  |
| -------------------- | ------- | ---------------------------- |
| \_fundFlowController | address | Fund flow controller address |

### setRewardsOracle

Sets the rewards oracle.

```solidity
function setRewardsOracle(address _rewardsOracle) external
```

#### Parameters

| Name            | Type    | Description            |
| --------------- | ------- | ---------------------- |
| \_rewardsOracle | address | Rewards oracle address |

### setMaxRewardChangeBPS

Sets the max reward change allowed per update in basis points.

```solidity
function setMaxRewardChangeBPS(uint256 _maxRewardChangeBPS) external
```

#### Parameters

| Name                 | Type    | Description                        |
| -------------------- | ------- | ---------------------------------- |
| \_maxRewardChangeBPS | uint256 | Max reward change per update (bps) |
