generated from refcell/femplate
-
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
Bug fix: kickWithDeposit
likely push LUP
below HTP
affecting healthy loans
#894
Merged
Merged
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
b301603
Merge pull request #874 from ajna-finance/develop
grandizzy e76de2b
Initial proposal: remove internal accounting
grandizzy e98167b
Revert if bucket price is lower than current LUP, fix tests
grandizzy 375f52d
Reorg code and revert, fix tests
grandizzy 7dd9939
Redo QT3 - bond escrowed are always guaranteed
grandizzy a9a983c
Recalculate LUP after kick actions, with additional debt from kick pe…
grandizzy 670c21f
Fix commented test
grandizzy f38431e
Update kickWithDeposit Natspec, remove obsolete event
grandizzy 531d311
Consistent way to return lup and pool debt
grandizzy cf9459e
Merge branch 'develop', remote-tracking branch 'origin' into kick-wit…
grandizzy 8843778
Rename kickWithDeposit to lenderKickAuction
grandizzy cc83947
Merge remote-tracking branch 'origin' into kick-with-deposit-re
grandizzy f9ea0c6
Rename lenderKickAuction to lenderKick
grandizzy 4a268bc
Log lender kick in invariants
grandizzy 3ff9ca5
Merge remote-tracking branch 'origin' into kick-with-deposit-re
grandizzy ccfb7d7
Merge branch 'develop' into kick-with-deposit-re
grandizzy aebee03
Fix compile errors after merge
grandizzy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,19 +67,6 @@ library KickerActions { | |
uint256 kickPenalty; // [WAD] current debt added as kick penalty | ||
} | ||
|
||
/// @dev Struct used for `kickWithDeposit` function local vars. | ||
struct KickWithDepositLocalVars { | ||
uint256 amountToDebitFromDeposit; // [WAD] the amount of quote tokens used to kick and debited from lender deposit | ||
uint256 bucketCollateral; // [WAD] amount of collateral in bucket | ||
uint256 bucketDeposit; // [WAD] amount of quote tokens in bucket | ||
uint256 bucketLP; // [WAD] LP of the bucket | ||
uint256 bucketPrice; // [WAD] bucket price | ||
uint256 bucketScale; // [WAD] bucket scales | ||
uint256 bucketUnscaledDeposit; // [WAD] unscaled amount of quote tokens in bucket | ||
uint256 lenderLP; // [WAD] LP of lender in bucket | ||
uint256 redeemedLP; // [WAD] LP used by kick action | ||
} | ||
|
||
/**************/ | ||
/*** Events ***/ | ||
/**************/ | ||
|
@@ -101,7 +88,6 @@ library KickerActions { | |
error InsufficientLP(); | ||
error InvalidAmount(); | ||
error NoReserves(); | ||
error PriceBelowLUP(); | ||
error ReserveAuctionTooSoon(); | ||
|
||
/***************************/ | ||
|
@@ -160,115 +146,34 @@ library KickerActions { | |
Bucket storage bucket = buckets_[index_]; | ||
Lender storage lender = bucket.lenders[msg.sender]; | ||
|
||
KickWithDepositLocalVars memory vars; | ||
|
||
if (bucket.bankruptcyTime < lender.depositTime) vars.lenderLP = lender.lps; | ||
uint256 lenderLP = bucket.bankruptcyTime < lender.depositTime ? lender.lps : 0; | ||
uint256 bucketDeposit = Deposits.valueAt(deposits_, index_); | ||
|
||
vars.bucketLP = bucket.lps; | ||
vars.bucketCollateral = bucket.collateral; | ||
vars.bucketPrice = _priceAt(index_); | ||
vars.bucketUnscaledDeposit = Deposits.unscaledValueAt(deposits_, index_); | ||
vars.bucketScale = Deposits.scale(deposits_, index_); | ||
vars.bucketDeposit = Maths.wmul(vars.bucketUnscaledDeposit, vars.bucketScale); | ||
|
||
// calculate amount to remove based on lender LP in bucket | ||
vars.amountToDebitFromDeposit = Buckets.lpToQuoteTokens( | ||
vars.bucketCollateral, | ||
vars.bucketLP, | ||
vars.bucketDeposit, | ||
vars.lenderLP, | ||
vars.bucketPrice, | ||
// calculate amount lender is entitled in current bucket (based on lender LP in bucket) | ||
uint256 entitledAmount = Buckets.lpToQuoteTokens( | ||
bucket.collateral, | ||
bucket.lps, | ||
bucketDeposit, | ||
lenderLP, | ||
_priceAt(index_), | ||
Math.Rounding.Down | ||
); | ||
|
||
// cap the amount to remove at bucket deposit | ||
if (vars.amountToDebitFromDeposit > vars.bucketDeposit) vars.amountToDebitFromDeposit = vars.bucketDeposit; | ||
// cap the amount entitled at bucket deposit | ||
if (entitledAmount > bucketDeposit) entitledAmount = bucketDeposit; | ||
|
||
// revert if no amount that can be removed | ||
if (vars.amountToDebitFromDeposit == 0) revert InsufficientLiquidity(); | ||
// revert if no entitled amount | ||
if (entitledAmount == 0) revert InsufficientLiquidity(); | ||
|
||
// kick top borrower | ||
// kick borrower | ||
kickResult_ = _kick( | ||
auctions_, | ||
deposits_, | ||
loans_, | ||
poolState_, | ||
Loans.getMax(loans_).borrower, | ||
limitIndex_, | ||
vars.amountToDebitFromDeposit | ||
); | ||
|
||
// amount to remove from deposit covers entire bond amount | ||
if (vars.amountToDebitFromDeposit > kickResult_.amountToCoverBond) { | ||
// cap amount to remove from deposit at amount to cover bond | ||
vars.amountToDebitFromDeposit = kickResult_.amountToCoverBond; | ||
|
||
// recalculate the LUP with the amount to cover bond | ||
kickResult_.lup = Deposits.getLup(deposits_, poolState_.debt + vars.amountToDebitFromDeposit); | ||
// entire bond is covered from deposit, no additional amount to be send by lender | ||
kickResult_.amountToCoverBond = 0; | ||
} else { | ||
// lender should send additional amount to cover bond | ||
kickResult_.amountToCoverBond -= vars.amountToDebitFromDeposit; | ||
} | ||
|
||
// revert if the bucket price used to kick and remove is below new LUP | ||
if (vars.bucketPrice < kickResult_.lup) revert PriceBelowLUP(); | ||
|
||
// remove amount from deposits | ||
if (vars.amountToDebitFromDeposit == vars.bucketDeposit && vars.bucketCollateral == 0) { | ||
// In this case we are redeeming the entire bucket exactly, and need to ensure bucket LP are set to 0 | ||
vars.redeemedLP = vars.bucketLP; | ||
|
||
Deposits.unscaledRemove(deposits_, index_, vars.bucketUnscaledDeposit); | ||
vars.bucketUnscaledDeposit = 0; | ||
|
||
} else { | ||
vars.redeemedLP = Buckets.quoteTokensToLP( | ||
vars.bucketCollateral, | ||
vars.bucketLP, | ||
vars.bucketDeposit, | ||
vars.amountToDebitFromDeposit, | ||
vars.bucketPrice, | ||
Math.Rounding.Up | ||
); | ||
|
||
uint256 unscaledAmountToRemove = Maths.floorWdiv(vars.amountToDebitFromDeposit, vars.bucketScale); | ||
|
||
// revert if calculated unscaled amount is 0 | ||
if (unscaledAmountToRemove == 0) revert InsufficientLiquidity(); | ||
|
||
Deposits.unscaledRemove(deposits_, index_, unscaledAmountToRemove); | ||
vars.bucketUnscaledDeposit -= unscaledAmountToRemove; | ||
} | ||
|
||
vars.redeemedLP = Maths.min(vars.lenderLP, vars.redeemedLP); | ||
|
||
// revert if LP redeemed amount to kick auction is 0 | ||
if (vars.redeemedLP == 0) revert InsufficientLP(); | ||
|
||
uint256 bucketRemainingLP = vars.bucketLP - vars.redeemedLP; | ||
|
||
if (vars.bucketCollateral == 0 && vars.bucketUnscaledDeposit == 0 && bucketRemainingLP != 0) { | ||
bucket.lps = 0; | ||
bucket.bankruptcyTime = block.timestamp; | ||
|
||
emit BucketBankruptcy( | ||
index_, | ||
bucketRemainingLP | ||
); | ||
} else { | ||
// update lender and bucket LP balances | ||
lender.lps -= vars.redeemedLP; | ||
bucket.lps -= vars.redeemedLP; | ||
} | ||
|
||
emit RemoveQuoteToken( | ||
msg.sender, | ||
index_, | ||
vars.amountToDebitFromDeposit, | ||
vars.redeemedLP, | ||
kickResult_.lup | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quite happy to eliminate all this logic. |
||
entitledAmount | ||
); | ||
} | ||
|
||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 think we should add a check that
index_
is greater to or equal to thelup
here -- otherwise the provisional removal of the deposit would not actually lower the lup. In that case, the lender can just callremoveQuoteToken
if they wantThere 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.
done at https://github.com/ajna-finance/contracts/pull/894/files#diff-54056532b4b7aac8940fbec13725e98ceceb358bef02e1285edad2741dff83bdR159