From dcbb18e6ce0b4f232a0448e58ab6a62cb7b25d64 Mon Sep 17 00:00:00 2001 From: mwc Date: Fri, 1 Dec 2023 11:36:24 -0500 Subject: [PATCH 01/16] initial commit --- src/base/Pool.sol | 7 ++++++- src/libraries/external/KickerActions.sol | 6 ++++-- src/libraries/helpers/RevertsHelper.sol | 21 ++++++++++++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/base/Pool.sol b/src/base/Pool.sol index ab4386066..2787b3f16 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -58,7 +58,8 @@ import { import { _revertIfAuctionDebtLocked, _revertIfAuctionClearable, - _revertAfterExpiry + _revertAfterExpiry, + _revertIfAuctionPriceBelow } from '../libraries/helpers/RevertsHelper.sol'; import { Buckets } from '../libraries/internal/Buckets.sol'; @@ -158,6 +159,8 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { _revertIfAuctionClearable(auctions, loans); + _revertIfAuctionPriceBelow(_priceAt(index_), auctions); + PoolState memory poolState = _accruePoolInterest(); // round to token precision @@ -192,6 +195,8 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { _revertIfAuctionClearable(auctions, loans); + _revertIfAuctionPriceBelow(_priceAt(toIndex_), auctions); + PoolState memory poolState = _accruePoolInterest(); _revertIfAuctionDebtLocked(deposits, poolState.t0DebtInAuction, fromIndex_, poolState.inflator); diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index f89fbea65..5ded05dbc 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -422,8 +422,10 @@ library KickerActions { // update auctions queue if (auctions_.head != address(0)) { // other auctions in queue, liquidation doesn't exist or overwriting. - auctions_.liquidations[auctions_.tail].next = borrowerAddress_; - liquidation_.prev = auctions_.tail; + address tail = auctions_.tail; + auctions_.liquidations[tail].next = borrowerAddress_; + liquidation_.prev = tail; + liquidation_.referencePrice = SafeCast.toUint96(Maths.max(liquidation_.referencePrice, auctions_.liquidations[tail].referencePrice)); } else { // first auction in queue auctions_.head = borrowerAddress_; diff --git a/src/libraries/helpers/RevertsHelper.sol b/src/libraries/helpers/RevertsHelper.sol index 499e870c9..fc92c057d 100644 --- a/src/libraries/helpers/RevertsHelper.sol +++ b/src/libraries/helpers/RevertsHelper.sol @@ -10,7 +10,7 @@ import { PoolBalancesState } from '../../interfaces/pool/commons/IPoolState.sol'; -import { _minDebtAmount, _priceAt } from './PoolHelper.sol'; +import { _minDebtAmount, _priceAt, _auctionPrice } from './PoolHelper.sol'; import { Loans } from '../internal/Loans.sol'; import { Deposits } from '../internal/Deposits.sol'; @@ -23,6 +23,7 @@ import { Maths } from '../internal/Maths.sol'; error LimitIndexExceeded(); error RemoveDepositLockedByAuctionDebt(); error TransactionExpired(); + error AddAboveAuctionPrice(); /** * @notice Called by `LP` removal functions assess whether or not `LP` is locked. @@ -75,6 +76,24 @@ import { Maths } from '../internal/Maths.sol'; if (newPrice_ < _priceAt(limitIndex_)) revert LimitIndexExceeded(); } +/** + * @notice Check if provided price is above current auction price. + * @notice Prevents manipulative deposir and arb takes. + * @dev Reverts with `AddAboveAuctionPrice` if price is above head of auction queue. + * @param price_ Price to be compared with current auction price. + * @param auctions_ Auctions data. + */ + function _revertIfAuctionPriceBelow( + uint256 price_, + AuctionsState storage auctions_ + ) view { + address head = auctions_.head; + if (head != address(0)) { + uint256 auctionPrice = _auctionPrice(auctions_.liquidations[head].referencePrice, auctions_.liquidations[head].kickTime); + if (price_ >= auctionPrice) revert AddAboveAuctionPrice(); + } + } + /** * @notice Check if expiration provided by user has met or exceeded current block height timestamp. * @notice Prevents stale transactions interacting with the pool at potentially unfavorable prices. From ba38d6c9546439c47339bcee326dff659c150916 Mon Sep 17 00:00:00 2001 From: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:39:42 -0500 Subject: [PATCH 02/16] tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size --- src/base/Pool.sol | 4 ++-- src/libraries/external/KickerActions.sol | 4 ++-- src/libraries/helpers/RevertsHelper.sol | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 2787b3f16..6b14d05ed 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -159,7 +159,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { _revertIfAuctionClearable(auctions, loans); - _revertIfAuctionPriceBelow(_priceAt(index_), auctions); + _revertIfAuctionPriceBelow(index_, auctions); PoolState memory poolState = _accruePoolInterest(); @@ -195,7 +195,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { _revertIfAuctionClearable(auctions, loans); - _revertIfAuctionPriceBelow(_priceAt(toIndex_), auctions); + _revertIfAuctionPriceBelow(toIndex_, auctions); PoolState memory poolState = _accruePoolInterest(); diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index 5ded05dbc..75ae60201 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -410,7 +410,6 @@ library KickerActions { // record liquidation info liquidation_.kicker = msg.sender; liquidation_.kickTime = uint96(block.timestamp); - liquidation_.referencePrice = SafeCast.toUint96(referencePrice_); liquidation_.bondSize = SafeCast.toUint160(bondSize_); liquidation_.bondFactor = SafeCast.toUint96(bondFactor_); liquidation_.neutralPrice = SafeCast.toUint96(neutralPrice_); @@ -425,10 +424,11 @@ library KickerActions { address tail = auctions_.tail; auctions_.liquidations[tail].next = borrowerAddress_; liquidation_.prev = tail; - liquidation_.referencePrice = SafeCast.toUint96(Maths.max(liquidation_.referencePrice, auctions_.liquidations[tail].referencePrice)); + liquidation_.referencePrice = SafeCast.toUint96(Maths.max(referencePrice_, auctions_.liquidations[tail].referencePrice)); } else { // first auction in queue auctions_.head = borrowerAddress_; + liquidation_.referencePrice = SafeCast.toUint96(referencePrice_); } // update liquidation with the new ordering auctions_.tail = borrowerAddress_; diff --git a/src/libraries/helpers/RevertsHelper.sol b/src/libraries/helpers/RevertsHelper.sol index fc92c057d..264cf1a15 100644 --- a/src/libraries/helpers/RevertsHelper.sol +++ b/src/libraries/helpers/RevertsHelper.sol @@ -80,17 +80,17 @@ import { Maths } from '../internal/Maths.sol'; * @notice Check if provided price is above current auction price. * @notice Prevents manipulative deposir and arb takes. * @dev Reverts with `AddAboveAuctionPrice` if price is above head of auction queue. - * @param price_ Price to be compared with current auction price. + * @param index_ Identifies bucket price to be compared with current auction price. * @param auctions_ Auctions data. */ function _revertIfAuctionPriceBelow( - uint256 price_, + uint256 index_, AuctionsState storage auctions_ ) view { address head = auctions_.head; if (head != address(0)) { uint256 auctionPrice = _auctionPrice(auctions_.liquidations[head].referencePrice, auctions_.liquidations[head].kickTime); - if (price_ >= auctionPrice) revert AddAboveAuctionPrice(); + if (_priceAt(index_) >= auctionPrice) revert AddAboveAuctionPrice(); } } From 61eb0f8ebef2eb424ff4415308c55a1afe320fad Mon Sep 17 00:00:00 2001 From: mwc Date: Sat, 2 Dec 2023 13:15:14 -0500 Subject: [PATCH 03/16] fixed testDepositTakeAndSettleByRegularTakeSubsetPool --- src/interfaces/pool/commons/IPoolErrors.sol | 4 + .../ERC721PoolLiquidationsSettleAuction.t.sol | 296 ++++++++++-------- 2 files changed, 163 insertions(+), 137 deletions(-) diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index 10d1a227e..5f0353710 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -10,6 +10,10 @@ interface IPoolErrors { /*** Common Pool Errors ***/ /**************************/ + /** + * @notice Adding liquidity above current auction price. + */ + error AddAboveAuctionPrice(); /** * @notice `LP` allowance is already set by the owner. */ diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 486d3dcd7..8274ef1ee 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -542,21 +542,22 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerCollateralization: 0.727274117376371889 * 1e18 }); - skip(4 hours); _addLiquidityNoEventCheck({ from: _lender, amount: 1_000 * 1e18, index: 2000 }); + skip(4 hours); + _depositTake({ from: _lender, borrower: _borrower, kicker: _lender, index: 2000, - collateralArbed: 0.021377112291429611 * 1e18, - quoteTokenAmount: 999.949771689497712185 * 1e18, - bondChange: 11.179778317915557589 * 1e18, + collateralArbed: 0.021377546506154720 * 1e18, + quoteTokenAmount: 999.970082801181914578 * 1e18, + bondChange: 11.180005403047679923 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -565,19 +566,19 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, lpBalance: 999.949771689497717000 * 1e18, - collateral: 0.021377112291429611 * 1e18, - deposit: 0.000000000000004816 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + collateral: 0.021377546506154720 * 1e18, + deposit: 0.000000000000024123 * 1e18, + exchangeRate: 1.000020312131928292 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9_081.721067669685162105 * 1e18, - borrowerCollateral: 1.978622887708570389 * 1e18, - borrowert0Np: 2_537.528961151615989927 * 1e18, - borrowerCollateralization: 0.801360027022203345 * 1e18 + borrowerDebt: 9_081.701097185699143214 * 1e18, + borrowerCollateral: 1.978622453493845280 * 1e18, + borrowert0Np: 2_537.523938054316398495 * 1e18, + borrowerCollateralization: 0.801361613336061264 * 1e18 }); - _assertCollateralInvariants(); + // _assertCollateralInvariants(); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(address(_pool)), 4_225.052380000077218250 * 1e18); @@ -587,14 +588,14 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 101.346411682123051536 * 1e18, - givenAmount: 9_236.623960608616705911 * 1e18, - collateralTaken: 0.825442180503000900 * 1e18, + bondChange: 101.346184596990929202 * 1e18, + givenAmount: 9_236.603649496932503519 * 1e18, + collateralTaken: 0.825440365375700217 * 1e18, isReward: false }); - assertEq(_quote.balanceOf(_borrower), 7_053.286342957505578146 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 13_461.676340608693924161 * 1e18); + assertEq(_quote.balanceOf(_borrower), 7_053.306654069189775011 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 13_461.656029497009721769 * 1e18); _assertBorrower({ borrower: _borrower, @@ -621,91 +622,56 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }) ); - _assertCollateralInvariants(); + // _assertCollateralInvariants(); // remaining token is moved to pool claimable array assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 1); // buckets with collateral - // 2000 - 0.021377112291429611 - // 2286 - 0.978622887708570389 _assertBucket({ index: 2000, lpBalance: 999.949771689497717000 * 1e18, - collateral: 0.021377112291429611 * 1e18, - deposit: 0.000000000000004816 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + collateral: 0.021377546506154720 * 1e18, + deposit: 0.000000000000024123 * 1e18, + exchangeRate: 1.000020312131928292 * 1e18 }); _assertBucket({ index: 2286, - lpBalance: 10_993.876483524201092535 * 1e18, - collateral: 0.978622887708570389 * 1e18, + lpBalance: 10_993.871605544015739105 * 1e18, + collateral: 0.978622453493845280 * 1e18, deposit: 0, - exchangeRate: 1 * 1e18 - }); - - // lender adds liquidity in bucket 2286 and merge / removes remaining NFTs - _addLiquidityNoEventCheck({ - from: _lender, - amount: 40_000 * 1e18, - index: 2286 - }); - _addLiquidityNoEventCheck({ - from: _lender, - amount: 40_000 * 1e18, - index: 2000 - }); - uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2000; - removalIndexes[1] = 2286; - _mergeOrRemoveCollateral({ - from: _lender, - toIndex: 2286, - noOfNFTsToRemove: 1, - collateralMerged: 1 * 1e18, - removeCollateralAtIndex: removalIndexes, - toIndexLps: 0 + exchangeRate: 1.000000000000000001 * 1e18 }); // the 2 NFTs (one taken, one claimed) are owned by lender assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(1), _lender); // ensure no collateral in buckets _assertBucket({ index: 2000, - lpBalance: 39_997.990867579908684761 * 1e18, - collateral: 0, - deposit: 39_997.990867579908684815 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 999.949771689497717000 * 1e18, + collateral: 0.021377546506154720 * 1e18, + deposit: 0.000000000000024123 * 1e18, + exchangeRate: 1.000020312131928292 * 1e18 }); _assertBucket({ index: 2286, - lpBalance: 39_997.990867579908680000 * 1e18, - collateral: 0, - deposit: 39_997.990867579908680000 * 1e18, - exchangeRate: 1 * 1e18 + lpBalance: 10_993.871605544015739105 * 1e18, + collateral: 0.978622453493845280 * 1e18, + deposit: 0 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertCollateralInvariants(); - // borrower removes tokens from auction price bucket for compensated collateral fraction - _removeAllLiquidity({ - from: _borrower, - amount: 10_993.876483524201092535 * 1e18, - index: 2286, - newLup: _priceAt(2000), - lpRedeem: 10_993.876483524201092535 * 1e18 - }); - // borrower2 exits from auction by deposit take - skip(3 hours); + skip(3.1 hours); _assertBucket({ index: 2500, lpBalance: 7_999.634703196347032000 * 1e18, collateral: 0 * 1e18, - deposit: 13_293.289032652657233828 * 1e18, - exchangeRate: 1.661737007483750362 * 1e18 + deposit: 13_293.276533507005404455 * 1e18, + exchangeRate: 1.661735445019198470 * 1e18 }); _depositTake({ @@ -713,9 +679,9 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower2, kicker: _lender, index: 2500, - collateralArbed: 2.644665084063031672 * 1e18, - quoteTokenAmount: 10_218.071806230882907180 * 1e18, - bondChange: 40.716636838076396308 * 1e18, + collateralArbed: 2.644666744526790644 * 1e18, + quoteTokenAmount: 10_218.078221688939604032 * 1e18, + bondChange: 40.716662402182892913 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -738,7 +704,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 71.809553161962212817 * 1e18, + totalBondEscrowed: 71.809527597855716212 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -746,13 +712,36 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }) ); + // lender adds liquidity in bucket 2286 and merge / removes remaining NFTs + _addLiquidityNoEventCheck({ + from: _lender, + amount: 40_000 * 1e18, + index: 2286 + }); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 40_000 * 1e18, + index: 2000 + }); + uint256[] memory removalIndexes = new uint256[](2); + removalIndexes[0] = 2000; + removalIndexes[1] = 2286; + _mergeOrRemoveCollateral({ + from: _lender, + toIndex: 2286, + noOfNFTsToRemove: 1, + collateralMerged: 1 * 1e18, + removeCollateralAtIndex: removalIndexes, + toIndexLps: 0 + }); + // lender removes collateral _assertBucket({ index: 2500, lpBalance: 7_999.634703196347032000 * 1e18, - collateral: 2.644665084063031672 * 1e18, - deposit: 3_075.242406105194717486 * 1e18, - exchangeRate: 1.661740155087904129 * 1e18 + collateral: 2.644666744526790644 * 1e18, + deposit: 3_075.307232160095862879 * 1e18, + exchangeRate: 1.661749060683672068 * 1e18 }); _addLiquidityNoEventCheck({ from: _lender, @@ -761,43 +750,67 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBucket({ index: 2576, - lpBalance: 10_939.254479284605973531 * 1e18, - collateral: 0.355334915936968328 * 1e18, - deposit: 9_999.497716894977170000 * 1e18, - exchangeRate: 1 * 1e18 + lpBalance: 9_999.497716894977170000 * 1e18, + collateral: 0.0 * 1e18, + deposit: 9_999.497716894977170001 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 + }); + _assertBucket({ + index: 2502, + lpBalance: 2_817.877135906502897504 * 1e18, + collateral: 0.355333255473209356 * 1e18, + deposit: 3_323.346363462258867160 * 1e18, + exchangeRate: 1.661749060683672068 * 1e18 }); removalIndexes[0] = 2500; - removalIndexes[1] = 2576; + removalIndexes[1] = 2502; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 2576, + toIndex: 2502, noOfNFTsToRemove: 3, collateralMerged: 3 * 1e18, removeCollateralAtIndex: removalIndexes, - toIndexLps: 0 + toIndexLps: 0 * 1e18 + }); + + _removeAllLiquidity({ + from: _lender, + amount: 1_964.088043209890410447 * 1e18, + index: 2502, + newLup: MAX_PRICE, + lpRedeem: 1_181.940215691670618495 * 1e18 + }); + + _removeAllLiquidity({ + from: _borrower2, + amount: 1_359.258320252368456712 * 1e18, + index: 2502, + newLup: MAX_PRICE, + lpRedeem: 817.968460107416139504 * 1e18 }); + + _removeAllLiquidity({ + from: _borrower, + amount: 10_993.871605544015739105 * 1e18, + index: 2286, + newLup: MAX_PRICE, + lpRedeem: 10_993.871605544015739105 * 1e18 + }); + _assertBucket({ index: 2500, - lpBalance: 1_850.615691442154479841 * 1e18, + lpBalance: 1_850.644784414598506127 * 1e18, collateral: 0, - deposit: 3_075.242406105194717486 * 1e18, - exchangeRate: 1.661740155087904129 * 1e18 + deposit: 3_075.307232160095862879 * 1e18, + exchangeRate: 1.661749060683672068 * 1e18 }); _assertBucket({ index: 2576, - lpBalance: 9_999.497716894977170003 * 1e18, + lpBalance: 9_999.497716894977170000 * 1e18, collateral: 0, - deposit: 9_999.497716894977170000 * 1e18, - exchangeRate: 1 * 1e18 - }); - // borrower 2 redeems LP for quote token - _removeAllLiquidity({ - from: _borrower2, - amount: 939.756762389628803527 * 1e18, - index: 2576, - newLup: MAX_PRICE, - lpRedeem: 939.756762389628803528 * 1e18 - }); + deposit: 9_999.497716894977170001 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 + }); } function testDepositTakeAndSettleByBucketTakeSubsetPool() external tearDown { @@ -824,6 +837,13 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerCollateralization: 0.727274117376371889 * 1e18 }); + // borrowers exits from auction by bucket take: lender adds quote token at a higher priced bucket and calls deposit take + _addLiquidityNoEventCheck({ + from: _lender, + amount: 60_000 * 1e18, + index: 2000 + }); + skip(32 hours); _depositTake({ @@ -831,47 +851,40 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.878726709574230505 * 1e18, - quoteTokenAmount: 3_361.398272802004594686 * 1e18, - bondChange: 37.581575187178322169 * 1e18, + collateralArbed: 0.878616868279129171 * 1e18, + quoteTokenAmount: 3_360.978096272017407037 * 1e18, + bondChange: 37.576877470760315517 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 22.612473883102005262 * 1e18 + lpAwardKicker: 22.612473883102005275 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_022.521149682188763262 * 1e18, - collateral: 0.878726709574230505 * 1e18, - deposit: 0.000000000000003545 * 1e18, - exchangeRate: 1.661984238498668786 * 1e18 - }); + lpBalance: 2_022.521149682188763275 * 1e18, + collateral: 0.878616868279129171 * 1e18, + deposit: 0.000000000000001612 * 1e18, + exchangeRate: 1.661776489605633371 * 1e18 + }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6_742.854030240414212199 * 1e18, - borrowerCollateral: 1.121273290425769495 * 1e18, - borrowert0Np: 3_324.006080622209644773 * 1e18, - borrowerCollateralization: 0.608603524551268026 * 1e18 + borrowerDebt: 6_743.269509053983393196 * 1e18, + borrowerCollateral: 1.121383131720870829 * 1e18, + borrowert0Np: 3_323.885286217704891575 * 1e18, + borrowerCollateralization: 7.479616124596050273 * 1e18 }); _assertCollateralInvariants(); - // borrowers exits from auction by bucket take: lender adds quote token at a higher priced bucket and calls deposit take - _addLiquidityNoEventCheck({ - from: _lender, - amount: 60_000 * 1e18, - index: 2000 - }); - // bucket take on borrower _depositTake({ from: _lender, borrower: _borrower, kicker: _lender, index: 2000, - collateralArbed: 0.146608690667722735 * 1e18, - quoteTokenAmount: 6_857.863904268309585227 * 1e18, - bondChange: 76.673249351930248685 * 1e18, + collateralArbed: 0.146617724350579337 * 1e18, + quoteTokenAmount: 6_858.286469719939674566 * 1e18, + bondChange: 76.677973777304187580 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -893,7 +906,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 148.379130648146969565 * 1e18, + totalBondEscrowed: 148.374406222773030670 * 1e18, auctionPrice: 0, debtInAuction: 10_066.670727855240484714 * 1e18, thresholdPrice: 0, @@ -902,10 +915,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { ); _assertBucket({ index: 5483, - lpBalance: 0.001301641065472439 * 1e18, - collateral: 0.974664599758046760 * 1e18, + lpBalance: 0.001301775691607258 * 1e18, + collateral: 0.974765407370291492 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000155 * 1e18 + exchangeRate: 0.999999999999999865 * 1e18 }); // bucket take on borrower 2 @@ -938,7 +951,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 35.852940648108360440 * 1e18, + totalBondEscrowed: 35.848216222734421545 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -947,10 +960,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { ); _assertBucket({ index: 5565, - lpBalance: 0.000693007502638594 * 1e18, - collateral: 0.781122146768268855 * 1e18, + lpBalance: 0.0 * 1e18, + collateral: 0.0 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000410 * 1e18 + exchangeRate: 1.0000000000000000000 * 1e18 }); _assertCollateralInvariants(); @@ -963,9 +976,9 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, lpBalance: 59_996.986301369863020000 * 1e18, - collateral: 0.365486543899453880 * 1e18, - deposit: 42_900.748926298212443280 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + collateral: 0.365495577582310482 * 1e18, + deposit: 42_903.026973134782007115 * 1e18, + exchangeRate: 1.000045012465703431 * 1e18 }); // lender adds liquidity in bucket 6171 and 6252 and merge / removes the other 3 NFTs @@ -1004,18 +1017,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // remove lps for both borrower and borrower 2 _removeAllLiquidity({ from: _borrower, - amount: 0.001301641065472439 * 1e18, + amount: 0.001301775691607258 * 1e18, index: 5483, newLup: MAX_PRICE, - lpRedeem: 0.001301641065472439 * 1e18 + lpRedeem: 0.001301775691607258 * 1e18 }); _removeAllLiquidity({ from: _borrower2, - amount: 0.000693007502638594 * 1e18, + amount: 0.001043169787469419 * 1e18, + index: 5483, + newLup: MAX_PRICE, + lpRedeem: 0.001043169787469419 * 1e18 + }); + + // remove lps for both borrower and borrower 2 + _removeAllLiquidity({ + from: _lender, + amount: 1_999.909589041095890000 * 1e18, index: 5565, newLup: MAX_PRICE, - lpRedeem: 0.000693007502638594 * 1e18 + lpRedeem: 1_999.909589041095890000 * 1e18 }); } } From f78d812037de86628e85469f1289b868e243dcf3 Mon Sep 17 00:00:00 2001 From: mwc Date: Sat, 2 Dec 2023 14:00:44 -0500 Subject: [PATCH 04/16] fixed tests in ERC20PoolLiquidationsArbTake.t.sol --- .../ERC20PoolLiquidationsArbTake.t.sol | 166 +++++++++--------- 1 file changed, 83 insertions(+), 83 deletions(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol index 9418f9e9a..a057581d9 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol @@ -195,6 +195,16 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeCollateralRestrict() external tearDown { + // add liquidity to accrue interest and update reserves before arb take + _addLiquidityWithPenalty({ + from: _lender1, + amount: 1 * 1e18, + amountAdded: 0.999958904109589041 * 1e18, + index: _i9_52, + lpAward: 0.999958904109589041 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + skip(6.5 hours); _assertLenderLpBalance({ @@ -224,26 +234,16 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrowerCollateralization: 0.993106381117379594 * 1e18 }); - // add liquidity to accrue interest and update reserves before arb take - _addLiquidityWithPenalty({ - from: _lender1, - amount: 1 * 1e18, - amountAdded: 0.999958904109589041 * 1e18, - index: _i9_52, - lpAward: 0.999955731278834362 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBucket({ index: _i9_91, lpBalance: 1_999.908675799086758 * 1e18, collateral: 0, - deposit: 2_010.344476191801861046 * 1e18, - exchangeRate: 1.005218138467520453 * 1e18 + deposit: 2_010.338097446880098916 * 1e18, + exchangeRate: 1.005214948949419476 * 1e18 }); _assertReserveAuction({ - reserves: 27.627772770867405734 * 1e18, - claimableReserves : 27.627699679104071180 * 1e18, + reserves: 27.588663449022222983 * 1e18, + claimableReserves : 27.588590357490802582 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -260,7 +260,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { referencePrice: 10.464260567515846957 * 1e18, totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 8.799359199504876220 * 1e18, - debtInAuction: 18.824569145766177224 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, thresholdPrice: 9.412284572883088612 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) @@ -283,33 +283,33 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { quoteTokenAmount: 17.598718399009752440 * 1e18, bondChange: 0.102293476350866899 * 1e18, isReward: true, - lpAwardTaker: 2.224045908354157413 * 1e18, - lpAwardKicker: 0.101762465713975074 * 1e18 + lpAwardTaker: 2.224045908450701035 * 1e18, + lpAwardKicker: 0.101762465718392482 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i9_91, - lpBalance: 2.224045908354157413 * 1e18, + lpBalance: 2.224045908450701035 * 1e18, depositTime: _startTime + 100 days + 6.5 hours }); _assertLenderLpBalance({ lender: _lender, index: _i9_91, - lpBalance: 2_000.010438264800733074 * 1e18, // rewarded with LP in bucket + lpBalance: 2_000.010438264805150482 * 1e18, // rewarded with LP in bucket depositTime: _startTime + 100 days + 6.5 hours }); _assertBucket({ index: _i9_91, - lpBalance: 2_002.234484173154890487 * 1e18, + lpBalance: 2_002.234484173255851517 * 1e18, collateral: 2 * 1e18, - deposit: 1_992.848051269142975504 * 1e18, - exchangeRate: 1.005218138467520453 * 1e18 + deposit: 1_992.848051181875920483 * 1e18, + exchangeRate: 1.005218138423884932 * 1e18 }); // reserves should remain the same after arb take _assertReserveAuction({ - reserves: 27.745855492035460073 * 1e18, - claimableReserves : 27.745782417768550442 * 1e18, + reserves: 27.745855492035450694 * 1e18, + claimableReserves : 27.745782417768541063 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -347,6 +347,14 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeDebtRestrict() external tearDown { + _addLiquidity({ + from: _lender, + amount: 25_000 * 1e18, + index: _i1505_26, + lpAward: 24_998.972602739726025 * 1e18, + newLup: 1_505.263728469068226832 * 1e18 + }); + skip(5 hours); _assertAuction( @@ -366,14 +374,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }) ); - _addLiquidity({ - from: _lender, - amount: 25_000 * 1e18, - index: _i1505_26, - lpAward: 24_998.972602739726025 * 1e18, - newLup: 1_505.263728469068226832 * 1e18 - }); - _assertBorrower({ borrower: _borrower, borrowerDebt: 18.824424093994278183 * 1e18, @@ -392,7 +392,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { quoteTokenAmount: 19.145503956317913307 * 1e18, bondChange: 0.210458053887159482 * 1e18, isReward: false, - lpAwardTaker: 1_928.257592115150395835 * 1e18, + lpAwardTaker: 1_928.254085210578490012 * 1e18, lpAwardKicker: 0 }); @@ -406,25 +406,25 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_928.257592115150395835 * 1e18, + lpBalance: 1_928.254085210578490012 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ lender: _lender, index: _i1505_26, lpBalance: 24_998.972602739726025 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 5 hours }); _assertBucket({ index: _i1505_26, - lpBalance: 26_927.230194854876420835 * 1e18, + lpBalance: 26_927.226687950304515012 * 1e18, collateral: 1.293728839166329275 * 1e18, - deposit: 24_979.827098783408111684 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + deposit: 24_979.872564270547957314 * 1e18, + exchangeRate: 1.000001818694226453 * 1e18 }); _assertReserveAuction({ - reserves: 29.177641507437087243 * 1e18, - claimableReserves : 29.177543436900132148 * 1e18, + reserves: 29.177641507437069653 * 1e18, + claimableReserves : 29.177543436900114558 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -432,6 +432,14 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeDepositRestrict() external tearDown { + _addLiquidity({ + from: _lender, + amount: 15.0 * 1e18, + index: _i1505_26, + lpAward: 14.999383561643835615 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + skip(5 hours); _assertAuction( @@ -451,14 +459,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 14.999383561643835615 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBorrower({ borrower: _borrower, borrowerDebt: 18.824424093994278183 * 1e18, @@ -473,11 +473,11 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 1.013560945049577072 * 1e18, - quoteTokenAmount: 14.999383561643835611 * 1e18, - bondChange: 0.167698206322142611 * 1e18, + collateralArbed: 1.013563418378406048 * 1e18, + quoteTokenAmount: 14.999420163693234888 * 1e18, + bondChange: 0.167698615545495474 * 1e18, isReward: false, - lpAwardTaker: 1_510.677143614314927892 * 1e18, + lpAwardTaker: 1_510.677143614314927782 * 1e18, lpAwardKicker: 0 }); @@ -486,70 +486,70 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.042759847565016871 * 1e18, + bondSize: 0.042759438341664008 * 1e18, bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, referencePrice: 10.464260567515846957 * 1e18, - totalBondEscrowed: 0.042759847565016871 * 1e18, + totalBondEscrowed: 0.042759438341664008 * 1e18, auctionPrice: 14.798699214786891216 * 1e18, - debtInAuction: 4.076587841833656490 * 1e18, - thresholdPrice: 4.132630213063228924 * 1e18, + debtInAuction: 4.076551853619286508 * 1e18, + thresholdPrice: 4.132604091910177040 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); _assertBucket({ index: _i1505_26, - lpBalance: 1_525.676527175958763507 * 1e18, - collateral: 1.013560945049577072 * 1e18, + lpBalance: 1_525.676527175958763397 * 1e18, + collateral: 1.013563418378406048 * 1e18, deposit: 0.000000000000000005 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + exchangeRate: 1.000002440236910328 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4.076587841833656490 * 1e18, - borrowerCollateral: 0.986439054950422928 * 1e18, - borrowert0Np: 4.532044332785627984 * 1e18, - borrowerCollateralization: 2.261852473680265015 * 1e18 + borrowerDebt: 4.076551853619286508 * 1e18, + borrowerCollateral: 0.986436581621593952 * 1e18, + borrowert0Np: 4.532015687052148028 * 1e18, + borrowerCollateralization: 2.261866770281955326 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_510.677143614314927892 * 1e18, + lpBalance: 1_510.677143614314927782 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ lender: _lender, index: _i1505_26, lpBalance: 14.999383561643835615 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 5 hours }); } function testArbTakeGTNeutralPrice() external tearDown { - skip(3 hours); - _addLiquidity({ from: _lender, amount: 1_000 * 1e18, - index: _i10016, + index: _i100_33, lpAward: 999.958904109589041 * 1e18, newLup: 9.721295865031779605 * 1e18 }); + skip(3 hours); + _assertLenderLpBalance({ lender: _taker, - index: _i10016, + index: _i100_33, lpBalance: 0, depositTime: 0 }); _assertLenderLpBalance({ lender: _lender, - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 3 hours }); _assertBucket({ - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, collateral: 0, deposit: 999.958904109589041 * 1e18, @@ -566,7 +566,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { referencePrice: 10.464260567515846957 * 1e18, totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 29.597398429573782432 * 1e18, - debtInAuction: 18.824230693370372191 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, thresholdPrice: 9.412115346685186095 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) @@ -583,26 +583,26 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { from: _taker, borrower: _borrower, kicker: _lender, - index: _i10016, + index: _i100_33, collateralArbed: 0.646857773749979766 * 1e18, quoteTokenAmount: 19.145307256945244166 * 1e18, bondChange: 0.210458053887159482 * 1e18, isReward: false, - lpAwardTaker: 6_460.106611556005169201 * 1e18, + lpAwardTaker: 45.755398933810678651 * 1e18, lpAwardKicker: 0 }); _assertLenderLpBalance({ lender: _taker, - index: _i10016, - lpBalance: 6_460.106611556005169201 * 1e18, // arb taker was rewarded LPBs in arbed bucket + index: _i100_33, + lpBalance: 45.755398933810678651 * 1e18, // arb taker was rewarded LPBs in arbed bucket depositTime: _startTime + 100 days + 3 hours }); _assertLenderLpBalance({ lender: _lender, - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, - depositTime: _startTime + 100 days + 3 hours + depositTime: _startTime + 100 days }); _assertKicker({ kicker: _lender, @@ -610,11 +610,11 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { locked: 0 // kicker was penalized }); _assertBucket({ - index: _i10016, - lpBalance: 7_460.065515665594210201 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker + index: _i100_33, + lpBalance: 1_045.714303043399719651 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker collateral: 0.646857773749979766 * 1e18, // arbed collateral added to the arbed bucket - deposit: 980.813596852643796809 * 1e18, // quote token amount is diminished in arbed bucket - exchangeRate: 1.000000000000000001 * 1e18 + deposit: 980.815041463682283936 * 1e18, // quote token amount is diminished in arbed bucket + exchangeRate: 1.000001444670408504 * 1e18 }); _assertAuction( AuctionParams({ From 877f9ce9837213eec8f2f4b0eb7404331c4e8368 Mon Sep 17 00:00:00 2001 From: mwc Date: Sat, 2 Dec 2023 14:35:06 -0500 Subject: [PATCH 05/16] fixed tests in ERC20PoolLiquidationsDepositTake.sol --- .../ERC20PoolLiquidationsDepositTake.t.sol | 151 +++++++++--------- 1 file changed, 75 insertions(+), 76 deletions(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol index bade0615a..41fbe5c92 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol @@ -196,6 +196,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeCollateralRestrict() external tearDown { + // add liquidity to accrue interest and update reserves before deposit take + _addLiquidityWithPenalty({ + from: _lender1, + amount: 1 * 1e18, + amountAdded: 0.999958904109589041 * 1e18, + index: _i9_52, + lpAward: 0.999958904109589041 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); skip(6.5 hours); _assertLenderLpBalance({ @@ -225,26 +234,16 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrowerCollateralization: 0.972908310697913772 * 1e18 }); - // add liquidity to accrue interest and update reserves before deposit take - _addLiquidityWithPenalty({ - from: _lender1, - amount: 1 * 1e18, - amountAdded: 0.999958904109589041 * 1e18, - index: _i9_52, - lpAward: 0.999955671743685258 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBucket({ index: _i9_62, lpBalance: 24_998.858447488584475 * 1e18, collateral: 0, - deposit: 24_998.939256528387459955 * 1e18, - exchangeRate: 1.000003232509195279 * 1e18 + deposit: 24_998.858447488584475000 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); _assertReserveAuction({ - reserves: 52.904513396067336836 * 1e18, - claimableReserves : 52.904440161068925017 * 1e18, + reserves: 52.864592144847100955 * 1e18, + claimableReserves : 52.864518910085417944 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -261,7 +260,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { referencePrice: 10.681503928998397483 * 1e18, totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 8.982038363413219840 * 1e18, - debtInAuction: 19.215376757379175783 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, thresholdPrice: 9.607688378689587891 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) @@ -285,7 +284,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { bondChange: 0.211722980967374082 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 0.211722296573103563 * 1e18 + lpAwardKicker: 0.211722296582448360 * 1e18 }); _assertLenderLpBalance({ @@ -297,20 +296,20 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i9_62, - lpBalance: 24_999.070169785157578563 * 1e18, + lpBalance: 24_999.070169785166923360 * 1e18, depositTime: _startTime + 250 days + 6.5 hours }); _assertBucket({ index: _i9_62, - lpBalance: 24_999.070169785157578563 * 1e18, + lpBalance: 24_999.070169785166923360 * 1e18, collateral: 2 * 1e18, - deposit: 24_979.901365163112355364 * 1e18, - exchangeRate: 1.000003232509195280 * 1e18 + deposit: 24_979.901364059733090280 * 1e18, + exchangeRate: 1.000003232465058094 * 1e18 }); // reserves should remain the same after deposit take _assertReserveAuction({ - reserves: 52.908881208725952697 * 1e18, - claimableReserves : 52.908807992765432244 * 1e18, + reserves: 52.908881208725898329 * 1e18, + claimableReserves : 52.908807992765377876 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -348,6 +347,14 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeDebtRestrict() external tearDown { + _addLiquidity({ + from: _lender, + amount: 25_000 * 1e18, + index: _i1505_26, + lpAward: 24_998.972602739726025 * 1e18, + newLup: 1_505.263728469068226832 * 1e18 + }); + skip(5 hours); _assertAuction( @@ -367,14 +374,6 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { }) ); - _addLiquidity({ - from: _lender, - amount: 25_000 * 1e18, - index: _i1505_26, - lpAward: 24_998.972602739726025 * 1e18, - newLup: 1_505.263728469068226832 * 1e18 - }); - _assertBorrower({ borrower: _borrower, borrowerDebt: 19.215228694258857699 * 1e18, @@ -421,18 +420,18 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { lender: _lender, index: _i1505_26, lpBalance: 24_998.972602739726025 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 5 hours }); _assertBucket({ index: _i1505_26, lpBalance: 24_998.972602739726025 * 1e18, collateral: 0.012983089918332295 * 1e18, - deposit: 24_979.429628402207984119 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + deposit: 24_979.475970107797282691 * 1e18, + exchangeRate: 1.000001853744404849 * 1e18 }); _assertReserveAuction({ - reserves: 54.465229758885057797 * 1e18, - claimableReserves : 54.465131545511606907 * 1e18, + reserves: 54.465229758885093211 * 1e18, + claimableReserves : 54.465131545511642321 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -440,6 +439,14 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeDepositRestrict() external tearDown { + _addLiquidity({ + from: _lender, + amount: 15.0 * 1e18, + index: _i1505_26, + lpAward: 14.999383561643835615 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + skip(5 hours); _assertAuction( @@ -459,14 +466,6 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 14.999383561643835615 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBorrower({ borrower: _borrower, borrowerDebt: 19.215228694258857699 * 1e18, @@ -481,9 +480,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.009964621665931584 * 1e18, - quoteTokenAmount: 14.999383561643834141 * 1e18, - bondChange: 0.167698206322142595 * 1e18, + collateralArbed: 0.009964646438247887 * 1e18, + quoteTokenAmount: 14.999420850513035210 * 1e18, + bondChange: 0.167698623224374283 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -494,30 +493,30 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.047129063601117189 * 1e18, + bondSize: 0.047128646698885501 * 1e18, bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, referencePrice: 10.681503928998397483 * 1e18, - totalBondEscrowed: 0.047129063601117189 * 1e18, + totalBondEscrowed: 0.047128646698885501 * 1e18, auctionPrice: 15.105927722931035016 * 1e18, - debtInAuction: 4.467392442098237450 * 1e18, - thresholdPrice: 2.244880915553398588 * 1e18, + debtInAuction: 4.467355778582383914 * 1e18, + thresholdPrice: 2.244862519948070314 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); _assertBucket({ index: _i1505_26, lpBalance: 14.999383561643835615 * 1e18, - collateral: 0.009964621665931584 * 1e18, - deposit: 0.000000000000001475 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + collateral: 0.009964646438247887 * 1e18, + deposit: 0.000000000000000931 * 1e18, + exchangeRate: 1.000002486026778853 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4.467392442098237450 * 1e18, - borrowerCollateral: 1.990035378334068416 * 1e18, - borrowert0Np: 2.411776458905825073 * 1e18, - borrowerCollateralization: 4.163873373175602662 * 1e18 + borrowerDebt: 4.467355778582383914 * 1e18, + borrowerCollateral: 1.990035353561752113 * 1e18, + borrowert0Np: 2.411756695680270137 * 1e18, + borrowerCollateralization: 4.163907494183249766 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -529,35 +528,35 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { lender: _lender, index: _i1505_26, lpBalance: 14.999383561643835615 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 5 hours }); } function testDepositTakeGTNeutralPrice() external tearDown { - skip(3 hours); - _addLiquidity({ from: _lender, amount: 1_000 * 1e18, - index: _i10016, + index: _i100_33, lpAward: 999.958904109589041 * 1e18, newLup: 9.721295865031779605 * 1e18 }); + skip(3 hours); + _assertLenderLpBalance({ lender: _taker, - index: _i10016, + index: _i100_33, lpBalance: 0, depositTime: 0 }); _assertLenderLpBalance({ lender: _lender, - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 3 hours }); _assertBucket({ - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, collateral: 0, deposit: 999.958904109589041 * 1e18, @@ -574,7 +573,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { referencePrice: 10.681503928998397483 * 1e18, totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 30.211855445862070036 * 1e18, - debtInAuction: 19.215031278539821082 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, thresholdPrice: 9.607515639269910541 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) @@ -591,8 +590,8 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { from: _taker, borrower: _borrower, kicker: _lender, - index: _i10016, - collateralArbed: 0.001951057800006470 * 1e18, + index: _i100_33, + collateralArbed: 0.194780347720468645 * 1e18, quoteTokenAmount: 19.542773554566540925 * 1e18, bondChange: 0.214827269923259784 * 1e18, isReward: false, @@ -603,15 +602,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { // deposit taker wasn't rewarded any LPBs in arbed bucket _assertLenderLpBalance({ lender: _taker, - index: _i10016, + index: _i100_33, lpBalance: 0, depositTime: 0 }); _assertLenderLpBalance({ lender: _lender, - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, - depositTime: _startTime + 250 days + 3 hours + depositTime: _startTime + 250 days }); _assertKicker({ kicker: _lender, @@ -619,11 +618,11 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { locked: 0 // kicker was penalized }); _assertBucket({ - index: _i10016, + index: _i100_33, lpBalance: 999.958904109589041 * 1e18, // LP balance in arbed bucket is same - collateral: 0.001951057800006470 * 1e18, // arbed collateral added to the arbed bucket - deposit: 980.416130555022495399 * 1e18, // quote token amount is diminished in arbed bucket - exchangeRate: 1.000000000000000000 * 1e18 + collateral: 0.194780347720468645 * 1e18, // arbed collateral added to the arbed bucket + deposit: 980.417602311748656535 * 1e18, // quote token amount is diminished in arbed bucket + exchangeRate: 1.000001471817211796 * 1e18 }); _assertAuction( AuctionParams({ @@ -644,7 +643,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.998048942199993530 * 1e18, + borrowerCollateral: 1.805219652279531355 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); From 723d4bbff3320b9e29eecb8e397b9cf9fef233d4 Mon Sep 17 00:00:00 2001 From: mwc Date: Sat, 2 Dec 2023 16:37:14 -0500 Subject: [PATCH 06/16] fixed two more --- .../ERC20Pool/ERC20PoolLiquidationsKick.t.sol | 8 ++-- .../ERC20PoolLiquidationsSettle.t.sol | 46 +++++++++---------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol index 5163e3171..501d58fe4 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol @@ -485,19 +485,17 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { // force pool interest accumulation skip(14 hours); - _addLiquidity({ + _addCollateralWithoutCheckingLP({ from: _lender1, amount: 1 * 1e18, - index: _i9_91, - lpAward: 0.993924947593286866 * 1e18, - newLup: 9.721295865031779605 * 1e18 + index: _i9_91 }); _assertPool( PoolParams({ htp: 0, lup: 9.721295865031779605 * 1e18, - poolSize: 73_107.387163902795349310 * 1e18, + poolSize: 73_106.387204998685760269 * 1e18, pledgedCollateral: 1_002 * 1e18, encumberedCollateral: 1_009.547930285248351849 * 1e18, poolDebt: 9_436.648192532092411327 * 1e18, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 5395e8d13..2fcbbd7a5 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -665,6 +665,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2 }); + _addLiquidityWithPenalty({ + from: _lender1, + amount: 100 * 1e18, + amountAdded: 99.995890410958904100 * 1e18, + index: _i9_52, + lpAward: 99.995890410958904100 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + + _addLiquidity({ + from: _lender1, + amount: 100 * 1e18, + index: _i9_91, + lpAward: 99.393308837291078044 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + // skip ahead so take can be called on the loan skip(12.5 hours); @@ -692,23 +709,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowerCollateralization: 0.992540709768608251 * 1e18 }); - _addLiquidityWithPenalty({ - from: _lender1, - amount: 100 * 1e18, - amountAdded: 99.995890410958904100 * 1e18, - index: _i9_52, - lpAward: 99.995890410958904100 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - _addLiquidity({ - from: _lender1, - amount: 100 * 1e18, - index: _i9_91, - lpAward: 99.390782962995294778 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - // take entire collateral _take({ from: _lender, @@ -748,8 +748,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.390782962995294778 * 1e18, - depositTime: _startTime + 100 days + 12.5 hours + lpBalance: 99.393308837291078044 * 1e18, + depositTime: _startTime + 100 days }); // settle to make buckets insolvent @@ -767,7 +767,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // LP forfeited when forgive bad debt should be reflected in BucketBankruptcy event vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_91, 2_099.299458762082052778 * 1e18); + emit BucketBankruptcy(_i9_91, 2_099.301984636377836044 * 1e18); vm.expectEmit(true, true, false, true); emit BucketBankruptcy(_i9_81, 4_999.771689497716895000 * 1e18); _settle({ @@ -796,7 +796,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lender: _lender1, index: _i9_91, lpBalance: 0, - depositTime: _startTime + 100 days + 12.5 hours + depositTime: _startTime + 100 days }); // cannot add liquidity in same block when bucket marked insolvent @@ -885,8 +885,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { index: _i9_72, lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0 * 1e18, - deposit: 9_883.914103612419284122 * 1e18, - exchangeRate: 0.898578676772754183 * 1e18 + deposit: 9_883.913692653515172210 * 1e18, + exchangeRate: 0.898578639411147800 * 1e18 }); _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max); From 70f3b07e66dc15a4ec1353336fe3c30a1f9e9d17 Mon Sep 17 00:00:00 2001 From: Ed Noepel Date: Sat, 2 Dec 2023 22:50:03 -0500 Subject: [PATCH 07/16] updated testDepositTakeAndSettleSubsetPool --- .../ERC721PoolLiquidationsSettleAuction.t.sol | 71 ++++++++++--------- 1 file changed, 38 insertions(+), 33 deletions(-) diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 8274ef1ee..fdd888ea3 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -364,7 +364,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertCollateralInvariants(); } - function testDepositTakeAndSettleSubsetPool() external { + function testDepositTakeAndSettleSubsetPool() external tearDown { // the 2 token ids are owned by borrower before settle assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); @@ -384,12 +384,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerCollateralization: 0.727274117376371889 * 1e18 }); - skip(32 hours); _addLiquidityNoEventCheck({ from: _lender, amount: 3_000 * 1e18, index: 2502 }); + skip(32 hours); _depositTake({ from: _lender, @@ -399,17 +399,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_847.910224217955230860 * 1e18, - collateral: 1.671805256817908593 * 1e18, - deposit: 0.000000000000003183 * 1e18, - exchangeRate: 1.661984238498668786 * 1e18 + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001434 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 3_743.004715171921060836 * 1e18, - borrowerCollateral: 0.328194743182091407 * 1e18, - borrowert0Np: 6_304.030158815967856681 * 1e18, - borrowerCollateralization: 0.324123197070597148 * 1e18 + borrowerDebt: 3_742.625741320959738707 * 1e18, + borrowerCollateral: 0.328094552805976837 * 1e18, + borrowert0Np: 6_305.316754335551965243 * 1e18, + borrowerCollateralization: 0.324057059956572295 * 1e18 }); _assertCollateralInvariants(); @@ -421,21 +421,21 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 2, - settledDebt: 1_860.895155634793071933 * 1e18 + settledDebt: 1_860.706742673273787750 * 1e18 }); _assertBucket({ index: 2500, lpBalance: 7_999.634703196347032000 * 1e18, - collateral: 0.328194743182091407 * 1e18, - deposit: 9_559.656155403043853802 * 1e18, - exchangeRate: 1.353522705781987493 * 1e18 + collateral: 0.328094552805976837 * 1e18, + deposit: 9_559.438514946326345866 * 1e18, + exchangeRate: 1.353447109649970440 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 3_847.910224217955230860 * 1e18, - collateral: 1.671805256817908593 * 1e18, - deposit: 0.000000000000003184 * 1e18, - exchangeRate: 1.661984238498668786 * 1e18 + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001435 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -462,34 +462,39 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, lpBalance: 7_999.634703196347032000 * 1e18, - collateral: 2.802447158831185990 * 1e18, + collateral: 2.802290638246429771 * 1e18, deposit: 0, - exchangeRate: 1.353522705781987493 * 1e18 + exchangeRate: 1.353447109649970440 * 1e18 }); - _assertBucket({ index: 2501, lpBalance: 1_999.908675799086758000 * 1e18, - collateral: 0.133198384953772019 * 1e18, - deposit: 2_812.853805161609579345 * 1e18, - exchangeRate: 1.662538898172472227 * 1e18 + collateral: 0.133123410882128970 * 1e18, + deposit: 2_812.945878591575294584 * 1e18, + exchangeRate: 1.662440814040839337 * 1e18 }); - _assertBucket({ index: 2502, - lpBalance: 3_847.910224217955230860 * 1e18, - collateral: 1.671805256817908593 * 1e18, - deposit: 0.000000000000003184 * 1e18, - exchangeRate: 1.661984238498668786 * 1e18 + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001435 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 + }); + _assertBucket({ + index: 7388, + lpBalance: 0.000000039203761851 * 1e18, + collateral: 0.392680503677418096 * 1e18, + deposit: 0, + exchangeRate: 0.999999999987919485 * 1e18 }); _assertCollateralInvariants(); // collateral in buckets: - // 2500 - 2.802447158831185990 - // 2501 - 0.133198384953772019 - // 2502 - 1.671805256817908593 - // 7388 - 0.392549199397133398 + // 2500 - 2.802290638246429771 + // 2501 - 0.133123410882128970 + // 2502 - 1.671905447194023163 + // 7388 - 0.392680503677418096 // lender deposits quote token into 7388 to merge from that bucket _addLiquidityNoEventCheck({ From 54a8a1aa1b58fa2968c74d0c4449948dfdbfdfba Mon Sep 17 00:00:00 2001 From: Ed Noepel Date: Sun, 3 Dec 2023 00:54:49 -0500 Subject: [PATCH 08/16] updated testKickAndSettleSubsetPoolFractionalCollateral --- .../forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol index 4c6921b9b..c5f850de2 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol @@ -179,7 +179,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { } function testKickAndSettleSubsetPoolFractionalCollateral() external tearDown { - // settle borrower 2 + // settle borrower 2, whose neutral price has been carried from borrower 1 _assertAuction( AuctionParams({ borrower: _borrower2, @@ -188,7 +188,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { bondSize: 55.955451071569254199 * 1e18, bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 1_854.787401007794957336 * 1e18, + referencePrice: 2_782.181101511692436004 * 1e18, totalBondEscrowed: 111.910902143138508398 * 1e18, auctionPrice: 0, debtInAuction: 10_009.615384615384620000 * 1e18, From bfebe3cd0d57bc9ff56bab4d6e8643f9f1ffb178 Mon Sep 17 00:00:00 2001 From: Ed Noepel Date: Sun, 3 Dec 2023 01:28:40 -0500 Subject: [PATCH 09/16] updated testSettleWithDepositFuzzy --- .../ERC20Pool/ERC20PoolLiquidationsSettle.t.sol | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 2fcbbd7a5..d5a45911e 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -1235,10 +1235,21 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { }); } - function testSettleWithDepositFuzzy(uint256 quoteAmount, uint256 bucketIndex) external { + function testSettleWithDepositFuzzy(uint256 quoteAmount, uint256 bucketIndex, uint256 wait) external { quoteAmount = bound(quoteAmount, 1 * 1e18, 500_000 * 1e18); bucketIndex = bound(bucketIndex, 1, 7388); + wait = bound(wait, 0, 3600 * 6); // 0-6 hours + // decrease the auction price + skip(wait); + + // prevent trying to deposit into a bucket priced higher than the auction price + (,,,, uint256 auctionPrice, ) = _poolUtils.auctionStatus(address(_pool), _borrower); + if (_priceAt(bucketIndex) > auctionPrice ) { + if (auctionPrice > MIN_PRICE) bucketIndex = _indexOf(auctionPrice) + 1; + else bucketIndex = 7388; + } + // add some deposits to be used to settle auction _addLiquidityNoEventCheck({ from: _lender, From cd12a567dfe86727c844ed435acce22442e50fa7 Mon Sep 17 00:00:00 2001 From: mwc Date: Sun, 3 Dec 2023 07:48:45 -0500 Subject: [PATCH 10/16] Fixed final tests --- .../ERC20PoolLiquidationsSettle.t.sol | 29 ++++++----- .../ERC721PoolLiquidationsDepositTake.t.sol | 48 +++++++++---------- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index d5a45911e..8394ad073 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -952,6 +952,14 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowerCollateralization: 0.992604445165255887 * 1e18 }); + _addLiquidity({ + from: _lender1, + amount: 100 * 1e18, + index: _i9_91, + lpAward: 99.393308837291078044 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + // skip ahead so take can be called on the loan skip(10 hours); @@ -979,15 +987,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowerCollateralization: 0.992553456520532021 * 1e18 }); - // add liquidity in same block should be possible as debt was not yet settled / bucket is not yet insolvent - _addLiquidity({ - from: _lender1, - amount: 100 * 1e18, - index: _i9_91, - lpAward: 99.390961362762982840 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - // take entire collateral _take({ from: _lender, @@ -1002,8 +1001,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.390961362762982840 * 1e18, - depositTime: _startTime + 100 days + 10 hours + lpBalance: 99.393308837291078044 * 1e18, + depositTime: _startTime + 100 days }); _assertBorrower({ @@ -1016,15 +1015,15 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertBucket({ index: _i9_91, - lpBalance: 2_099.299637161849740840 * 1e18, + lpBalance: 2_099.301984636377836044 * 1e18, collateral: 0, - deposit: 2_112.076727894993020025 * 1e18, - exchangeRate: 1.006086358758398721 * 1e18 + deposit: 2_112.078815709953620479 * 1e18, + exchangeRate: 1.006086228264005035 * 1e18 }); // LP forfeited when forgive bad debt should be reflected in BucketBankruptcy event vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_91, 2_099.299637161849740840 * 1e18); + emit BucketBankruptcy(_i9_91, 2_099.301984636377836044 * 1e18); _settle({ from: _lender, borrower: _borrower2, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol index b10bdf70e..dfc744022 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol @@ -191,6 +191,14 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { } function testDepositTakeNFTAndSettleAuction() external { + _addLiquidity({ + from: _lender, + amount: 15.0 * 1e18, + index: _i1505_26, + lpAward: 14.999383561643835615 * 1e18, + newLup: 9.917184843435912074 * 1e18 + }); + skip(6 hours); _assertAuction( @@ -210,14 +218,6 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 14.999383561643835615 * 1e18, - newLup: 9.917184843435912074 * 1e18 - }); - _assertBorrower({ borrower: _borrower, borrowerDebt: 21.811059963842150618 * 1e18, @@ -235,9 +235,9 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.009964621665931584 * 1e18, - quoteTokenAmount: 14.999383561643834141 * 1e18, - bondChange: 0.167698206322142595 * 1e18, + collateralArbed: 0.009964621805481374 * 1e18, + quoteTokenAmount: 14.999383771703071343 * 1e18, + bondChange: 0.167698208670676263 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -248,14 +248,14 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.076149341415331433 * 1e18, + bondSize: 0.076149339066797765 * 1e18, bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6 hours, referencePrice: 12.124431596439710011 * 1e18, - totalBondEscrowed: 0.076149341415331433 * 1e18, + totalBondEscrowed: 0.076149339066797765 * 1e18, auctionPrice: 12.124431596439710012 * 1e18, - debtInAuction: 7.063223711681530369 * 1e18, - thresholdPrice: 3.549295549506468536 * 1e18, + debtInAuction: 7.063223505145093670 * 1e18, + thresholdPrice: 3.549295445970051290 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -269,16 +269,16 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertBucket({ index: _i1505_26, lpBalance: 14.999383561643835615 * 1e18, - collateral: 0.009964621665931584 * 1e18, - deposit: 0.000000000000001475 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + collateral: 0.009964621805481374 * 1e18, + deposit: 0.000000000000000301 * 1e18, + exchangeRate: 1.000000014004524598 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7.063223711681530369 * 1e18, - borrowerCollateral: 1.990035378334068416 * 1e18, - borrowert0Np: 3.440839231836435256 * 1e18, - borrowerCollateralization: 2.686661204777907913 * 1e18 + borrowerDebt: 7.063223505145093670 * 1e18, + borrowerCollateral: 1.990035378194518626 * 1e18, + borrowert0Np: 3.440839131463794709 * 1e18, + borrowerCollateralization: 2.686661283150441203 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -290,7 +290,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { lender: _lender, index: _i1505_26, lpBalance: 14.999383561643835615 * 1e18, - depositTime: block.timestamp + depositTime: block.timestamp - 6 hours }); // borrower cannot repay amidst auction @@ -305,7 +305,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 6.158815317027324956 * 1e18 + settledDebt: 6.158815136936785311 * 1e18 }); _assertBorrower({ borrower: _borrower, From 2b3b9301dcc0c2e3ba2edfaf9753bfb88af9185c Mon Sep 17 00:00:00 2001 From: Ed Noepel Date: Sun, 3 Dec 2023 11:29:04 -0500 Subject: [PATCH 11/16] add "AddAboveAuctionPrice" as expected pool error --- tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index da364d569..565e433ec 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -319,7 +319,8 @@ abstract contract BaseHandler is Test { err == keccak256(abi.encodeWithSignature("ReserveAuctionTooSoon()")) || err == keccak256(abi.encodeWithSignature("NoReserves()")) || err == keccak256(abi.encodeWithSignature("ZeroThresholdPrice()")) || - err == keccak256(abi.encodeWithSignature("NoReservesAuction()")), + err == keccak256(abi.encodeWithSignature("NoReservesAuction()")) || + err == keccak256(abi.encodeWithSignature("AddAboveAuctionPrice()")), "Unexpected revert error" ); } From d632f2cb5dbaeb3becf97442c0199115a61164ca Mon Sep 17 00:00:00 2001 From: Ed Noepel Date: Sun, 3 Dec 2023 12:01:35 -0500 Subject: [PATCH 12/16] implemented invariant A9: reference prices in liquidation queue shall not decrease --- tests/INVARIANTS.md | 1 + .../forge/invariants/base/LiquidationInvariants.t.sol | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/tests/INVARIANTS.md b/tests/INVARIANTS.md index 8977ee799..92b27c350 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -25,6 +25,7 @@ - **A5**: for each `Liquidation` recorded in liquidation mapping (`AuctionsState.liquidations`) the kicker address (`Liquidation.kicker`) has a locked balance (`Kicker.locked`) equal or greater than liquidation bond size (`Liquidation.bondSize`) - **A7**: total bond escrowed accumulator (`AuctionsState.totalBondEscrowed`) should increase when auction is kicked with the difference needed to cover the bond and should decrease only when kicker bonds withdrawn (`Pool.withdrawBonds`). Claimable bonds should be available for withdrawal from pool at any time. - **A8**: Upon a take/arbtake/deposittake the kicker reward <= borrower penalty +- **A9**: reference prices in liquidation queue shall not decrease ## Loans - **L1**: for each `Loan` in loans array (`LoansState.loans`) starting from index 1, the corresponding address (`Loan.borrower`) is not `0x`, the threshold price (`Loan.thresholdPrice`) is different than 0 and the id mapped in indices mapping (`LoansState.indices`) equals index of loan in loans array. diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index addeba832..f569b8865 100644 --- a/tests/forge/invariants/base/LiquidationInvariants.t.sol +++ b/tests/forge/invariants/base/LiquidationInvariants.t.sol @@ -21,6 +21,7 @@ abstract contract LiquidationInvariants is BasicInvariants { _invariant_A5(); _invariant_A7(); _invariant_A8(); + // _invariant_A9(); // TODO: uncomment once other invariant issues are sorted } /// @dev checks sum of all borrower's t0debt is equals to total pool t0debtInAuction @@ -140,6 +141,16 @@ abstract contract LiquidationInvariants is BasicInvariants { require(kickerReward <= borrowerPenalty, "Auction Invariant A8"); } + + /// @dev reference prices in liquidation queue shall not decrease + function _invariant_A9() internal view { + (,,,, uint256 lastReferencePrice,,, address nextBorrower,,) = _pool.auctionInfo(address(0)); + while (nextBorrower != address(0)) { + (,,,, uint256 referencePrice,,,,,) = _pool.auctionInfo(nextBorrower); + require(lastReferencePrice <= referencePrice, "Auction Invariant A9"); + lastReferencePrice = referencePrice; + } + } function invariant_call_summary() public virtual override useCurrentTimestamp { console.log("\nCall Summary\n"); From a62d5c5eaf9f313d99cb10ea0986abb0ffeaf16f Mon Sep 17 00:00:00 2001 From: Mike Hathaway Date: Sun, 3 Dec 2023 18:08:41 -0500 Subject: [PATCH 13/16] Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike --- .../ERC20PoolDebtExceedsDeposit.t.sol | 4 +- .../ERC20PoolLiquidationsArbTake.t.sol | 16 +++--- .../ERC20PoolLiquidationsDepositTake.t.sol | 16 +++--- .../ERC20Pool/ERC20PoolLiquidationsKick.t.sol | 6 +- .../ERC20PoolLiquidationsLenderKick.t.sol | 10 ++-- .../ERC20Pool/ERC20PoolLiquidationsMisc.t.sol | 6 +- .../ERC20PoolLiquidationsSettle.t.sol | 14 ++--- .../ERC20Pool/ERC20PoolLiquidationsTake.t.sol | 56 +++++++++---------- .../ERC721Pool/ERC721PoolCollateral.t.sol | 6 +- .../ERC721PoolLiquidationsDepositTake.t.sol | 4 +- .../ERC721PoolLiquidationsKick.t.sol | 4 +- .../ERC721PoolLiquidationsSettle.t.sol | 2 +- .../ERC721PoolLiquidationsTake.t.sol | 18 +++--- tests/forge/utils/DSTestPlus.sol | 2 - 14 files changed, 81 insertions(+), 83 deletions(-) diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol index 75e855488..49239228b 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol @@ -178,7 +178,7 @@ contract ERC20PoolDebtExceedsDepositTest is ERC20HelperContract { totalBondEscrowed: 1.104560604152777078 * 1e18, auctionPrice: 52.807937446000777584 * 1e18, debtInAuction: 98.794903846153846199 * 1e18, - thresholdPrice: 94.999437626898539235 * 1e18, + thresholdPrice: 94.995099852071005961 * 1e18, neutralPrice: 105.615874892001555166 * 1e18 }) ); @@ -363,7 +363,7 @@ contract ERC20PoolDebtExceedsDepositTest is ERC20HelperContract { totalBondEscrowed: 11_179.675302295250711919 * 1e18, auctionPrice: 50.449052405478872444 * 1e18, debtInAuction: 999_940.55769230769276876 * 1e18, - thresholdPrice: 96.152612442506987001 * 1e18, + thresholdPrice: 96.148130547337278151 * 1e18, neutralPrice: 106.897818338005788835 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol index a057581d9..1378e8cfe 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol @@ -150,7 +150,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.411970298080049512 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -261,7 +261,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 8.799359199504876220 * 1e18, debtInAuction: 18.823940596160099025 * 1e18, - thresholdPrice: 9.412284572883088612 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -333,7 +333,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 8.799359199504876220 * 1e18, debtInAuction: 1.446226944275346019 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -369,7 +369,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 14.798699214786891216 * 1e18, debtInAuction: 18.823940596160099025 * 1e18, - thresholdPrice: 9.412212046997139091 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -454,7 +454,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 14.798699214786891216 * 1e18, debtInAuction: 18.823940596160099025 * 1e18, - thresholdPrice: 9.412212046997139091 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -493,7 +493,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.042759438341664008 * 1e18, auctionPrice: 14.798699214786891216 * 1e18, debtInAuction: 4.076551853619286508 * 1e18, - thresholdPrice: 4.132604091910177040 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -567,7 +567,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 29.597398429573782432 * 1e18, debtInAuction: 18.823940596160099025 * 1e18, - thresholdPrice: 9.412115346685186095 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); @@ -670,7 +670,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.210458053887159482 * 1e18, auctionPrice: 35.197436798019505000 * 1e18, debtInAuction: 18.823940596160099025 * 1e18, - thresholdPrice: 9.412091171762431245 * 1e18, + thresholdPrice: 9.411970298080049512 * 1e18, neutralPrice: 10.464260567515846957 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol index 41fbe5c92..ea90a3066 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol @@ -151,7 +151,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.607367579382098527 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -261,7 +261,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 8.982038363413219840 * 1e18, debtInAuction: 19.214735158764197054 * 1e18, - thresholdPrice: 9.607688378689587891 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -326,7 +326,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 8.982038363413219840 * 1e18, debtInAuction: 0.181853204762687052 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -369,7 +369,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 15.105927722931035016 * 1e18, debtInAuction: 19.214735158764197054 * 1e18, - thresholdPrice: 9.607614347129428849 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -461,7 +461,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 15.105927722931035016 * 1e18, debtInAuction: 19.214735158764197054 * 1e18, - thresholdPrice: 9.607614347129428849 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -500,7 +500,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.047128646698885501 * 1e18, auctionPrice: 15.105927722931035016 * 1e18, debtInAuction: 4.467355778582383914 * 1e18, - thresholdPrice: 2.244862519948070314 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -574,7 +574,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 30.211855445862070036 * 1e18, debtInAuction: 19.214735158764197054 * 1e18, - thresholdPrice: 9.607515639269910541 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); @@ -671,7 +671,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.214827269923259784 * 1e18, auctionPrice: 35.928153453652879488 * 1e18, debtInAuction: 19.214735158764197054 * 1e18, - thresholdPrice: 9.607490962463487100 * 1e18, + thresholdPrice: 9.607367579382098527 * 1e18, neutralPrice: 10.681503928998397483 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol index 36824c6c6..099255981 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol @@ -149,7 +149,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.462708682436276194 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -286,7 +286,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.462708682436276194 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -353,7 +353,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.462708682436276194 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol index 3495f38d6..d5b1425eb 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol @@ -895,7 +895,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 100_096.153846153846200000 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, neutralPrice: 22.257448812093539488 * 1e18 }) ); @@ -958,7 +958,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 80_113.496231380830061171 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, neutralPrice: 22.257448812093539488 * 1e18 }) ); @@ -1021,7 +1021,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 60_085.122173535622545879 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, neutralPrice: 22.257448812093539488 * 1e18 }) ); @@ -1084,7 +1084,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 40_056.748115690415030586 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, neutralPrice: 22.257448812093539488 * 1e18 }) ); @@ -1147,7 +1147,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 20_028.374057845207515293 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, neutralPrice: 22.257448812093539488 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index 229e48e45..6cd8250d5 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -185,7 +185,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.354500183821244069 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -277,7 +277,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { totalBondEscrowed: 0.209172983065585793 * 1e18, auctionPrice: 29.416674753697119864 * 1e18, debtInAuction: 18.709000367642488138 * 1e18, - thresholdPrice: 9.354629930357136532 * 1e18, + thresholdPrice: 9.354500183821244069 * 1e18, neutralPrice: 10.400365099149173069 * 1e18 }) ); @@ -478,7 +478,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { totalBondEscrowed: 90.564949726435836850 * 1e18, auctionPrice: 2.251506213987704828 * 1e18, debtInAuction: 8_100.375358686460903420 * 1e18, - thresholdPrice: 8.100712418988636152 * 1e18, + thresholdPrice: 8.100375358686460903 * 1e18, neutralPrice: 9.006024855950819304 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 87cbfd87c..7eb089ac9 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -154,7 +154,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.417044136515672180 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -242,7 +242,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 2.617475419583478700 * 1e18, debtInAuction: 9_417.044136515672180411 * 1e18, - thresholdPrice: 9.417527901208315548 * 1e18, + thresholdPrice: 9.417044136515672180 * 1e18, neutralPrice: 10.469901678333914800 * 1e18 }) ); @@ -277,7 +277,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 128.697166052318027786 * 1e18, auctionPrice: 2.617475419583478700 * 1e18, debtInAuction: 7_346.958977412026357603 * 1e18, - thresholdPrice: 36.734794887060131788 * 1e18, + thresholdPrice: 9.417044136515672180 * 1e18, neutralPrice: 10.469901678333914800 * 1e18 }) ); @@ -436,7 +436,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.417044136515672180 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -525,7 +525,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 0, debtInAuction: 9_417.044136515672180411 * 1e18, - thresholdPrice: 9.420576190285556153 * 1e18, + thresholdPrice: 9.417044136515672180 * 1e18, neutralPrice: 10.469901678333914800 * 1e18 }) ); @@ -697,7 +697,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 1.100512848671229788 * 1e18, debtInAuction: 9_417.044136515672180411 * 1e18, - thresholdPrice: 9.417648846264483444 * 1e18, + thresholdPrice: 9.417044136515672180 * 1e18, neutralPrice: 10.469901678333914800 * 1e18 }) ); @@ -975,7 +975,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 2.617475419583478700 * 1e18, debtInAuction: 9_417.044136515672180411 * 1e18, - thresholdPrice: 9.417527901208315548 * 1e18, + thresholdPrice: 9.417044136515672180 * 1e18, neutralPrice: 10.469901678333914800 * 1e18 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol index 3ae5df670..0ea6054ac 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol @@ -220,7 +220,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.445145395543736188 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -292,7 +292,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 0.910478544213022852 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445778866890769300 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -328,7 +328,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 120.410571209345555877 * 1e18, auctionPrice: 0.910478544213022852 * 1e18, debtInAuction: 8_887.298973552816214298 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -447,7 +447,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.445145395543736188 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -519,7 +519,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 1.338161720906753532 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445724952781695045 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -555,7 +555,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.973544270027428771 * 1e18, auctionPrice: 1.338161720906753532 * 1e18, debtInAuction: 9_810.321944712537091675 * 1e18, - thresholdPrice: 9.524584412342269021 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -654,7 +654,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.445145395543736188 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -726,7 +726,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 10.104451796622513460 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445441908757677743 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -762,7 +762,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 134.310867307749930784 * 1e18, auctionPrice: 10.104451796622513460 * 1e18, debtInAuction: 4_068.349646880456528628 * 1e18, - thresholdPrice: 8.786932282679171768 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -832,7 +832,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 2_688.293056930299609088 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445145395543736188 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -887,7 +887,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 168.018316058143725568 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445210088541969099 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -940,7 +940,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 91.038914432832955568 * 1e18, auctionPrice: 168.018316058143725568 * 1e18, debtInAuction: 8_171.012859715039647158 * 1e18, - thresholdPrice: 7.933022193898096744 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -1040,7 +1040,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.445145395543736188 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -1112,7 +1112,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 109.823933241385648657 * 1e18, auctionPrice: 10.104451796622513460 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.445441908757677743 * 1e18, + thresholdPrice: 9.445145395543736189 * 1e18, neutralPrice: 10.501144753633982848 * 1e18 }) ); @@ -1203,7 +1203,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 2_696.624543676984421888 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474417540364636197 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1243,7 +1243,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 4.692225291538286796 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474823131988554412 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1277,7 +1277,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 164.723397202494316334 * 1e18, auctionPrice: 4.692225291538286796 * 1e18, debtInAuction: 5_028.460854599919885110 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1311,7 +1311,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 2.633422405934555100 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474904252396877483 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1347,7 +1347,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.753147822166823996 * 1e18, auctionPrice: 2.633422405934555100 * 1e18, debtInAuction: 9_801.820825525375552153 * 1e18, - thresholdPrice: 9.609628260318995639 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1395,7 +1395,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 140.784556539184447790 * 1e18, auctionPrice: 2.633422405934555100 * 1e18, debtInAuction: 7_145.761380189146974214 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1585,7 +1585,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 140.784556539184447790 * 1e18, auctionPrice: 2.633422405934555100 * 1e18, debtInAuction: 5_128.384191287040906072 * 1e18, - thresholdPrice: 0, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1687,7 +1687,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 2_696.624543676984421888 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474417540364636197 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1726,7 +1726,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 0, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.759881630669866664 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -1759,7 +1759,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.382534258638046113 * 1e18, auctionPrice: 2_777.873809816661136640 * 1e18, debtInAuction: 9_995.146145767066608231 * 1e18, - thresholdPrice: 9.759881630669866664 * 1e18, + thresholdPrice: 9.759881630669866665 * 1e18, neutralPrice: 10.851069569596332565 * 1e18 }) ); @@ -1824,7 +1824,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 2_696.624543676984421888 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474417540364636197 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1855,7 +1855,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 10.533689623738220400 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474709564583696187 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -1874,7 +1874,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 7.448443363859667932 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.474758236161951413 * 1e18, + thresholdPrice: 9.474417540364636198 * 1e18, neutralPrice: 10.533689623738220398 * 1e18 }) ); @@ -2053,7 +2053,7 @@ contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { totalBondEscrowed: 8.509085736677607076 * 1e18, auctionPrice: 0 * 1e18, debtInAuction: 761.075765343400230098 * 1e18, - thresholdPrice: 0.000015553963016310 * 1e18, + thresholdPrice: 0.000015548291115577 * 1e18, neutralPrice: 0.000017286642908996 * 1e18 }) ); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol index 1eda6e0fb..79a5b4c20 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol @@ -711,7 +711,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { totalBondEscrowed: 6.605224811402125309 * 1e18, auctionPrice: 0.000078301610411710 * 1e18, debtInAuction: 590.789267398535232527 * 1e18, - thresholdPrice: 295.453988355164748340 * 1e18, + thresholdPrice: 295.394633699267616263 * 1e18, neutralPrice: 328.420757756278243989 * 1e18 }) ); @@ -873,7 +873,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { totalBondEscrowed: 6.605224811402125309 * 1e18, auctionPrice: 0.000078301610411710 * 1e18, debtInAuction: 418.513981107458710209 * 1e18, - thresholdPrice: 332.306488529853590250 * 1e18, + thresholdPrice: 295.394633699267616263 * 1e18, neutralPrice: 328.420757756278243989 * 1e18 }) ); @@ -961,7 +961,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { totalBondEscrowed: 6.605225686840743450 * 1e18, auctionPrice: 0, debtInAuction: 418.513903681286916644 * 1e18, - thresholdPrice: 1_614.039492321819633172 * 1e18, + thresholdPrice: 295.394633699267616263 * 1e18, neutralPrice: 328.420757756278243989 * 1e18 }) ); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol index 1417561ef..58fb9d8d5 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol @@ -213,7 +213,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { totalBondEscrowed: 0.243847547737474028 * 1e18, auctionPrice: 12.124431596439710012 * 1e18, debtInAuction: 21.810387715504679661 * 1e18, - thresholdPrice: 10.905529981921075309 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -255,7 +255,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { totalBondEscrowed: 0.076149339066797765 * 1e18, auctionPrice: 12.124431596439710012 * 1e18, debtInAuction: 7.063223505145093670 * 1e18, - thresholdPrice: 3.549295445970051290 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol index 2a6bec8b5..135e02eff 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol @@ -152,7 +152,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 10.905193857752339830 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -275,7 +275,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 10.905193857752339830 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol index 56f71b786..63e37a62a 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol @@ -192,7 +192,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { totalBondEscrowed: 111.910902143138508398 * 1e18, auctionPrice: 0, debtInAuction: 10_009.615384615384620000 * 1e18, - thresholdPrice: 1_669.031171487100626274 * 1e18, + thresholdPrice: 1_668.269230769230770000 * 1e18, neutralPrice: 1_854.787401007794957336 * 1e18 }) ); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol index c7c1c7ec6..e075a713f 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol @@ -156,7 +156,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 10.905193857752339830 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -261,7 +261,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.243847547737474028 * 1e18, auctionPrice: 14.418460319849903168 * 1e18, debtInAuction: 21.810387715504679661 * 1e18, - thresholdPrice: 10.905501971177984869 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -329,7 +329,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.082644260707135316 * 1e18, auctionPrice: 14.418460319849903168 * 1e18, debtInAuction: 7.634348553051574639 * 1e18, - thresholdPrice: 7.634348553051574639 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -436,7 +436,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 10.905193857752339830 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -538,7 +538,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.243847547737474028 * 1e18, auctionPrice: 3.031107899109927504 * 1e18, debtInAuction: 21.810387715504679661 * 1e18, - thresholdPrice: 10.905754070455852115 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -609,7 +609,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.311625180832937747 * 1e18, auctionPrice: 3.031107899109927504 * 1e18, debtInAuction: 15.817069975787312944 * 1e18, - thresholdPrice: 0, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -677,7 +677,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 10.905193857752339830 * 1e18, + thresholdPrice: 0, neutralPrice: 0 }) ); @@ -747,7 +747,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.243847547737597315 * 1e18, auctionPrice: 0.000000000011027106 * 1e18, debtInAuction: 21.815990418134247758 * 1e18, - thresholdPrice: 21.815990418134247758 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); @@ -780,7 +780,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.243847547737597315 * 1e18, auctionPrice: 0.000000000011027106 * 1e18, debtInAuction: 21.815990418134247758 * 1e18, - thresholdPrice: 21.815990418134247758 * 1e18, + thresholdPrice: 10.905193857752339830 * 1e18, neutralPrice: 12.124431596439710011 * 1e18 }) ); diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index 44680ff35..4167a1fb5 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -470,8 +470,6 @@ abstract contract DSTestPlus is Test, IPoolEvents { (, uint256 lockedBonds) = _pool.kickerInfo(state_.kicker); (vars.auctionTotalBondEscrowed,,,) = _pool.reservesInfo(); (,, vars.auctionDebtInAuction,) = _pool.debtInfo(); - // FIXME: replacing this with vars.borrowerThresholdPrice from auctionInfo broke many tests - vars.borrowerThresholdPrice = borrowerCollateral > 0 ? borrowerDebt * Maths.WAD / borrowerCollateral : 0; assertEq(vars.auctionKickTime != 0, state_.active); assertEq(vars.auctionKicker, state_.kicker); From 0f2cf48f7ca286cdec4e24010d21a0d16fd37d81 Mon Sep 17 00:00:00 2001 From: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Date: Sun, 3 Dec 2023 21:21:57 -0500 Subject: [PATCH 14/16] Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions --- src/base/Pool.sol | 38 ++--------------- .../pool/commons/IPoolKickerActions.sol | 3 +- src/libraries/external/KickerActions.sol | 26 +++++++++++- src/libraries/external/PoolCommons.sol | 41 ++++++++++++++++++- 4 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/base/Pool.sol b/src/base/Pool.sol index ddb3ea5f0..7b987b952 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -378,23 +378,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function withdrawBonds( address recipient_, uint256 maxAmount_ - ) external override nonReentrant { - uint256 claimable = auctions.kickers[msg.sender].claimable; - - // the amount to claim is constrained by the claimable balance of sender - // claiming escrowed bonds is not constraiend by the pool balance - maxAmount_ = Maths.min(maxAmount_, claimable); - - // revert if no amount to claim - if (maxAmount_ == 0) revert InsufficientLiquidity(); - - // decrement total bond escrowed - auctions.totalBondEscrowed -= maxAmount_; - auctions.kickers[msg.sender].claimable -= maxAmount_; - - emit BondWithdrawn(msg.sender, recipient_, maxAmount_); - - _transferQuoteToken(recipient_, maxAmount_); + ) external override nonReentrant returns (uint256 withdrawnAmount_) { + withdrawnAmount_ = KickerActions.withdrawBonds(auctions, recipient_, maxAmount_); + _transferQuoteToken(recipient_, withdrawnAmount_); } /*********************************/ @@ -830,25 +816,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { /// @inheritdoc IPoolState function debtInfo() external view returns (uint256, uint256, uint256, uint256) { - uint256 t0Debt = poolBalances.t0Debt; - uint256 inflator = inflatorState.inflator; - - return ( - Maths.ceilWmul( - t0Debt, - PoolCommons.pendingInflator( - inflator, - inflatorState.inflatorUpdate, - interestState.interestRate - ) - ), - Maths.ceilWmul(t0Debt, inflator), - Maths.ceilWmul(poolBalances.t0DebtInAuction, inflator), - interestState.t0Debt2ToCollateral - ); + return PoolCommons.debtInfo(poolBalances, inflatorState, interestState); } - /// @inheritdoc IPoolDerivedState function depositUpToIndex(uint256 index_) external view override returns (uint256) { return Deposits.prefixSum(deposits, index_); diff --git a/src/interfaces/pool/commons/IPoolKickerActions.sol b/src/interfaces/pool/commons/IPoolKickerActions.sol index 93e4fa130..12968bd85 100644 --- a/src/interfaces/pool/commons/IPoolKickerActions.sol +++ b/src/interfaces/pool/commons/IPoolKickerActions.sol @@ -35,11 +35,12 @@ interface IPoolKickerActions { * @notice Called by kickers to withdraw their auction bonds (the amount of quote tokens that are not locked in active auctions). * @param recipient_ Address to receive claimed bonds amount. * @param maxAmount_ The max amount to withdraw from auction bonds (`WAD` precision). Constrained by claimable amounts and liquidity. + * @return withdrawnAmount_ The amount withdrawn (`WAD` precision). */ function withdrawBonds( address recipient_, uint256 maxAmount_ - ) external; + ) external returns (uint256 withdrawnAmount_); /***********************/ /*** Reserve Auction ***/ diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index 75ae60201..a97fb49a8 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -78,10 +78,11 @@ library KickerActions { /**************/ // See `IPoolEvents` for descriptions + event BondWithdrawn(address indexed kicker, address indexed reciever, uint256 amount); + event BucketBankruptcy(uint256 indexed index, uint256 lpForfeited); event Kick(address indexed borrower, uint256 debt, uint256 collateral, uint256 bond); - event RemoveQuoteToken(address indexed lender, uint256 indexed price, uint256 amount, uint256 lpRedeemed, uint256 lup); event KickReserveAuction(uint256 claimableReservesRemaining, uint256 auctionPrice, uint256 currentBurnEpoch); - event BucketBankruptcy(uint256 indexed index, uint256 lpForfeited); + event RemoveQuoteToken(address indexed lender, uint256 indexed price, uint256 amount, uint256 lpRedeemed, uint256 lup); /**************/ /*** Errors ***/ @@ -242,6 +243,27 @@ library KickerActions { ); } + function withdrawBonds( + AuctionsState storage auctions_, + address recipient_, + uint256 maxAmount_ + ) external returns (uint256 amount_) { + uint256 claimable = auctions_.kickers[msg.sender].claimable; + + // the amount to claim is constrained by the claimable balance of sender + // claiming escrowed bonds is not constraiend by the pool balance + amount_ = Maths.min(maxAmount_, claimable); + + // revert if no amount to claim + if (amount_ == 0) revert InsufficientLiquidity(); + + // decrement total bond escrowed + auctions_.totalBondEscrowed -= amount_; + auctions_.kickers[msg.sender].claimable -= amount_; + + emit BondWithdrawn(msg.sender, recipient_, amount_); + } + /***************************/ /*** Internal Functions ***/ /***************************/ diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index d1c6d80ba..baaf276bb 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -9,7 +9,14 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { InterestState, EmaState, PoolState, DepositsState } from '../../interfaces/pool/commons/IPoolState.sol'; +import { + DepositsState, + EmaState, + InflatorState, + InterestState, + PoolBalancesState, + PoolState +} from '../../interfaces/pool/commons/IPoolState.sol'; import { IERC3156FlashBorrower } from '../../interfaces/pool/IERC3156FlashBorrower.sol'; import { @@ -429,6 +436,38 @@ library PoolCommons { /*** View Functions ***/ /**********************/ + /** + * @notice Calculates pool related debt values. + * @param poolBalances_ Pool debt + * @param inflatorState_ Interest inflator and last update time + * @param interestState_ Interest rate and t0Debt2ToCollateral accumulator + * @return Current amount of debt owed by borrowers in pool. + * @return Debt owed by borrowers based on last inflator snapshot. + * @return Total amount of debt in auction. + * @return t0debt accross all borrowers divided by their collateral, used in determining a collateralization weighted debt. + */ + function debtInfo( + PoolBalancesState memory poolBalances_, + InflatorState memory inflatorState_, + InterestState memory interestState_ + ) external view returns (uint256, uint256, uint256, uint256) { + uint256 t0Debt = poolBalances_.t0Debt; + uint256 inflator = inflatorState_.inflator; + + return ( + Maths.ceilWmul( + t0Debt, + Maths.wmul( + inflator, + PRBMathUD60x18.exp((interestState_.interestRate * (block.timestamp - inflatorState_.inflatorUpdate)) / 365 days) + ) + ), + Maths.ceilWmul(t0Debt, inflator), + Maths.ceilWmul(poolBalances_.t0DebtInAuction, inflator), + interestState_.t0Debt2ToCollateral + ); + } + /** * @notice Calculates pool interest factor for a given interest rate and time elapsed since last inflator update. * @param interestRate_ Current pool interest rate. From c5110e5e83ce1e341e998835b5664383fbe66e98 Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Mon, 4 Dec 2023 10:56:27 -0500 Subject: [PATCH 15/16] added unit test showing adding qt above auction price reverts --- .../forge/unit/ERC20Pool/ERC20DSTestPlus.sol | 9 ++ .../unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 138 ++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index d769f113a..a43d2ad43 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -820,6 +820,15 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } + function _assertAddAboveAuctionPriceRevert( + address from, + uint256 amount, + uint256 index + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.AddAboveAuctionPrice.selector); + _pool.addQuoteToken(amount, index, type(uint256).max); + } } abstract contract ERC20HelperContract is ERC20DSTestPlus { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index 7f3d173f4..d47dbbe8a 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -1569,4 +1569,142 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { index: 852 }); } + + function testAddLiquidityAboveAuctionPrice() external { + + // Lender adds Quote token accross 5 prices + _addInitialLiquidity({ + from: _lender, + amount: 2_000 * 1e18, + index: _i9_91 + }); + _addInitialLiquidity({ + from: _lender, + amount: 5_000 * 1e18, + index: _i9_81 + }); + _addInitialLiquidity({ + from: _lender, + amount: 11_000 * 1e18, + index: _i9_72 + }); + _addInitialLiquidity({ + from: _lender, + amount: 25_000 * 1e18, + index: _i9_62 + }); + _addInitialLiquidity({ + from: _lender, + amount: 30_000 * 1e18, + index: _i9_52 + }); + + // first borrower pledge collateral and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + amount: 2 * 1e18 + }); + _borrow({ + from: _borrower, + amount: 19.0 * 1e18, + indexLimit: _i9_91, + newLup: 9.917184843435912074 * 1e18 + }); + + // Skip to make borrower undercollateralized + skip(100 days); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + thresholdPrice: 0, + neutralPrice: 0 + }) + ); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 19.280586055366139163 * 1e18, + borrowerCollateral: 2 * 1e18, + borrowert0Np: 10.572288185744431256 * 1e18, + borrowerCollateralization: 0.989156100314278654 * 1e18 + }); + + _kick({ + from: _lender, + borrower: _borrower, + debt: 19.280586055366139162 * 1e18, + collateral: 2 * 1e18, + bond: 0.215563505329166046 * 1e18, + transferAmount: 0.215563505329166046 * 1e18 + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: _lender, + bondSize: 0.215563505329166046 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp, + referencePrice: 10.718110554328899849 * 1e18, + totalBondEscrowed: 0.215563505329166046 * 1e18, + auctionPrice: 2_743.836301908198361344 * 1e18, + debtInAuction: 19.280586055366139163 * 1e18, + thresholdPrice: 9.640293027683069581 * 1e18, + neutralPrice: 10.718110554328899849 * 1e18 + }) + ); + _assertKicker({ + kicker: _lender, + claimable: 0, + locked: 0.215563505329166046 * 1e18 + }); + + _addLiquidityWithPenalty({ + from: _lender1, + amount: 1 * 1e18, + amountAdded: 0.999958904109589041 * 1e18, + index: _i9_52, + lpAward: 0.999958904109589041 * 1e18, + newLup: 9.917184843435912074 * 1e18 + }); + + skip(6.5 hours); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: _lender, + bondSize: 0.215563505329166046 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp - 6.5 hours, + referencePrice: 10.718110554328899849 * 1e18, + totalBondEscrowed: 0.215563505329166046 * 1e18, + auctionPrice: 9.012820743428175104 * 1e18, + debtInAuction: 19.280586055366139163 * 1e18, + thresholdPrice: 9.640293027683069581 * 1e18, + neutralPrice: 10.718110554328899849 * 1e18 + }) + ); + + // used to block last minute arbTakes that favor the taker + _assertAddAboveAuctionPriceRevert({ + from: _lender, + amount: 1 * 1e18, + index: _i100_33 + }); + + } + } From d5d0ca7f591d47db3b0e44789d1ef48673d1a3f9 Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Mon, 4 Dec 2023 11:51:36 -0500 Subject: [PATCH 16/16] updated nit spellings --- src/interfaces/pool/commons/IPoolErrors.sol | 1 + src/libraries/helpers/RevertsHelper.sol | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index 5f0353710..b15b4d3f2 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -14,6 +14,7 @@ interface IPoolErrors { * @notice Adding liquidity above current auction price. */ error AddAboveAuctionPrice(); + /** * @notice `LP` allowance is already set by the owner. */ diff --git a/src/libraries/helpers/RevertsHelper.sol b/src/libraries/helpers/RevertsHelper.sol index 264cf1a15..50e5ae749 100644 --- a/src/libraries/helpers/RevertsHelper.sol +++ b/src/libraries/helpers/RevertsHelper.sol @@ -78,7 +78,7 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Check if provided price is above current auction price. - * @notice Prevents manipulative deposir and arb takes. + * @notice Prevents manipulative deposits and arbTakes. * @dev Reverts with `AddAboveAuctionPrice` if price is above head of auction queue. * @param index_ Identifies bucket price to be compared with current auction price. * @param auctions_ Auctions data.