> 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/blocks.md).

# Blocks

## Block Architecture

A "block" is a standardized smart contract that performs a specific action on a DeFi protocol. Each block must implement the functions of the following interface:

```solidity
interface IStrategCommonBlock {
    /// @notice The IPFS hash of the block metadata file
    function ipfsHash() external view returns (string memory);

    /// @notice Return dynamic parameters needed for the block execution
    /// @param _exec The type of block execution
    /// @param _parameters The parameters of the block execution
    /// @param _oracleState The state of the oracle
    /// @param _percent The percentage of the block execution
    /// @return dynParamsNeeded Whether the strategy block execution needs dynamic parameters
    /// @return dynParamsType The type of dynamic parameters needed
    /// @return dynParamsInfo The information of the dynamic parameters needed
    function dynamicParamsInfo(
        DataTypes.BlockExecutionType _exec,
        bytes memory _parameters,
        DataTypes.OracleState memory _oracleState,
        uint256 _percent
    ) external view returns (bool, DataTypes.DynamicParamsType, bytes memory);
}
```

* `ipfsHash` returns an IPFS hash of a JSON file containing its metadata(s).
* `dynamicParamsInfo` function indicates if the block needs dynamic parameters during execution. Dynamic parameters are offchain parameters, computed by operators during vault operations.&#x20;
  * &#x20;`_exec` represents the execution context (ENTER, EXIT or HARVEST).
  * *`_parameters`* is a byte containing block parameters.
  * *`_oracleState`* contains the list of assets available during execution.
  * `_percent` is the percentage in basis points in the exit context (withdraw). In other contexts, it is always equal to 100%.

## Block Metadata(s)

The underlying file must be a JSON file containing block metadata. For example, the deposit on Aave V3 contains the following metadata.

```json
{
    "id":"AAVE_V3_DEPOSIT",
    "type":"block",
    "gitUrl":"https://github.com/StrategProtocol/strateg-protocol-block-aave-v3",
    "resolver":"QmP9yBZwnRcpEh1dqyFDkkha3dGXPgcgaYgjVfvGJzNKT4",
    "name":"Aave V3 Deposit Strateg. Block",
    "description":"Block to deposit a token on Aave V3",
    "action":"Deposit",
    "protocolId":"AAVE_V3",
    "protocolName":"Aave v3",
    "paramsTuple":"tuple(uint256 tokenInPercent, address token)",
    "params":[
        {
            "attribute":"tokenInPercent",
            "name":"Amount",
            "type":"percent",
            "underlyingType":"uint256"
        },
        {
            "attribute":"token",
            "name":"Deposit",
            "type":"ERC20",
            "underlyingType":"address",
            "resolved":"true"
        }
    ]
}
```

* **id**: It corresponds to the unique block identifier for a single chain. It must be composed of the protocol identifier followed by the action in uppercase Camel.
* **type**: There are three possible values for this attribute:
  * **block**: Define the block as a strategy block. The block contract must be compliant with the StrategStrategyBlock interface.
  * **harvest-block:** Define the block as a harvest block. The block contract must be compliant with the StrategHarvestBlock interface.
  * **position-manager:** Define the block as a position manager, which an extension of the StrategStrategyBlock interface. For this type of block, a remote contract from the borrow module must be deployed during the vault deployment process.
* **gitUrl**: The link to the public git repository containing smart contracts code.
* **resolver**: IPFS hash containing a typescript file executed as a lambda that returns all available configurations of the block.
* **name**: Human readable block name.
* **description**: Human readable description explaining block action(s).
* **action**: Human readable short action description (1 or 2 words).
* **protocolId**: Protocol identifier uppercase and camelcase.
* **protocolName**: Human readable protocol name.
* **paramsTuple**: Tuple of parameters taken by the block when the strategy is defined.
* **params**: List of object describing block's parameters for frontend rendering.

## Block Types

There are two different types of blocks.

### Strategy Block

Strategy blocks are primarily responsible for managing the vault strategy execution. This includes entering and exiting positions. They must implement the following interface functions.

```solidity
interface IStrategStrategyBlock is IStrategCommonBlock {

    /// @notice Execute hook block function 
    /// @param _index The index of the block
    /// @param _executionType execution type: Enter for deposit and Exit for withdraw
    function hook(uint256 _index, DataTypes.BlockExecutionType _executionType) external;

    /// @notice Execute enter block function 
    /// @param _index The index of the block
    function enter(uint256 _index) external;

    /// @notice Execute exit block function
    /// @param _index The index of the block
    /// @param _percent The percentage of the assets used for the exit execution
    function exit(uint256 _index, uint256 _percent) external;

    /// @notice Execute the oracle enter function
    /// @param previous The previous state of the oracle
    /// @param parameters The parameters of the oracle enter
    /// @return The new state of the oracle
    function oracleEnter(DataTypes.OracleState memory previous, bytes memory parameters)
        external
        view
        returns (DataTypes.OracleState memory);

    /// @notice Execute the oracle exit function
    /// @param previous The previous state of the oracle
    /// @param parameters The parameters of the oracle exit
    /// @param _percent The percentage of the assets used for the exit execution
    /// @return The new state of the oracle
    function oracleExit(DataTypes.OracleState memory previous, bytes memory parameters, uint256 _percent)
        external
        view
        returns (DataTypes.OracleState memory);
}
```

* `hook` function is executed during a deposit or withdraw action on the vault before the internal TVL computation. It is useful to update the remote protocol state beforehand, to avoid TVL computation based on obsolete data.
  * `_index` number is given to the function, enabling the block to retrieve its parameters using a storage pointer pointing to a byte variable.
  * `_executionType` determines the execution context in the strategy.
* `enter` function is called by the vault via a delegate call, which is executed within the vault context. The function must execute the action for which the block is written for.&#x20;
  * `_index` number is given to the function, enabling the block to retrieve its parameters using a storage pointer pointing to a byte variable.
* `exit` function is called by the vault via a delegate call, which is executed within the vault context. The function must execute the opposit action of what the `enter` function is written for.
  * `_index` number is given to the function, enabling the block to retrieve its parameters using a storage pointer pointing to a byte variable.
  * `_percent` is the percentage of assets used, in basis points.
* `enterOracle` function is called by the vault to simulate the `enter` function.&#x20;
  * `OracleState` is used by the function, with simulated tokens amounts at block execution time. The goal is to have the same parameters as the execution function.
  * `parameters` bytes are the same as those received by the corresponding execution function.
* `exitOracle` function is called by the vault to simulate the`exit` function.
  * `OracleState` is used by the function, with simulated tokens amounts at block execution time. The goal is to have the same parameters as the execution function.
  * `parameters` bytes are the same as those received by the corresponding execution function.
  * `_percent` is the percentage of assets used, in basis points.

### Harvest Block

Harvest block is based on the same concept as the strategy block, where the harvest block list is executed on vault harvest.

```solidity
interface IStrategStrategyBlock is IStrategCommonBlock {
    /// @notice Execute harvest block function 
    /// @param _index The index of the block
    function harvest(uint256 _index) external;
    
    /// @notice Execute the oracle harvest function
    /// @param previous The previous state of the oracle
    /// @param parameters The parameters of the oracle enter
    /// @return The new state of the oracle
    function oracleHarvest(DataTypes.OracleState memory previous, bytes memory parameters)
        external
        returns (DataTypes.OracleState memory);
}
```

* `harvest` executes the harvest block function.
  * `_index` number is given to the function, enabling the block to retrieve its parameters using a storage pointer pointing to a byte variable.
* `oracleHarvest` is a non view function to be usable with Curve like claims on which there is a need to update a local variable.
  * `OracleState` is used by the function, with simulated tokens amounts at block execution time. The goal is to have the same parameters as the execution function.
  * `parameters` bytes are the same as those received by the corresponding execution function.
