The information provided by Aloe Labs, Inc. (โ€œwe,โ€ โ€œusโ€ or โ€œourโ€) on (the โ€œSiteโ€) is for general informational purposes only. All information on the Site is provided in good faith, however we make no representation or warranty of any kind, express or implied, regarding the accuracy, adequacy, validity, reliability, availability or completeness of any information on the Site.

Under no circumstance shall we have any liability to you for any loss or damage of any kind incurred as a result of the use of the site or reliance on any information provided on the site. Your use of the site and your reliance on any information on the site is solely at your own risk.


In Aloe II, the Lender is responsible for tracking borrows. This means two things:

  • recording the amount each address has borrowed

  • accounting for the growth of these borrows as interest accrues

The interest compounds continuously, so borrow growth should be modeled with the exponential function:

totalBorrowst=T=totalBorrowst=0โ‹…erT\text{totalBorrows}_{t=T}=\text{totalBorrows}_{t=0} \cdot e^{rT}

Since there are no borrows at deployment time, and different users request borrows at different times, totalBorrowst=0\text{totalBorrows}_{t=0} is purely hypothetical. When a user takes on some amount of newBorrows\text{newBorrows}, we must update the hypothetical value:

totalBorrowst=T+newBorrows=(totalBorrowst=0+x)โ‹…erT\text{totalBorrows}_{t=T} + \text{newBorrows}=(\text{totalBorrows}_{t=0} + x) \cdot e^{rT}

totalBorrowst=0โ‹…erT+newBorrows=totalBorrowst=0โ‹…erT+xerT\text{totalBorrows}_{t=0} \cdot e^{rT} + \text{newBorrows}=\text{totalBorrows}_{t=0} \cdot e^{rT} + xe^{rT}



So when a user calls borrow, we add xx to borrows-at-deployment-time, and when a user calls repay, we do the opposite: subtract from borrows-at-deployment-time. This addition and subtraction applies both to the user's borrows, and to the pool's total borrowBase.

We'd be done if r were constant, but it's not๏ผthe interest rate changes with time, as a function of utilization. Instead of an elegant exponential, we get a piecewise function:

totalBorrowst={totalBorrowst=0โ‹…er0ttโ‰คT0totalBorrowst=0โ‹…er0T0er1(tโˆ’T0)T0<tโ‰คT1totalBorrowst=0โ‹…er0T0er1(T1โˆ’T0)er2(tโˆ’T1)T1<tโ‰คT2...\text{totalBorrows}_{t}= \begin{cases} \text{totalBorrows}_{t=0} \cdot e^{r_0 t} & t \leq T_0 \\ \text{totalBorrows}_{t=0} \cdot e^{r_0 T_0} e^{r_1 (t - T_0)} & T_0 \lt t \leq T_1 \\ \text{totalBorrows}_{t=0} \cdot e^{r_0 T_0} e^{r_1 (T_1 - T_0)} e^{r_2 (t - T_1)} & T_1 \lt t \leq T_2 \\ ... \end{cases}

The product of this chain of exponentials is the borrowIndex. For precision, it starts at 101210^{12} (instead of 1) and it gets updated in the first call to the pool in a given block. Subsequent calls in the same block do nothing because block.timestamp is the same. The update looks like:

borrowIndex *= e ** (currentRate * secondsSinceLastUpdate)

In practice we do change-of-base and implement (1 + yieldPerSecond) ** T, but the concept is the same.

As for the coefficient, totalBorrowst=0\text{totalBorrows}_{t=0}, we scale that up by 2322^{32} and call it borrowBase. Individual users have their own personal borrowBases stored in the borrows mapping (we use the expression for xx from earlier, but scale up by 2322^{32} and divide by borrowIndex instead of the plain exponential).


Total Borrows

borrowBase * borrowIndex / (2**32 * 10**12)

User's Borrows*

borrows[user] * borrowIndex / (2**32 * 10**12)

*In the code, we subtract one from borrows[user] because the first unit is used for whitelisting; it's not real debt.

Interest Rate

The interest rate is a function of utilization, defined in RateModel. The default RateModel is a rational function.

The supply rate (earned by lenders) is always less than the borrow rate (paid by borrowers). Given utilization UU and reserve factor ff, they are related like so:

ratesupply=(1โˆ’1f)โ‹…Uโ‹…rateborrow\text{rate}_{supply}=(1 - \frac{1}{f}) \cdot U \cdot \text{rate}_{borrow}

Last updated