Skip to content

Commit eba679d

Browse files
committed
some documentation
1 parent f48cf66 commit eba679d

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Suilend
2+
Lending protocol on the Sui Blockchain
3+
4+
# Overview of terminology
5+
6+
A LendingMarket object holds many Reserves and Obligations.
7+
8+
An Obligation is a representations of a user's deposits and borrows. An obligation has exactly one lending market.
9+
10+
There is 1 Reserve per token type (e.g a SUI Reserve, a SOL Reserve, a USDC Reserve).
11+
A user can supply assets to the reserve to earn interest, and/or borrow assets from a reserve and pay interest.
12+
When a user deposits assets into a reserve, they will receive CTokens.
13+
The CToken represents the user's ownership of their deposit, and entitles the user to earn interest on their deposit.

math.md

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
The goal of this page is to be a self-contained explanation of the big mathematical concepts involved in building a lending protocol.
2+
3+
# Reserve
4+
5+
For a given lending market, a reserve holds all deposits of a coin type for a given lending market.
6+
For example, the Suilend Main Market will have exactly 1 SUI reserve and 1 USDC reserve.
7+
8+
If a user deposits/repays SUI, the SUI reserve will increase in supply.
9+
10+
If a user borrows/withdraws SUI, the SUI reserve will decrease in supply.
11+
12+
## Reserve Utilization
13+
14+
$$U_{r} = B_{r} / T_r = B_r / (B_{r} + A_{r})$$
15+
16+
Where:
17+
- $U_{r}$ is reserve utilization. $0 < U_{reserve} < 1$
18+
- $B_r$ is the amount of tokens lent to borrowers from reserve $r$.
19+
- $A_r$ is the amount of tokens available in reserve $r$. These are tokens that are have been deposited into the reserve but not borrowed yet.
20+
- $T_r$ is the total supply of tokens in reserve $r$.
21+
22+
Example: Say I (ripleys) deposit 100 USDC into Suilend, and Soju (our bd guy) deposit 100 SUI and borrows 50 USDC.
23+
24+
The reserve utilization on the USDC reserve is $50 / (50 + 50)$ = 50%.
25+
26+
## CTokens
27+
28+
When a user deposits SUI into Suilend, they will mint (ie get back) CSUI. This CSUI entitles the user to obtain their deposit from Suilend + additional interest. The interest is obtained by lending out the tokens to borrowers.
29+
30+
The CToken ratio denotes the exchange rate between the CToken and its underlying asset. Formally, the ctoken ratio is calculated by:
31+
$$C_r = (B_r + A_r) / T_{C_r}$$
32+
33+
Where:
34+
- $C_r$ is the ctoken ratio for reserve $r$
35+
- $B_r$ is the amount of tokens lent to borrowers for reserve $r$ (including interest)
36+
- $A_r$ is the amount of available tokens (ie not lent out) for reserve $r$
37+
- $T_{C_r}$ is the total supply of ctokens in reserve $r$.
38+
39+
40+
Notes:
41+
- $C_r$ starts at 1 when the reserve is initialized, and grows over time. The CToken ratio never decreases.
42+
- a user cannot always exchange their CSUI back to SUI. In a worst case scenario, all deposited SUI could be lent out, so the protocol won't have any left for redemption. However, in this scenario, the interest rates will skyrocket, incentivizing new depositors and also incentivizing borrowers to pay back their debts.
43+
- the ctoken ratio captures the interest earned by a deposit.
44+
45+
# Obligations
46+
47+
An obligation tracks a user's deposits and borrows in a given lending market.
48+
49+
The USD value of a user's borrows can never exceed the USD value of a user's deposits. Otherwise, the protocol can pick up bad debt!
50+
51+
## Obligation statuses
52+
53+
### Healthy
54+
55+
An obligation O is healthy if:
56+
57+
$$ \sum_{r}^{M}{B(O, r)} < \sum_{r}^{M}{LTV_{open}(r) * D(O, r)}$$
58+
59+
Where:
60+
- $M$ is the lending market
61+
- $r$ is a reserve in $M$
62+
- $B(O, r)$ is the USD value of obligation O's borrows from reserve $r$
63+
- $D(O, r)$ is the USD value of obligation O's deposits from reserve $r$
64+
- $LTV_{open}(r)$ is the open LTV for reserve $r$. ($0 <= LTV_{open}(r) < 1$)
65+
66+
67+
### Unhealthy
68+
69+
An obligation O is unhealthy and eligible for liquidation if:
70+
71+
$$ \sum_{r}^{M}{B(O, r)} >= \sum_{r}^{M}{LTV_{close}(r) * D(O, r)}$$
72+
73+
Where:
74+
- $LTV_{close}(r)$ is the close LTV for reserve $r$. ($0 <= LTV_{close}(r) < 1$)
75+
76+
### Underwater
77+
78+
An obligation O is underwater if:
79+
80+
$$ \sum_{r}^{M}{B(O, r)} > \sum_{r}^{M}{D(O, r)}$$
81+
82+
In this situation, the protocol has picked up bad debt.
83+
84+
# Compounding debt and calculating interest rates
85+
86+
In Suilend, debt is compounded every second.
87+
88+
Compounded debt is tracked per obligation _and_ per reserve. Debt needs to be tracked per reserve because it affects the ctoken ratio. Debt needs to be tracked per obligation because otherwise users won't pay back their debt!
89+
90+
This section is a bit complicated and only relevant if you want to understand the source code of the protocol.
91+
92+
## APR (Annual Percentage Rate)
93+
94+
An APR is a representation of the yearly interest paid on your debt, without accounting for compounding.
95+
96+
In Suilend, the APR is a function of reserve utilization. The exact function is subject to change.
97+
98+
Note that reserve utilization only changes on a borrow or repay action.
99+
100+
## Compound debt per reserve
101+
102+
$B_r$ from prior formulas (total tokens borrowed in reserve $r$) provides us a convenient way to compound global debt on a per-reserve basis.
103+
104+
The formula below describes how to compound debt on a reserve:
105+
106+
$$B(t=1)_r = B(t=0)_r * (1 + APR(U_r) / Y_{seconds})^1$$
107+
108+
Where:
109+
- $B(t)_r$ is the total amount of tokens borrowed in reserve $r$ at time $t$.
110+
- $APR(U_r)$ is the APR for a given utilization value.
111+
- $Y_{seconds}$ is the number of seconds in a year.
112+
113+
Note that even if no additional users borrow tokens after $t=0$, due to compound interest, the borrowed amount will increase over time.
114+
115+
## Compound debt per obligation
116+
117+
This is tricky to do efficiently since the APR can change every second and our borrowed amount can change on every borrow/repay action. Let's work through a simple example first.
118+
119+
Lets say the owner of obligation $O$ initially borrows $b$ tokens from reserve $r$ at $t=T_1$.
120+
121+
What is the compounded debt at $t=T_2$?.
122+
123+
$$b\prod_{t=T_1 + 1}^{T_2}{(1 + APR_r(t)/365)}$$
124+
Where:
125+
- $B$ is the amount of tokens borrowed from reserve $r$ at $t=0$.
126+
- $APR_r(t)$ is the variable APR for reserve $r$ at time $t$.
127+
128+
Lets define a new variable I that accumulates the products.
129+
130+
$$I_r(T) = \prod_{t=1}^{T}{(1 + APR_r(t)/365)}$$
131+
132+
Now, simplifying our first expression:
133+
134+
$$b * I_r(T_2) / I_r(T_1) $$
135+
136+
Note that the term $b / I_r(T_1)$ is effectively normalizing the debt to $t=0$. In other words, if you borrowed $b / I_r(T_1)$ tokens at t=0, your debt at $t=T_1$ would be $b$ after compounding interest.
137+
138+
Each obligation would "snapshot" the latest value of $I_r(t)$ after any action. This is equivalent to $I_r(T_1)$ in the expression above.
139+
140+
$I_r(t)$ can be tracked globally per reserve. This is equivalent to $I_r(T_2)$ in the expression above.
141+
142+
## Compounding debt invariant
143+
144+
At any time T and for any reserve, the following expression is true.
145+
146+
$$B_r = \sum_{o}^{M}{B_r(o) * I_r(T) / I_r(T'(o))}$$
147+
Where:
148+
- $B_r$ is the total amount of tokens borrowed in reserve $r$ at time $T$.
149+
- $B_r(o)$ is the amount of tokens borrowed from reserve $r$ by obligation $O$.
150+
- $I_r(T)$ is the latest cumulative borrow rate product for reserve $r$.
151+
- $T'(o)$ is the last time the obligation's debt was compounded.
152+
153+
In other words, the global borrowed amount equals the sum of all borrowed tokens per obligation after compounding.
154+
155+
# Liquidations
156+
157+
The goal of liquidations is to force repay an unhealthy obligation's debt _before_ it goes underwater. Recall that an obligation O is unhealthy and eligible for liquidation if:
158+
159+
$$ \sum_{r}^{M}{B(O, r)} >= \sum_{r}^{M}{LTV_{close}(r) * D(O, r)}$$
160+
161+
Where:
162+
- $M$ is the lending market
163+
- $r$ is a reserve in $M$
164+
- $B(O, r)$ is the USD value of obligation O's borrows from reserve $r$
165+
- $D(O, r)$ is the USD value of obligation O's deposits from reserve $r$
166+
- $LTV_{close}(r)$ is the close LTV for reserve $r$. ($0 <= LTV_{close}(r) < 1$)
167+
168+
Say the total value of a user's borrowed (deposited) amount is $B_{usd}$ ($D_{usd}$). The liquidator can repay $B_{usd} * CF$ of debt to receive $B_{usd} * CF * (1 + LB)$ worth of deposits.
169+
170+
Where:
171+
- $CF$ is the close factor (see parameters section)
172+
- $LB$ is the liquidation bonus (see parameters section)
173+
174+
Notes:
175+
- when an obligation is unhealthy but not underwater, the LTV decreases after a liquidation. This is good.
176+
- the liquidation bonus (LB) is what makes the liquidation profitable for a liquidator.
177+
178+
# Parameters
179+
180+
## Open LTV (Loan-to-value)
181+
182+
Open LTV is a percentage that limits how much can be _initially_ borrowed against a deposit.
183+
184+
Open LTV is less than or equal to 1, and is defined _per_ reserve. This is because some tokens are more risky than others. For example, using USDC as collateral is much safer than using DOGE.
185+
186+
## Close LTV
187+
188+
Close LTV is a percentage that represents the maximum amount that can be borrowed against a deposit.
189+
190+
For a given reserve, Close LTV > Open LTV.
191+
192+
## Close Factor (CF)
193+
194+
The Close Factor determines the percentage of an obligation's borrow that can be repaid on liquidation.
195+
196+
Bounds: $0 < CF <= 1$
197+
198+
## Liquidation Bonus (LB)
199+
200+
The liquidation bonus determines the bonus a liquidator gets when they liquidate an obligation. This bonus value is what makes a liquidation profitable for the liquidator.
201+
202+
Bounds: $0 <= LB < 1$
203+

0 commit comments

Comments
 (0)