Monitoring yield on AAVE periodically

In this tutorial we'll show you how to create multiple streams that get the yield for assets on AAVE
It's broken up into three main phases

  1. Creating a blueprint that will allow us to watch the yield for any asset on AAVE
  2. Deploying a stream that will watch a specific asset
  3. Consuming that stream to see historical and real-time changes of the rate

Monitoring yield on AAVE assets through contract view functions

Creating a blueprint for all assets

We start by creating a blueprint. A blueprint is a way for us to describe what we want to filter for as well as supporting variables for reusability of the same general functionality.

Navigate to the Streams tab and the Stream Blueprints view and click the Create Stream Blueprint button.

26322632

There we select the Contract View Function Periodically, since what we want is to call a view function periodically and get the results.

26002600

We choose the Ethereum network, and we input the lending pool contract for AAVE v2.

26002600

Now when we look at the available View functions on this contract, we don't see any. This is because AAVE uses a proxy pattern, so we need to get the current implementation of this lending pool contract. It can be seen on etherscan for example, and there we can see the address for the implementation contract being 0xc6845a5c768bf8d7681249f8927877efda425baf. We search for that, and that replaces the ABI we will be working with.

26002600

Now that we are looking at the correct contract, we can select the view function we want to call.
For our use case we want to look at the getReserveData as that holds in the information regarding interest rates.

26002600

Now once we have chosen that function, we can input the asset we want to get reserve data for.
In our case, since we are creating a blueprint that we will use to watch multiple assets, we want to make this a variable, so we check the variable button on the form and save.

26002600

We allow the time period to be Hourly so we will get a datapoint about the variable rates every hour 24/7.
And we keep the timezone as "Europe/London +00:00". The timezone only matters if we would use a custom cron expression. So if you want it to run at 01:00 after midnight but on CET time. You would put in your custom cron expression and pick the timezone you want.

26002600

Now we are all done with our Blueprint, we give it a name, in our case Monitoring yiled on AAVE for asset: X.
We then have the option to Save that will save the blueprint for later use, or Save and Deploy that will save the blueprint and push us into the flow of creating a stream from that blueprint.
We will choose save, and then continue in the next section on deploying a stream from a blueprint.

26002600

Deploying a stream that will watch a specific asset

in this section we will be using the Blueprint we created earlier and deploying it to a stream.
A stream is a running process that is watching and querying the blockchain.
We want to deploy the blueprint we created earlier for two different streams

  1. One that is watching AAVE interest rates on LUSD
  2. Another that is watching AAVE interest rates on BAL

We will deploy one of them through the UI, and the other using the REST API.

Deployment of stream through the UI

To deploy a stream, we start by going to the Stream Blueprints page and and clicking the Deploy button on the blueprint card.

26002600

We fill that in with all the relevant information,
Changing the name to Monitoring yiled on AAVE for: LUSD and entering the LUSD address into the asset variable.
Since we are using variables, we will be able to deploy the same blueprint to different streams, changing only the value of the asset we are monitoring.

20582058

We then press Deploy Stream and it will start running immediately. Watching for and querying the blockchain for the data we want.

Summary

We have now deployed two streams from the same blueprint using variables to differentiate the asset being monitored.
In the next section we will take a look at how we can consume those streams and use the data to plot out yield both in real-time as well as historically.

Consuming streams

We start by Taking a look at our Deployed streams page, where we can see that these are both running and have some events.

26002600

We can now programatically get the events from these streams and having a look at them.
To query for the stream, we will use this to query our BAL stream

curl --request GET \
     --url https://api.hal.xyz/v1/streams/78ce23e3-b110-473f-9e9f-a52df70c0dd9/events \
     --header 'Accept: application/json' \
     --header 'Content-Type: application/json' \
     --header 'X-Api-Key: <YOUR API KEY>'

And that will give us a list of events, with each event being a call to the AAVE lending pool contract.

[
    {
    "context": {
        "ViewFunctionOutput": {
            "0": {
                "aTokenAddress": "0x272f97b7a56a387ae942350bbc7df5700f8a4576",
                "configuration": {
                    "data": 3.6893853548324978e+22
                },
                "currentLiquidityRate": 3.854677030247532e+25,
                "currentStableBorrowRate": 1.6554588278967864e+26,
                "currentVariableBorrowRate": 1.0554588278967865e+26,
                "id": 22,
                "interestRateStrategyAddress": "0xfc0eace19aa7498e0f36ef1607d282a8d6debbdd",
                "lastUpdateTimestamp": 1663065537,
                "liquidityIndex": 1.0665430827346292e+27,
                "stableDebtTokenAddress": "0xe569d31590307d05da3812964f1edd551d665a0b",
                "variableBorrowIndex": 1.1909379656255389e+27,
                "variableDebtTokenAddress": "0x13210d4fe0d5402bd7ecbc4b5bc5cfca3b71adb0"
            }
        },
        "blockHash": "0x8397dd0e6e8723b62650f2bd1922ca23cff49fda0958a0c433d4d1ec53692f61",
        "blockNumber": 15527039,
        "blockTimestamp": 1663073573,
        "viewFunctionInput": {
            "Args": {
                "asset": "0xba100000625a3754423978a60c9317c58a424e3d"
            },
            "contractAddress": "0x7d2768de32b0b80b7a3454c06bdac94a69ddc7a9",
            "method": "getReserveData"
        }
    },
    "createdAt": "2022-09-13T12:53:59.613704+00:00",
    "id": "c4bb54ab-4ad3-4b60-9fb8-89599d2ed866"
    },
    ... // more events just like the one above
]

We can see that this gives us a lot of information, but one example would be to query for all the "currentVariableBorrowRate"

http GET https://apigw.staging.hal.xyz/v1/streams/78bf24e3-b220-473f-9e9f-a52df70c0dd9/events/events \
    X-Api-Key:<YOUR API KEY> |  \
    jq '.[] | .context.ViewFunctionOutput."0".currentVariableBorrowRate / 100000000000000000000000000'

Will return you a nice list

10.554588278967863
10.554588278967863
10.554588278967863
...

Summary

In this tutorial, we created a blueprint to track the yield on any asset on AAVE, created two streams from that blueprint, tracking LUSD and BAL set it up to monitor the chain and gives us information once a day.
We then consumed the events on those streams using a simple API call.