Protocol admins can modify the loan term settings. This action can inadvertently default existing loans created under different terms.
Positions in the Particle LAMM protocol are created for a configurable period of time, defined by the LOAN_TERM
variable. If the loan exceeds this duration, and the LP owner stops renewals that affect their position, the lien can be liquidated.
358: // check for liquidation condition
359: ///@dev the liquidation condition is that
360: /// (EITHER premium is not enough) OR (cutOffTime > startTime AND currentTime > startTime + LOAN_TERM)
361: if (
362: !((closeCache.tokenFromPremium < liquidateCache.tokenFromOwed ||
363: closeCache.tokenToPremium < liquidateCache.tokenToOwed) ||
364: (lien.startTime < lps.getRenewalCutoffTime(lien.tokenId) &&
365: lien.startTime + LOAN_TERM < block.timestamp))
366: ) {
367: revert Errors.LiquidationNotMet();
368: }
The liquidation condition in line 365 does the check using the current value of LOAN_TERM
. As the loan term can be updated using updateLoanTerm()
, this means that reducing this value may inadvertently cause the liquidation of existing positions that were originally intended for a longer period of time.
Let's say the current configured loan term in ParticlePositionManager is 2 weeks.
- A user creates a new position, expecting it to last at least 2 weeks.
- The owner of the LP calls
reclaimLiquidity()
to stop it from being renewed. - The protocol changes the loan term setting to 1 week.
- The user is liquidated after 1 week.
Store the loan term value at the time the position was created in the Lien structure, e.g. in lien.loanTerm
. When checking the liquidation condition, calculate the end time using this value to honor the original loan term.
if (
!((closeCache.tokenFromPremium < liquidateCache.tokenFromOwed ||
closeCache.tokenToPremium < liquidateCache.tokenToOwed) ||
(lien.startTime < lps.getRenewalCutoffTime(lien.tokenId) &&
- lien.startTime + LOAN_TERM < block.timestamp))
+ lien.startTime + lien.loanTerm < block.timestamp))
) {
revert Errors.LiquidationNotMet();
}