Skip to content

ADR: Revise interest curve utilization rate definition#303

Open
jordanschalm wants to merge 3 commits intomainfrom
jord/adr-interest-curve-utilization
Open

ADR: Revise interest curve utilization rate definition#303
jordanschalm wants to merge 3 commits intomainfrom
jord/adr-interest-curve-utilization

Conversation

@jordanschalm
Copy link
Copy Markdown
Member

No description provided.

Comment on lines +24 to +25
- User B deposits 105 units of X -> totalDebit(X) = 0
- User B still owes 5 units of X, but totalDebit(X) = 0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why B depositing 105 units would make totalDebit(X) to 0? Could you add more details in the comments.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because they are unsigned and clamp to zero. From the paragraph above:

They are stored as absolute (not interest-adjusted) unsigned values, which can cause updates to the values to clamp to zero

Also added a ceil function in the equation to represent the "unsigned-ness"

Co-authored-by: Leo Zhang <zhangchiqing@gmail.com>
Co-authored-by: Jordan Schalm <jordan.schalm@gmail.com>
@jordanschalm jordanschalm requested review from a team and zhangchiqing April 8, 2026 15:53
### Minimal Example
- User A deposits 100 units of X
- User B withdraws (borrows) 100 units of X -> totalDebit(X) = 100
- Suppose debit rate on X is 10%, and 1 year passes
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still confused by this example. What does this "10% debit rate and 1 year passes" change? I thought after 1 year pass, User B would need to pay 110 units of X, then after B deposits 105 units of X, the totalDebit(X) would be 110 - 105 = 5, instead of ceil(100 - 105, 0) = 0. Did I miss anything?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • When User B withdraws 100X, totalDebit(X) is set to 100
  • After a year passes with 10% interest rate:
    • User B owes 110 units of X
    • But totalDebit(X) is still 100 - the value only changes on deposits and withdrawals, and does not account for interest, as it is currently implemented.

Let's describe the definition wlog for `totalTrueDebitBalance`:
- Let `X` be some token
- Let `debitPositions(X)` be the set of positions which have a debit balance for token `X`
- Let `totalTrueDebitBalance(X)` be the sum of token X debit balances for all positions in `debitPositions(X)`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems there is a cycle dependency:

  1. the calculation of utilization needs the totalTrueCreditBalance and totalTrueDebitBalance
  2. the calculation of totalTrueCreditBalance needs interest
  3. the calculation of interest needs utilization. (cycle?)

Copy link
Copy Markdown
Member Author

@jordanschalm jordanschalm Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The interest and utilization are inter-related, but I think in practice that is OK. We apply each change in sequence, modifying one at a time:

  1. Something mutates (wlog) totalTrueCreditBalance(X), eg. addToCreditBalance(trueCreditValue)
  • totalTrueCreditBalance is stored as a scaled value
  • we compute scaledCreditValue based on interestIndex(X)
  • at this point, interestIndex(X) is the index before the addToCreditBalance(trueCreditValue) operation occurs
  • we set totalScaledCreditBalance = totalScaledCreditBalance + scaledCreditValue
  1. The next time we do something that requires an interest rate, we re-compute the interest index based on the latest state.
  • we compute utilization rate based on totalTrueCreditBalance, as modified in step 1

Abstractly, for discrete time steps t:

  • totalTrueCreditBalance[t] = someFunction(totalTrueCreditBalance[t-1], interestIndex[t-1])
  • interestIndex[t] = someOtherFunction(totalTrueCreditBalance[t-1], interestIndex[t-1])

Besides being convenient (and possible to compute), I think this is also the most conceptually correct way to calculate these values.

  • Interest accumulates over time
  • I make a (wlog) deposit at time t, the last update was at time t-1, and the next update is at time t+1
  • The update at time t should include interest accumulated between t-1 and t
  • The interest A accumulated between t-1 and t occurs before my deposit at time t -- my deposit shouldn't affect A, because it happened after A was accumulated
  • The interest B accumulated between t and t+1 occurs after my deposit at time t -- my deposit should affect B, because it happened before B was accumulated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants