-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Use last zombie trove first in a redemption sequence #426
Conversation
f6b40e9
to
b5c000d
Compare
b5c000d
to
a6397d7
Compare
c879e70
to
654211f
Compare
654211f
to
4c91464
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Nice solution.
@@ -53,6 +53,8 @@ interface ITroveManager is ILiquityBase { | |||
|
|||
function getCurrentICR(uint256 _troveId, uint256 _price) external view returns (uint256); | |||
|
|||
function lastZombieTroveId() external view returns (uint256); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"last" here refers to the last Trove that was redeemed to below MIN_DEBT right?
if (newDebt > 0) { | ||
lastZombieTroveId = _singleRedemption.troveId; | ||
} | ||
} else if (newDebt == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, so newDebt == 0
implies this Trove was fully redeemed, therefore we unzombify it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn’t say “unzombified”. It’s still zombie, but it doesn’t hold the pointer to be the first one in the next redemption sequence anymore.
@@ -730,15 +745,27 @@ contract TroveManager is LiquityBase, ITroveManager, ITroveEvents { | |||
uint256 remainingBold = _boldamount; | |||
|
|||
SingleRedemptionValues memory singleRedemption; | |||
singleRedemption.troveId = sortedTrovesCached.getLast(); | |||
// Let’s check if there’s a pending zombie trove from previous redemption | |||
if (lastZombieTroveId != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can never have a valid troveId == 0, right?
@@ -769,6 +796,7 @@ contract TroveManager is LiquityBase, ITroveManager, ITroveEvents { | |||
|
|||
remainingBold -= singleRedemption.boldLot; | |||
singleRedemption.troveId = nextUserToCheck; | |||
singleRedemption.isZombieTrove = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only need to do this if it was a zombieTrove
. Though seems fine to just do it here at the end.
@@ -1450,6 +1483,8 @@ contract TroveManager is LiquityBase, ITroveManager, ITroveEvents { | |||
} else { | |||
if (trove.status == Status.active) { | |||
sortedTroves.remove(_troveId); | |||
} else if (trove.status == Status.zombie && lastZombieTroveId == _troveId) { | |||
lastZombieTroveId = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this logic twice? Could we do it once at the end?
Closes #425
Note: with this implementation, it can happen that a trove belonging to a batch, has both entire and recorded debt, due to the batch being updated (even the function
redeemCollateral
does that as a preliminary step) but without a direct action on the trove, and the trove is still zombie and holds the pointer to the last zombie trove, so it gets redeemed first in the list.This seems like quite an edge case, and the user can easily prevent it by taking care of the trove before.