Registry flows

In each chain we have a singleton registry contract that is responsible for holding and serving the information of the vaults.

Vaults information:

  • Address of accountingManager

  • Address of base token of the vault (token that we use for book keeping)

  • List of connectors

  • List of trusted tokens of the vault

  • List of trusted position blueprint

  • List of positions that we hold at the moment

  • Governance addresses

So in each vault that is defined in the registry, there is one accounting manager contract and a set of active connectors.

Flows

Creating a new vault

The maintainer (the timelock contract of the governance) can use this function to add a new vault to the registry. It needs to choose a vaultId and base token of the vault, deploy the accounting manager and set the governance addresses. Then call the function below

Copy

function addVault(
        uint256 vaultId,
        address _accountingManager,
        address _baseToken,
        address _governer,
        address _maintainer,
        address _maintainerWithoutTimelock,
        address _keeperContract,
        address _watcher,
        address _emergency,
        address[] calldata _trustedTokens
    );

Adding a connector to a vault

This set of smart contracts are responsible for connecting to a protocol. Once a connector is deployed, it needs to be added to the registry to function properly. This can be done by using the function below.

function addConnector(uint256 vaultId, address[] calldata _connectorAddresses, bool[] calldata _enableds)
        external
        onlyVaultMaintainer(vaultId)
        vaultExists(vaultId);

Updating connector trusted tokens

In each vault there is a list of trusted tokens for each connector. By adding trusted tokens we can add positions blue prints that use those tokens. For example to be able to add a LP position on uniswap, we have to add the blue print of that position in uniswap and for doing so we have to add the tokens of that pool to the trusted tokens of the uniswap connector.

function updateConnectorTrustedTokens(
        uint256 vaultId,
        address _connectorAddress,
        address[] calldata _tokens,
        bool trusted
    )onlyVaultMaintainer(vaultId)
        vaultExists(vaultId);

Only the vault maintainer can call this which means it's protected by timelock contract.

Adding trusted position blue prints

TrustedPostions work as the blueprint for the holding positions. For example we store the pool information of uniswapV3 in TrustedPostions and the actual information of LP tokens in the holding positions.

For each position, we might have different logic and data to calculate the value of that position based on the base token. The CalculatorConnector is the address of the connector, which will be called when the accountingManager wants to calculate the value of the position based on the base token of the vault.

function addTrustedPosition(
        uint256 vaultId,
        uint256 _positionTypeId,
        address calculatorConnector,
        bool onlyOwner,
        bool _isDebt,
        bytes calldata _data,
        bytes calldata _additionalData
    )

Holding positions and their role in registry

Holding positions are for storing information of the actual positions. The connectors will use this function to add their positions in TVLHelper.

It’s being created when the vault is added to the registry. At that time, one empty position is being added to the vault so we make sure that there is no active position in index 0 of this array.

Later we can add positions to this array using the updateHoldingPosition function.

For each holding position of the vault, we calculate the holdingPositionId and use that as the key in the isPositionUsed mapping and use the index of that position in the array as the value. This is the reason that we added a dummy position in the array at the beginning (so we can check this mapping to see if a position exists with this Id (if the value is 0 means that it’s not been added to this mapping or it’s dummy position)).

For example, in an aave position, in “supply” function, we call calculatePositionId first and then call updateHoldingPosition to add the position to the vault.

Later, when the accountingManager is trying to get the TVL of the vault, it loops through this array and calls the getPositionTVL of the BaseConnector which will call the _getPositionTVL of aave connector. This function will return the value of our deposits into aave and convert it to the base token.

function updateHoldingPosition(
        uint256 vaultId,
        bytes32 _positionId,
        bytes calldata _data,
        bytes calldata additionalData,
        bool removePosition
    ) public vaultExists(vaultId);

Holding positions with timestamp

For some positions, we can’t calculate the TVL of the moment (for example the positions that are on other chains). So we update them regularly and save the TVL amount in the registry. For these positions we use this function to set the time.

function updateHoldingPostionWithTime(
        uint256 vaultId,
        bytes32 _positionId,
        bytes calldata _data,
        bytes calldata additionalData,
        bool removePosition,
        uint256 positionTimestamp
    ) external vaultExists(vaultId)

Last updated