-
Notifications
You must be signed in to change notification settings - Fork 19
Pool Claim Function
DebtLocker contracts are used by Pools to claim funds from Loans and to enable permissioning for triggering Loan liquidations. For the launch of the Maple protocol, there will only be one DebtLockerFactory that will create DebtLockers that just hold LoanFDTs custody, but the architecture of the protocol allows for different DebtLockerFactory contracts to be validated and integrated to the protocol. DebtLockers are kept track of with a mapping in the pool debtLockers[loan][debtLockerFactory]
.
When a Pool Delegate wants to fund a Loan, they call Pool.fundLoan(address loan, address dlFactory, uint256 amt)
. This function checks if this Loan has already been funded using a DebtLocker from this DebtLockerFactory, if not, it instantiates one.
This allows a Pool Delegate to:
- Fund the same Loan multiple times with the same DebtLocker strategy.
- Fund the same Loan multiple times with different DebtLocker strategies.
When a debtLocker is used to fund a Loan, the LoanFDTs that get minted from that function are held in custody in that DebtLocker.
It should be noted that in the vast majority of cases, a Loan will only be funded once using one DebtLocker. For launch there will only be one DebtLockerFactory so it can effectively be treated as a constant.
One of the most important and also most complex functions in the Maple protocol is the claim function. The Pool claims funds by calling Pool.claim(address loan, address dlFactory)
. This goes into IDebtLocker(debtLockers[loan][dlFactory]).claim();
.
The DebtLocker claim function does the following at a high level (NOTE: Not the same order as the code):
- Claims all claimable funds from the Loan using the LoanFDT function
loan.withdrawFunds()
- Calculates deltas of all Loan accounting variables since the last claim. These values are:
-
interestPaid
- Total interest paid to date on the loan -
principalPaid
- Total principal paid to date on the loan (only updated once until non interest-only loans are supported) -
feePaid
- Total investor fee paid (only updated once) -
excessReturned
- Total excess funds not used by drawdown or from callingunwind
(only updated once) -
amountRecovered
- Total amount of liquidityAsset recovered from a liquidation
- Calculates the proportional amount of the total claimed amount that belongs to each of these categories. Example:
totalInterest = interestDelta * claimBal / sumDeltas
- Calculates the
defaultSuffered
from the Loan (if applicable), and what portion of that belongs to this DebtLocker. - Transfers funds from DebtLocker to Pool, along with accounting information in the return array.
The Pool receives the funds and an array claimInfo
from the DebtLocker, which it uses to calculate the poolDelegatePortion
and stakeLockerPortion
.
- The
poolDelegatePortion
isinterest * delegateFee + feePaid
- The
stakeLockerPortion
isinterest * stakingFee
The Pool also calculates the amounts that are to be registered as principal and interest.
- Principal is
principal + excessReturned + amountRecovered
- Interest is
interest * (100% - (delegateFee + stakingFee))
The Pool then transfers the poolDelegatePortion
and stakeLockerPortion
to the PoolDelegate and StakeLocker respectively, and updates StakeLocker FDT accounting.
The Pool also updates the principalOut
and interestSum
by principalClaim
and interestClaim
and transfers principalClaim + interestClaim
to the LiquidityLocker. Note that this is NOT the remaining amount left in the Pool from the claim. There is some dust that accrues in the portion calculations in the DebtLocker, so to address that, the amounts that are used to update the state variables are used to transfer the funds so that the amounts always stay exactly in sync.
Since interestSum
was incremented, the PoolFDT accounting also gets updated with updateFundsRecieved()
.
If there is a defaultSuffered
value that gets passed through the DebtLocker claim function, the handeDefault
flow starts, which performs BPT burning.
handleDefault
burns the lowest amount of BPTs possible to cover the full defaultSuffered
amount. If all BPTs in the StakeLocker are burned and there is still a shortfall, poolLosses
is incremented by the remaining difference, and the principalOut
is decremented by the full defaultSuffered
, passing the losses onto the liquidity providers.