Vizium-based LTV and loan amount source proposal

Problem

Currently, the source of truth for borrow and supply amounts in our backend system is the borrower service's positions table. The supplied_amount and borrowed_amount are updated based on smart contract events emitted by the concrete protocol contracts. These events are mostly based on user actions, for example updated after a collateral deposit is made or a borrow is made. This presents a challenge: The 'owed'/borrow amount of any loan is a sum of the borrowed amount and accrued interest, instead of just the borrowed amount. The borrower service currently has no mechanism to reliably calculate accrued interest, and therefore the borrow amount will deviate from the actual borrow amount. This problem is significant for LTV calculations, frontend displays, and loan repayment attempts.

Proposed solution

Vizium has a websocket endpoint that allows us to subscribe to 'position updates'. We give it a borrower address(in our case, a user blueprint address), and it streams updates about borrow amounts, supply amounts, and even LTV. We can leverage this endpoint to always store an up-to-date representation of these values for any given loan.

{
    "pos": {
        "cBal": 1540.62814645,
        "dBal": 163.92919491,
        "aBal": 1076.27646298,
        "liqTh": 83.0,
        "hf": 7.800449225972471,
        "ltv": 0.10640412826919635,
        "posByAsset": {
            "DAI": {
                "supply": "0",
                "sBorrow": "0",
                "vBorrow": "58.24741363566247748"
            },
            "USDC": {
                "supply": "0",
                "sBorrow": "0",
                "vBorrow": "105.5086"
            },
            "WBTC": {
                "supply": "0",
                "sBorrow": "0",
                "vBorrow": "0.00000283"
            },
            "WETH": {
                "supply": "0.506152492523728924",
                "sBorrow": "0",
                "vBorrow": "0"
            }
        }
    }
}

Since streaming updates for thousands of loans and performing database update queries to the borrower service's positions table may prove to be too resource-intensive, the following architecture is proposed.

The graph above describes a couple of flows, and one new 'service' that lives inside the ltv monitor repo.

The position listener service

The position listener service will be responsible for maintaining a websocket connection with the vizium api, and receiving position updates as they come in.

  • On startup, it will read a list of open loans from the ltv monitor database and subscribe to position updates for these loans. It has been confirmed with the vizium team that the position api is built with this kind of scale in mind(at least for initial launch)

  • When it receives a position update, it will then save the latest data to the redis cache/database

Other flows

  • When an LTV monitor worker is processing the loan, instead of calculating LTVs based on the borrower service's data, it will get the LTV from the redis database

  • When the frontend needs to get the latest position data, it can use a REST route exposed by the LTV monitor's existing REST service.

Last updated