Repay and Withdraw Flow
Repay and Withdraw Flow
Repaying a Loan: A borrower (or anyone on their behalf) can repay a loan by calling
repay(asset, amount, rateMode, onBehalfOf)
. The contract checks the user’s outstanding stable and variable debt for that asset. Ifamount
is set totype(uint256).max
, it will repay the full outstanding amount. The appropriate debt token contract is then invoked to burn the debt tokens equal to the repaid amount (reducing the borrower’s recorded debt). The reserve state is updated for interest accrual before and after this operation – repaying increases available liquidity, soupdateState()
andupdateInterestRates()
are called withliquidityAdded = amountRepaid
, which will typically lower borrow rates and liquidity rate slightly. The actual asset tokens are transferred from the payer to the aToken contract (essentially returning liquidity to the pool). Finally,aToken.handleRepayment()
is called – this might trigger any internal accounting needed on the aToken side (for Aave, this was used to redirect interest to the right places). ARepay
event is emitted with the repaid amount. After repayment, the user’s health factor improves (since debt is reduced). If the loan is fully repaid (remainingDebt == 0
), the user’s configuration is updated to mark they are no longer borrowing that asset. Repaying also triggers the incentives controller update via the debt token burn: the borrower’s reward accrual for that debt token pool will be updated (their debt balance goes down, so their share of future rewards is lower, but they keep any PRFI accrued so far).Withdrawing Collateral: A user can withdraw their deposited asset by calling
withdraw(asset, amount, to)
. If the amount is set tomax
, the user’s entire aToken balance for that asset will be withdrawn. The protocol first checks that after withdrawal, the user’s remaining collateral can still cover their current borrowings (if any) – this uses the oracle to ensure the user’s health factor stays ≥ 1. If the withdrawal would make the loan under-collateralized, it is rejected byValidationLogic.validateWithdraw
. Upon a valid withdrawal, the reserve is updated for interest (accrue up to current time) and interest rates are adjusted withliquidityTaken = amountWithdrawn
(since liquidity is leaving the pool). If the user is withdrawing their full balance, the protocol also marks that asset as no longer being used as collateral in the user’s config (since they’ll have zero aTokens left). The aTokenburn()
function is then called to burn the user’s aTokens and transfer the corresponding underlying asset out to the specified address (the user’s wallet or another address they choose). AWithdraw
event is emitted with the amount. This process effectively redeems the user’s underlying, including any interest earned (because the aTokens burned are valued with the latest liquidity index). From the rewards perspective, the aToken burn triggers the incentives controller to update the user’s balance in that reward pool. If the user fully exits, theiramount
in the Chef controller for that pool becomes 0, but any pending rewards they had earned remain available to claim (the system will not erase accrued rewards even if balance goes to zero). Thus, a user can withdraw and later still claim the PRFI tokens they accrued while they were supplying.
Last updated