Late Repayments - How it works

First to achieve trackable and "fair" late repayments, we need to track the balances of each user in a "fair" way.

A fair way means a transparent and uniform way, tracking balances based on the actual amount they hold (meaning for example if a users sells LP tokens after depositing, he loses the right for future late repayments).

πŸ“˜

In order to receive a late repayment you need to have your shares in your wallet at the point of time the epoch rolls over. Otherwise late repayments will not be credited to you.

Users can claim the BRZ coming from late repayments at any cycle. For this, we need a way to know the user's balance and the pool's balance at that cycle (to know how much corresponds to him).
We don't store the user's balance at each cycle, instead we have a way of calculating it.

For this we use a concept called "relevant changes" which stores in which cycle the user changed his balance (because of a deposit, a withdrawal or a transfer of tokens). This means that to get the user's balance at any cycle we just need to iterate through the relevant changes and find one that happened either in the same cycle we are querying or in a cycle after it (when this happens, we just use the immediate previous relevant change)

To do this, we added a few variables for each user and then implemented it into the functions that manipulate important values.

The new variables per user are:

  • relevantChanges
    • we decided to implement this as an array to loop over it (looping is viable as cycle length is 90 days)
      • mapping(address => uint[])
  • lpTokenBalancePerCycle
    • which is a mapping tracking balances of each user per cycle
      • mapping(uint => mapping(address => uint))
  • recoveryClaimedUser
    • tracks the amount the user claimed in total of a cycle with late repayments
      • mapping(uint => mapping(address => uint))

We also needed a global variable to account for the recovered amount per cycle:

  • lateRecovered
    • tracks the amount that has been late recovered per cycle
      • mapping(uint => uint)

Functions modified for LateRepayments:

  • repay
    • if the loan is being repaid and the cycle it corresponds to already passed, we assign the BRZ to the already passed cycle as recovered capital
  • poolTokenUpdate (hook that is called automatically after successfully transferring a pool token)
    • most importantly we change the LPBalance and relevant changes based on transfers to then have a fair accounting based on the shares you held at the end of a certain cycle
  • queueWithdraw
    • LPBalance will be updated for the coming cycle
  • cancelWithdraw
    • LPToken will be sent back and reset
  • finalizeDepositQueue
    • Tokens will be minted and the LPBalance and relevant changes are updated based on the cycle he deposited into
  • directDeposit
    • Tokens will be minted and the LPBalance and relevant changes updated
  • directWithdraw
    • Tokens will be burned and the LPBalance updated

New functions for LateRepayments:

  • insertIntoRelevantChanges
    • inserts relevant changes of their LP Balance of the user if there is a need for it
      • there is a need if for example they didn't finalize a withdraw or deposit but bought tokens so old balances need to be updated to account for the correct amount they deserve
  • getLateRepaymentAmount
    • returns the amount a user can claim in a certain cycle based on their balance and the amount that has been repaid.
  • claimLateRepayment
    • claims the amount that corresponds to the user in cycle x

Example

If we for example have a User A that deposits into a pool:
User A -> 1000BRZ -> Pool

Let's assume this is the only money in the pool.

Now let's take out a loan of 200BRZ

The loan is repaid not in that cycle but in the next one (all the distribution, etc, is processed normally)

Essentially the pool shares User A holds are now worth 800BRZ.

Now even if he withdraws and burns all his shares, User A can query the amount he can claim and has rights to his percentage of the repayment (even if other LPs now join the pool).

As he was the only LP at the point of time he receives 100% of the repayment

User A can now withdraw 200 BRZ as late repayment