> For the complete documentation index, see [llms.txt](https://developers.strateg.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.strateg.io/core-protocol/vault-strategy.md).

# Vault Strategy

## Strategy Definition

A vault strategy is defined by two lists of strateg blocks. A strategy setup in a *StrategVault* contract is defined by the `setStrat` function. All these parameters determine the vault executions during its operations.

```solidity
function setStrat(
    address[] positionManagers, 
    address[] stratBlocks, 
    bytes[] stratBlocksParameters, 
    bool[] isFinalBlock, 
    address[] harvestBlocks, 
    bytes[] harvestBlocksParameters
) external;
```

* **positionManagers**: List of position managers owned by the vault. These addresses have the ability to call a whitelisted function during a position manager rebalance operation.
* **stratBlocks**: Ordered list of strategy block addresses executed during strategy execution.
* **stratBlocksParameters**: Ordered list of bytes containing encoded parameters of the block in the same index as the one in the stratBlocks list.
* **isFinalBlock**: Ordered list of boolean to set a block in the stratBlocks as the last block. This function is only used in the event of a strategy exit. When a block is a final block, it receives the current exit percentage, otherwise it receives 100% as exit percentage.
* **harvestBlocks**: Ordered list of harvest block addresses executed during harvest execution.&#x20;
* **harvestBlocksParameters**: Ordered list of bytes containing encoded parameters of block in the same index in harvestBlocks list

## Internal Oracle System

When a *StrategVault* contract needs to compute the TVL of its assets (e.g deposit/withdraw), it does so by calling the oracleExit functions of the blocks, from last to the first one, as follows.

```solidity
/**
 * @dev Internal function to get the native TVL (Total Value Locked) of the vault.
 * @return The native TVL of the vault.
 */
function _getNativeTVL() internal view returns (uint256) {
    address _asset = asset();

    DataTypes.OracleState memory oracleState;
    oracleState.vault = address(this);

    uint256 _strategyBlocksLength = strategyBlocksLength;
    if (_strategyBlocksLength == 0 || !isLive) {
        return IERC20(_asset).balanceOf(address(this)) + IERC20(_asset).allowance(buffer, address(this));
    } else if (_strategyBlocksLength == 1) {
        oracleState =
            IStrategStrategyBlock(strategyBlocks[0]).oracleExit(
                oracleState, 
                LibBlock.getStrategyStorageByIndex(0), 
                10000
            );
    } else {
        uint256 revertedIndex = _strategyBlocksLength - 1;
        for (uint256 i = 0; i < _strategyBlocksLength; i++) {
            uint256 index = revertedIndex - i;
            oracleState = IStrategStrategyBlock(strategyBlocks[index]).oracleExit(
                oracleState, LibBlock.getStrategyStorageByIndex(index), 10000
            );
        }
    }

    return oracleState.findTokenAmount(_asset) + IERC20(_asset).balanceOf(address(this))
        + IERC20(_asset).allowance(buffer, address(this));
}
```

By exemple:

<figure><img src="/files/eZejeqGoEuUZL85Y6v0N" alt=""><figcaption></figcaption></figure>

Here the call to oracle exit of Aura block will provide the number of Balancer LP Token which will be returned by a withdraw. This state is passed to the Balancer Block which will determine the number of WETH which will be returned based on the previous block state&#x20;

## Dynamic Parameters

Vault strategy can be operated with dynamic parameters that adjust their behavior based on external inputs. These parameters can be passed during operations (e.g rebalancing/harvesting) to adapt the strategy to current market conditions or specific operational needs. There are different types of dynamic parameters.

### Portal Swap

Dynamic swap parameters can be used in blocks to define a token swap requirement via the Strateg Portal Module. The block can provide a token swap operation dynamically during the execution of a block. These parameters can be adjusted based on the current state, enabling the block to perform optimized token swaps based on current market conditions or specific block requirements.

```solidity
/// @notice Enum representing the different types of swap value
enum SwapValueType {
    INPUT_STRICT_VALUE,
    INPUT_PERCENT_VALUE,
    OUTPUT_STRICT_VALUE
}

/// @notice Struct representing the dynamic swap parameters
/// @param fromToken The address of the token to swap from
/// @param toToken The address of the token to swap to
/// @param value The amount of tokens to swap
/// @param valueType The type of value to swap
struct DynamicSwapParams {
    address fromToken;
    address toToken;
    uint256 value;
    SwapValueType valueType; 
}

/// @notice Struct representing the dynamic swap data
/// @param route The route to use for the swap
/// @param sourceAsset The address of the asset to swap from
/// @param approvalAddress The address to approve for the swap
/// @param targetAsset The address of the asset to swap to
/// @param amount The amount of tokens to swap
/// @param data The data to send to the swap
struct DynamicSwapData {
    uint8 route;
    address sourceAsset;
    address approvalAddress;
    address targetAsset;
    uint256 amount;
    bytes data;
}
```

* `SwapValueType`
  * INPUT\_STRICT\_VALUE
  * INPUT\_PERCENT\_VALUE
  * OUTPUT\_STRICT\_VALUE
* `DynamicSwapParams`
  * fromToken
  * toToken
  * value
  * SwapValueType
* `DynamicSwapData`
  * route
  * sourceAsset
  * approvalAddress
  * targetAsset
  * amount
  * data

For exemple, if the block need to execute a swap, it must return the following data on the `dynamicParamsInfo` is called:

```solidity
return true, DataTypes.DynamicParamsType.PORTAL_SWAP, DynamicSwapParams({
    fromToken: <tokenIn address>,
    toToken: <tokenOut address>,
    value: <amount>,
    valueType: <Type of the value provided>
})
```

### Static call

This dynamic parameters will ask to the operator to request an `eth_call` on the EVM RPC on the provided address with the specified data. It can be useful if the block need a protection against market manipulation by comparing call data with the data during the execution.&#x20;

```solidity
/// @notice Struct representing the static call parameters
/// @param to The address of the contract to call
/// @param data The data to send to the contract
struct StaticCallParams {
    address to;
    bytes data;
}
```

### Merkle

This dynamic parameters doesn't need to return data on `dynamicParamsInfo` call. The operators will call the merkle API to check if the vault address have pending rewards and provided merkle proof to claim them to the block.

## From dApp creation graph to vault strategy

As exemple, we will use the following strategy:

<figure><img src="/files/A2mWkXU3krOCFnSGRUnE" alt=""><figcaption></figcaption></figure>

From this graph, there is logics applied to generate the strategy payload:

* Edges loop removal: it remove every edges which is returning on a block already included is the strategy
* Strategy splitting: split strategy and harvest block in two groups
* &#x20;Number formating: convert number inputs to big numbers&#x20;
* Percent formating: format percent and adapt them to be apply correctly in the strategy\
  Exemple: a 33% / 33% / 33% fork will be result as 33% / 50% / 100%&#x20;
* Set each block without output edges as final.&#x20;

So in this exemple, the list of strategy block will be composed by:

Strategy enter execution:&#x20;

1. Aave v3 Deposit with 50% of WETH available
2. Balancer Deposit with 100% of remaining WETH
3. Deposit 100% of Balancer LP in Aura &#x20;

Strategy exit execution of x percent:&#x20;

1. Withdraw x% of Balancer LP deposited in Aura
2. Withdraw 100% of Balancer LP available
3. Withdraw x% of WETH availble in Aave v3

Harvest execution:&#x20;

1. Claim Aura rewards (Aura + Bal)
2. Swap 100% of available Bal to WETH
3. Swap 100% of available Aura to WETH &#x20;
