From 2d6bbcb39a020a041d5243eadd8f4cb77e85c41b Mon Sep 17 00:00:00 2001 From: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:30:58 -0500 Subject: [PATCH] Merge develop to master (#1047) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Logging for RewardsManager and PositionManager invariants (#925) * added logging for positionManager * added rewards and position logging * clean up * updated rewards mapping back to public so tests pass * how modifier was being called in rewardsPoolHandler * revised so logging pools is not required when logging positions * cleanup * readme cleanup --------- Co-authored-by: Ian Harvey * Invariants Improvement: Add multiple pool support in position and rewards manager invariant testing (#927) * Add multiple pools in position and rewards manager invariant testing * Fix RW6 regression test * Fix rewardsClaimed and updateRewardsClaimed in Rewards manager * Fix compile error * PR feedback * Add configurable number of pools for position and rewards manager invariant testing * Positions Invariants: Multiple positions, transfer positions (#926) * added randomness * added the ability to transfer positions * increased chance of rewards being claimed in handlers * cleanup * responded to comments --------- Co-authored-by: Ian Harvey * Fuzz test additions (#924) * Add fuzz test for borrower borrows fuzzed amount and getting kick after some time * Add fuzz test for take fuzzed amount of collateral from auction * Add fuzz test for settle with fuzzed pool deposit * Add fuzz test for add and remove collateral in ERC721Pool * Fuzzed buckets used in borrow and kick fuzz test * PR feedback * Invariant Improvements: Position rewards logging for multiple pools (#931) * Update position and rewards manager invariant logging for multiple pools * Fix regression test to run for any token precision and Quote token limits * PR feedback * Invariants Improvements: Add Multiple position in single handler in Position (#928) * Update Position invariants handler to memorialize and redeem multiple positions * PR feedback * Add partial random positions redeem in redeem position handler * Add random time skips between epochs in rewards manager * Add bucket bankruptcy scenario for rewards manager (#930) * Add bucket bankruptcy scenario for rewards manager * Fix evm reverts * PR feedback * Update prepare test methods to add position in NFT if there is no position in it * Fixed RewardsManager exchangeRate emit (#941) * stopped updatedExchangeRates emit when the rates are not updated * removed epoch check in _updateBucketExchangeRates --------- Co-authored-by: Ian Harvey * Invariant Improvements: Add settle invariant scenario (#933) * Add settle invariant scenario * Reduce Loans and skip time to make undercollateralize * Reduce time to skip in bucket bankruptcy scenario setup to fix regression tests (#936) * Update unit test to increase test coverage (#938) * Add unit tests to check deposits and debt limits in pool (#939) * Add unit test to check exp function limit * Add unit tests to check pool deposit and debt limits * PR cleanup * Add missing external function calls (#946) * Update Position Manager unit tests to test against both ERC721 subset Pool and Collection Pool (#945) * Merge changes from private-contracts repo into develop (#950) * Merge Develop into Master (#934) * Logging for RewardsManager and PositionManager invariants (#925) * added logging for positionManager * added rewards and position logging * clean up * updated rewards mapping back to public so tests pass * how modifier was being called in rewardsPoolHandler * revised so logging pools is not required when logging positions * cleanup * readme cleanup --------- Co-authored-by: Ian Harvey * Invariants Improvement: Add multiple pool support in position and rewards manager invariant testing (#927) * Add multiple pools in position and rewards manager invariant testing * Fix RW6 regression test * Fix rewardsClaimed and updateRewardsClaimed in Rewards manager * Fix compile error * PR feedback * Add configurable number of pools for position and rewards manager invariant testing * Positions Invariants: Multiple positions, transfer positions (#926) * added randomness * added the ability to transfer positions * increased chance of rewards being claimed in handlers * cleanup * responded to comments --------- Co-authored-by: Ian Harvey * Fuzz test additions (#924) * Add fuzz test for borrower borrows fuzzed amount and getting kick after some time * Add fuzz test for take fuzzed amount of collateral from auction * Add fuzz test for settle with fuzzed pool deposit * Add fuzz test for add and remove collateral in ERC721Pool * Fuzzed buckets used in borrow and kick fuzz test * PR feedback * Invariant Improvements: Position rewards logging for multiple pools (#931) * Update position and rewards manager invariant logging for multiple pools * Fix regression test to run for any token precision and Quote token limits * PR feedback * Invariants Improvements: Add Multiple position in single handler in Position (#928) * Update Position invariants handler to memorialize and redeem multiple positions * PR feedback * Add partial random positions redeem in redeem position handler * Add random time skips between epochs in rewards manager * Add bucket bankruptcy scenario for rewards manager (#930) * Add bucket bankruptcy scenario for rewards manager * Fix evm reverts * PR feedback * Update prepare test methods to add position in NFT if there is no position in it --------- Co-authored-by: Ian Harvey Co-authored-by: Prateek Gupta * manually merged from private-contracts/immutable-kicks * eliminated alreadyTaken (drawio needs updating) * annotated failing unit tests * new limit to induce testAccruePoolInterestRevertDueToExpLimit revert * fixed testUpdateInterestTuLimit * fixed testAccrueInterestNewInterestLimit * removed alreadyTaken from drawios * updated drawio-generated html * merged Prateek's post-merge changes --------- Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey Co-authored-by: Prateek Gupta * Return amount repaid in repayDebt and amount take in take (#947) * Remove multicall from position manager (#948) * L2 license grant (#949) * updated license * adjustment for public chains * Pool info utils multicall (#944) * Add PoolInfoUtilsMulticall contract to call multiple PoolInfoUtils methods in a single call to reduce rpc calls from subgraph * Add tests for PoolInfoutilsMulticall * Added comments and code improvements * altered license --------- Co-authored-by: Ian Harvey * removed mention of momp in testPoolInfoUtilsMulticall (#952) Co-authored-by: Ian Harvey * resolved compilation warnings and removed unused code (#953) * Reuse _isCollateralized method in repayment (#959) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * PR template (#963) * changed PR template * commented out example test, as requested in PR review * Low-lying fruit (#967) * added a fenwick OOB test * unit test to prove 0 loan heap insertions don't break anythnig * test harness for the auction queue and simple unit tests * comment to resolve Kirill L-07 * removed redundant code per Kirill L-05 * added SafeCasts * Fix incorrect lup is used to calculate new interest rate in lenderKick (#972) * correct reserve auction kick timing logic (#974) * Add debt and collateral settled returns in settle function (#960) * Return debt and collateral settled from settle method * Add isBorrowerSettled return in settle method * Catch interest accrual and update interest overflow (#954) * Add try catch for interest accrual and update interest method to avoid pool locking * PR feedback * Incorrect(Unscaled) deposits are used to check bucket bankruptcy in forgive bad debt (#971) * Fix incorrect deposits used to check bucket bankruptcy in forgive bad debt * PR feedback * Use bucket price for BPF calculation (#970) * use bucket price in BPF calc where applicable * fixed unit tests * revert CRA kick if a liquidation awaits settlement (#977) * First borrower (#968) * this did not work; cannot prevent rate from changing after 12 hours * fixed issue with _updateInterestState * fixed unit tests * removed unused test utility * Contract size mitigation (#979) * moved inflator state update logic to PoolHelper * moved flashLoan impl into PoolCommons * Memorialize borrower threshold price on kick (#976) * Memorialize borrower threshold price at time of kick to calculate bpf on take * Fix tests * Record borrower threshold price inside _recordAuction method * Remove redundant conversions * Fix natspec * Fix unit tests * Remove redundant variable * Borrower with threshold price less than `MIN_PRICE` cannot be kicked. (#973) * Add test for borrower with tp less than min price cannot be kicked * Update _isCollateralized method to return borrower is not collateralized if TP < MIN_PRICE and LUP = MIN_PRICE * Set borrower to be undercollateralized if LUP = MIN_PRICE * Fix unit tests * Fix regression test * Fix regression test * Optimize stake cost by reducing calls to currentBurnEpoch (#940) * reduce external calls to burn epoch * Don't cast epoch * further reduce gas in stake by casting curBurnEpoch on use * moved changes off of kirill-L01-dust-test to a fresh branch (#980) Co-authored-by: Ian Harvey * Merge rc9 (#1010) * Universal deposit fee (#983) * charge fee on all deposit * unit tests compile * test harness updates * working on ERC20PoolQuoteTokenTest * removed deposit fee cap * more work on ERC20PoolQuoteTokenTest * do not charge deposit fee if moving liquidity to higher price * Eliminate reserves bad debt allocation and add margin to TP (#962) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Add 1.04 factor in borrower collateralization * Update nptp ratio to '1 + sqrt(r)/2' * Remove Settle debt with pool reserves * Remove 0.995 factor from claimable reserves calculation * Update bond factor calculation to minimum 0.005 * added testcase where debt exceeds deposit * updated test so debt exceeds deposit * allow up to half of current orig fee to be used to settle bad debt * updated testTakeAndSettle * more test fixes * Enabled settling with all reserves if Deposits.treeSum==0 or 72 hrs pass * cleanup * Half orig fee res | Matt example (#966) * added Matts test as proof that attack no longer works on his branch * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * added test testSpendOrigFeePushBadDebtToBorrowers test * cleaned up testStealReservesWithMarginm to match minted balances * responded to Matts comments --------- Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Revert "Remove Settle debt with pool reserves" This reverts commit 290d6cf6f7baa1fb17a66322faf755b78a4a379c. * Update half origination fees reserves settlement time to 144 hours from kickTime * Fix alignment and extra spaces * Fix some unit tests * PR feedback * Update encumberance and collateralization method in poolInfoUtils * Fix some unit tests --------- Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Fix invariant setup * Fix some unit tests * ERC20PoolQuoteTokenTest updated * updated ERC20PoolPurchaseQuoteTokenTest * Fixed tests in ERC20PoolReserveAuction.t.sol * updated ERC20PoolBorrowTest and ERC20PoolBorrowFuzzyTest * Fix ERC20PoolCollateral and ERC20PoolInfoUtils tests * Fixed ERC20 arbtake and depositTake tests * Fix ERC20PoolLiquidationsKickTest, ERC20PoolLiquidationKickFuzzyTest and ERC20PoolLiquidationsLenderKickAuctionTest * updated ERC20PoolMulticallTest * cleaned up ERC20PoolDebtExceedsDepositTest * fixed testTakeLoanColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosResidual * fixed testTakeCallerColConstraintBpfNegResidual * fixed testTakeLoanDebtConstraintBpfPosResidual * fixed testTakeAndSettle * cleaned up ERC20PoolDebtExceedsDepositTest * updated ERC20PoolPrecisionTest * Update ERC20PoolLiquidationsSettleTest * Update ERC20PoolLiquidationsMisc * Update ERC20PoolLiquidationSettleFuzzyTest * Update ERC20PoolLiquidationTakeFuzzyTest * fixeed revert tests * ERC20PoolLiquidationsTake -- fixed rest * Mh update tests (#985) * fix most position manager tests * fix additional pm tests * fix rewards requiredCollateralRewards setup * fix ClaimRewards tests * update additional rewards manager tests * fix additional tests * more test fixes * commit wip bankruptcy tests * fixed testMoveLiquidityToOverwriteBankruptBucket * fix additional tests * fix testMoveLiquidityWithDebtInPool * fix remaining rewards manager tests --------- Co-authored-by: Mike Co-authored-by: mwc * Add 1.04 factor in HTP calculations (#987) * Add 1.04 factor in HTP calculations * Add COLLATERALIZATION_FACTOR constant in PoolHelpers * Add collateralization factor in dwatp * Fix poolPricesInfo * Update ERC20PoolBorrowFuzzyTest * Fix some unit tests * Fix some unit tests * Fix some unit tests * Update ERC20PoolTransferLPs * fix most rewards manager tests * update remaining rewards manager tests * update ERC721SubsetPoolBorrowTest and commit wip changes to testMergeOrRemoveERC721Collateral * updated testSettlePartialDebtSubsetPool (#988) * updated testSettlePartialDebtSubsetPool * re-added teardown --------- Co-authored-by: Ian Harvey * fix ERC721PoolCollateral tests * fix borrowRepayDebtFuzzy and additional PM tests * cleaned up testBorrowAndRepayWith4DecimalQuote --------- Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey * Fix some unit tests * Deployment updates for RC8+ releases (#986) * cherry-picked from master * updated README * Fix ERC721PoolLiquidationsTakeTest * updated ERC721PoolReserveAuctionTest * updated testMergeOrRemoveERC721Collateral (#989) Co-authored-by: Ian Harvey * updated ERC721PoolPurchaseQuoteTest and fixed bug in ERC721 tearDown * cleaned up testLiquidationLenderKickAuction, testLiquidationSingleBorrower, testSettleAuctionWithoutTakes * updated testMoveLiquidityToOverwriteBankruptBucket * updated PoolHelperTest * cleaned up asserts in addLiquidity * update testMoveLiquidityInBankruptBucket_LP_report_179_494 * updated ERC721PoolEMAsTest * fixed testKickHighThresholdPriceBorrower * updated testBorrowerInterestCalculationAfterRepayingAllDebtOnce and testBorrowerInterestCalculation * updated testMultipleBorrowerInterestAccumulation * Fix regression tests * updated RE3, fixed _addQuoteToken * addQuoteToken - return amount added (#993) * addQuoteToken now returns amount added * update unit tests to validate return values * Fix up add liquidity (#992) * cleaned up addLiquidity() method in ERC20PoolLiquidationsScaled.t.sol * remove console --------- Co-authored-by: Ian Harvey * fixed issue with test_regression_fenwick_index_2 in non-18-decimal env * added regression tests for two failing reserves scenarios * rename tests such that automake runs them with other regression tests * UnboundedLiquidationPoolHandler bucketTake fix (#994) * updated UnboundedLiquidationPoolHandler to handle compensated collateral in bucketTake * cleanup, trap unhandled use case * settle event now emits actual debt settled rather than t0 amount (#999) * settle event now emits actual debt settled rather than t0 amount * updated test_regression_settle_with_reserves * Updated auctionInfo (#996) * add thresholdPrice to auctionInfo; update test iterface usages * temp fix tests * remove unneeded comment * Update auction status (#998) * wip auction status update w/ stack too deep * update auctionStatus; add auctionInfo method to poolInfoUtils --------- Co-authored-by: Mike --------- Co-authored-by: Mike * updated brownie tests, removed obsolete invariant tests (#1001) * Block addqt above auction price (#997) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * added unit test showing adding qt above auction price reverts * updated nit spellings --------- Co-authored-by: mwc Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey * Invariant testing fixes (#1006) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * documented a sample of invariant failures in regression tests * added unit test showing adding qt above auction price reverts * fixed _isCollateralized bug not returning true in all 0-debt use cases * updated nit spellings * fixed underflow calculating kicker reward * _repayDebtByThirdParty should check for expected pool errors * Round down when reward kicker, round up when kicker is penalized Fix roundings in tests * update test comments * fix and enable A9 invariant --------- Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * RC9 suggested improvements (#1005) * Revert AuctionNotTakeable in same place, load auction kickTime only once from storage * Calculate ERC721 collateralTaken only once cosmetize code (read from result struct in local var and reuse) Results in shrinking a little bit contract sizes * Read borrower Np Tp ratio from storage only once when kick * If block style, proper indentation * Proposed changes to PR #972: - avoid calculating current LUP twice in lender kick - change _kick function to accept proposed LUP (for regular kick proposed LUP is current LUP, for lender kick proposed LUP is calculated based on additional debt) - in both kick cases return current LUP in kick result - reduce gas costs by saving a Fenwick traversal - reduce contract size by removing LUP calculation within Pool * Cosmetic flashloan code changes, PoolCommons.flashLoan doesn't return false but always reverts if flashloan fails * PR#983 style, remove redundant line * PR#999 suggested improvement - calculate current settled debt only once and include in settle result for state update * PR #962 proposed changes: - get Fenwick deposits only once when settle with reserves - define constants for min bond factor and max npTp ratio values * PR #987 proposed improvement: - add and reuse _htp helper function (instead duplicated maths) * Continuation of PR #962: (#1008) - Record settle amount limmit in Liquidtion struct, at the time of kick (that is instead incrementing accumulator in Borrower struct, each time debt is drawn) - This way accumulator will be reseted when auction is settled - fix tests TODO: - assert Liquidation.t0ReserveSettleAmount in unit tests (_assertAuction), make sure is set to 0 after auction settled and decreased when partial settles done - update invariant test to check new introduced accumulator * Misc test fixes (#1009) * handle another reward rounding error use case * fix intermittant fuzz test failure - cannot draw debt from liquidity in bucket 7388 * PositionManager should expect AddAboveAuctionPrice, which can happen in moveLiquidity * Invariant fix: round up quote tokens calculated from rewarded LP (because LP rewarded are calculated in bucketTake as rewarded quote tokens -> LP rounded down) * Pr feedback * Fix failing unit tests --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: prateek105 Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * [L-02] Some unit tests are not properly executed - split priceToIndex and indexToPrice revert tests * removed several unused errors and one unused event, per Kirill I-03 * eliminated unused TakeLocalVars.factor * removed unused KickResult.poolDebt * Remove more unused vars (#1022) * Remove DrawDebtLocalVars.compensatedCollateral and RepayDebtLocalVars.compensatedCollateral * remove unused `ConstructTokenURIParams::pool` and `ConstructTokenURIParams::indexes` * Include 1.04 COLLATERALIZATION_FACTOR (#1021) * Include 1.04 COLLATERALIZATION_FACTOR in neutral price used in kicks * fixed `testDepositTakeAndSettleByBucketTakeSubsetPool` * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * Moved `wmul` inside `mulDiv` * fix position, rewards, and poolInfoUtils tests * fix pool factory emit; fix borrowAndRepay tests * updated ERC20PoolBorrowTest, ERC20PoolCollateralTest, and ERC20PoolDebtExceedsDepositTest * rounding update * updated ERC20PoolQuoteTokenTest and ERC20PoolPrecisionTest * Fix ERC721 unit tests * Fix ERC20PoolLiquidationsArbTakeTest and ERC20PoolLiquidationsDepositTakeTest * Fix ERC20PoolFactory, ERC20PoolLenderKick and ERC20PoolKick * Fix ERC20PoolLiquidationSettleFuzzyTest and ERC20PoolLiquidationTakeFuzzyTest * Fix ERC20PoolLiquidationsMisc * Fix ERC20PoolLiquidationsLowPriceCollateralTest, ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest and PositionManagerERC20PoolTest * Fix ERC20PoolLiquidationsSettle test * Fix testTakeWithFlashLoan test * Fix ERC20PoolLiquidationsTakeTest * Include COLLATERALIZATION_FACTOR in loanInfo * Remove redundant code from testTakeAndSettle that was already been tested in other tests * Update testTakeAndSettle --------- Co-authored-by: mwc Co-authored-by: Mike Co-authored-by: Ed Noepel Co-authored-by: grandizzy Co-authored-by: prateek105 * Kirill [M-07] | Liquidation of positions with bad debt can cause losses for `HPB` depositors (#1024) - Don’t allow calls to `kickReserveAuction` until all pending auctions are fully settled - revert with AuctionNotCleared if so - update unit test to cover scenario - apply consistent style for _revertIfAuctionPriceBelow helper (storage param first) * Fixed Take event emit for ERC721 pools (#1026) * fixed emit for take * Fix testDepositTakeAndSettleByRegularTakeSubsetPool --------- Co-authored-by: Ian Harvey Co-authored-by: prateek105 * removed COLLATERALIZATION_FACTOR where it was not used (#1018) * removed collateralization_factor where it was not used * Import missing COLLATERALIZATION_FACTOR --------- Co-authored-by: Ian Harvey Co-authored-by: prateek105 * Address merge-rc9 PR feedback (#1025) * reuse pendingInflator logic * better wording --------- Co-authored-by: prateek105 * Expand code coverage (#1013) * Universal deposit fee (#983) * charge fee on all deposit * unit tests compile * test harness updates * working on ERC20PoolQuoteTokenTest * removed deposit fee cap * more work on ERC20PoolQuoteTokenTest * do not charge deposit fee if moving liquidity to higher price * Eliminate reserves bad debt allocation and add margin to TP (#962) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Add 1.04 factor in borrower collateralization * Update nptp ratio to '1 + sqrt(r)/2' * Remove Settle debt with pool reserves * Remove 0.995 factor from claimable reserves calculation * Update bond factor calculation to minimum 0.005 * added testcase where debt exceeds deposit * updated test so debt exceeds deposit * allow up to half of current orig fee to be used to settle bad debt * updated testTakeAndSettle * more test fixes * Enabled settling with all reserves if Deposits.treeSum==0 or 72 hrs pass * cleanup * Half orig fee res | Matt example (#966) * added Matts test as proof that attack no longer works on his branch * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * added test testSpendOrigFeePushBadDebtToBorrowers test * cleaned up testStealReservesWithMarginm to match minted balances * responded to Matts comments --------- Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Revert "Remove Settle debt with pool reserves" This reverts commit 290d6cf6f7baa1fb17a66322faf755b78a4a379c. * Update half origination fees reserves settlement time to 144 hours from kickTime * Fix alignment and extra spaces * Fix some unit tests * PR feedback * Update encumberance and collateralization method in poolInfoUtils * Fix some unit tests --------- Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Fix invariant setup * Fix some unit tests * ERC20PoolQuoteTokenTest updated * updated ERC20PoolPurchaseQuoteTokenTest * Fixed tests in ERC20PoolReserveAuction.t.sol * updated ERC20PoolBorrowTest and ERC20PoolBorrowFuzzyTest * Fix ERC20PoolCollateral and ERC20PoolInfoUtils tests * Fixed ERC20 arbtake and depositTake tests * Fix ERC20PoolLiquidationsKickTest, ERC20PoolLiquidationKickFuzzyTest and ERC20PoolLiquidationsLenderKickAuctionTest * updated ERC20PoolMulticallTest * cleaned up ERC20PoolDebtExceedsDepositTest * fixed testTakeLoanColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosResidual * fixed testTakeCallerColConstraintBpfNegResidual * fixed testTakeLoanDebtConstraintBpfPosResidual * fixed testTakeAndSettle * cleaned up ERC20PoolDebtExceedsDepositTest * updated ERC20PoolPrecisionTest * Update ERC20PoolLiquidationsSettleTest * Update ERC20PoolLiquidationsMisc * Update ERC20PoolLiquidationSettleFuzzyTest * Update ERC20PoolLiquidationTakeFuzzyTest * fixeed revert tests * ERC20PoolLiquidationsTake -- fixed rest * Mh update tests (#985) * fix most position manager tests * fix additional pm tests * fix rewards requiredCollateralRewards setup * fix ClaimRewards tests * update additional rewards manager tests * fix additional tests * more test fixes * commit wip bankruptcy tests * fixed testMoveLiquidityToOverwriteBankruptBucket * fix additional tests * fix testMoveLiquidityWithDebtInPool * fix remaining rewards manager tests --------- Co-authored-by: Mike Co-authored-by: mwc * Add 1.04 factor in HTP calculations (#987) * Add 1.04 factor in HTP calculations * Add COLLATERALIZATION_FACTOR constant in PoolHelpers * Add collateralization factor in dwatp * Fix poolPricesInfo * Update ERC20PoolBorrowFuzzyTest * Fix some unit tests * Fix some unit tests * Fix some unit tests * Update ERC20PoolTransferLPs * fix most rewards manager tests * update remaining rewards manager tests * update ERC721SubsetPoolBorrowTest and commit wip changes to testMergeOrRemoveERC721Collateral * updated testSettlePartialDebtSubsetPool (#988) * updated testSettlePartialDebtSubsetPool * re-added teardown --------- Co-authored-by: Ian Harvey * fix ERC721PoolCollateral tests * fix borrowRepayDebtFuzzy and additional PM tests * cleaned up testBorrowAndRepayWith4DecimalQuote --------- Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey * Fix some unit tests * Deployment updates for RC8+ releases (#986) * cherry-picked from master * updated README * Fix ERC721PoolLiquidationsTakeTest * updated ERC721PoolReserveAuctionTest * updated testMergeOrRemoveERC721Collateral (#989) Co-authored-by: Ian Harvey * updated ERC721PoolPurchaseQuoteTest and fixed bug in ERC721 tearDown * cleaned up testLiquidationLenderKickAuction, testLiquidationSingleBorrower, testSettleAuctionWithoutTakes * updated testMoveLiquidityToOverwriteBankruptBucket * updated PoolHelperTest * cleaned up asserts in addLiquidity * update testMoveLiquidityInBankruptBucket_LP_report_179_494 * updated ERC721PoolEMAsTest * fixed testKickHighThresholdPriceBorrower * updated testBorrowerInterestCalculationAfterRepayingAllDebtOnce and testBorrowerInterestCalculation * updated testMultipleBorrowerInterestAccumulation * Fix regression tests * updated RE3, fixed _addQuoteToken * addQuoteToken - return amount added (#993) * addQuoteToken now returns amount added * update unit tests to validate return values * Fix up add liquidity (#992) * cleaned up addLiquidity() method in ERC20PoolLiquidationsScaled.t.sol * remove console --------- Co-authored-by: Ian Harvey * fixed issue with test_regression_fenwick_index_2 in non-18-decimal env * added regression tests for two failing reserves scenarios * rename tests such that automake runs them with other regression tests * UnboundedLiquidationPoolHandler bucketTake fix (#994) * updated UnboundedLiquidationPoolHandler to handle compensated collateral in bucketTake * cleanup, trap unhandled use case * settle event now emits actual debt settled rather than t0 amount (#999) * settle event now emits actual debt settled rather than t0 amount * updated test_regression_settle_with_reserves * Updated auctionInfo (#996) * add thresholdPrice to auctionInfo; update test iterface usages * temp fix tests * remove unneeded comment * Update auction status (#998) * wip auction status update w/ stack too deep * update auctionStatus; add auctionInfo method to poolInfoUtils --------- Co-authored-by: Mike --------- Co-authored-by: Mike * updated brownie tests, removed obsolete invariant tests (#1001) * Block addqt above auction price (#997) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * added unit test showing adding qt above auction price reverts * updated nit spellings --------- Co-authored-by: mwc Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey * Invariant testing fixes (#1006) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * documented a sample of invariant failures in regression tests * added unit test showing adding qt above auction price reverts * fixed _isCollateralized bug not returning true in all 0-debt use cases * updated nit spellings * fixed underflow calculating kicker reward * _repayDebtByThirdParty should check for expected pool errors * Round down when reward kicker, round up when kicker is penalized Fix roundings in tests * update test comments * fix and enable A9 invariant --------- Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * RC9 suggested improvements (#1005) * Revert AuctionNotTakeable in same place, load auction kickTime only once from storage * Calculate ERC721 collateralTaken only once cosmetize code (read from result struct in local var and reuse) Results in shrinking a little bit contract sizes * Read borrower Np Tp ratio from storage only once when kick * If block style, proper indentation * Proposed changes to PR #972: - avoid calculating current LUP twice in lender kick - change _kick function to accept proposed LUP (for regular kick proposed LUP is current LUP, for lender kick proposed LUP is calculated based on additional debt) - in both kick cases return current LUP in kick result - reduce gas costs by saving a Fenwick traversal - reduce contract size by removing LUP calculation within Pool * Cosmetic flashloan code changes, PoolCommons.flashLoan doesn't return false but always reverts if flashloan fails * PR#983 style, remove redundant line * PR#999 suggested improvement - calculate current settled debt only once and include in settle result for state update * PR #962 proposed changes: - get Fenwick deposits only once when settle with reserves - define constants for min bond factor and max npTp ratio values * PR #987 proposed improvement: - add and reuse _htp helper function (instead duplicated maths) * Continuation of PR #962: (#1008) - Record settle amount limmit in Liquidtion struct, at the time of kick (that is instead incrementing accumulator in Borrower struct, each time debt is drawn) - This way accumulator will be reseted when auction is settled - fix tests TODO: - assert Liquidation.t0ReserveSettleAmount in unit tests (_assertAuction), make sure is set to 0 after auction settled and decreased when partial settles done - update invariant test to check new introduced accumulator * Misc test fixes (#1009) * handle another reward rounding error use case * fix intermittant fuzz test failure - cannot draw debt from liquidity in bucket 7388 * PositionManager should expect AddAboveAuctionPrice, which can happen in moveLiquidity * Invariant fix: round up quote tokens calculated from rewarded LP (because LP rewarded are calculated in bucketTake as rewarded quote tokens -> LP rounded down) * full coverage of PermitERC20 and poolInfoUtils * create liquidation in PoolInfoUtils test (#1015) --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: prateek105 Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * Take high price (#1016) * Universal deposit fee (#983) * charge fee on all deposit * unit tests compile * test harness updates * working on ERC20PoolQuoteTokenTest * removed deposit fee cap * more work on ERC20PoolQuoteTokenTest * do not charge deposit fee if moving liquidity to higher price * Eliminate reserves bad debt allocation and add margin to TP (#962) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Add 1.04 factor in borrower collateralization * Update nptp ratio to '1 + sqrt(r)/2' * Remove Settle debt with pool reserves * Remove 0.995 factor from claimable reserves calculation * Update bond factor calculation to minimum 0.005 * added testcase where debt exceeds deposit * updated test so debt exceeds deposit * allow up to half of current orig fee to be used to settle bad debt * updated testTakeAndSettle * more test fixes * Enabled settling with all reserves if Deposits.treeSum==0 or 72 hrs pass * cleanup * Half orig fee res | Matt example (#966) * added Matts test as proof that attack no longer works on his branch * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * added test testSpendOrigFeePushBadDebtToBorrowers test * cleaned up testStealReservesWithMarginm to match minted balances * responded to Matts comments --------- Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Revert "Remove Settle debt with pool reserves" This reverts commit 290d6cf6f7baa1fb17a66322faf755b78a4a379c. * Update half origination fees reserves settlement time to 144 hours from kickTime * Fix alignment and extra spaces * Fix some unit tests * PR feedback * Update encumberance and collateralization method in poolInfoUtils * Fix some unit tests --------- Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Fix invariant setup * Fix some unit tests * ERC20PoolQuoteTokenTest updated * updated ERC20PoolPurchaseQuoteTokenTest * Fixed tests in ERC20PoolReserveAuction.t.sol * updated ERC20PoolBorrowTest and ERC20PoolBorrowFuzzyTest * Fix ERC20PoolCollateral and ERC20PoolInfoUtils tests * Fixed ERC20 arbtake and depositTake tests * Fix ERC20PoolLiquidationsKickTest, ERC20PoolLiquidationKickFuzzyTest and ERC20PoolLiquidationsLenderKickAuctionTest * updated ERC20PoolMulticallTest * cleaned up ERC20PoolDebtExceedsDepositTest * fixed testTakeLoanColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosResidual * fixed testTakeCallerColConstraintBpfNegResidual * fixed testTakeLoanDebtConstraintBpfPosResidual * fixed testTakeAndSettle * cleaned up ERC20PoolDebtExceedsDepositTest * updated ERC20PoolPrecisionTest * Update ERC20PoolLiquidationsSettleTest * Update ERC20PoolLiquidationsMisc * Update ERC20PoolLiquidationSettleFuzzyTest * Update ERC20PoolLiquidationTakeFuzzyTest * fixeed revert tests * ERC20PoolLiquidationsTake -- fixed rest * Mh update tests (#985) * fix most position manager tests * fix additional pm tests * fix rewards requiredCollateralRewards setup * fix ClaimRewards tests * update additional rewards manager tests * fix additional tests * more test fixes * commit wip bankruptcy tests * fixed testMoveLiquidityToOverwriteBankruptBucket * fix additional tests * fix testMoveLiquidityWithDebtInPool * fix remaining rewards manager tests --------- Co-authored-by: Mike Co-authored-by: mwc * Add 1.04 factor in HTP calculations (#987) * Add 1.04 factor in HTP calculations * Add COLLATERALIZATION_FACTOR constant in PoolHelpers * Add collateralization factor in dwatp * Fix poolPricesInfo * Update ERC20PoolBorrowFuzzyTest * Fix some unit tests * Fix some unit tests * Fix some unit tests * Update ERC20PoolTransferLPs * fix most rewards manager tests * update remaining rewards manager tests * update ERC721SubsetPoolBorrowTest and commit wip changes to testMergeOrRemoveERC721Collateral * updated testSettlePartialDebtSubsetPool (#988) * updated testSettlePartialDebtSubsetPool * re-added teardown --------- Co-authored-by: Ian Harvey * fix ERC721PoolCollateral tests * fix borrowRepayDebtFuzzy and additional PM tests * cleaned up testBorrowAndRepayWith4DecimalQuote --------- Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey * Fix some unit tests * Deployment updates for RC8+ releases (#986) * cherry-picked from master * updated README * Fix ERC721PoolLiquidationsTakeTest * updated ERC721PoolReserveAuctionTest * updated testMergeOrRemoveERC721Collateral (#989) Co-authored-by: Ian Harvey * updated ERC721PoolPurchaseQuoteTest and fixed bug in ERC721 tearDown * cleaned up testLiquidationLenderKickAuction, testLiquidationSingleBorrower, testSettleAuctionWithoutTakes * updated testMoveLiquidityToOverwriteBankruptBucket * updated PoolHelperTest * cleaned up asserts in addLiquidity * update testMoveLiquidityInBankruptBucket_LP_report_179_494 * updated ERC721PoolEMAsTest * fixed testKickHighThresholdPriceBorrower * updated testBorrowerInterestCalculationAfterRepayingAllDebtOnce and testBorrowerInterestCalculation * updated testMultipleBorrowerInterestAccumulation * Fix regression tests * updated RE3, fixed _addQuoteToken * addQuoteToken - return amount added (#993) * addQuoteToken now returns amount added * update unit tests to validate return values * Fix up add liquidity (#992) * cleaned up addLiquidity() method in ERC20PoolLiquidationsScaled.t.sol * remove console --------- Co-authored-by: Ian Harvey * fixed issue with test_regression_fenwick_index_2 in non-18-decimal env * added regression tests for two failing reserves scenarios * rename tests such that automake runs them with other regression tests * UnboundedLiquidationPoolHandler bucketTake fix (#994) * updated UnboundedLiquidationPoolHandler to handle compensated collateral in bucketTake * cleanup, trap unhandled use case * settle event now emits actual debt settled rather than t0 amount (#999) * settle event now emits actual debt settled rather than t0 amount * updated test_regression_settle_with_reserves * Updated auctionInfo (#996) * add thresholdPrice to auctionInfo; update test iterface usages * temp fix tests * remove unneeded comment * Update auction status (#998) * wip auction status update w/ stack too deep * update auctionStatus; add auctionInfo method to poolInfoUtils --------- Co-authored-by: Mike --------- Co-authored-by: Mike * updated brownie tests, removed obsolete invariant tests (#1001) * Block addqt above auction price (#997) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * added unit test showing adding qt above auction price reverts * updated nit spellings --------- Co-authored-by: mwc Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey * Invariant testing fixes (#1006) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * documented a sample of invariant failures in regression tests * added unit test showing adding qt above auction price reverts * fixed _isCollateralized bug not returning true in all 0-debt use cases * updated nit spellings * fixed underflow calculating kicker reward * _repayDebtByThirdParty should check for expected pool errors * Round down when reward kicker, round up when kicker is penalized Fix roundings in tests * update test comments * fix and enable A9 invariant --------- Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * RC9 suggested improvements (#1005) * Revert AuctionNotTakeable in same place, load auction kickTime only once from storage * Calculate ERC721 collateralTaken only once cosmetize code (read from result struct in local var and reuse) Results in shrinking a little bit contract sizes * Read borrower Np Tp ratio from storage only once when kick * If block style, proper indentation * Proposed changes to PR #972: - avoid calculating current LUP twice in lender kick - change _kick function to accept proposed LUP (for regular kick proposed LUP is current LUP, for lender kick proposed LUP is calculated based on additional debt) - in both kick cases return current LUP in kick result - reduce gas costs by saving a Fenwick traversal - reduce contract size by removing LUP calculation within Pool * Cosmetic flashloan code changes, PoolCommons.flashLoan doesn't return false but always reverts if flashloan fails * PR#983 style, remove redundant line * PR#999 suggested improvement - calculate current settled debt only once and include in settle result for state update * PR #962 proposed changes: - get Fenwick deposits only once when settle with reserves - define constants for min bond factor and max npTp ratio values * PR #987 proposed improvement: - add and reuse _htp helper function (instead duplicated maths) * Continuation of PR #962: (#1008) - Record settle amount limmit in Liquidtion struct, at the time of kick (that is instead incrementing accumulator in Borrower struct, each time debt is drawn) - This way accumulator will be reseted when auction is settled - fix tests TODO: - assert Liquidation.t0ReserveSettleAmount in unit tests (_assertAuction), make sure is set to 0 after auction settled and decreased when partial settles done - update invariant test to check new introduced accumulator * Misc test fixes (#1009) * handle another reward rounding error use case * fix intermittant fuzz test failure - cannot draw debt from liquidity in bucket 7388 * PositionManager should expect AddAboveAuctionPrice, which can happen in moveLiquidity * Invariant fix: round up quote tokens calculated from rewarded LP (because LP rewarded are calculated in bucketTake as rewarded quote tokens -> LP rounded down) * initial commit * cleaned up, its executing * updated * rough draft of tests written * cleaned up examples added collateral asserts * borrower change not needed in PR * added new class inside ERC721PoolLiquidationsTake.t.sol * updated tests to adjust for take event --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: prateek105 Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * Emit subset hash on pool creation (#1029) * updated unit tests following merge of PR#1013 (#1030) * Continuation of #1021 - clear TP naming and improved code descriptions (#1027) * Continuation of #1021 - better naming and improved code descriptions - change Loan.thresholdPrice and Liquidation.thresholdPrice to unadjustedThresholdPrice naming in order to reflect Collateral factor not applied to these values - reflect in var names where max unadjusted threshold price is used (Move/Remove param struct) - natspec update - rename MAX_NP_TP_RATIO to MAX_BOND_FACTOR * clear Tp naming - t0DebtToCollateral : ( t0Debt / collateral ) - debtToCollateral : ( debt / collateral ) - t0ThresholdPrice : ( t0Debt / collateral ) * collateralization factor - thresholdPrice : ( debt / collateral ) * collateralization factor * Fix HeapTest * Update LoansInfo and LoanInfo methods to return maxT0DebtToCollateral and t0DebtToCollateral * Fix unit tests * Update assertLoans in tests and fix htp in BaseHandler * Update loansInfo and threshold Price in Loans library * Rename thresholdPrice to debtToCollateral in assertAuction in tests * updated zerothresholdprice error to zerodebttocollateral * removed unused _htp import in pool.sol * updated invariants to include ZeroDebtToCollateral * Use SafeCast in Loans library --------- Co-authored-by: prateek105 Co-authored-by: Ian Harvey * Fix unit test (#1034) * `_revertIfActiveAuctions` helper should revert with `ActiveAuction` error (#1031) * _revertIfActiveAuctions helper should revert with ActiveAuction error * Fix comment * added min protection to restrict underflow on `bucketTake` (#1033) * added min protection to restrict ability to underflow * updated repay --------- Co-authored-by: Ian Harvey * Calculate reserve auction price using kicked amount (#1032) * implement reserve auction pricing as originally described in whitepaper * bug fixes * wip updating RewardsManager tests * disable rewards unit tests * handle 0 bids on reserve auctions * updated erc721 reserve auction unit tests * fixed issue bidding on more than the quote token trading increment * updated new unit test * added tearDown to testZeroBid * removed rayToWad --------- Co-authored-by: Ian Harvey * Modify computation of quotetoken amount in TakerActions.sol (#1035) * test_regression_exchange_rate_failure * Modify computation of quotetoken amount in TakerActions.sol to compute bond reward accurately for collateral constrained takes with collateral tokens with decimals != 18. * Fix tests (#1036) * updated baseline --------- Co-authored-by: Ed Noepel Co-authored-by: mwc Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * Invariants improvements (#955) * Fix test_regression_failure_A8_5 * Remove repayDebtByThirdParty handler in SettleERC20PoolHandler, as repayment for borrower in auction is restricted * Add failing regression test_regression_bucket_take_arithmetic_over_underflow * Fix test_regression_bucket_take_arithmetic_over_underflow * Invariant RE9 improvement * Add failing regression test_regression_bucket_take_reserves_failure * Fix test_regression_bucket_take_reserves_failure * Add failing regression test_regression_bucket_take_re9_failure * Move failing regression tests to RegressionTestReservesWith8QuotePrecision12CollateralPrecisionERC20Pool * Fix test_regression_bucket_take_re9_failure * Fix regression tests failing due to reserve error margin calculation when auction price is 0 * Universal deposit fee (#983) * charge fee on all deposit * unit tests compile * test harness updates * working on ERC20PoolQuoteTokenTest * removed deposit fee cap * more work on ERC20PoolQuoteTokenTest * do not charge deposit fee if moving liquidity to higher price * Eliminate reserves bad debt allocation and add margin to TP (#962) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Add 1.04 factor in borrower collateralization * Update nptp ratio to '1 + sqrt(r)/2' * Remove Settle debt with pool reserves * Remove 0.995 factor from claimable reserves calculation * Update bond factor calculation to minimum 0.005 * added testcase where debt exceeds deposit * updated test so debt exceeds deposit * allow up to half of current orig fee to be used to settle bad debt * updated testTakeAndSettle * more test fixes * Enabled settling with all reserves if Deposits.treeSum==0 or 72 hrs pass * cleanup * Half orig fee res | Matt example (#966) * added Matts test as proof that attack no longer works on his branch * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * added test testSpendOrigFeePushBadDebtToBorrowers test * cleaned up testStealReservesWithMarginm to match minted balances * responded to Matts comments --------- Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Revert "Remove Settle debt with pool reserves" This reverts commit 290d6cf6f7baa1fb17a66322faf755b78a4a379c. * Update half origination fees reserves settlement time to 144 hours from kickTime * Fix alignment and extra spaces * Fix some unit tests * PR feedback * Update encumberance and collateralization method in poolInfoUtils * Fix some unit tests --------- Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Fix invariant setup * Fix some unit tests * ERC20PoolQuoteTokenTest updated * updated ERC20PoolPurchaseQuoteTokenTest * Fixed tests in ERC20PoolReserveAuction.t.sol * updated ERC20PoolBorrowTest and ERC20PoolBorrowFuzzyTest * Fix ERC20PoolCollateral and ERC20PoolInfoUtils tests * Fixed ERC20 arbtake and depositTake tests * Fix ERC20PoolLiquidationsKickTest, ERC20PoolLiquidationKickFuzzyTest and ERC20PoolLiquidationsLenderKickAuctionTest * updated ERC20PoolMulticallTest * cleaned up ERC20PoolDebtExceedsDepositTest * fixed testTakeLoanColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosResidual * fixed testTakeCallerColConstraintBpfNegResidual * fixed testTakeLoanDebtConstraintBpfPosResidual * fixed testTakeAndSettle * cleaned up ERC20PoolDebtExceedsDepositTest * updated ERC20PoolPrecisionTest * Update ERC20PoolLiquidationsSettleTest * Update ERC20PoolLiquidationsMisc * Update ERC20PoolLiquidationSettleFuzzyTest * Update ERC20PoolLiquidationTakeFuzzyTest * fixeed revert tests * ERC20PoolLiquidationsTake -- fixed rest * Mh update tests (#985) * fix most position manager tests * fix additional pm tests * fix rewards requiredCollateralRewards setup * fix ClaimRewards tests * update additional rewards manager tests * fix additional tests * more test fixes * commit wip bankruptcy tests * fixed testMoveLiquidityToOverwriteBankruptBucket * fix additional tests * fix testMoveLiquidityWithDebtInPool * fix remaining rewards manager tests --------- Co-authored-by: Mike Co-authored-by: mwc * Add 1.04 factor in HTP calculations (#987) * Add 1.04 factor in HTP calculations * Add COLLATERALIZATION_FACTOR constant in PoolHelpers * Add collateralization factor in dwatp * Fix poolPricesInfo * Update ERC20PoolBorrowFuzzyTest * Fix some unit tests * Fix some unit tests * Fix some unit tests * Update ERC20PoolTransferLPs * fix most rewards manager tests * update remaining rewards manager tests * update ERC721SubsetPoolBorrowTest and commit wip changes to testMergeOrRemoveERC721Collateral * updated testSettlePartialDebtSubsetPool (#988) * updated testSettlePartialDebtSubsetPool * re-added teardown --------- Co-authored-by: Ian Harvey * fix ERC721PoolCollateral tests * fix borrowRepayDebtFuzzy and additional PM tests * cleaned up testBorrowAndRepayWith4DecimalQuote --------- Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey * Fix some unit tests * Deployment updates for RC8+ releases (#986) * cherry-picked from master * updated README * Fix ERC721PoolLiquidationsTakeTest * updated ERC721PoolReserveAuctionTest * updated testMergeOrRemoveERC721Collateral (#989) Co-authored-by: Ian Harvey * updated ERC721PoolPurchaseQuoteTest and fixed bug in ERC721 tearDown * cleaned up testLiquidationLenderKickAuction, testLiquidationSingleBorrower, testSettleAuctionWithoutTakes * updated testMoveLiquidityToOverwriteBankruptBucket * updated PoolHelperTest * cleaned up asserts in addLiquidity * update testMoveLiquidityInBankruptBucket_LP_report_179_494 * updated ERC721PoolEMAsTest * fixed testKickHighThresholdPriceBorrower * updated testBorrowerInterestCalculationAfterRepayingAllDebtOnce and testBorrowerInterestCalculation * updated testMultipleBorrowerInterestAccumulation * Fix regression tests * updated RE3, fixed _addQuoteToken * addQuoteToken - return amount added (#993) * addQuoteToken now returns amount added * update unit tests to validate return values * Fix up add liquidity (#992) * cleaned up addLiquidity() method in ERC20PoolLiquidationsScaled.t.sol * remove console --------- Co-authored-by: Ian Harvey * fixed issue with test_regression_fenwick_index_2 in non-18-decimal env * added regression tests for two failing reserves scenarios * rename tests such that automake runs them with other regression tests * UnboundedLiquidationPoolHandler bucketTake fix (#994) * updated UnboundedLiquidationPoolHandler to handle compensated collateral in bucketTake * cleanup, trap unhandled use case * settle event now emits actual debt settled rather than t0 amount (#999) * settle event now emits actual debt settled rather than t0 amount * updated test_regression_settle_with_reserves * Updated auctionInfo (#996) * add thresholdPrice to auctionInfo; update test iterface usages * temp fix tests * remove unneeded comment * Update auction status (#998) * wip auction status update w/ stack too deep * update auctionStatus; add auctionInfo method to poolInfoUtils --------- Co-authored-by: Mike --------- Co-authored-by: Mike * updated brownie tests, removed obsolete invariant tests (#1001) * Block addqt above auction price (#997) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * added unit test showing adding qt above auction price reverts * updated nit spellings --------- Co-authored-by: mwc Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey * Invariant testing fixes (#1006) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * documented a sample of invariant failures in regression tests * added unit test showing adding qt above auction price reverts * fixed _isCollateralized bug not returning true in all 0-debt use cases * updated nit spellings * fixed underflow calculating kicker reward * _repayDebtByThirdParty should check for expected pool errors * Round down when reward kicker, round up when kicker is penalized Fix roundings in tests * update test comments * fix and enable A9 invariant --------- Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * RC9 suggested improvements (#1005) * Revert AuctionNotTakeable in same place, load auction kickTime only once from storage * Calculate ERC721 collateralTaken only once cosmetize code (read from result struct in local var and reuse) Results in shrinking a little bit contract sizes * Read borrower Np Tp ratio from storage only once when kick * If block style, proper indentation * Proposed changes to PR #972: - avoid calculating current LUP twice in lender kick - change _kick function to accept proposed LUP (for regular kick proposed LUP is current LUP, for lender kick proposed LUP is calculated based on additional debt) - in both kick cases return current LUP in kick result - reduce gas costs by saving a Fenwick traversal - reduce contract size by removing LUP calculation within Pool * Cosmetic flashloan code changes, PoolCommons.flashLoan doesn't return false but always reverts if flashloan fails * PR#983 style, remove redundant line * PR#999 suggested improvement - calculate current settled debt only once and include in settle result for state update * PR #962 proposed changes: - get Fenwick deposits only once when settle with reserves - define constants for min bond factor and max npTp ratio values * PR #987 proposed improvement: - add and reuse _htp helper function (instead duplicated maths) * Continuation of PR #962: (#1008) - Record settle amount limmit in Liquidtion struct, at the time of kick (that is instead incrementing accumulator in Borrower struct, each time debt is drawn) - This way accumulator will be reseted when auction is settled - fix tests TODO: - assert Liquidation.t0ReserveSettleAmount in unit tests (_assertAuction), make sure is set to 0 after auction settled and decreased when partial settles done - update invariant test to check new introduced accumulator * Misc test fixes (#1009) * handle another reward rounding error use case * fix intermittant fuzz test failure - cannot draw debt from liquidity in bucket 7388 * PositionManager should expect AddAboveAuctionPrice, which can happen in moveLiquidity * Invariant fix: round up quote tokens calculated from rewarded LP (because LP rewarded are calculated in bucketTake as rewarded quote tokens -> LP rounded down) * Take 1 - invariant code cleanup * Take 2: reserves and other helpers * Merge branch 'merge-rc9' into failing-regressions * Fix pool address in tests * Take 3 - more changes * Pr feedback * Fix failing unit tests * Fix failing unit tests * Take 4 * Fix test_regression_rw_reserves_failure_4 * buckettake reserves failure * Fix test_regression_failure_reserves_on_bucketTake, update Invariant RE9 * Fix _takeAuction * Fix unit tests * PR feedback * Fix bucketIndex in _bucketTake handler * Add getLoansInfo helper, remove duplicated settle code, more style * Additional code style and helper use * Add back Positions tests * Update TP naming in invariants --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * Reduce CRA interval to 5 days (#1040) * shortened CRA interval to 5 days * update comment * resolve build warning * update interval to a total of 120 hours * Update src/libraries/external/KickerActions.sol Co-authored-by: Kirill Fedoseev --------- Co-authored-by: Kirill Fedoseev * Fix HTP calculation in invariant logic (#1042) * deposits invariant failure on kick for both pool types * 18-decimal deposit on kick failure * Fix HTP calculation in _fenwickAccrueInterest * Update test comments --------- Co-authored-by: Ed Noepel * add external getters for borrower and bucketTokenIds (#1028) * add external getters for borrower and bucketTokenIds * update erc721 tests to use new methods * update comment pr feedback --------- Co-authored-by: Mike * Update poolInfoUtils.borrowerInfo to return thresholdPrice (#1017) * Universal deposit fee (#983) * charge fee on all deposit * unit tests compile * test harness updates * working on ERC20PoolQuoteTokenTest * removed deposit fee cap * more work on ERC20PoolQuoteTokenTest * do not charge deposit fee if moving liquidity to higher price * Eliminate reserves bad debt allocation and add margin to TP (#962) * this underflows instead of giving expected revert * move isCollateralized check after updating borrower collateral * remove local calculation of encumbered collateral * trying to properly fix testBorrowRepayPrecision * resolve rounding issue in fuzz test * testCollateralization improvements * updated unit tests for new _collateralization implementation * more collateralization tests * Add 1.04 factor in borrower collateralization * Update nptp ratio to '1 + sqrt(r)/2' * Remove Settle debt with pool reserves * Remove 0.995 factor from claimable reserves calculation * Update bond factor calculation to minimum 0.005 * added testcase where debt exceeds deposit * updated test so debt exceeds deposit * allow up to half of current orig fee to be used to settle bad debt * updated testTakeAndSettle * more test fixes * Enabled settling with all reserves if Deposits.treeSum==0 or 72 hrs pass * cleanup * Half orig fee res | Matt example (#966) * added Matts test as proof that attack no longer works on his branch * Revert "Remove multicall from position manager (#948)" (#961) This reverts commit f540c8a75fe58b9fdb8249da33f271a5f0ad335c. * added test testSpendOrigFeePushBadDebtToBorrowers test * cleaned up testStealReservesWithMarginm to match minted balances * responded to Matts comments --------- Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Revert "Remove Settle debt with pool reserves" This reverts commit 290d6cf6f7baa1fb17a66322faf755b78a4a379c. * Update half origination fees reserves settlement time to 144 hours from kickTime * Fix alignment and extra spaces * Fix some unit tests * PR feedback * Update encumberance and collateralization method in poolInfoUtils * Fix some unit tests --------- Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: Mike Hathaway * Fix invariant setup * Fix some unit tests * ERC20PoolQuoteTokenTest updated * updated ERC20PoolPurchaseQuoteTokenTest * Fixed tests in ERC20PoolReserveAuction.t.sol * updated ERC20PoolBorrowTest and ERC20PoolBorrowFuzzyTest * Fix ERC20PoolCollateral and ERC20PoolInfoUtils tests * Fixed ERC20 arbtake and depositTake tests * Fix ERC20PoolLiquidationsKickTest, ERC20PoolLiquidationKickFuzzyTest and ERC20PoolLiquidationsLenderKickAuctionTest * updated ERC20PoolMulticallTest * cleaned up ERC20PoolDebtExceedsDepositTest * fixed testTakeLoanColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosNoResidual * fixed testTakeCallerColConstraintBpfPosResidual * fixed testTakeCallerColConstraintBpfNegResidual * fixed testTakeLoanDebtConstraintBpfPosResidual * fixed testTakeAndSettle * cleaned up ERC20PoolDebtExceedsDepositTest * updated ERC20PoolPrecisionTest * Update ERC20PoolLiquidationsSettleTest * Update ERC20PoolLiquidationsMisc * Update ERC20PoolLiquidationSettleFuzzyTest * Update ERC20PoolLiquidationTakeFuzzyTest * fixeed revert tests * ERC20PoolLiquidationsTake -- fixed rest * Mh update tests (#985) * fix most position manager tests * fix additional pm tests * fix rewards requiredCollateralRewards setup * fix ClaimRewards tests * update additional rewards manager tests * fix additional tests * more test fixes * commit wip bankruptcy tests * fixed testMoveLiquidityToOverwriteBankruptBucket * fix additional tests * fix testMoveLiquidityWithDebtInPool * fix remaining rewards manager tests --------- Co-authored-by: Mike Co-authored-by: mwc * Add 1.04 factor in HTP calculations (#987) * Add 1.04 factor in HTP calculations * Add COLLATERALIZATION_FACTOR constant in PoolHelpers * Add collateralization factor in dwatp * Fix poolPricesInfo * Update ERC20PoolBorrowFuzzyTest * Fix some unit tests * Fix some unit tests * Fix some unit tests * Update ERC20PoolTransferLPs * fix most rewards manager tests * update remaining rewards manager tests * update ERC721SubsetPoolBorrowTest and commit wip changes to testMergeOrRemoveERC721Collateral * updated testSettlePartialDebtSubsetPool (#988) * updated testSettlePartialDebtSubsetPool * re-added teardown --------- Co-authored-by: Ian Harvey * fix ERC721PoolCollateral tests * fix borrowRepayDebtFuzzy and additional PM tests * cleaned up testBorrowAndRepayWith4DecimalQuote --------- Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey * Fix some unit tests * Deployment updates for RC8+ releases (#986) * cherry-picked from master * updated README * Fix ERC721PoolLiquidationsTakeTest * updated ERC721PoolReserveAuctionTest * updated testMergeOrRemoveERC721Collateral (#989) Co-authored-by: Ian Harvey * updated ERC721PoolPurchaseQuoteTest and fixed bug in ERC721 tearDown * cleaned up testLiquidationLenderKickAuction, testLiquidationSingleBorrower, testSettleAuctionWithoutTakes * updated testMoveLiquidityToOverwriteBankruptBucket * updated PoolHelperTest * cleaned up asserts in addLiquidity * update testMoveLiquidityInBankruptBucket_LP_report_179_494 * updated ERC721PoolEMAsTest * fixed testKickHighThresholdPriceBorrower * updated testBorrowerInterestCalculationAfterRepayingAllDebtOnce and testBorrowerInterestCalculation * updated testMultipleBorrowerInterestAccumulation * Fix regression tests * updated RE3, fixed _addQuoteToken * addQuoteToken - return amount added (#993) * addQuoteToken now returns amount added * update unit tests to validate return values * Fix up add liquidity (#992) * cleaned up addLiquidity() method in ERC20PoolLiquidationsScaled.t.sol * remove console --------- Co-authored-by: Ian Harvey * fixed issue with test_regression_fenwick_index_2 in non-18-decimal env * added regression tests for two failing reserves scenarios * rename tests such that automake runs them with other regression tests * UnboundedLiquidationPoolHandler bucketTake fix (#994) * updated UnboundedLiquidationPoolHandler to handle compensated collateral in bucketTake * cleanup, trap unhandled use case * settle event now emits actual debt settled rather than t0 amount (#999) * settle event now emits actual debt settled rather than t0 amount * updated test_regression_settle_with_reserves * Updated auctionInfo (#996) * add thresholdPrice to auctionInfo; update test iterface usages * temp fix tests * remove unneeded comment * Update auction status (#998) * wip auction status update w/ stack too deep * update auctionStatus; add auctionInfo method to poolInfoUtils --------- Co-authored-by: Mike --------- Co-authored-by: Mike * updated brownie tests, removed obsolete invariant tests (#1001) * Block addqt above auction price (#997) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * added unit test showing adding qt above auction price reverts * updated nit spellings --------- Co-authored-by: mwc Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Ed Noepel Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey * Invariant testing fixes (#1006) * initial commit * tweaks to Matt's PR to block adding quote token above auction price (#1000) * reduce cost of reference price assignment * reduce pool contract size * fixed testDepositTakeAndSettleByRegularTakeSubsetPool * fixed tests in ERC20PoolLiquidationsArbTake.t.sol * fixed tests in ERC20PoolLiquidationsDepositTake.sol * fixed two more * updated testDepositTakeAndSettleSubsetPool * updated testKickAndSettleSubsetPoolFractionalCollateral * updated testSettleWithDepositFuzzy * Fixed final tests * add "AddAboveAuctionPrice" as expected pool error * implemented invariant A9: reference prices in liquidation queue shall not decrease * Update assertAuction to use ThresholdPrice from auctionInfo (#1003) * use auctionInfo thresholdprice instead of recalculating * fix most tests * update remaining tests --------- Co-authored-by: Mike * Contract size mitigation (#1004) * moved debtInfo to PoolCommons, saving 10 bytes * moved withdrawBonds to KickerActions * documented a sample of invariant failures in regression tests * added unit test showing adding qt above auction price reverts * fixed _isCollateralized bug not returning true in all 0-debt use cases * updated nit spellings * fixed underflow calculating kicker reward * _repayDebtByThirdParty should check for expected pool errors * Round down when reward kicker, round up when kicker is penalized Fix roundings in tests * update test comments * fix and enable A9 invariant --------- Co-authored-by: mwc Co-authored-by: Mike Hathaway Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * RC9 suggested improvements (#1005) * Revert AuctionNotTakeable in same place, load auction kickTime only once from storage * Calculate ERC721 collateralTaken only once cosmetize code (read from result struct in local var and reuse) Results in shrinking a little bit contract sizes * Read borrower Np Tp ratio from storage only once when kick * If block style, proper indentation * Proposed changes to PR #972: - avoid calculating current LUP twice in lender kick - change _kick function to accept proposed LUP (for regular kick proposed LUP is current LUP, for lender kick proposed LUP is calculated based on additional debt) - in both kick cases return current LUP in kick result - reduce gas costs by saving a Fenwick traversal - reduce contract size by removing LUP calculation within Pool * Cosmetic flashloan code changes, PoolCommons.flashLoan doesn't return false but always reverts if flashloan fails * PR#983 style, remove redundant line * PR#999 suggested improvement - calculate current settled debt only once and include in settle result for state update * PR #962 proposed changes: - get Fenwick deposits only once when settle with reserves - define constants for min bond factor and max npTp ratio values * PR #987 proposed improvement: - add and reuse _htp helper function (instead duplicated maths) * Continuation of PR #962: (#1008) - Record settle amount limmit in Liquidtion struct, at the time of kick (that is instead incrementing accumulator in Borrower struct, each time debt is drawn) - This way accumulator will be reseted when auction is settled - fix tests TODO: - assert Liquidation.t0ReserveSettleAmount in unit tests (_assertAuction), make sure is set to 0 after auction settled and decreased when partial settles done - update invariant test to check new introduced accumulator * Misc test fixes (#1009) * handle another reward rounding error use case * fix intermittant fuzz test failure - cannot draw debt from liquidity in bucket 7388 * PositionManager should expect AddAboveAuctionPrice, which can happen in moveLiquidity * Invariant fix: round up quote tokens calculated from rewarded LP (because LP rewarded are calculated in bucketTake as rewarded quote tokens -> LP rounded down) * Pr feedback * Fix failing unit tests * update poolInfoUtils.borrowerInfo interface * return thresholdPrice instead of t0ThresholdPrice * fix compile warnings * update borrowerInfo threshold price references * resolved comments on borrowerInfo --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: Ed Noepel Co-authored-by: Ian Harvey Co-authored-by: mwc Co-authored-by: Ian Harvey Co-authored-by: prateek105 Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> * Remove `RewardsManager.sol` (#1041) * compiles and unit tests run * remove additional rewards manager references * remove additional references * fix ERC20PoolPositionHandler init logic * cleaned up folder naming and removed redundant function calls and depreciated tests (#1043) Co-authored-by: Ian Harvey * resolved naming and re-introduced Eds changes from 04c6ccd0d83669371a331763a7ad10198c816c2f * Rename Positions dir --------- Co-authored-by: Ed Noepel Co-authored-by: Mike Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey Co-authored-by: grandizzy * Comment cleanup in ERC721PoolCollateral.t.sol (#1044) * cleaned up comment * comment and formatting cleanup * renamed some instances of token to NFT * cleaned up nit comment changes --------- Co-authored-by: Ian Harvey * Cherry pick merge from master, PoolInfoUtils update (#1045) * Unmask id variable (#932) * Update info multicall (#958) * add poolRatesAndFeesMulticall; add Multicall to poolInfoUtils * add poolDetailsMulticall method * add natspec; remove unused functions * update tests * add poolBalanceDetails for remaining subgraph rpc calls * expand poolInfoUtilsMulticall unit tests * normalize token balances in poolBalanceDetails * replace internal multicall usage --------- Co-authored-by: Mike * replace PoolInfoUtils.unutilizedDepositFeeRate with .depositFeeRate, update tests * eliminate custom multicall implementation * remove unused multicall utility functions --------- Co-authored-by: Brian L. McMichael Co-authored-by: Mike Hathaway Co-authored-by: Mike * Continuation of PR #1040 - code cleanup and comments (#1048) * Continuation of PR #1040 - code cleanup and comments - remove unused errors from Kicker and Taker actions libraries - improve natspec with revert error on CRA * Update Pool natspec * Fix slither CI - install forge in flow to compile (#1051) * Fix slither CI - install forge to be able to compile * Fix slither for external libraries, remove unused IERC20Token.transfer* functions to fix https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-erc20-interface warning * Revert with `InvalidAmount` if unscaled amount to add / remove in `Deposit` library (#1049) * add test_regression_B2_failure_moveQuote test * Revert when unscaled quote token amount to move is 0 * Remove redundant import * Update natspec doc * Add 'InvalidAmount' revert in Deposits library when amount to add / remove is zero, add check to remove only non-zero deposits in settleActions * added comment to test * added min protection to restrict underflow and cleaned up comments in settle flows * revised imp per Dizzy's request * comment clean up --------- Co-authored-by: grandizzy Co-authored-by: Ian Harvey * `invariant_reserves` failure when `take` / `bucketTake` (#1050) * Add test_regression_failure_reserves_bucketTake_18precision * Add regular take test failure * adjust reserves tolerance to allow for large inflators * fix issue with extreme TPs and reserves accrusing * Add test_regression_reservesTakeAction_failure * added tolerance for large inflator value in reserves change for takeAuction * added comments to regression test sequences * Commented change to reserves error margin * fixed up invariants.md to reflect code --------- Co-authored-by: mwc Co-authored-by: Ian Harvey --------- Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey Co-authored-by: Prateek Gupta Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: Mike Hathaway Co-authored-by: Brian L. McMichael Co-authored-by: mwc Co-authored-by: prateek105 Co-authored-by: Mike Co-authored-by: mattcushman <36414299+mattcushman@users.noreply.github.com> Co-authored-by: grandizzy Co-authored-by: Kirill Fedoseev --- .github/pull_request_template.md | 47 +- .github/workflows/slither.yml | 13 +- Makefile | 3 - README.md | 8 +- src/ERC20Pool.sol | 24 +- src/ERC20PoolFactory.sol | 2 +- src/ERC721Pool.sol | 30 +- src/ERC721PoolFactory.sol | 2 +- src/PoolInfoUtils.sol | 145 +- src/PoolInfoUtilsMulticall.sol | 194 +- src/PositionManager.sol | 14 +- src/RewardsManager.sol | 864 ---- src/base/FlashloanablePool.sol | 32 +- src/base/Pool.sol | 140 +- src/base/PoolDeployer.sol | 1 + src/interfaces/pool/IPool.sol | 6 - src/interfaces/pool/IPoolFactory.sol | 3 +- src/interfaces/pool/commons/IPoolErrors.sol | 19 +- src/interfaces/pool/commons/IPoolEvents.sol | 5 + .../pool/commons/IPoolInternals.sol | 18 +- .../pool/commons/IPoolKickerActions.sol | 3 +- .../pool/commons/IPoolLenderActions.sol | 11 +- .../pool/commons/IPoolSettlerActions.sol | 8 +- src/interfaces/pool/commons/IPoolState.sol | 69 +- .../pool/erc721/IERC721PoolState.sol | 19 +- .../position/IPositionManagerOwnerActions.sol | 4 +- src/interfaces/rewards/IRewardsManager.sol | 19 - .../rewards/IRewardsManagerDerivedState.sol | 21 - .../rewards/IRewardsManagerErrors.sol | 43 - .../rewards/IRewardsManagerEvents.sol | 75 - .../rewards/IRewardsManagerOwnerActions.sol | 64 - .../rewards/IRewardsManagerState.sol | 105 - src/libraries/external/BorrowerActions.sol | 22 +- src/libraries/external/KickerActions.sol | 161 +- src/libraries/external/LenderActions.sol | 70 +- src/libraries/external/PoolCommons.sol | 123 +- src/libraries/external/PositionNFTSVG.sol | 2 - src/libraries/external/SettlerActions.sol | 48 +- src/libraries/external/TakerActions.sol | 86 +- src/libraries/helpers/PoolHelper.sol | 129 +- src/libraries/helpers/RevertsHelper.sol | 34 +- src/libraries/internal/Deposits.sol | 19 + src/libraries/internal/Loans.sol | 49 +- src/libraries/internal/Maths.sol | 4 - tests/INVARIANTS.md | 23 +- tests/README.md | 18 +- tests/brownie/conftest.py | 8 +- tests/brownie/test_invariants.py | 639 --- tests/brownie/test_scaled_pool.py | 10 +- tests/brownie/test_stable_volatile.py | 12 +- .../interactions/BalancerUniswapExample.sol | 8 +- .../ERC20TakeWithExternalLiquidity.t.sol | 20 +- .../ERC721TakeWithExternalLiquidity.sol | 16 +- .../PurchaseQuoteWithExternalLiquidity.t.sol | 2 +- .../handlers/BasicERC20PoolHandler.sol | 59 +- .../handlers/LiquidationERC20PoolHandler.sol | 8 +- .../handlers/PanicExitERC20PoolHandler.sol | 29 +- .../handlers/SettleERC20PoolHandler.sol | 171 +- .../handlers/TradingERC20PoolHandler.sol | 31 +- .../UnboundedBasicERC20PoolHandler.sol | 71 +- .../BasicERC721PoolInvariants.t.sol | 14 +- .../handlers/BasicERC721PoolHandler.sol | 82 +- .../handlers/LiquidationERC721PoolHandler.sol | 4 +- .../handlers/PanicExitERC721PoolHandler.sol | 27 +- .../unbounded/BaseERC721PoolHandler.sol | 11 +- .../UnboundedBasicERC721PoolHandler.sol | 101 +- .../ERC20PoolPositionsInvariants.t.sol | 2 +- .../ERC721PoolPositionsInvariants.t.sol | 0 .../PositionsInvariants.sol | 6 +- .../handlers/BasePositionPoolHandler.sol | 52 +- .../handlers/ERC20PoolPositionHandler.sol} | 110 +- .../handlers/ERC721PoolPositionHandler.sol | 0 .../handlers/PositionPoolHandler.sol | 11 +- .../UnboundedBasePositionHandler.sol | 21 +- .../UnboundedPositionPoolHandler.sol | 231 +- ...BankruptcyERC20PoolRewardsInvariants.t.sol | 74 - .../ERC20PoolRewardsInvariants.t.sol | 75 - .../ERC721PoolRewardsInvariants.t.sol | 76 - .../RewardsInvariants.t.sol | 74 - .../handlers/BaseRewardsPoolHandler.sol | 76 - .../handlers/ERC20PoolPositionHandler.sol | 50 - .../handlers/ERC20PoolRewardsHandler.sol | 96 - .../handlers/ERC721PoolRewardsHandler.sol | 93 - .../handlers/RewardsPoolHandler.sol | 189 - .../unbounded/UnboundedRewardsPoolHandler.sol | 305 -- .../invariants/base/BasicInvariants.t.sol | 35 +- .../base/LiquidationInvariants.t.sol | 24 +- .../invariants/base/ReserveInvariants.t.sol | 10 +- .../base/handlers/BasicPoolHandler.sol | 96 +- .../base/handlers/LiquidationPoolHandler.sol | 134 +- .../base/handlers/ReservePoolHandler.sol | 13 +- .../base/handlers/unbounded/BaseHandler.sol | 243 +- .../unbounded/UnboundedBasicPoolHandler.sol | 101 +- .../UnboundedLiquidationPoolHandler.sol | 397 +- .../unbounded/UnboundedReservePoolHandler.sol | 15 +- .../invariants/interfaces/IBaseHandler.sol | 1 + ...wardsHandler.sol => IPositionsHandler.sol} | 9 +- .../RegressionTestBasicERC20Pool.t.sol | 8 +- .../RegressionTestLiquidationERC20Pool.t.sol | 77 +- .../RegressionTestReservesERC20Pool.t.sol | 3861 +++++++++++++++++ .../RegressionTestSettleERC20Pool.t.sol | 24 + .../RegressionTestLiquidationERC721Pool.t.sol | 119 + .../RegressionTestReservesERC721Pool.t.sol | 84 + ...sionTestBankBankruptcyERC20PoolRewards.sol | 430 -- ...egressionTestERC20PoolRewardsManager.t.sol | 538 --- ...gressionTestERC721PoolRewardsManager.t.sol | 77 - ...gressionTestERC20PoolPositionManager.t.sol | 23 +- ...ressionTestERC721PoolPositionManager.t.sol | 2 +- tests/forge/unit/Auctions.t.sol | 107 +- .../ERC20BorrowerTpLessThanMinPrice.t.sol | 54 + .../forge/unit/ERC20Pool/ERC20DSTestPlus.sol | 49 +- .../unit/ERC20Pool/ERC20PoolBorrow.t.sol | 543 ++- .../unit/ERC20Pool/ERC20PoolCollateral.t.sol | 68 +- .../ERC20PoolDebtExceedsDeposit.t.sol | 467 ++ .../unit/ERC20Pool/ERC20PoolFactory.t.sol | 17 +- .../unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol | 24 +- .../unit/ERC20Pool/ERC20PoolInfoUtils.t.sol | 230 +- .../ERC20Pool/ERC20PoolInputValidation.t.sol | 22 +- .../ERC20PoolInterestRateAndEMAs.t.sol | 305 +- .../ERC20PoolLiquidationsArbTake.t.sol | 414 +- .../ERC20PoolLiquidationsDepositTake.t.sol | 427 +- .../ERC20Pool/ERC20PoolLiquidationsKick.t.sol | 231 +- .../ERC20PoolLiquidationsLenderKick.t.sol | 490 ++- .../ERC20Pool/ERC20PoolLiquidationsMisc.t.sol | 306 +- .../ERC20PoolLiquidationsScaled.t.sol | 42 +- .../ERC20PoolLiquidationsSettle.t.sol | 660 ++- .../ERC20Pool/ERC20PoolLiquidationsTake.t.sol | 1135 +++-- .../unit/ERC20Pool/ERC20PoolLoanHeap.t.sol | 38 +- .../unit/ERC20Pool/ERC20PoolMulticall.t.sol | 42 +- .../unit/ERC20Pool/ERC20PoolPrecision.t.sol | 424 +- .../ERC20Pool/ERC20PoolPurchaseQuote.t.sol | 71 +- .../unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 562 ++- .../ERC20Pool/ERC20PoolReserveAuction.t.sol | 159 +- .../unit/ERC20Pool/ERC20PoolTransferLPs.t.sol | 62 +- .../ERC20Pool/ERC20SafeTransferTokens.sol | 4 +- .../unit/ERC721Pool/ERC721DSTestPlus.sol | 13 +- .../unit/ERC721Pool/ERC721PoolBorrow.t.sol | 235 +- .../ERC721Pool/ERC721PoolCollateral.t.sol | 402 +- .../unit/ERC721Pool/ERC721PoolEMAs.t.sol | 180 +- .../unit/ERC721Pool/ERC721PoolFactory.t.sol | 8 + .../ERC721PoolInputValidation.t.sol | 20 +- .../unit/ERC721Pool/ERC721PoolInterest.t.sol | 103 +- .../ERC721PoolLiquidationsDepositTake.t.sol | 136 +- .../ERC721PoolLiquidationsKick.t.sol | 116 +- .../ERC721PoolLiquidationsSettle.t.sol | 74 +- .../ERC721PoolLiquidationsSettleAuction.t.sol | 592 +-- .../ERC721PoolLiquidationsTake.t.sol | 874 +++- .../ERC721Pool/ERC721PoolPurchaseQuote.t.sol | 61 +- .../ERC721Pool/ERC721PoolReserveAuction.t.sol | 203 +- tests/forge/unit/FenwickTree.t.sol | 18 + tests/forge/unit/Heap.t.sol | 340 +- tests/forge/unit/MathTest.t.sol | 13 - tests/forge/unit/PoolHelperTest.t.sol | 194 +- .../CodearenaReports.t.sol | 108 +- .../PositionManager.t.sol | 465 +- tests/forge/unit/Rewards/ClaimRewards.t.sol | 366 -- .../forge/unit/Rewards/RewardsDSTestPlus.sol | 557 --- tests/forge/unit/Rewards/RewardsManager.t.sol | 2985 ------------- tests/forge/unit/Rewards/RoguePool.sol | 54 - tests/forge/utils/AuctionQueueInstance.sol | 122 + tests/forge/utils/DSTestPlus.sol | 184 +- tests/forge/utils/FenwickTreeInstance.sol | 11 +- tests/forge/utils/HeapInstance.sol | 18 +- 163 files changed, 12857 insertions(+), 14532 deletions(-) delete mode 100644 src/RewardsManager.sol delete mode 100644 src/interfaces/rewards/IRewardsManager.sol delete mode 100644 src/interfaces/rewards/IRewardsManagerDerivedState.sol delete mode 100644 src/interfaces/rewards/IRewardsManagerErrors.sol delete mode 100644 src/interfaces/rewards/IRewardsManagerEvents.sol delete mode 100644 src/interfaces/rewards/IRewardsManagerOwnerActions.sol delete mode 100644 src/interfaces/rewards/IRewardsManagerState.sol delete mode 100644 tests/brownie/test_invariants.py rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/ERC20PoolPositionsInvariants.t.sol (96%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/ERC721PoolPositionsInvariants.t.sol (100%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/PositionsInvariants.sol (93%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/handlers/BasePositionPoolHandler.sol (77%) rename tests/forge/invariants/{PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol => PositionManager/handlers/ERC20PoolPositionHandler.sol} (66%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/handlers/ERC721PoolPositionHandler.sol (100%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/handlers/PositionPoolHandler.sol (97%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/handlers/unbounded/UnboundedBasePositionHandler.sol (83%) rename tests/forge/invariants/{PositionsAndRewards => PositionManager}/handlers/unbounded/UnboundedPositionPoolHandler.sol (61%) delete mode 100644 tests/forge/invariants/PositionsAndRewards/BucketBankruptcyERC20PoolRewardsInvariants.t.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/BaseRewardsPoolHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol rename tests/forge/invariants/interfaces/{IPositionsAndRewardsHandler.sol => IPositionsHandler.sol} (52%) create mode 100644 tests/forge/regression/ERC20Pool/RegressionTestSettleERC20Pool.t.sol delete mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol delete mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol delete mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol rename tests/forge/regression/{PositionAndRewards => PositionManager}/RegressionTestERC20PoolPositionManager.t.sol (85%) rename tests/forge/regression/{PositionAndRewards => PositionManager}/RegressionTestERC721PoolPositionManager.t.sol (92%) create mode 100644 tests/forge/unit/ERC20Pool/ERC20BorrowerTpLessThanMinPrice.t.sol create mode 100644 tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol rename tests/forge/unit/{Positions => PositionManager}/CodearenaReports.t.sol (90%) rename tests/forge/unit/{Positions => PositionManager}/PositionManager.t.sol (89%) delete mode 100644 tests/forge/unit/Rewards/ClaimRewards.t.sol delete mode 100644 tests/forge/unit/Rewards/RewardsDSTestPlus.sol delete mode 100644 tests/forge/unit/Rewards/RewardsManager.t.sol delete mode 100644 tests/forge/unit/Rewards/RoguePool.sol create mode 100644 tests/forge/utils/AuctionQueueInstance.sol diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 53f44caf0..2870a6728 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,37 +1,24 @@ +## Description - -# Description of change -## High level -* - * + - + -# Description of bug or vulnerability and solution -* -* +## Impact -# Contract size -## Pre Change - -## Post Change - + -# Gas usage -## Pre Change - -## Post Change - +## Tasks +- [ ] Changes to protocol contracts are covered by unit tests executed by CI. +- [ ] Protocol contract size limits have not been exceeded. +- [ ] Gas consumption for impacted transactions have been compared with the target branch, and nontrivial changes cited in the _Impact_ section above. +- [ ] Scope labels have been assigned as appropriate. +- [ ] Invariant tests have been manually executed as appropriate for the nature of the change. diff --git a/.github/workflows/slither.yml b/.github/workflows/slither.yml index c6dab8de2..d6fcb869d 100644 --- a/.github/workflows/slither.yml +++ b/.github/workflows/slither.yml @@ -8,6 +8,11 @@ jobs: with: submodules: recursive + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Install and set solc version run: | pip install solc-select && solc-select install 0.8.18 && solc-select use 0.8.18 @@ -38,12 +43,6 @@ jobs: continue-on-error: true id: position-analyzer - - name: Analyze RewardsManager Contract - run: | - slither src/RewardsManager.sol - continue-on-error: true - id: rewards-analyzer - - name: Analyze PoolInfoUtils Contract run: | slither src/PoolInfoUtils.sol @@ -52,7 +51,7 @@ jobs: - name: Analyze Libraries run: | - slither src/libraries/external/. + slither src/libraries/external/ continue-on-error: true id: libraries-analyzer diff --git a/Makefile b/Makefile index 8efb142aa..f8c6d5381 100644 --- a/Makefile +++ b/Makefile @@ -29,8 +29,6 @@ test-invariant-erc20 :; forge t --mt invariant --nmc ${CONTR test-invariant-erc721 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC721 test-invariant-position-erc20 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC20PoolPosition test-invariant-position-erc721 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC721PoolPosition -test-invariant-rewards-erc20 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC20PoolRewards -test-invariant-rewards-erc721 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC721PoolRewards test-invariant :; forge t --mt ${MT} --nmc RegressionTest test-invariant-erc20-precision :; ./tests/forge/invariants/test-invariant-erc20-precision.sh test-invariant-erc721-precision :; ./tests/forge/invariants/test-invariant-erc721-precision.sh @@ -54,7 +52,6 @@ test-swap-load-erc20 :; FOUNDRY_INVARIANT_SHRINK_SEQUENCE=false RUST test-regression-all : test-regression-erc20 test-regression-erc721 test-regression-prototech test-regression-erc20 :; forge t --mt test_regression --mc ERC20 --nmc "RealWorldRegression|Prototech" test-regression-erc721 :; forge t --mt test_regression --mc ERC721 --nmc "RealWorldRegression|Prototech" -test-regression-rewards :; forge t --mt test_regression --mc Rewards --nmc "RealWorldRegression|Prototech" test-regression-position :; forge t --mt test_regression --mc Position --nmc "RealWorldRegression|Prototech" test-regression-prototech :; forge t --mt test_regression --mc Prototech test-regression-rw :; forge t --mt test_regression --mc RealWorldRegression diff --git a/README.md b/README.md index 2b52e62b5..57b2ea97c 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ Record these addresses. If Etherscan verification fails on the first try, copy Failing that, manual verification is possible. Following steps show how to do this on Goerli (chainId 5), using addresses from the example output above. * Open `broadcast/5/run-latest.json` and find the _"libraries"_ section towards the end of the file. * Copy/paste the _libraries_ config into the _[profile.default]_ section of `foundry.toml`, replacing the `:` with an `=`. -* Run the following commands, adjusting addresses as appropriate: +* Run the following commands, adjusting addresses as appropriate. _PoolInfoUtilsMulticall_ constructor takes the address of _PoolInfoUtils_. _PositionManager_ constructor takes the factory addresses. ``` forge verify-contract --chain-id 5 --watch 0x14F2474fB5ea9DF82059053c4F85A8C803Ab10C9 ERC20PoolFactory --constructor-args $(cast abi-encode "constructor(address)" ${AJNA_TOKEN}) forge verify-contract --chain-id 5 --watch 0xb0d1c875B240EE9f6C2c3284a31b10f1EC6De7d2 ERC721PoolFactory --constructor-args $(cast abi-encode "constructor(address)" ${AJNA_TOKEN}) @@ -221,7 +221,7 @@ Failing that, manual verification is possible. Following steps show how to do t Validate the deployment by creating a pool. Set relevant environment variables, and run the following: ``` -cast send ${ERC20_POOLFACTORY} "deployPool(address,address,uint256)(address)" \ +cast send ${AJNA_ERC20_POOLFACTORY} "deployPool(address,address,uint256)(address)" \ ${WBTC_TOKEN} ${DAI_TOKEN} 50000000000000000 \ --from ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY} ``` @@ -229,7 +229,7 @@ cast send ${ERC20_POOLFACTORY} "deployPool(address,address,uint256)(address)" \ Where did it deploy the pool? Let's find out: ``` export ERC20_NON_SUBSET_HASH=0x2263c4378b4920f0bef611a3ff22c506afa4745b3319c50b6d704a874990b8b2 -cast call ${ERC20_POOLFACTORY} "deployedPools(bytes32,address,address)(address)" \ +cast call ${AJNA_ERC20_POOLFACTORY} "deployedPools(bytes32,address,address)(address)" \ ${ERC20_NON_SUBSET_HASH} ${WBTC_TOKEN} ${DAI_TOKEN} ``` Record the pool address. @@ -238,6 +238,6 @@ Run an approval to let the contract spend some of your quote token, and then add ``` cast send ${DAI_TOKEN} "approve(address,uint256)" ${WBTC_DAI_POOL} 50000ether \ --from ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY} -cast send ${WBTC_DAI_POOL} "addQuoteToken(uint256,uint256)" 100ether 3232 \ +cast send ${WBTC_DAI_POOL} "addQuoteToken(uint256,uint256,uint256)" 100ether 3232 $(($(cast block -f timestamp) + 60)) \ --from ${DEPLOY_ADDRESS} --keystore ${DEPLOY_KEY} ``` diff --git a/src/ERC20Pool.sol b/src/ERC20Pool.sol index fc1e6a5bd..6dfc1b378 100644 --- a/src/ERC20Pool.sol +++ b/src/ERC20Pool.sol @@ -221,13 +221,14 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { limitIndex_ ); - emit RepayDebt(borrowerAddress_, result.quoteTokenToRepay, collateralAmountToPull_, result.newLup); - + amountRepaid_ = result.quoteTokenToRepay; // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; poolState.collateral = result.poolCollateral; + emit RepayDebt(borrowerAddress_, amountRepaid_, collateralAmountToPull_, result.newLup); + // adjust t0Debt2ToCollateral ratio _updateT0Debt2ToCollateral( result.debtPreAction, @@ -239,12 +240,12 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { // update pool interest rate state _updateInterestState(poolState, result.newLup); - if (result.quoteTokenToRepay != 0) { + if (amountRepaid_ != 0) { // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; // move amount to repay from sender to pool - _transferQuoteTokenFrom(msg.sender, result.quoteTokenToRepay); + _transferQuoteTokenFrom(msg.sender, amountRepaid_); } if (collateralAmountToPull_ != 0) { // update pool balances pledged collateral state @@ -253,8 +254,6 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { // move collateral from pool to address specified as collateral receiver _transferCollateral(collateralReceiver_, collateralAmountToPull_); } - - amountRepaid_ = result.quoteTokenToRepay; } /*********************************/ @@ -345,7 +344,7 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { function settle( address borrowerAddress_, uint256 maxDepth_ - ) external override nonReentrant { + ) external override nonReentrant returns (uint256 collateralSettled_, bool isBorrowerSettled_) { PoolState memory poolState = _accruePoolInterest(); SettleResult memory result = SettlerActions.settlePoolDebt( @@ -363,6 +362,9 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { ); _updatePostSettleState(result, poolState); + + collateralSettled_ = result.collateralSettled; + isBorrowerSettled_ = (result.debtPostAction == 0); } /** @@ -401,19 +403,19 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { _updatePostTakeState(result, poolState); - _transferCollateral(callee_, result.collateralAmount); + collateralTaken_ = result.collateralAmount; + + _transferCollateral(callee_, collateralTaken_); if (data_.length != 0) { IERC20Taker(callee_).atomicSwapCallback( - result.collateralAmount / collateralTokenScale, + collateralTaken_ / collateralTokenScale, result.quoteTokenAmount / poolState.quoteTokenScale, data_ ); } _transferQuoteTokenFrom(msg.sender, result.quoteTokenAmount); - - collateralTaken_ = result.collateralAmount; } /** diff --git a/src/ERC20PoolFactory.sol b/src/ERC20PoolFactory.sol index 9330af5cc..787c2115e 100644 --- a/src/ERC20PoolFactory.sol +++ b/src/ERC20PoolFactory.sol @@ -75,7 +75,7 @@ contract ERC20PoolFactory is PoolDeployer, IERC20PoolFactory { deployedPools[ERC20_NON_SUBSET_HASH][collateral_][quote_] = pool_; deployedPoolsList.push(pool_); - emit PoolCreated(pool_); + emit PoolCreated(pool_, ERC20_NON_SUBSET_HASH); pool.initialize(interestRate_); } diff --git a/src/ERC721Pool.sol b/src/ERC721Pool.sol index 75cab09a9..697e167c8 100644 --- a/src/ERC721Pool.sol +++ b/src/ERC721Pool.sol @@ -236,13 +236,14 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { limitIndex_ ); - emit RepayDebt(borrowerAddress_, result.quoteTokenToRepay, noOfNFTsToPull_, result.newLup); - + amountRepaid_ = result.quoteTokenToRepay; // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; poolState.collateral = result.poolCollateral; + emit RepayDebt(borrowerAddress_, amountRepaid_, noOfNFTsToPull_, result.newLup); + // adjust t0Debt2ToCollateral ratio _updateT0Debt2ToCollateral( result.debtPreAction, @@ -257,19 +258,17 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // update pool balances pledged collateral state poolBalances.pledgedCollateral = poolState.collateral; - if (result.quoteTokenToRepay != 0) { + if (amountRepaid_ != 0) { // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; // move amount to repay from sender to pool - _transferQuoteTokenFrom(msg.sender, result.quoteTokenToRepay); + _transferQuoteTokenFrom(msg.sender, amountRepaid_); } if (noOfNFTsToPull_ != 0) { // move collateral from pool to address specified as collateral receiver _transferFromPoolToAddress(collateralReceiver_, borrowerTokenIds[msg.sender], noOfNFTsToPull_); } - - amountRepaid_ = result.quoteTokenToRepay; } /*********************************/ @@ -344,7 +343,6 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // Total collateral in buckets meets the requested removal amount, noOfNFTsToRemove_ _transferFromPoolToAddress(msg.sender, bucketTokenIds, noOfNFTsToRemove_); } - } /** @@ -394,7 +392,7 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { function settle( address borrowerAddress_, uint256 maxDepth_ - ) external nonReentrant override { + ) external nonReentrant override returns (uint256 collateralSettled_, bool isBorrowerSettled_) { PoolState memory poolState = _accruePoolInterest(); SettleParams memory params = SettleParams({ @@ -417,6 +415,9 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // move token ids from borrower array to pool claimable array if any collateral used to settle bad debt _rebalanceTokens(params.borrower, result.collateralRemaining); + + collateralSettled_ = result.collateralSettled; + isBorrowerSettled_ = (result.debtPostAction == 0); } /** @@ -449,10 +450,11 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { _updatePostTakeState(result, poolState); // transfer rounded collateral from pool to taker + collateralTaken_ = result.collateralAmount / 1e18; uint256[] memory tokensTaken = _transferFromPoolToAddress( callee_, borrowerTokenIds[borrowerAddress_], - result.collateralAmount / 1e18 + collateralTaken_ ); uint256 totalQuoteTokenAmount = result.quoteTokenAmount + result.excessQuoteToken; @@ -473,8 +475,6 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // transfer from pool to borrower the excess of quote tokens after rounding collateral auctioned if (result.excessQuoteToken != 0) _transferQuoteToken(borrowerAddress_, result.excessQuoteToken); - - collateralTaken_ = result.collateralAmount / 1e18; } /** @@ -615,13 +615,13 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { /*******************************/ /// @inheritdoc IERC721PoolState - function totalBorrowerTokens(address borrower_) external view override returns(uint256) { - return borrowerTokenIds[borrower_].length; + function getBorrowerTokenIds(address borrower_) external view override returns(uint256[] memory) { + return borrowerTokenIds[borrower_]; } /// @inheritdoc IERC721PoolState - function totalBucketTokens() external view override returns(uint256) { - return bucketTokenIds.length; + function getBucketTokenIds() external view override returns(uint256[] memory) { + return bucketTokenIds; } } diff --git a/src/ERC721PoolFactory.sol b/src/ERC721PoolFactory.sol index 830132e24..eefb19ce9 100644 --- a/src/ERC721PoolFactory.sol +++ b/src/ERC721PoolFactory.sol @@ -85,7 +85,7 @@ contract ERC721PoolFactory is PoolDeployer, IERC721PoolFactory { deployedPools[subsetHash][collateral_][quote_] = pool_; deployedPoolsList.push(pool_); - emit PoolCreated(pool_); + emit PoolCreated(pool_, subsetHash); pool.initialize(tokenIds_, interestRate_); } diff --git a/src/PoolInfoUtils.sol b/src/PoolInfoUtils.sol index 748f9b669..001ac883c 100644 --- a/src/PoolInfoUtils.sol +++ b/src/PoolInfoUtils.sol @@ -19,8 +19,10 @@ import { _minDebtAmount, _priceAt, _reserveAuctionPrice, + _htp, MAX_FENWICK_INDEX, - MIN_PRICE + MIN_PRICE, + COLLATERALIZATION_FACTOR } from './libraries/helpers/PoolHelper.sol'; import { Buckets } from './libraries/internal/Buckets.sol'; @@ -35,6 +37,16 @@ import { PoolCommons } from './libraries/external/PoolCommons.sol'; */ contract PoolInfoUtils is Multicall { + /** + * @notice Struct contianing local variables used in `auctionStatus` to get around stack size limitations. + * @param lup The price value of the current `Lowest Utilized Price` (`LUP`) bucket, in `WAD` units. + * @param poolDebt Current amount of debt owed by borrowers in pool. (`WAD`). + */ + struct AuctionStatusLocalVars { + uint256 lup; + uint256 poolDebt; + } + /** * @notice Exposes status of a liquidation auction. * @param ajnaPool_ Address of `Ajna` pool. @@ -45,6 +57,9 @@ contract PoolInfoUtils is Multicall { * @return isCollateralized_ `True` if loan is collateralized. * @return price_ Current price of the auction. (`WAD`) * @return neutralPrice_ Price at which bond holder is neither rewarded nor penalized. (`WAD`) + * @return referencePrice_ Price used to determine auction start price. (`WAD`) + * @return debtToCollateral_ Borrower debt to collateral at time of kick. (`WAD`) + * @return bondFactor_ The factor used for calculating bond size. (`WAD`) */ function auctionStatus(address ajnaPool_, address borrower_) external @@ -55,30 +70,71 @@ contract PoolInfoUtils is Multicall { uint256 debtToCover_, bool isCollateralized_, uint256 price_, - uint256 neutralPrice_ + uint256 neutralPrice_, + uint256 referencePrice_, + uint256 debtToCollateral_, + uint256 bondFactor_ ) { - IPool pool = IPool(ajnaPool_); - uint256 referencePrice; - ( , , , kickTime_, referencePrice, neutralPrice_, , , ) = pool.auctionInfo(borrower_); + AuctionStatusLocalVars memory vars; + ( , + bondFactor_, + , + kickTime_, + referencePrice_, + neutralPrice_, + debtToCollateral_, , , ) = IPool(ajnaPool_).auctionInfo(borrower_); + if (kickTime_ != 0) { - (debtToCover_, collateral_, ) = this.borrowerInfo(ajnaPool_, borrower_); - - (uint256 poolDebt,,,) = pool.debtInfo(); - uint256 lup_ = _priceAt(pool.depositIndex(poolDebt)); - isCollateralized_ = _isCollateralized(debtToCover_, collateral_, lup_, pool.poolType()); + (debtToCover_, collateral_, , ) = this.borrowerInfo(ajnaPool_, borrower_); - price_ = _auctionPrice(referencePrice, kickTime_); + (vars.poolDebt,,,) = IPool(ajnaPool_).debtInfo(); + vars.lup = _priceAt(IPool(ajnaPool_).depositIndex(vars.poolDebt)); + isCollateralized_ = _isCollateralized(debtToCover_, collateral_, vars.lup, IPool(ajnaPool_).poolType()); + + price_ = _auctionPrice(referencePrice_, kickTime_); } } + /** + * @notice Returns details of an auction for a given borrower address. + * @dev Calls and returns all values from pool.auctionInfo(). + * @param ajnaPool_ Address of `Ajna` pool. + * @param borrower_ Address of the borrower that is liquidated. + * @return kicker_ Address of the kicker that is kicking the auction. + * @return bondFactor_ The factor used for calculating bond size. + * @return bondSize_ The bond amount in quote token terms. + * @return kickTime_ Time the liquidation was initiated. + * @return referencePrice_ Price used to determine auction start price. + * @return neutralPrice_ `Neutral Price` of auction. + * @return debtToCollateral_ Borrower debt to collateral at time of kick, which is used in BPF for kicker's reward calculation. + * @return head_ Address of the head auction. + * @return next_ Address of the next auction in queue. + * @return prev_ Address of the prev auction in queue. + */ + function auctionInfo(address ajnaPool_, address borrower_) external view returns ( + address kicker_, + uint256 bondFactor_, + uint256 bondSize_, + uint256 kickTime_, + uint256 referencePrice_, + uint256 neutralPrice_, + uint256 debtToCollateral_, + address head_, + address next_, + address prev_ + ) { + return IPool(ajnaPool_).auctionInfo(borrower_); + } + /** * @notice Retrieves info of a given borrower in a given `Ajna` pool. - * @param ajnaPool_ Address of `Ajna` pool. - * @param borrower_ Borrower's address. - * @return debt_ Current debt owed by borrower (`WAD`). - * @return collateral_ Pledged collateral, including encumbered (`WAD`). - * @return t0Np_ `Neutral price` (`WAD`). + * @param ajnaPool_ Address of `Ajna` pool. + * @param borrower_ Borrower's address. + * @return debt_ Current debt owed by borrower (`WAD`). + * @return collateral_ Pledged collateral, including encumbered (`WAD`). + * @return t0Np_ `Neutral price` (`WAD`). + * @return thresholdPrice_ Borrower's `Threshold Price` (`WAD`). */ function borrowerInfo(address ajnaPool_, address borrower_) external @@ -86,7 +142,8 @@ contract PoolInfoUtils is Multicall { returns ( uint256 debt_, uint256 collateral_, - uint256 t0Np_ + uint256 t0Np_, + uint256 thresholdPrice_ ) { IPool pool = IPool(ajnaPool_); @@ -104,9 +161,9 @@ contract PoolInfoUtils is Multicall { uint256 npTpRatio; (t0Debt, collateral_, npTpRatio) = pool.borrowerInfo(borrower_); - t0Np_ = collateral_ == 0 ? 0 : Math.mulDiv(t0Debt, npTpRatio, collateral_); - + t0Np_ = collateral_ == 0 ? 0 : Math.mulDiv(Maths.wmul(t0Debt, COLLATERALIZATION_FACTOR), npTpRatio, collateral_); debt_ = Maths.ceilWmul(t0Debt, pendingInflator); + thresholdPrice_ = collateral_ == 0 ? 0 : Maths.wmul(Maths.wdiv(debt_, collateral_), COLLATERALIZATION_FACTOR); } /** @@ -205,9 +262,18 @@ contract PoolInfoUtils is Multicall { hpbIndex_ = pool.depositIndex(1); hpb_ = _priceAt(hpbIndex_); - (, uint256 maxThresholdPrice,) = pool.loansInfo(); + (, uint256 maxT0DebtToCollateral,) = pool.loansInfo(); + + ( + uint256 inflator, + uint256 inflatorUpdate + ) = pool.inflatorInfo(); + + (uint256 interestRate, ) = pool.interestRateInfo(); - htp_ = maxThresholdPrice; + uint256 pendingInflator = PoolCommons.pendingInflator(inflator, inflatorUpdate, interestRate); + + htp_ = _htp(maxT0DebtToCollateral, pendingInflator); htpIndex_ = htp_ >= MIN_PRICE ? _indexOf(htp_) : MAX_FENWICK_INDEX; lupIndex_ = pool.depositIndex(debt); lup_ = _priceAt(lupIndex_); @@ -224,7 +290,7 @@ contract PoolInfoUtils is Multicall { ( uint256 bondEscrowed, uint256 unclaimedReserve, - , + , , ) = pool.reservesInfo(); uint256 escrowedAmounts = bondEscrowed + unclaimedReserve; @@ -260,7 +326,7 @@ contract PoolInfoUtils is Multicall { uint256 quoteTokenBalance = IERC20Token(pool.quoteTokenAddress()).balanceOf(ajnaPool_) * pool.quoteTokenScale(); - (uint256 bondEscrowed, uint256 unclaimedReserve, uint256 auctionKickTime, ) = pool.reservesInfo(); + (uint256 bondEscrowed, uint256 unclaimedReserve, uint256 auctionKickTime, uint256 lastKickedReserves, ) = pool.reservesInfo(); // due to rounding issues, especially in Auction.settle, this can be slighly negative if (poolDebt + quoteTokenBalance >= poolSize + bondEscrowed + unclaimedReserve) { @@ -276,7 +342,7 @@ contract PoolInfoUtils is Multicall { ); claimableReservesRemaining_ = unclaimedReserve; - auctionPrice_ = _reserveAuctionPrice(auctionKickTime); + auctionPrice_ = _reserveAuctionPrice(auctionKickTime, lastKickedReserves); timeRemaining_ = 3 days - Maths.min(3 days, block.timestamp - auctionKickTime); } @@ -410,7 +476,19 @@ contract PoolInfoUtils is Multicall { function htp( address ajnaPool_ ) external view returns (uint256 htp_) { - (, htp_, ) = IPool(ajnaPool_).loansInfo(); + IPool pool = IPool(ajnaPool_); + + (, uint256 maxT0DebtToCollateral,) = pool.loansInfo(); + + ( + uint256 inflator, + uint256 inflatorUpdate + ) = pool.inflatorInfo(); + + (uint256 interestRate, ) = pool.interestRateInfo(); + uint256 pendingInflator = PoolCommons.pendingInflator(inflator, inflatorUpdate, interestRate); + + htp_ = _htp(maxT0DebtToCollateral, pendingInflator); } /** @@ -426,11 +504,11 @@ contract PoolInfoUtils is Multicall { } /** - * @notice Calculates unutilized deposit fee rate for a pool. - * @notice Calculated as current annualized rate divided by `365` (`24` hours of interest). + * @notice Calculates deposit fee rate for a pool. + * @notice Calculated as current annualized rate divided by 365 * 3 (8 hours of interest) * @return Fee rate calculated from the pool interest rate. */ - function unutilizedDepositFeeRate( + function depositFeeRate( address ajnaPool_ ) external view returns (uint256) { (uint256 interestRate,) = IPool(ajnaPool_).interestRateInfo(); @@ -455,7 +533,6 @@ contract PoolInfoUtils is Multicall { bucketCollateral, bucketDeposit, lp_, - bucketDeposit, _priceAt(index_) ); } @@ -497,7 +574,7 @@ contract PoolInfoUtils is Multicall { uint256 debt_, uint256 price_ ) pure returns (uint256 encumberance_) { - return price_ != 0 && debt_ != 0 ? Maths.wdiv(debt_, price_) : 0; + return price_ != 0 ? Maths.wdiv(Maths.wmul(COLLATERALIZATION_FACTOR , debt_), price_) : 0; } /** @@ -512,8 +589,12 @@ contract PoolInfoUtils is Multicall { uint256 collateral_, uint256 price_ ) pure returns (uint256) { - uint256 encumbered = _encumberance(debt_, price_); - return encumbered != 0 ? Maths.wdiv(collateral_, encumbered) : Maths.WAD; + // cannot be undercollateralized if there is no debt + if (debt_ == 0) return 1e18; + + // borrower is undercollateralized when lup at MIN_PRICE + if (price_ == MIN_PRICE) return 0; + return Maths.wdiv(Maths.wmul(collateral_, price_), Maths.wmul(COLLATERALIZATION_FACTOR, debt_)); } /** diff --git a/src/PoolInfoUtilsMulticall.sol b/src/PoolInfoUtilsMulticall.sol index b0ac9fe2f..842f0f3a5 100644 --- a/src/PoolInfoUtilsMulticall.sol +++ b/src/PoolInfoUtilsMulticall.sol @@ -106,7 +106,7 @@ contract PoolInfoUtilsMulticall { // retrieve rates and fees poolRatesAndFees_.lenderInterestMargin = poolInfoUtils.lenderInterestMargin(ajnaPool_); poolRatesAndFees_.borrowFeeRate = poolInfoUtils.borrowFeeRate(ajnaPool_); - poolRatesAndFees_.depositFeeRate = poolInfoUtils.unutilizedDepositFeeRate(ajnaPool_); + poolRatesAndFees_.depositFeeRate = poolInfoUtils.depositFeeRate(ajnaPool_); // retrieve reserves info ( @@ -130,11 +130,11 @@ contract PoolInfoUtilsMulticall { * @notice Retrieves info of lenderInterestMargin, borrowFeeRate and depositFeeRate * @param ajnaPool_ Address of `Ajna` pool * @return lenderInterestMargin Lender interest margin in pool - * @return borrowFeeRate Borrow fee rate calculated from the pool interest ra + * @return borrowFeeRate Borrow fee rate calculated from the pool interest rate * @return depositFeeRate Deposit fee rate calculated from the pool interest rate */ function poolRatesAndFeesMulticall(address ajnaPool_) - external + external view returns ( uint256 lenderInterestMargin, @@ -144,7 +144,7 @@ contract PoolInfoUtilsMulticall { { lenderInterestMargin = poolInfoUtils.lenderInterestMargin(ajnaPool_); borrowFeeRate = poolInfoUtils.borrowFeeRate(ajnaPool_); - depositFeeRate = poolInfoUtils.unutilizedDepositFeeRate(ajnaPool_); + depositFeeRate = poolInfoUtils.depositFeeRate(ajnaPool_); } /** @@ -186,190 +186,4 @@ contract PoolInfoUtilsMulticall { poolBalanceDetails_.collateralTokenBalance = poolCollateralBalance * collateralScale; } } - - /** - * @notice Aggregate results from multiple read-only function calls - * @param functionSignatures_ Array of signatures of read-only functions to be called - * @param args_ Array of serialized function arguments of all read-only functions to called - * @return results_ Array of result of all read-only function calls in bytes - */ - function multicall(string[] calldata functionSignatures_, string[] calldata args_) external returns (bytes[] memory results_) { - uint256 currentIndex = 0; - results_ = new bytes[](functionSignatures_.length); - for(uint256 i = 0; i < functionSignatures_.length; i++) { - string[] memory parameters = _parseFunctionSignature(functionSignatures_[i]); - uint256 noOfParams = parameters.length; - bytes memory callData; - if (noOfParams == 1) { - if (keccak256(bytes(parameters[0])) == keccak256(bytes("uint256"))) { - uint256 arg = _stringToUint(args_[currentIndex]); - callData = abi.encodeWithSignature(functionSignatures_[i], arg); - } - if (keccak256(bytes(parameters[0])) == keccak256(bytes("address"))) { - address arg = _stringToAddress(args_[currentIndex]); - callData = abi.encodeWithSignature(functionSignatures_[i], arg); - } - } - - if (noOfParams == 2) { - if (keccak256(bytes(parameters[1])) == keccak256(bytes("uint256"))) { - address arg1 = _stringToAddress(args_[currentIndex]); - uint256 arg2 = _stringToUint(args_[currentIndex + 1]); - callData = abi.encodeWithSignature(functionSignatures_[i], arg1, arg2); - } - if (keccak256(bytes(parameters[1])) == keccak256(bytes("address"))) { - address arg1 = _stringToAddress(args_[currentIndex]); - address arg2 = _stringToAddress(args_[currentIndex + 1]); - callData = abi.encodeWithSignature(functionSignatures_[i], arg1, arg2); - } - } - - if (noOfParams == 3) { - address arg1 = _stringToAddress(args_[currentIndex]); - uint256 arg2 = _stringToUint(args_[currentIndex + 1]); - uint256 arg3 = _stringToUint(args_[currentIndex + 2]); - callData = abi.encodeWithSignature(functionSignatures_[i], arg1, arg2, arg3); - } - - currentIndex += noOfParams; - (, results_[i]) = address(poolInfoUtils).call(callData); - } - } - - // Returns all function parameters - function _parseFunctionSignature(string memory signature_) internal pure returns (string[] memory parameters_) { - // Remove the function name and parentheses from the signature - string memory parametersString = _removeParentheses(signature_); - - parameters_ = _splitString(parametersString, ","); - } - - // Remove function name and Parentheses from signature - function _removeParentheses(string memory signature_) internal pure returns (string memory trimmedSignature_) { - // Remove function name - trimmedSignature_ = _trimFunctionName(signature_); - - // Check if the string starts with '(' and ends with ')' - if (bytes(trimmedSignature_).length >= 2 && bytes(trimmedSignature_)[0] == bytes("(")[0] && bytes(trimmedSignature_)[bytes(trimmedSignature_).length - 1] == bytes(")")[0]) { - // Remove the first and last characters - trimmedSignature_ = _substring(trimmedSignature_, 1, bytes(trimmedSignature_).length - 2); - } - } - - // Splits a string into an array of strings using a specified delimiter - function _splitString(string memory str_, string memory delimiter_) internal pure returns (string[] memory parts_) { - uint256 numDelimiters = _countOccurrences(str_, delimiter_) + 1; - parts_ = new string[](numDelimiters); - - uint256 currentIndex = 0; - for (uint256 i = 0; i < numDelimiters - 1; i++) { - uint256 delimiterIndex = uint256(_indexOf(str_, delimiter_, currentIndex)); - parts_[i] = _substring(str_, currentIndex, delimiterIndex - 1); - currentIndex = delimiterIndex + bytes(delimiter_).length; - } - parts_[numDelimiters - 1] = _substring(str_, currentIndex, bytes(str_).length - 1); - } - - // Removes the function name from a string - function _trimFunctionName(string memory str_) internal pure returns (string memory) { - uint256 start = 0; - uint256 end = bytes(str_).length - 1; - - while (start <= end && bytes(str_)[start] != bytes("(")[0]) { - start++; - } - - if (end >= start) { - return _substring(str_, start, end); - } else { - return ""; - } - } - - // Counts the occurrences of a pattern within a string - function _countOccurrences(string memory str_, string memory pattern_) internal pure returns (uint256 count_) { - uint256 lastIndex = 0; - while (_indexOf(str_, pattern_, lastIndex) != int256(-1)) { - lastIndex = uint256(_indexOf(str_, pattern_, lastIndex)) + bytes(pattern_).length; - count_++; - } - } - - // Finds the index of a pattern within a string - function _indexOf(string memory str_, string memory pattern_, uint256 startIndex_) internal pure returns (int256) { - bytes memory strBytes = bytes(str_); - bytes memory patternBytes = bytes(pattern_); - - for (uint256 i = startIndex_; i <= strBytes.length - patternBytes.length; i++) { - bool found = true; - for (uint256 j = 0; j < patternBytes.length; j++) { - if (strBytes[i + j] != patternBytes[j]) { - found = false; - break; - } - } - if (found) { - return int256(i); - } - } - return int256(-1); - } - - // Extracts a substring from a given string - function _substring(string memory str_, uint256 startIndex_, uint256 endIndex_) internal pure returns (string memory) { - require(startIndex_ <= endIndex_, "Invalid substring indices"); - bytes memory strBytes = bytes(str_); - bytes memory result = new bytes(endIndex_ - startIndex_ + 1); - - for (uint256 i = startIndex_; i <= endIndex_; i++) { - result[i - startIndex_] = strBytes[i]; - } - - return string(result); - } - - // Converts a string to an unsigned integer - function _stringToUint(string memory str_) internal pure returns (uint256 result_) { - bytes memory strBytes = bytes(str_); - for (uint256 i = 0; i < strBytes.length; i++) { - uint256 val = uint256(uint8(strBytes[i])); - if (val >= 48 && val <= 57) { - result_ = result_ * 10 + (val - 48); - } - } - } - - // Converts a hexadecimal character to its decimal value - function _hexCharToDecimal(uint8 character_) internal pure returns (uint8) { - if (bytes1(character_) >= bytes1('0') && bytes1(character_) <= bytes1('9')) { - return character_ - uint8(bytes1('0')); - } - if (bytes1(character_) >= bytes1('a') && bytes1(character_) <= bytes1('f')) { - return 10 + character_ - uint8(bytes1('a')); - } - if (bytes1(character_) >= bytes1('A') && bytes1(character_) <= bytes1('F')) { - return 10 + character_ - uint8(bytes1('A')); - } - return 0; - } - - // Converts a hexadecimal string to bytes - function _hexStringToBytes(string memory str_) internal pure returns (bytes memory bytesString_) { - bytes memory strBytes = bytes(str_); - require(strBytes.length % 2 == 0); // length must be even - bytesString_ = new bytes(strBytes.length / 2); - for (uint i = 1; i < strBytes.length / 2; ++i) { - bytesString_[i] = bytes1(_hexCharToDecimal(uint8(strBytes[2 * i])) * 16 + _hexCharToDecimal(uint8(strBytes[2 * i + 1]))); - } - } - - // Converts a hexadecimal string to an Ethereum address - function _stringToAddress(string calldata str_) internal pure returns (address tempAddress_) { - bytes memory strBytes = _hexStringToBytes(str_); - require(strBytes.length >= 1 + 20, "toAddress_outOfBounds"); - - assembly { - tempAddress_ := div(mload(add(add(strBytes, 0x20), 1)), 0x1000000000000000000000000) - } - } } \ No newline at end of file diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 0a91dd553..6f74c123b 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.18; import { ERC20 } from '@openzeppelin/contracts/token/ERC20/ERC20.sol'; import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { EnumerableSet } from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import { Multicall } from '@openzeppelin/contracts/utils/Multicall.sol'; import { ReentrancyGuard } from '@openzeppelin/contracts/security/ReentrancyGuard.sol'; import { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; @@ -36,7 +37,7 @@ import { PositionNFTSVG } from './libraries/external/PositionNFTSVG.sol'; * - `redeem` positions for given buckets * - `burn` positions `NFT` */ -contract PositionManager is PermitERC721, IPositionManager, ReentrancyGuard { +contract PositionManager is PermitERC721, IPositionManager, Multicall, ReentrancyGuard { using EnumerableSet for EnumerableSet.UintSet; using SafeERC20 for ERC20; @@ -291,8 +292,7 @@ contract PositionManager is PermitERC721, IPositionManager, ReentrancyGuard { uint256 tokenId_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_, - bool revertIfBelowLup_ + uint256 expiry_ ) external override nonReentrant mayInteract(pool_, tokenId_) { TokenInfo storage tokenInfo = positionTokens[tokenId_]; Position storage fromPosition = tokenInfo.positions[fromIndex_]; @@ -324,7 +324,6 @@ contract PositionManager is PermitERC721, IPositionManager, ReentrancyGuard { vars.bucketCollateral, vars.bucketDeposit, vars.fromLP, - vars.bucketDeposit, _priceAt(fromIndex_) ); @@ -336,8 +335,7 @@ contract PositionManager is PermitERC721, IPositionManager, ReentrancyGuard { vars.maxQuote, fromIndex_, toIndex_, - expiry_, - revertIfBelowLup_ + expiry_ ); EnumerableSet.UintSet storage positionIndexes = tokenInfo.positionIndexes; @@ -593,9 +591,7 @@ contract PositionManager is PermitERC721, IPositionManager, ReentrancyGuard { collateralTokenSymbol: tokenSymbol(collateralTokenAddress), quoteTokenSymbol: tokenSymbol(quoteTokenAddress), tokenId: tokenId_, - pool: pool, - owner: ownerOf(tokenId_), - indexes: tokenInfo.positionIndexes.values() + owner: ownerOf(tokenId_) }); return PositionNFTSVG.constructTokenURI(params); diff --git a/src/RewardsManager.sol b/src/RewardsManager.sol deleted file mode 100644 index 892b20bdd..000000000 --- a/src/RewardsManager.sol +++ /dev/null @@ -1,864 +0,0 @@ -// SPDX-License-Identifier: BUSL-1.1 - -pragma solidity 0.8.18; - -import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; -import { IERC721 } from '@openzeppelin/contracts/token/ERC721/IERC721.sol'; -import { SafeERC20 } from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; - -import { IPool } from './interfaces/pool/IPool.sol'; -import { IPositionManager } from './interfaces/position/IPositionManager.sol'; -import { IPositionManagerOwnerActions } from './interfaces/position/IPositionManagerOwnerActions.sol'; -import { - IRewardsManager, - IRewardsManagerOwnerActions, - IRewardsManagerState, - IRewardsManagerDerivedState -} from './interfaces/rewards/IRewardsManager.sol'; -import { - StakeInfo, - BucketState, - PoolRewardsInfo -} from './interfaces/rewards/IRewardsManagerState.sol'; - -import { PositionManager } from './PositionManager.sol'; - -import { Maths } from './libraries/internal/Maths.sol'; - -/** - * @title Rewards (staking) Manager contract - * @notice Pool lenders can optionally mint `NFT` that represents their positions. - * The Rewards contract allows pool lenders with positions `NFT` to stake and earn `Ajna` tokens. - * Lenders with `NFT`s can: - * - `stake` token - * - `update bucket exchange rate` and earn rewards - * - `claim` rewards - * - `unstake` token - */ -contract RewardsManager is IRewardsManager { - - using SafeERC20 for IERC20; - - /*****************/ - /*** Constants ***/ - /*****************/ - - /** - * @notice Maximum percentage of tokens burned that can be claimed as `Ajna` token `LP` `NFT` rewards. - */ - uint256 internal constant REWARD_CAP = 800000000000000000; // 0.8 * 1e18 - /** - * @notice Maximum percentage of tokens burned that can be claimed as `Ajna` token update rewards. - */ - uint256 internal constant UPDATE_CAP = 100000000000000000; // 0.1 * 1e18 - /** - * @notice Reward factor by which to scale the total rewards earned. - * @dev ensures that rewards issued to staked lenders in a given pool are less than the `Ajna` tokens burned in that pool. - */ - uint256 internal constant REWARD_FACTOR = 500000000000000000; // 0.5 * 1e18 - /** - * @notice Reward factor by which to scale rewards earned for updating a buckets exchange rate. - */ - uint256 internal constant UPDATE_CLAIM_REWARD = 50000000000000000; // 0.05 * 1e18 - /** - * @notice Time period after a burn event in which buckets exchange rates can be updated. - */ - uint256 internal constant UPDATE_PERIOD = 2 weeks; - - /***********************/ - /*** State Variables ***/ - /***********************/ - - /// @dev `tokenID => epoch => bool has claimed` mapping. - mapping(uint256 => mapping(uint256 => bool)) public override isEpochClaimed; - - /// @dev Mapping `pool address => Pool rewards info`. - mapping(address => PoolRewardsInfo) internal poolRewardsInfo; - - /// @dev Mapping `tokenID => Stake info`. - mapping(uint256 => StakeInfo) internal stakes; - - /******************/ - /*** Immutables ***/ - /******************/ - - /// @dev Address of the `Ajna` token. - address public immutable ajnaToken; - /// @dev The `PositionManager` contract - IPositionManager public immutable positionManager; - - /*******************/ - /*** Constructor ***/ - /*******************/ - - /** - * @notice Deploys the RewardsManager contract. - * @param ajnaToken_ Address of the token which will be distributed to staked Position owners. - * @param positionManager_ Address of the PositionManager contract. - */ - constructor(address ajnaToken_, IPositionManager positionManager_) { - if ( - ajnaToken_ == address(0) || address(positionManager_) == address(0) - ) revert DeployWithZeroAddress(); - - ajnaToken = ajnaToken_; - positionManager = positionManager_; - } - - /**************************/ - /*** External Functions ***/ - /**************************/ - - /** - * @inheritdoc IRewardsManagerOwnerActions - * @dev === Revert on === - * @dev not owner `NotOwnerOfDeposit()` - * @dev already claimed `AlreadyClaimed()` - * @dev === Emit events === - * @dev - `ClaimRewards` - */ - function claimRewards( - uint256 tokenId_, - uint256 epochToClaim_, - uint256 minAmount_ - ) external override { - StakeInfo storage stakeInfo = stakes[tokenId_]; - - if (msg.sender != stakeInfo.owner) revert NotOwnerOfDeposit(); - - if (isEpochClaimed[tokenId_][epochToClaim_]) revert AlreadyClaimed(); - - uint256 rewardsEarned = _calculateAndClaimAllRewards( - stakeInfo, - tokenId_, - epochToClaim_, - true, - stakeInfo.ajnaPool - ); - - // transfer rewards to claimer, ensuring amount is not below specified min amount - _transferAjnaRewards({ - transferAmount_: rewardsEarned, - minAmount_: minAmount_ - }); - } - - /** - * @inheritdoc IRewardsManagerOwnerActions - * @dev === Revert on === - * @dev not owner `NotOwnerOfDeposit()` - * @dev === Emit events === - * @dev - `Stake` - */ - function stake( - uint256 tokenId_ - ) external override { - address ajnaPool = positionManager.poolKey(tokenId_); - - // check that msg.sender is owner of tokenId - if (IERC721(address(positionManager)).ownerOf(tokenId_) != msg.sender) revert NotOwnerOfDeposit(); - - StakeInfo storage stakeInfo = stakes[tokenId_]; - stakeInfo.owner = msg.sender; - stakeInfo.ajnaPool = ajnaPool; - - uint96 curBurnEpoch = uint96(IPool(ajnaPool).currentBurnEpoch()); - - // record the staking epoch - stakeInfo.stakingEpoch = curBurnEpoch; - - // initialize last time interaction at staking epoch - stakeInfo.lastClaimedEpoch = curBurnEpoch; - - uint256[] memory positionIndexes = positionManager.getPositionIndexes(tokenId_); - uint256 noOfPositions = positionIndexes.length; - uint256 bucketId; - - for (uint256 i = 0; i < noOfPositions; ) { - bucketId = positionIndexes[i]; - - BucketState storage bucketState = stakeInfo.snapshot[bucketId]; - // record the number of lps in bucket at the time of staking - bucketState.lpsAtStakeTime = positionManager.getLP(tokenId_, bucketId); - // record the bucket exchange rate at the time of staking - bucketState.rateAtStakeTime = IPool(ajnaPool).bucketExchangeRate(bucketId); - - // iterations are bounded by array length (which is itself bounded), preventing overflow / underflow - unchecked { ++i; } - } - - emit Stake(msg.sender, ajnaPool, tokenId_); - - // transfer LP NFT to this contract - IERC721(address(positionManager)).transferFrom(msg.sender, address(this), tokenId_); - - // calculate rewards for updating exchange rates, if any - uint256 updateReward = _updateBucketExchangeRates( - ajnaPool, - positionIndexes - ); - - // transfer bucket update rewards to sender even if there's not enough balance for entire amount - _transferAjnaRewards({ - transferAmount_: updateReward, - minAmount_: 0 - }); - } - - /** - * @inheritdoc IRewardsManagerOwnerActions - * @dev === Revert on === - * @dev not owner `NotOwnerOfDeposit()` - * @dev === Emit events === - * @dev - `ClaimRewards` - * @dev - `Unstake` - */ - function unstake( - uint256 tokenId_ - ) external override { - _unstake({ - tokenId_: tokenId_, - claimRewards_: true - }); - } - - /** - * @inheritdoc IRewardsManagerOwnerActions - * @dev === Revert on === - * @dev not owner `NotOwnerOfDeposit()` - * @dev === Emit events === - * @dev - `Unstake` - */ - function emergencyUnstake( - uint256 tokenId_ - ) external override { - _unstake({ - tokenId_: tokenId_, - claimRewards_: false - }); - } - - /** - * @inheritdoc IRewardsManagerOwnerActions - * @dev === Emit events === - * @dev - `UpdateExchangeRates` - */ - function updateBucketExchangeRatesAndClaim( - address pool_, - bytes32 subsetHash_, - uint256[] calldata indexes_ - ) external override returns (uint256 updateReward) { - // revert if trying to update exchange rates for a non Ajna pool - if (!positionManager.isAjnaPool(pool_, subsetHash_)) revert NotAjnaPool(); - - updateReward = _updateBucketExchangeRates(pool_, indexes_); - - // transfer bucket update rewards to sender even if there's not enough balance for entire amount - _transferAjnaRewards({ - transferAmount_: updateReward, - minAmount_: 0 - }); - } - - /*******************************/ - /*** External View Functions ***/ - /*******************************/ - - /// @inheritdoc IRewardsManagerDerivedState - function calculateRewards( - uint256 tokenId_, - uint256 epochToClaim_ - ) external view override returns (uint256 rewards_) { - address ajnaPool = stakes[tokenId_].ajnaPool; - uint256 lastClaimedEpoch = stakes[tokenId_].lastClaimedEpoch; - uint256 stakingEpoch = stakes[tokenId_].stakingEpoch; - - uint256[] memory positionIndexes = positionManager.getPositionIndexesFiltered(tokenId_); - - // iterate through all burn periods to calculate and claim rewards - for (uint256 epoch = lastClaimedEpoch; epoch < epochToClaim_; ) { - - rewards_ += _calculateNextEpochRewards( - tokenId_, - epoch, - stakingEpoch, - ajnaPool, - positionIndexes - ); - - unchecked { ++epoch; } - } - } - - /// @inheritdoc IRewardsManagerState - function getStakeInfo( - uint256 tokenId_ - ) external view override returns (address, address, uint256) { - return ( - stakes[tokenId_].owner, - stakes[tokenId_].ajnaPool, - stakes[tokenId_].lastClaimedEpoch - ); - } - - /// @inheritdoc IRewardsManagerState - function getBucketStateStakeInfo( - uint256 tokenId_, - uint256 bucketId_ - ) external view override returns (uint256, uint256) { - return ( - stakes[tokenId_].snapshot[bucketId_].lpsAtStakeTime, - stakes[tokenId_].snapshot[bucketId_].rateAtStakeTime - ); - } - - /// @inheritdoc IRewardsManagerState - function isBucketUpdated( - address pool_, - uint256 bucketIndex_, - uint256 epoch_ - ) external view override returns (bool) { - return poolRewardsInfo[pool_].bucketExchangeRates[bucketIndex_][epoch_] != 0; - } - - /// @inheritdoc IRewardsManagerState - function getRewardsClaimed( - address pool_, - uint256 epoch_ - ) external view override returns (uint256) { - return poolRewardsInfo[pool_].rewardsClaimed[epoch_]; - } - - /// @inheritdoc IRewardsManagerState - function getUpdateRewardsClaimed( - address pool_, - uint256 epoch_ - ) external view override returns (uint256) { - return poolRewardsInfo[pool_].updateBucketRewardsClaimed[epoch_]; - } - - /**************************/ - /*** Internal Functions ***/ - /**************************/ - - /** - * @notice Calculate the amount of rewards that have been accumulated by a staked `NFT`. - * @dev Rewards are calculated as the difference in exchange rates between the last interaction burn event and the current burn event. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - * @param epochToClaim_ The burn epoch to claim rewards for (rewards calculation starts from the last claimed epoch). - * @return rewards_ Amount of rewards earned by the `NFT`. - */ - function _calculateAndClaimStakingRewards( - uint256 tokenId_, - uint256 epochToClaim_ - ) internal returns (uint256 rewards_) { - address ajnaPool = stakes[tokenId_].ajnaPool; - uint256 lastClaimedEpoch = stakes[tokenId_].lastClaimedEpoch; - uint256 stakingEpoch = stakes[tokenId_].stakingEpoch; - - mapping(uint256 => uint256) storage rewardsClaimed = poolRewardsInfo[ajnaPool].rewardsClaimed; - - uint256[] memory positionIndexes = positionManager.getPositionIndexesFiltered(tokenId_); - - // iterate through all burn periods to calculate and claim rewards - for (uint256 epoch = lastClaimedEpoch; epoch < epochToClaim_; ) { - - uint256 nextEpochRewards = _calculateNextEpochRewards( - tokenId_, - epoch, - stakingEpoch, - ajnaPool, - positionIndexes - ); - - rewards_ += nextEpochRewards; - - unchecked { ++epoch; } - - // update epoch token claim trackers - rewardsClaimed[epoch] += nextEpochRewards; - isEpochClaimed[tokenId_][epoch] = true; - } - } - - /** - * @notice Calculate the amount of rewards that have been accumulated by a staked `NFT` in next epoch. - * @dev Rewards are calculated as the difference in exchange rates between the last interaction burn event and the current burn event. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - * @param epoch_ The current epoch. - * @param stakingEpoch_ The epoch in which token was staked. - * @param ajnaPool_ Address of the pool. - * @param positionIndexes_ Bucket ids associated with `NFT` staked. - * @return epochRewards_ Calculated rewards in epoch. - */ - function _calculateNextEpochRewards( - uint256 tokenId_, - uint256 epoch_, - uint256 stakingEpoch_, - address ajnaPool_, - uint256[] memory positionIndexes_ - ) internal view returns (uint256 epochRewards_) { - - uint256 nextEpoch = epoch_ + 1; - uint256 claimedRewardsInNextEpoch = poolRewardsInfo[ajnaPool_].rewardsClaimed[nextEpoch]; - uint256 bucketIndex; - uint256 interestEarned; - - // iterate through all buckets and calculate epoch rewards for each bucket - StakeInfo storage _stakeInfo = stakes[tokenId_]; - uint256 noOfPositions = positionIndexes_.length; - for (uint256 i = 0; i < noOfPositions; ) { - bucketIndex = positionIndexes_[i]; - BucketState storage bucketSnapshot = _stakeInfo.snapshot[bucketIndex]; - - uint256 bucketRate; - if (epoch_ != stakingEpoch_) { - - // if staked in a previous epoch then use the initial exchange rate of epoch - bucketRate = poolRewardsInfo[ajnaPool_].bucketExchangeRates[bucketIndex][epoch_]; - } else { - - // if staked during the epoch then use the bucket rate at the time of staking - bucketRate = bucketSnapshot.rateAtStakeTime; - } - - // calculate the amount of interest accrued in current epoch - interestEarned += _calculateExchangeRateInterestEarned( - ajnaPool_, - nextEpoch, - bucketIndex, - bucketSnapshot.lpsAtStakeTime, - bucketRate - ); - unchecked { ++i; } - } - - // calculate and accumulate rewards if interest earned - if (interestEarned != 0) { - epochRewards_ = _calculateNewRewards( - ajnaPool_, - interestEarned, - nextEpoch, - claimedRewardsInNextEpoch - ); - } - } - - /** - * @notice Calculate the amount of interest that has accrued to a lender in a bucket based upon their `LP`. - * @param pool_ Address of the pool whose exchange rates are being checked. - * @param nextEventEpoch_ The next event epoch to check the exchange rate for. - * @param bucketIndex_ Index of the bucket to check the exchange rate for. - * @param bucketLP_ Amount of `LP` in bucket. - * @param exchangeRate_ Exchange rate in current epoch. - * @return interestEarned_ The amount of interest accrued. - */ - function _calculateExchangeRateInterestEarned( - address pool_, - uint256 nextEventEpoch_, - uint256 bucketIndex_, - uint256 bucketLP_, - uint256 exchangeRate_ - ) internal view returns (uint256 interestEarned_) { - - if (exchangeRate_ != 0) { - - uint256 nextExchangeRate = poolRewardsInfo[pool_].bucketExchangeRates[bucketIndex_][nextEventEpoch_]; - - // calculate interest earned only if next exchange rate is higher than current exchange rate - if (nextExchangeRate > exchangeRate_) { - - // calculate the equivalent amount of quote tokens given the stakes lp balance, - // and the exchange rate at the next and current burn events - interestEarned_ = Maths.wmul(nextExchangeRate - exchangeRate_, bucketLP_); - } - - } - } - - /** - * @notice Calculate new rewards between current and next epoch, based on earned interest. - * @param ajnaPool_ Address of the pool. - * @param interestEarned_ The amount of interest accrued to current epoch. - * @param nextEpoch_ The next burn event epoch to calculate new rewards. - * @param rewardsClaimedInEpoch_ Rewards claimed in epoch. - * @return newRewards_ New rewards between current and next burn event epoch. - */ - function _calculateNewRewards( - address ajnaPool_, - uint256 interestEarned_, - uint256 nextEpoch_, - uint256 rewardsClaimedInEpoch_ - ) internal view returns (uint256 newRewards_) { - ( - , - // total interest accumulated by the pool over the claim period - uint256 totalBurnedInPeriod, - // total tokens burned over the claim period - uint256 totalInterestEarnedInPeriod - ) = _getEpochInfo(ajnaPool_, nextEpoch_); - - // calculate rewards earned - newRewards_ = totalInterestEarnedInPeriod == 0 ? 0 : Maths.floorWdiv( - Maths.wmul( - Maths.wmul(interestEarned_, totalBurnedInPeriod), - REWARD_FACTOR - ), - totalInterestEarnedInPeriod - ); - - uint256 rewardsCapped = Maths.wmul(REWARD_CAP, totalBurnedInPeriod); - - // Check rewards claimed - check that less than 80% of the tokens for a given burn event have been claimed. - if (rewardsClaimedInEpoch_ + newRewards_ > rewardsCapped) { - - // set claim reward to difference between cap and reward - newRewards_ = rewardsClaimedInEpoch_ > rewardsCapped ? 0 : rewardsCapped - rewardsClaimedInEpoch_; - } - } - - /** - * @notice Claim rewards that have been accumulated by a staked `NFT`. - * @param stakeInfo_ `StakeInfo` struct containing details of stake to claim rewards for. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - * @param epochToClaim_ The burn epoch to claim rewards for (rewards calculation starts from the last claimed epoch) - * @param validateEpoch_ True if the epoch is received as a parameter and needs to be validated (lower or equal with latest epoch). - * @param ajnaPool_ Address of `Ajna` pool associated with the stake. - */ - function _calculateAndClaimAllRewards( - StakeInfo storage stakeInfo_, - uint256 tokenId_, - uint256 epochToClaim_, - bool validateEpoch_, - address ajnaPool_ - ) internal returns (uint256 rewardsEarned_) { - - // revert if higher epoch to claim than current burn epoch - if (validateEpoch_ && epochToClaim_ > IPool(ajnaPool_).currentBurnEpoch()) revert EpochNotAvailable(); - - // update bucket exchange rates and claim associated rewards - rewardsEarned_ = _updateBucketExchangeRates( - ajnaPool_, - positionManager.getPositionIndexes(tokenId_) - ); - - if (!isEpochClaimed[tokenId_][epochToClaim_]) { - rewardsEarned_ += _calculateAndClaimStakingRewards(tokenId_, epochToClaim_); - } - - uint256[] memory burnEpochsClaimed = _getBurnEpochsClaimed( - stakeInfo_.lastClaimedEpoch, - epochToClaim_ - ); - - emit ClaimRewards( - msg.sender, - ajnaPool_, - tokenId_, - burnEpochsClaimed, - rewardsEarned_ - ); - - // update last interaction burn event - stakeInfo_.lastClaimedEpoch = uint96(epochToClaim_); - } - - /** - * @notice Retrieve an array of burn epochs from which a depositor has claimed rewards. - * @param lastClaimedEpoch_ The last burn period in which a depositor claimed rewards. - * @param burnEpochToStartClaim_ The most recent burn period from a depositor earned rewards. - * @return burnEpochsClaimed_ Array of burn epochs from which a depositor has claimed rewards. - */ - function _getBurnEpochsClaimed( - uint256 lastClaimedEpoch_, - uint256 burnEpochToStartClaim_ - ) internal pure returns (uint256[] memory burnEpochsClaimed_) { - burnEpochsClaimed_ = new uint256[](burnEpochToStartClaim_ - lastClaimedEpoch_); - - uint256 i; - uint256 claimEpoch = ++lastClaimedEpoch_; - while (claimEpoch <= burnEpochToStartClaim_) { - burnEpochsClaimed_[i] = claimEpoch; - - // iterations are bounded by array length (which is itself bounded), preventing overflow / underflow - unchecked { - ++i; - ++claimEpoch; - } - } - } - - /** - * @notice Update the exchange rate of a list of buckets. - * @dev Called as part of `stake`, `unstake`, and `claimRewards`, as well as `updateBucketExchangeRatesAndClaim`. - * @dev Caller can claim `5%` of the rewards that have accumulated to each bucket since the last burn event, if it hasn't already been updated. - * @param pool_ Address of the pool whose exchange rates are being updated. - * @param indexes_ List of bucket indexes to be updated. - * @return updatedRewards_ Update exchange rate rewards. - */ - function _updateBucketExchangeRates( - address pool_, - uint256[] memory indexes_ - ) internal returns (uint256 updatedRewards_) { - // get the current burn epoch from the given pool - uint256 curBurnEpoch = IPool(pool_).currentBurnEpoch(); - - // retrieve epoch values used to determine if updater receives rewards - ( - uint256 curBurnTime, - uint256 totalBurnedInEpoch, - uint256 totalInterestEarned - ) = _getEpochInfo(pool_, curBurnEpoch); - - // Update exchange rates without reward if first epoch or if the epoch does not have burned tokens associated with it - if (totalBurnedInEpoch == 0) { - uint256 noOfIndexes = indexes_.length; - - for (uint256 i = 0; i < noOfIndexes; ) { - _updateBucketExchangeRate( - pool_, - indexes_[i], - curBurnEpoch - ); - - // iterations are bounded by array length (which is itself bounded), preventing overflow / underflow - unchecked { ++i; } - } - } - else { - if (block.timestamp <= curBurnTime + UPDATE_PERIOD) { - mapping(uint256 => uint256) storage updateRewardsClaimed = poolRewardsInfo[pool_].updateBucketRewardsClaimed; - - // update exchange rates and calculate rewards if tokens were burned and within allowed time period - uint256 noOfIndexes = indexes_.length; - for (uint256 i = 0; i < noOfIndexes; ) { - - // calculate rewards earned for updating bucket exchange rate - updatedRewards_ += _updateBucketExchangeRateAndCalculateRewards( - pool_, - indexes_[i], - curBurnEpoch, - totalBurnedInEpoch, - totalInterestEarned - ); - - // iterations are bounded by array length (which is itself bounded), preventing overflow / underflow - unchecked { ++i; } - } - - uint256 rewardsCap = Maths.wmul(UPDATE_CAP, totalBurnedInEpoch); - uint256 rewardsClaimedInEpoch = updateRewardsClaimed[curBurnEpoch]; - - // update total tokens claimed for updating bucket exchange rates tracker - if (rewardsClaimedInEpoch + updatedRewards_ >= rewardsCap) { - // if update reward is greater than cap, set to remaining difference - updatedRewards_ = rewardsClaimedInEpoch > rewardsCap ? 0 : rewardsCap - rewardsClaimedInEpoch; - } - - // accumulate the full amount of additional rewards - updateRewardsClaimed[curBurnEpoch] += updatedRewards_; - } else { - // block.timestamp is greater than curBurnTime + UPDATE_PERIOD do not emit UpdateExchangeRates - return 0; - } - } - - // emit event with the list of bucket indexes updated - emit UpdateExchangeRates(msg.sender, pool_, indexes_, updatedRewards_); - } - - /** - * @notice Update the exchange rate of a specific bucket. - * @param pool_ Address of the pool whose exchange rates are being updated. - * @param bucketIndex_ Bucket index to update exchange rate. - * @param burnEpoch_ Current burn epoch of the pool. - */ - function _updateBucketExchangeRate( - address pool_, - uint256 bucketIndex_, - uint256 burnEpoch_ - ) internal { - // cache storage pointer for reduced gas - mapping(uint256 => uint256) storage _bucketExchangeRates = poolRewardsInfo[pool_].bucketExchangeRates[bucketIndex_]; - uint256 burnExchangeRate = _bucketExchangeRates[burnEpoch_]; - - // update bucket exchange rate at epoch only if it wasn't previously updated - if (burnExchangeRate == 0) { - uint256 curBucketExchangeRate = IPool(pool_).bucketExchangeRate(bucketIndex_); - - // record bucket exchange rate at epoch - _bucketExchangeRates[burnEpoch_] = curBucketExchangeRate; - } - } - - /** - * @notice Update the exchange rate of a specific bucket and calculate rewards based on prev exchange rate. - * @param pool_ Address of the pool whose exchange rates are being updated. - * @param bucketIndex_ Bucket index to update exchange rate. - * @param burnEpoch_ Current burn epoch of the pool. - * @param totalBurned_ Total `Ajna` tokens burned in pool. - * @param interestEarned_ Total interest rate earned in pool. - * @return rewards_ Rewards for bucket exchange rate update. - */ - function _updateBucketExchangeRateAndCalculateRewards( - address pool_, - uint256 bucketIndex_, - uint256 burnEpoch_, - uint256 totalBurned_, - uint256 interestEarned_ - ) internal returns (uint256 rewards_) { - // cache storage pointer for reduced gas - mapping(uint256 => uint256) storage _bucketExchangeRates = poolRewardsInfo[pool_].bucketExchangeRates[bucketIndex_]; - uint256 burnExchangeRate = _bucketExchangeRates[burnEpoch_]; - - // update bucket exchange rate at epoch only if it wasn't previously updated - if (burnExchangeRate == 0) { - uint256 curBucketExchangeRate = IPool(pool_).bucketExchangeRate(bucketIndex_); - - // record bucket exchange rate at epoch - _bucketExchangeRates[burnEpoch_] = curBucketExchangeRate; - - // retrieve the bucket exchange rate at the previous epoch - uint256 prevBucketExchangeRate = _bucketExchangeRates[--burnEpoch_]; - - // skip reward calculation if update at the previous epoch was missed and if exchange rate decreased due to bad debt - // prevents excess rewards from being provided from using a 0 value as an input to the interestFactor calculation below. - if (prevBucketExchangeRate != 0 && prevBucketExchangeRate < curBucketExchangeRate) { - - // retrieve current deposit of the bucket - (, , , uint256 bucketDeposit, ) = IPool(pool_).bucketInfo(bucketIndex_); - - uint256 burnFactor = Maths.wmul(totalBurned_, bucketDeposit); - - // calculate rewards earned for updating bucket exchange rate - rewards_ = interestEarned_ == 0 ? 0 : Maths.wdiv( - Maths.wmul( - UPDATE_CLAIM_REWARD, - Maths.wmul( - burnFactor, - curBucketExchangeRate - prevBucketExchangeRate - ) - ), - Maths.wmul(curBucketExchangeRate, interestEarned_) - ); - } - } - } - - /** - * @notice Utility function to unstake the position token. - * @dev Used by `stake` function to unstake and claim rewards. - * @dev Used by `emergencyUnstake` function to unstake without claiming rewards. - * @param tokenId_ The token id to unstake. - * @param claimRewards_ Wether the rewards to be calculated and claimed (true for `stake`, false for `emergencyUnstake`) - */ - function _unstake(uint256 tokenId_, bool claimRewards_) internal { - StakeInfo storage stakeInfo = stakes[tokenId_]; - - if (msg.sender != stakeInfo.owner) revert NotOwnerOfDeposit(); - - address ajnaPool = stakeInfo.ajnaPool; - uint256 rewardsEarned; - - // gracefully unstake, claim rewards if any - if (claimRewards_) { - rewardsEarned = _calculateAndClaimAllRewards( - stakeInfo, - tokenId_, - IPool(ajnaPool).currentBurnEpoch(), - false, - ajnaPool - ); - } - - // remove bucket snapshots recorded at the time of staking - uint256[] memory positionIndexes = positionManager.getPositionIndexes(tokenId_); - uint256 noOfIndexes = positionIndexes.length; - - for (uint256 i = 0; i < noOfIndexes; ) { - delete stakeInfo.snapshot[positionIndexes[i]]; // reset BucketState struct for current position - - unchecked { ++i; } - } - - // remove recorded stake info - delete stakes[tokenId_]; - - emit Unstake(msg.sender, ajnaPool, tokenId_); - - // gracefully unstake, transfer rewards to claimer ensuring entire amount - if (claimRewards_) { - _transferAjnaRewards({ - transferAmount_: rewardsEarned, - minAmount_: rewardsEarned - }); - } - - // transfer LP NFT from contract to sender - IERC721(address(positionManager)).transferFrom(address(this), msg.sender, tokenId_); - } - - /** - * @notice Utility function to transfer `Ajna` rewards to the sender. - * @dev This function is used to transfer rewards to the `msg.sender` after a successful claim or update. - * @dev It is used to ensure that rewards claimers are able to claim portion from remaining tokens if a claim would exceed the remaining contract balance. - * @dev Reverts with `InsufficientLiquidity` if calculated rewards or contract balance is below specified min amount to receive limit. - * @param transferAmount_ Amount of rewards earned by the caller. - * @param minAmount_ Min amount that rewards claimer wants to recieve. - */ - function _transferAjnaRewards(uint256 transferAmount_, uint256 minAmount_) internal { - uint256 ajnaBalance = IERC20(ajnaToken).balanceOf(address(this)); - - // cap amount to transfer at available contract balance - if (transferAmount_ > ajnaBalance) transferAmount_ = ajnaBalance; - - // revert if amount to transfer is lower than limit amount - if (transferAmount_ < minAmount_) revert InsufficientLiquidity(); - - if (transferAmount_ != 0) { - // transfer amount to rewards claimer - IERC20(ajnaToken).safeTransfer(msg.sender, transferAmount_); - } - } -} - - /**********************/ - /** Rewards Utilities */ - /**********************/ - - /** - * @notice Retrieve the total ajna tokens burned and total interest earned over a given epoch. - * @param pool_ Address of the `Ajna` pool to retrieve accumulators of. - * @param epoch_ time window used to identify time between Ajna burn events (kickReserve and takeReserve actions). - * @return currentBurnTime_ timestamp of the latest burn event. - * @return tokensBurned_ total `Ajna` tokens burned in epoch. - * @return interestEarned_ total interest earned in epoch. - */ - function _getEpochInfo( - address pool_, - uint256 epoch_ - ) view returns (uint256 currentBurnTime_, uint256 tokensBurned_, uint256 interestEarned_) { - - // 0 epoch won't have any ajna burned or interest associated with it - if (epoch_ != 0) { - - uint256 totalInterestLatest; - uint256 totalBurnedLatest; - - ( - currentBurnTime_, - totalInterestLatest, - totalBurnedLatest - ) = IPool(pool_).burnInfo(epoch_); - - ( - , - uint256 totalInterestPrev, - uint256 totalBurnedPrev - ) = IPool(pool_).burnInfo(epoch_ - 1); - - // calculate total tokens burned and interest earned in epoch - tokensBurned_ = totalBurnedLatest != 0 ? totalBurnedLatest - totalBurnedPrev : 0; - interestEarned_ = totalInterestLatest != 0 ? totalInterestLatest - totalInterestPrev : 0; - } - } diff --git a/src/base/FlashloanablePool.sol b/src/base/FlashloanablePool.sol index a6d35f176..b6e9143f7 100644 --- a/src/base/FlashloanablePool.sol +++ b/src/base/FlashloanablePool.sol @@ -6,6 +6,7 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { Pool } from './Pool.sol'; +import { PoolCommons } from '../libraries/external/PoolCommons.sol'; import { IERC3156FlashBorrower } from '../interfaces/pool/IERC3156FlashBorrower.sol'; /** @@ -23,39 +24,18 @@ abstract contract FlashloanablePool is Pool { * @param token_ Address of the `ERC20` token caller wants to borrow. * @param amount_ The denormalized amount (dependent upon token precision) of tokens to borrow. * @param data_ User-defined calldata passed to the receiver. - * @return success_ `True` if flashloan was successful. + * @return `True` if flashloan was successful. */ function flashLoan( IERC3156FlashBorrower receiver_, address token_, uint256 amount_, bytes calldata data_ - ) external virtual override nonReentrant returns (bool success_) { + ) external virtual override nonReentrant returns (bool) { if (!_isFlashloanSupported(token_)) revert FlashloanUnavailableForToken(); - - IERC20 tokenContract = IERC20(token_); - - uint256 initialBalance = tokenContract.balanceOf(address(this)); - - tokenContract.safeTransfer( - address(receiver_), - amount_ - ); - - if (receiver_.onFlashLoan(msg.sender, token_, amount_, 0, data_) != - keccak256("ERC3156FlashBorrower.onFlashLoan")) revert FlashloanCallbackFailed(); - - tokenContract.safeTransferFrom( - address(receiver_), - address(this), - amount_ - ); - - if (tokenContract.balanceOf(address(this)) != initialBalance) revert FlashloanIncorrectBalance(); - - success_ = true; - - emit Flashloan(address(receiver_), token_, amount_); + PoolCommons.flashLoan(receiver_, token_, amount_, data_); + // if flashLoan call didn't revert then flashloan was successful + return true; } /** diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 0f7cf3504..8d66973f3 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -50,13 +50,17 @@ import { } from '../interfaces/pool/commons/IPoolInternals.sol'; import { + COLLATERALIZATION_FACTOR, + _determineInflatorState, _priceAt, _roundToScale } from '../libraries/helpers/PoolHelper.sol'; import { _revertIfAuctionDebtLocked, _revertIfAuctionClearable, - _revertAfterExpiry + _revertAfterExpiry, + _revertIfAuctionPriceBelow, + _revertIfActiveAuctions } from '../libraries/helpers/RevertsHelper.sol'; import { Buckets } from '../libraries/internal/Buckets.sol'; @@ -150,27 +154,27 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function addQuoteToken( uint256 amount_, uint256 index_, - uint256 expiry_, - bool revertIfBelowLup_ - ) external override nonReentrant returns (uint256 bucketLP_) { + uint256 expiry_ + ) external override nonReentrant returns (uint256 bucketLP_, uint256 addedAmount_) { _revertAfterExpiry(expiry_); _revertIfAuctionClearable(auctions, loans); + _revertIfAuctionPriceBelow(auctions, index_); + PoolState memory poolState = _accruePoolInterest(); // round to token precision amount_ = _roundToScale(amount_, poolState.quoteTokenScale); uint256 newLup; - (bucketLP_, newLup) = LenderActions.addQuoteToken( + (bucketLP_, addedAmount_, newLup) = LenderActions.addQuoteToken( buckets, deposits, poolState, AddQuoteParams({ amount: amount_, - index: index_, - revertIfBelowLup: revertIfBelowLup_ + index: index_ }) ); @@ -186,23 +190,23 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 maxAmount_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_, - bool revertIfBelowLup_ + uint256 expiry_ ) external override nonReentrant returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_) { _revertAfterExpiry(expiry_); _revertIfAuctionClearable(auctions, loans); + _revertIfAuctionPriceBelow(auctions, toIndex_); + PoolState memory poolState = _accruePoolInterest(); _revertIfAuctionDebtLocked(deposits, poolState.t0DebtInAuction, fromIndex_, poolState.inflator); MoveQuoteParams memory moveParams; - moveParams.maxAmountToMove = maxAmount_; - moveParams.fromIndex = fromIndex_; - moveParams.toIndex = toIndex_; - moveParams.thresholdPrice = Loans.getMax(loans).thresholdPrice; - moveParams.revertIfBelowLup = revertIfBelowLup_; + moveParams.maxAmountToMove = maxAmount_; + moveParams.fromIndex = fromIndex_; + moveParams.toIndex = toIndex_; + moveParams.maxT0DebtToCollateral = Loans.getMax(loans).t0DebtToCollateral; uint256 newLup; ( @@ -242,9 +246,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { deposits, poolState, RemoveQuoteParams({ - maxAmount: Maths.min(maxAmount_, _availableQuoteToken()), - index: index_, - thresholdPrice: Loans.getMax(loans).thresholdPrice + maxAmount: Maths.min(maxAmount_, _availableQuoteToken()), + index: index_, + maxT0DebtToCollateral: Loans.getMax(loans).t0DebtToCollateral }) ); @@ -375,23 +379,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_); } /*********************************/ @@ -404,11 +394,15 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { * @dev increment `latestBurnEpoch` counter * @dev update `reserveAuction.latestBurnEventEpoch` and burn event `timestamp` state * @dev === Reverts on === - * @dev 2 weeks not passed `ReserveAuctionTooSoon()` + * @dev no reserves to claim `NoReserves()` + * @dev 5 days not passed `ReserveAuctionTooSoon()` + * @dev unsettled liquidation `AuctionActive()` * @dev === Emit events === * @dev - `KickReserveAuction` */ function kickReserveAuction() external override nonReentrant { + _revertIfActiveAuctions(auctions); + // start a new claimable reserve auction, passing in relevant parameters such as the current pool size, debt, balance, and inflator value KickerActions.kickReserveAuction( auctions, @@ -434,7 +428,8 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 ajnaRequired; (amount_, ajnaRequired) = TakerActions.takeReserves( reserveAuction, - maxAmount_ + maxAmount_, + _getArgUint256(QUOTE_SCALE) ); // burn required number of ajna tokens to take quote from reserves @@ -553,27 +548,31 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { // Calculate prior pool debt poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); - // calculate elapsed time since inflator was last updated + // calculate elapsed time since inflator was last updated uint256 elapsed = block.timestamp - inflatorState.inflatorUpdate; - // set isNewInterestAccrued field to true if elapsed time is not 0, indicating that new interest may have accrued + // set isNewInterestAccrued field to true if elapsed time is not 0, indicating that new interest may have accrued poolState_.isNewInterestAccrued = elapsed != 0; // if new interest may have accrued, call accrueInterest function and update inflator and debt fields of poolState_ struct if (poolState_.isNewInterestAccrued) { - (uint256 newInflator, uint256 newInterest) = PoolCommons.accrueInterest( + try PoolCommons.accrueInterest( emaState, deposits, poolState_, - Loans.getMax(loans).thresholdPrice, + Loans.getMax(loans).t0DebtToCollateral, elapsed - ); - poolState_.inflator = newInflator; - // After debt owed to lenders has accrued, calculate current debt owed by borrowers - poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); - - // update total interest earned accumulator with the newly accrued interest - reserveAuction.totalInterestEarned += newInterest; + ) returns (uint256 newInflator, uint256 newInterest) { + poolState_.inflator = newInflator; + // After debt owed to lenders has accrued, calculate current debt owed by borrowers + poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); + + // update total interest earned accumulator with the newly accrued interest + reserveAuction.totalInterestEarned += newInterest; + } catch { + poolState_.isNewInterestAccrued = false; + emit InterestUpdateFailure(); + } } } } @@ -621,7 +620,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { PoolState memory poolState_ ) internal { // update in memory pool state struct - poolState_.debt -= Maths.wmul(result_.t0DebtSettled, poolState_.inflator); + poolState_.debt -= result_.debtSettled; poolState_.t0Debt -= result_.t0DebtSettled; poolState_.t0DebtInAuction -= result_.t0DebtSettled; poolState_.collateral -= result_.collateralSettled; @@ -679,19 +678,13 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { PoolState memory poolState_, uint256 lup_ ) internal { - - PoolCommons.updateInterestState(interestState, emaState, deposits, poolState_, lup_); - - // update pool inflator - if (poolState_.isNewInterestAccrued) { - inflatorState.inflator = uint208(poolState_.inflator); - inflatorState.inflatorUpdate = uint48(block.timestamp); - // if the debt in the current pool state is 0, also update the inflator and inflatorUpdate fields in inflatorState - // slither-disable-next-line incorrect-equality - } else if (poolState_.debt == 0) { - inflatorState.inflator = uint208(Maths.WAD); - inflatorState.inflatorUpdate = uint48(block.timestamp); + try PoolCommons.updateInterestState(interestState, emaState, deposits, poolState_, lup_) {} catch { + emit InterestUpdateFailure(); } + + (uint208 newInflator, bool updateTimestamp) = _determineInflatorState(poolState_, inflatorState); + inflatorState.inflator = newInflator; + if (updateTimestamp) inflatorState.inflatorUpdate = uint48(block.timestamp); } /** @@ -747,6 +740,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 kickTime_, uint256 referencePrice_, uint256 neutralPrice_, + uint256 debtToCollateral_, address head_, address next_, address prev_ @@ -759,6 +753,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { liquidation.kickTime, liquidation.referencePrice, liquidation.neutralPrice, + liquidation.debtToCollateral, auctions.head, liquidation.next, liquidation.prev @@ -824,25 +819,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_); @@ -933,7 +912,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { Loan memory loan = Loans.getByIndex(loans, loanId_); return ( loan.borrower, - loan.thresholdPrice + loan.t0DebtToCollateral ); } @@ -942,7 +921,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { Loan memory maxLoan = Loans.getMax(loans); return ( maxLoan.borrower, - Maths.wmul(maxLoan.thresholdPrice, inflatorState.inflator), + maxLoan.t0DebtToCollateral, Loans.noOfLoans(loans) ); } @@ -953,11 +932,12 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { } /// @inheritdoc IPoolState - function reservesInfo() external view override returns (uint256, uint256, uint256, uint256) { + function reservesInfo() external view override returns (uint256, uint256, uint256, uint256, uint256) { return ( auctions.totalBondEscrowed, reserveAuction.unclaimed, reserveAuction.kicked, + reserveAuction.lastKickedReserves, reserveAuction.totalInterestEarned ); } diff --git a/src/base/PoolDeployer.sol b/src/base/PoolDeployer.sol index 91c2c5303..e0851d176 100644 --- a/src/base/PoolDeployer.sol +++ b/src/base/PoolDeployer.sol @@ -77,6 +77,7 @@ abstract contract PoolDeployer { * @notice Returns the list of all deployed pools. * @dev This function is used by integrations to access deployed pools. * @dev Each factory implementation maintains its own list of deployed pools. + * @dev This method should only be used by off-chain integrations. * @return List of all deployed pools. */ function getDeployedPoolsList() external view returns (address[] memory) { diff --git a/src/interfaces/pool/IPool.sol b/src/interfaces/pool/IPool.sol index 7cb8c6c66..3d7d12ba9 100644 --- a/src/interfaces/pool/IPool.sol +++ b/src/interfaces/pool/IPool.sol @@ -44,12 +44,6 @@ interface IERC20Token { function balanceOf(address account) external view returns (uint256); function burn(uint256 amount) external; function decimals() external view returns (uint8); - function transfer(address to, uint256 amount) external returns (bool); - function transferFrom( - address from, - address to, - uint256 amount - ) external returns (bool); } /// @dev `ERC721` token interface. diff --git a/src/interfaces/pool/IPoolFactory.sol b/src/interfaces/pool/IPoolFactory.sol index 1bfbcfe47..4abd47e70 100644 --- a/src/interfaces/pool/IPoolFactory.sol +++ b/src/interfaces/pool/IPoolFactory.sol @@ -44,6 +44,7 @@ interface IPoolFactory { /** * @notice Emitted when a new pool is created. * @param pool_ The address of the new pool. + * @param subsetHash_ The subset hash for the pool lookup */ - event PoolCreated(address pool_); + event PoolCreated(address pool_, bytes32 subsetHash_); } diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index 52f8cca27..53fb77ab1 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -11,9 +11,9 @@ interface IPoolErrors { /**************************/ /** - * @notice `LP` allowance is already set by the owner. + * @notice Adding liquidity above current auction price. */ - error AllowanceAlreadySet(); + error AddAboveAuctionPrice(); /** * @notice The action cannot be executed on an active auction. @@ -138,11 +138,6 @@ interface IPoolErrors { */ error LUPBelowHTP(); - /** - * @notice Liquidation must result in `LUP` below the borrowers threshold price. - */ - error LUPGreaterThanTP(); - /** * @notice From index and to index arguments to move are the same. */ @@ -180,12 +175,6 @@ interface IPoolErrors { error NoDebt(); /** - * @notice Borrower is attempting to borrow an amount of quote tokens that will push the pool into under-collateralization. - */ - error PoolUnderCollateralized(); - - /** - * @notice Actor is attempting to add or move quote tokens at a price below the `LUP`. * @notice Actor is attempting to kick with bucket price below the `LUP`. */ error PriceBelowLUP(); @@ -216,8 +205,8 @@ interface IPoolErrors { error TransferToSameOwner(); /** - * @notice The threshold price of the loan to be inserted in loans heap is zero. + * @notice The DebtToCollateral of the loan to be inserted in loans heap is zero. */ - error ZeroThresholdPrice(); + error ZeroDebtToCollateral(); } diff --git a/src/interfaces/pool/commons/IPoolEvents.sol b/src/interfaces/pool/commons/IPoolEvents.sol index ededcc548..e26f7c589 100644 --- a/src/interfaces/pool/commons/IPoolEvents.sol +++ b/src/interfaces/pool/commons/IPoolEvents.sol @@ -367,4 +367,9 @@ interface IPoolEvents { uint256 newRate ); + /** + * @notice Emitted when interest accural or update interest overflows. + */ + event InterestUpdateFailure(); + } \ No newline at end of file diff --git a/src/interfaces/pool/commons/IPoolInternals.sol b/src/interfaces/pool/commons/IPoolInternals.sol index 468988855..bef1384d5 100644 --- a/src/interfaces/pool/commons/IPoolInternals.sol +++ b/src/interfaces/pool/commons/IPoolInternals.sol @@ -15,7 +15,6 @@ struct KickResult { uint256 amountToCoverBond; // [WAD] amount of bond that needs to be covered uint256 t0KickedDebt; // [WAD] new t0 debt after kick uint256 collateralPreAction; // [WAD] The amount of borrower collateral before kick, same as the one after kick - uint256 poolDebt; // [WAD] current debt in pool after kick uint256 lup; // [WAD] current LUP in pool after kick } @@ -34,6 +33,7 @@ struct SettleResult { uint256 collateralRemaining; // [WAD] The amount of borrower collateral left after settle uint256 collateralSettled; // [WAD] The amount of borrower collateral settled uint256 t0DebtSettled; // [WAD] The amount of t0 debt settled + uint256 debtSettled; // [WAD] The amount of actual debt settled } /// @dev Struct used to return result of `TakerAction.take` and `TakerAction.bucketTake` actions. @@ -70,23 +70,21 @@ struct KickReserveAuctionParams { struct AddQuoteParams { uint256 amount; // [WAD] amount to be added uint256 index; // the index in which to deposit - bool revertIfBelowLup; // revert tx if index in which to deposit is below LUP } /// @dev Struct used to hold parameters for `LenderAction.moveQuoteToken` action. struct MoveQuoteParams { - uint256 fromIndex; // the deposit index from where amount is moved - uint256 maxAmountToMove; // [WAD] max amount to move between deposits - uint256 toIndex; // the deposit index where amount is moved to - uint256 thresholdPrice; // [WAD] max threshold price in pool - bool revertIfBelowLup; // revert tx if quote token is moved from above the LUP to below the LUP + uint256 fromIndex; // the deposit index from where amount is moved + uint256 maxAmountToMove; // [WAD] max amount to move between deposits + uint256 toIndex; // the deposit index where amount is moved to + uint256 maxT0DebtToCollateral; // [WAD] max t0 debt to collateral in pool } /// @dev Struct used to hold parameters for `LenderAction.removeQuoteToken` action. struct RemoveQuoteParams { - uint256 index; // the deposit index from where amount is removed - uint256 maxAmount; // [WAD] max amount to be removed - uint256 thresholdPrice; // [WAD] max threshold price in pool + uint256 index; // the deposit index from where amount is removed + uint256 maxAmount; // [WAD] max amount to be removed + uint256 maxT0DebtToCollateral; // [WAD] max t0 debt to collateral in pool } /*************************************/ 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/interfaces/pool/commons/IPoolLenderActions.sol b/src/interfaces/pool/commons/IPoolLenderActions.sol index 25ac4c048..9c2286e06 100644 --- a/src/interfaces/pool/commons/IPoolLenderActions.sol +++ b/src/interfaces/pool/commons/IPoolLenderActions.sol @@ -16,15 +16,14 @@ interface IPoolLenderActions { * @param amount_ The amount of quote token to be added by a lender (`WAD` precision). * @param index_ The index of the bucket to which the quote tokens will be added. * @param expiry_ Timestamp after which this transaction will revert, preventing inclusion in a block with unfavorable price. - * @param revertIfBelowLup_ The tx will revert if price of the bucket to which the quote tokens will be added is below `LUP` price (and avoid paying fee for deposit below `LUP`). * @return bucketLP_ The amount of `LP` changed for the added quote tokens (`WAD` precision). + * @return addedAmount_ The amount of quote token added (`WAD` precision). */ function addQuoteToken( uint256 amount_, uint256 index_, - uint256 expiry_, - bool revertIfBelowLup_ - ) external returns (uint256 bucketLP_); + uint256 expiry_ + ) external returns (uint256 bucketLP_, uint256 addedAmount_); /** * @notice Called by lenders to move an amount of credit from a specified price bucket to another specified price bucket. @@ -32,7 +31,6 @@ interface IPoolLenderActions { * @param fromIndex_ The bucket index from which the quote tokens will be removed. * @param toIndex_ The bucket index to which the quote tokens will be added. * @param expiry_ Timestamp after which this transaction will revert, preventing inclusion in a block with unfavorable price. - * @param revertIfBelowLup_ The tx will revert if quote token is moved from above the `LUP` to below the `LUP` (and avoid paying fee for move below `LUP`). * @return fromBucketLP_ The amount of `LP` moved out from bucket (`WAD` precision). * @return toBucketLP_ The amount of `LP` moved to destination bucket (`WAD` precision). * @return movedAmount_ The amount of quote token moved (`WAD` precision). @@ -41,8 +39,7 @@ interface IPoolLenderActions { uint256 maxAmount_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_, - bool revertIfBelowLup_ + uint256 expiry_ ) external returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_); /** diff --git a/src/interfaces/pool/commons/IPoolSettlerActions.sol b/src/interfaces/pool/commons/IPoolSettlerActions.sol index 0639e4574..a376f5c38 100644 --- a/src/interfaces/pool/commons/IPoolSettlerActions.sol +++ b/src/interfaces/pool/commons/IPoolSettlerActions.sol @@ -9,13 +9,15 @@ interface IPoolSettlerActions { /** * @notice Called by actors to settle an amount of debt in a completed liquidation. - * @param borrowerAddress_ Address of the auctioned borrower. - * @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt. + * @param borrowerAddress_ Address of the auctioned borrower. + * @param maxDepth_ Measured from `HPB`, maximum number of buckets deep to settle debt. + * @return collateralSettled_ Amount of collateral settled. + * @return isBorrowerSettled_ True if all borrower's debt is settled. * @dev `maxDepth_` is used to prevent unbounded iteration clearing large liquidations. */ function settle( address borrowerAddress_, uint256 maxDepth_ - ) external; + ) external returns (uint256 collateralSettled_, bool isBorrowerSettled_); } \ No newline at end of file diff --git a/src/interfaces/pool/commons/IPoolState.sol b/src/interfaces/pool/commons/IPoolState.sol index 027e7670c..b44a6ca6d 100644 --- a/src/interfaces/pool/commons/IPoolState.sol +++ b/src/interfaces/pool/commons/IPoolState.sol @@ -9,16 +9,17 @@ interface IPoolState { /** * @notice Returns details of an auction for a given borrower address. - * @param borrower_ Address of the borrower that is liquidated. - * @return kicker_ Address of the kicker that is kicking the auction. - * @return bondFactor_ The factor used for calculating bond size. - * @return bondSize_ The bond amount in quote token terms. - * @return kickTime_ Time the liquidation was initiated. - * @return referencePrice_ Price used to determine auction start price. - * @return neutralPrice_ `Neutral Price` of auction. - * @return head_ Address of the head auction. - * @return next_ Address of the next auction in queue. - * @return prev_ Address of the prev auction in queue. + * @param borrower_ Address of the borrower that is liquidated. + * @return kicker_ Address of the kicker that is kicking the auction. + * @return bondFactor_ The factor used for calculating bond size. + * @return bondSize_ The bond amount in quote token terms. + * @return kickTime_ Time the liquidation was initiated. + * @return referencePrice_ Price used to determine auction start price. + * @return neutralPrice_ `Neutral Price` of auction. + * @return debtToCollateral_ Borrower debt to collateral, which is used in BPF for kicker's reward calculation. + * @return head_ Address of the head auction. + * @return next_ Address of the next auction in queue. + * @return prev_ Address of the prev auction in queue. */ function auctionInfo(address borrower_) external @@ -30,6 +31,7 @@ interface IPoolState { uint256 kickTime_, uint256 referencePrice_, uint256 neutralPrice_, + uint256 debtToCollateral_, address head_, address next_, address prev_ @@ -198,9 +200,9 @@ interface IPoolState { /** * @notice Returns information about a loan in the pool. - * @param loanId_ Loan's id within loan heap. Max loan is position `1`. - * @return borrower_ Borrower address at the given position. - * @return thresholdPrice_ Borrower threshold price in pool. + * @param loanId_ Loan's id within loan heap. Max loan is position `1`. + * @return borrower_ Borrower address at the given position. + * @return t0DebtToCollateral_ Borrower t0 debt to collateral. */ function loanInfo( uint256 loanId_ @@ -209,21 +211,21 @@ interface IPoolState { view returns ( address borrower_, - uint256 thresholdPrice_ + uint256 t0DebtToCollateral_ ); /** * @notice Returns information about pool loans. - * @return maxBorrower_ Borrower address with highest threshold price. - * @return maxThresholdPrice_ Highest threshold price in pool. - * @return noOfLoans_ Total number of loans. + * @return maxBorrower_ Borrower address with highest t0 debt to collateral. + * @return maxT0DebtToCollateral_ Highest t0 debt to collateral in pool. + * @return noOfLoans_ Total number of loans. */ function loansInfo() external view returns ( address maxBorrower_, - uint256 maxThresholdPrice_, + uint256 maxT0DebtToCollateral_, uint256 noOfLoans_ ); @@ -232,6 +234,7 @@ interface IPoolState { * @return liquidationBondEscrowed_ Amount of liquidation bond across all liquidators. * @return reserveAuctionUnclaimed_ Amount of claimable reserves which has not been taken in the `Claimable Reserve Auction`. * @return reserveAuctionKicked_ Time a `Claimable Reserve Auction` was last kicked. + * @return lastKickedReserves_ Amount of reserves upon last kick, used to calculate price. * @return totalInterestEarned_ Total interest earned by all lenders in the pool */ function reservesInfo() @@ -241,6 +244,7 @@ interface IPoolState { uint256 liquidationBondEscrowed_, uint256 reserveAuctionUnclaimed_, uint256 reserveAuctionKicked_, + uint256 lastKickedReserves_, uint256 totalInterestEarned_ ); @@ -378,15 +382,15 @@ struct LoansState { /// @dev Struct holding loan state. struct Loan { - address borrower; // borrower address - uint96 thresholdPrice; // [WAD] Loan's threshold price. + address borrower; // borrower address + uint96 t0DebtToCollateral; // [WAD] Borrower t0 debt to collateral. } /// @dev Struct holding borrower state. struct Borrower { - uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool. - uint256 collateral; // [WAD] Collateral deposited by borrower. - uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral. + uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool. + uint256 collateral; // [WAD] Collateral deposited by borrower. + uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral. } /**********************/ @@ -405,14 +409,16 @@ struct AuctionsState { /// @dev Struct holding liquidation state. struct Liquidation { - address kicker; // address that initiated liquidation - uint96 bondFactor; // [WAD] bond factor used to start liquidation - uint96 kickTime; // timestamp when liquidation was started - address prev; // previous liquidated borrower in auctions queue - uint96 referencePrice; // [WAD] used to calculate auction start price - address next; // next liquidated borrower in auctions queue - uint160 bondSize; // [WAD] liquidation bond size - uint96 neutralPrice; // [WAD] Neutral Price when liquidation was started + address kicker; // address that initiated liquidation + uint96 bondFactor; // [WAD] bond factor used to start liquidation + uint96 kickTime; // timestamp when liquidation was started + address prev; // previous liquidated borrower in auctions queue + uint96 referencePrice; // [WAD] used to calculate auction start price + address next; // next liquidated borrower in auctions queue + uint160 bondSize; // [WAD] liquidation bond size + uint96 neutralPrice; // [WAD] Neutral Price when liquidation was started + uint256 debtToCollateral; // [WAD] Borrower debt to collateral, which is used in BPF for kicker's reward calculation + uint256 t0ReserveSettleAmount; // [WAD] Amount of t0Debt that could be settled via reserves in this auction } /// @dev Struct holding kicker state. @@ -428,6 +434,7 @@ struct Kicker { /// @dev Struct holding reserve auction state. struct ReserveAuctionState { uint256 kicked; // Time a Claimable Reserve Auction was last kicked. + uint256 lastKickedReserves; // [WAD] Amount of reserves upon last kick, used to calculate price. uint256 unclaimed; // [WAD] Amount of claimable reserves which has not been taken in the Claimable Reserve Auction. uint256 latestBurnEventEpoch; // Latest burn event epoch. uint256 totalAjnaBurned; // [WAD] Total ajna burned in the pool. diff --git a/src/interfaces/pool/erc721/IERC721PoolState.sol b/src/interfaces/pool/erc721/IERC721PoolState.sol index e6fb2777a..ba50ee2cb 100644 --- a/src/interfaces/pool/erc721/IERC721PoolState.sol +++ b/src/interfaces/pool/erc721/IERC721PoolState.sol @@ -37,17 +37,16 @@ interface IERC721PoolState { ) external view returns (uint256 tokenId); /** - * @notice Returns the total `NFT` pledged by a borrower. - * @param borrower_ The address of borrower that pledged the `NFT`. - * @return Total number of `NFT`s pledged by borrower. + * @notice Returns the list of `NFT` tokenIds pledged by a borrower in a pool. + * @param borrower_ The address of borrower that pledged the `NFT`s. + * @return List of `NFT`s pledged by borrower. */ - function totalBorrowerTokens( - address borrower_ - ) external view returns (uint256); + function getBorrowerTokenIds(address borrower_) external view returns(uint256[] memory); /** - * @notice Returns the total `NFT` added in pool bucket. - * @return Total number of `NFT`s in buckets (claimable from pool). + * @notice Returns the list of `NFT` tokenIds added to pool buckets. + * @return List of `NFT`s that are claimable from the pool. */ - function totalBucketTokens() external view returns (uint256); -} \ No newline at end of file + function getBucketTokenIds() external view returns(uint256[] memory); + +} diff --git a/src/interfaces/position/IPositionManagerOwnerActions.sol b/src/interfaces/position/IPositionManagerOwnerActions.sol index 3af266a9d..835fbb69f 100644 --- a/src/interfaces/position/IPositionManagerOwnerActions.sol +++ b/src/interfaces/position/IPositionManagerOwnerActions.sol @@ -55,15 +55,13 @@ interface IPositionManagerOwnerActions { * @param fromIndex_ The bucket index from which liquidity should be moved. * @param toIndex_ The bucket index to which liquidity should be moved. * @param expiry_ Timestamp after which this TX will revert, preventing inclusion in a block with unfavorable price. - * @param revertIfBelowLup_ The tx will revert if quote token is moved from above the `LUP` to below the `LUP` (and avoid paying fee for move below `LUP`). */ function moveLiquidity( address pool_, uint256 tokenId_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_, - bool revertIfBelowLup_ + uint256 expiry_ ) external; /** diff --git a/src/interfaces/rewards/IRewardsManager.sol b/src/interfaces/rewards/IRewardsManager.sol deleted file mode 100644 index 1d9a50d89..000000000 --- a/src/interfaces/rewards/IRewardsManager.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -import { IRewardsManagerOwnerActions } from './IRewardsManagerOwnerActions.sol'; -import { IRewardsManagerState } from './IRewardsManagerState.sol'; -import { IRewardsManagerDerivedState } from './IRewardsManagerDerivedState.sol'; -import { IRewardsManagerEvents } from './IRewardsManagerEvents.sol'; -import { IRewardsManagerErrors } from './IRewardsManagerErrors.sol'; - -interface IRewardsManager is - IRewardsManagerOwnerActions, - IRewardsManagerState, - IRewardsManagerDerivedState, - IRewardsManagerErrors, - IRewardsManagerEvents -{ - -} diff --git a/src/interfaces/rewards/IRewardsManagerDerivedState.sol b/src/interfaces/rewards/IRewardsManagerDerivedState.sol deleted file mode 100644 index d6f759358..000000000 --- a/src/interfaces/rewards/IRewardsManagerDerivedState.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -/** - * @title Rewards Manager Derived State - */ -interface IRewardsManagerDerivedState { - - /** - * @notice Calculate the amount of rewards that have been accumulated by a staked `NFT`. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - * @param epochToClaim_ The end burn epoch to calculate rewards for (rewards calculation starts from the last claimed epoch). - * @return The amount of rewards earned by the staked `NFT`. - */ - function calculateRewards( - uint256 tokenId_, - uint256 epochToClaim_ - ) external view returns (uint256); - -} diff --git a/src/interfaces/rewards/IRewardsManagerErrors.sol b/src/interfaces/rewards/IRewardsManagerErrors.sol deleted file mode 100644 index d2aedd13d..000000000 --- a/src/interfaces/rewards/IRewardsManagerErrors.sol +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -/** - * @title Rewards Manager Errors - */ -interface IRewardsManagerErrors { - /** - * @notice User attempted to claim rewards multiple times. - */ - error AlreadyClaimed(); - - /** - * @notice User attempted to claim rewards for an epoch that is not yet available. - */ - error EpochNotAvailable(); - - /** - * @notice Insufficient Token Balance in contract to transfer rewards - */ - error InsufficientLiquidity(); - - /** - * @notice User provided move index params that didn't match in size. - */ - error MoveStakedLiquidityInvalid(); - - /** - * @notice User attempted to update exchange rates for a pool that wasn't deployed by an `Ajna` factory. - */ - error NotAjnaPool(); - - /** - * @notice User attempted to interact with an `NFT` they aren't the owner of. - */ - error NotOwnerOfDeposit(); - - /** - * @notice Can't deploy with `Ajna` token or position manager address `0x`. - */ - error DeployWithZeroAddress(); -} \ No newline at end of file diff --git a/src/interfaces/rewards/IRewardsManagerEvents.sol b/src/interfaces/rewards/IRewardsManagerEvents.sol deleted file mode 100644 index 995d06b9a..000000000 --- a/src/interfaces/rewards/IRewardsManagerEvents.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -/** - * @title Rewards Manager Events - */ -interface IRewardsManagerEvents { - - /** - * @notice Emitted when lender claims rewards that have accrued to their staked `NFT`. - * @param owner Owner of the staked `NFT`. - * @param ajnaPool Address of the `Ajna` pool the `NFT` corresponds to. - * @param tokenId `ID` of the staked `NFT`. - * @param epochsClaimed Array of burn epochs claimed. - * @param amount The amount of `Ajna` tokens claimed by the staker. - */ - event ClaimRewards( - address indexed owner, - address indexed ajnaPool, - uint256 indexed tokenId, - uint256[] epochsClaimed, - uint256 amount - ); - - /** - * @notice Emitted when moves liquidity in a staked `NFT` between buckets. - * @param tokenId `ID` of the staked `NFT`. - * @param fromIndexes Array of indexes from which liquidity was moved. - * @param toIndexes Array of indexes to which liquidity was moved. - */ - event MoveStakedLiquidity( - uint256 tokenId, - uint256[] fromIndexes, - uint256[] toIndexes - ); - - /** - * @notice Emitted when lender stakes their `LP` `NFT` in the rewards contract. - * @param owner Owner of the staked `NFT`. - * @param ajnaPool Address of the `Ajna` pool the `NFT` corresponds to. - * @param tokenId `ID` of the staked `NFT`. - */ - event Stake( - address indexed owner, - address indexed ajnaPool, - uint256 indexed tokenId - ); - - /** - * @notice Emitted when someone records the latest exchange rate for a bucket in a pool, and claims the associated reward. - * @param caller Address of the recorder. The address which will receive an update reward, if applicable. - * @param ajnaPool Address of the `Ajna` pool whose exchange rates are being updated. - * @param indexesUpdated Array of bucket indexes whose exchange rates are being updated. - * @param rewardsClaimed Amount of `Ajna` tokens claimed by the recorder as a reward for updating each bucket index. - */ - event UpdateExchangeRates( - address indexed caller, - address indexed ajnaPool, - uint256[] indexesUpdated, - uint256 rewardsClaimed - ); - - /** - * @notice Emitted when lender withdraws their `LP` `NFT` from the rewards contract. - * @param owner Owner of the staked `NFT`. - * @param ajnaPool Address of the `Ajna` pool the `NFT` corresponds to. - * @param tokenId `ID` of the staked `NFT`. - */ - event Unstake( - address indexed owner, - address indexed ajnaPool, - uint256 indexed tokenId - ); -} \ No newline at end of file diff --git a/src/interfaces/rewards/IRewardsManagerOwnerActions.sol b/src/interfaces/rewards/IRewardsManagerOwnerActions.sol deleted file mode 100644 index 2a25e6f82..000000000 --- a/src/interfaces/rewards/IRewardsManagerOwnerActions.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -/** - * @title Rewards Manager Owner Actions - */ -interface IRewardsManagerOwnerActions { - - /** - * @notice Claim `Ajna` token rewards that have accrued to a staked `LP` `NFT`. - * @dev Updates exchange rates for each bucket the `NFT` is associated with. - * @dev Reverts with `InsufficientLiquidity` if calculated rewards or contract balance is below specified min amount to receive limit. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - * @param epochToClaim_ The burn epoch to claim rewards for. - * @param minAmount_ Minimum amount to be received by rewards claimer. - */ - function claimRewards( - uint256 tokenId_, - uint256 epochToClaim_, - uint256 minAmount_ - ) external; - - /** - * @notice Stake a `LP` `NFT` into the rewards contract. - * @dev Updates exchange rates for each bucket the `NFT` is associated with. - * @param tokenId_ `ID` of the `LP` `NFT` to stake in the `Rewards contract. - */ - function stake( - uint256 tokenId_ - ) external; - - /** - * @notice Withdraw a staked `LP` `NFT` from the rewards contract. - * @notice If rewards are available, claim all available rewards before withdrawal. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - */ - function unstake( - uint256 tokenId_ - ) external; - - /** - * @notice Withdraw a staked `LP` `NFT` from the rewards contract without claiming any rewards before withdrawal. - * @param tokenId_ `ID` of the staked `LP` `NFT`. - */ - function emergencyUnstake( - uint256 tokenId_ - ) external; - - /** - * @notice Update the exchange rate of a list of buckets. - * @dev Caller can claim `5%` of the rewards that have accumulated to each bucket since the last burn event, if it hasn't already been updated. - * @param pool_ Address of the pool whose exchange rates are being updated. - * @param subsetHash_ Factory's subset hash pool that dpeloyed the Ajna pool. Used to validate that the `pool_` address is a legit Ajna pool. - * @param indexes_ List of bucket indexes to be updated. - * @return Returns reward amount for updating bucket exchange rates. - */ - function updateBucketExchangeRatesAndClaim( - address pool_, - bytes32 subsetHash_, - uint256[] calldata indexes_ - ) external returns (uint256); - -} \ No newline at end of file diff --git a/src/interfaces/rewards/IRewardsManagerState.sol b/src/interfaces/rewards/IRewardsManagerState.sol deleted file mode 100644 index 6c4c50598..000000000 --- a/src/interfaces/rewards/IRewardsManagerState.sol +++ /dev/null @@ -1,105 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.18; - -/** - * @title Rewards Manager State - */ -interface IRewardsManagerState { - - /** - * @notice Track whether a bucket's exchange rate has been updated in a given burn event epoch. - * @param pool_ The pool to check the update status of. - * @param bucketIndex_ The bucket index to check the update status of. - * @param epoch_ The burn epoch to check the bucket index in. - * @return `True` if the buckets exchange rate was updated in the given epoch, else false. - */ - function isBucketUpdated( - address pool_, - uint256 bucketIndex_, - uint256 epoch_ - ) external view returns (bool); - - /** - * @notice Track whether a depositor has claimed rewards for a given burn event epoch. - * @param tokenId_ ID of the staked `LP` `NFT`. - * @param epoch_ The burn epoch to track if rewards were claimed. - * @return `True` if rewards were claimed for the given epoch, else false. - */ - function isEpochClaimed( - uint256 tokenId_, - uint256 epoch_ - ) external view returns (bool); - - /** - * @notice Track the total amount of rewards that have been claimed for a given epoch. - * @param pool_ The pool to get the rewards claimed for. - * @param epoch_ The burn epoch to track if rewards were claimed. - * @return The amount of rewards claimed in given epoch. - */ - function getRewardsClaimed( - address pool_, - uint256 epoch_ - ) external view returns (uint256); - - /** - * @notice Track the total amount of rewards that have been claimed for a given burn event's bucket updates. - * @param pool_ The pool to get the update rewards claimed for. - * @param epoch_ The burn epoch to track if rewards were claimed. - * @return The amount of update rewards claimed in given epoch. - */ - function getUpdateRewardsClaimed( - address pool_, - uint256 epoch_ - ) external view returns (uint256); - - /** - * @notice Retrieve information about a given stake. - * @param tokenId_ `ID` of the `NFT` staked in the rewards contract to retrieve information about. - * @return owner_ The owner of a given `NFT` stake. - * @return pool_ The `Pool` the `NFT` represents positions in. - * @return lastClaimedEpoch_ The last burn epoch in which the owner of the `NFT` claimed rewards. - */ - function getStakeInfo( - uint256 tokenId_ - ) external view returns (address owner_, address pool_, uint256 lastClaimedEpoch_); - - /** - * @notice Retrieve information about recorded `LP` and rate values for a given bucket and a given stake, at stake time. - * @param tokenId_ `ID` of the `NFT` staked in the rewards contract to retrieve information about. - * @param bucketId_ `ID` of the bucket to retrieve recorded information at stake time. - * @return `LP` amount (in `WAD`) the `NFT` owner is entitled in current bucket at the time of staking. - * @return Current bucket exchange rate (`WAD`) at the time of staking. - */ - function getBucketStateStakeInfo( - uint256 tokenId_, - uint256 bucketId_ - ) external view returns (uint256, uint256); - -} - -/*********************/ -/*** State Structs ***/ -/*********************/ - -/// @dev Struct holding stake info state. -struct StakeInfo { - address ajnaPool; // address of the Ajna pool the NFT corresponds to - uint96 lastClaimedEpoch; // last epoch the stake claimed rewards - address owner; // owner of the LP NFT - uint96 stakingEpoch; // epoch at staking time - mapping(uint256 => BucketState) snapshot; // the LP NFT's balances and exchange rates in each bucket at the time of staking -} - -/// @dev Struct holding bucket state at stake time. -struct BucketState { - uint256 lpsAtStakeTime; // [WAD] LP amount the NFT owner is entitled in current bucket at the time of staking - uint256 rateAtStakeTime; // [WAD] current bucket exchange rate at the time of staking -} - -/// @dev Struct holding Pool rewards info -struct PoolRewardsInfo { - mapping(uint256 => uint256) rewardsClaimed; // staking rewards claimed in a epoch - mapping(uint256 => uint256) updateBucketRewardsClaimed; // update exchange rate rewards claimed in a epoch - mapping(uint256 => mapping(uint256 => uint256)) bucketExchangeRates; // bucket exchange rates at a given burn event for each bucket -} diff --git a/src/libraries/external/BorrowerActions.sol b/src/libraries/external/BorrowerActions.sol index 02ce36855..500831c7b 100644 --- a/src/libraries/external/BorrowerActions.sol +++ b/src/libraries/external/BorrowerActions.sol @@ -46,7 +46,6 @@ library BorrowerActions { struct DrawDebtLocalVars { bool borrow; // true if borrow action uint256 borrowerDebt; // [WAD] borrower's accrued debt - uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP (NFTs only) uint256 t0BorrowAmount; // [WAD] t0 amount to borrow uint256 t0DebtChange; // [WAD] additional t0 debt resulted from draw debt action bool pledge; // true if pledge action @@ -56,7 +55,6 @@ library BorrowerActions { /// @dev Struct used for `repayDebt` function local vars. struct RepayDebtLocalVars { uint256 borrowerDebt; // [WAD] borrower's accrued debt - uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP (NFTs only) bool pull; // true if pull action bool repay; // true if repay action bool stampNpTpRatio; // true if loan's Np to Tp ratio should be restamped (when repay settles auction or pull collateral) @@ -120,7 +118,7 @@ library BorrowerActions { if (amountToBorrow_ > maxAvailable_) revert InsufficientLiquidity(); // revert if borrower is in auction - if(_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); + if (_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); DrawDebtLocalVars memory vars; vars.pledge = collateralToPledge_ != 0; @@ -238,7 +236,7 @@ library BorrowerActions { // revert if no amount to pull or repay if (!vars.repay && !vars.pull) revert InvalidAmount(); - if(_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); + if (_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); Borrower memory borrower = loans_.borrowers[borrowerAddress_]; @@ -291,18 +289,18 @@ library BorrowerActions { // calculate LUP only if it wasn't calculated in repay action if (!vars.repay) result_.newLup = Deposits.getLup(deposits_, result_.poolDebt); - uint256 encumberedCollateral = Maths.wdiv(vars.borrowerDebt, result_.newLup); - if ( - borrower.t0Debt != 0 && encumberedCollateral == 0 || // case when small amount of debt at a high LUP results in encumbered collateral calculated as 0 - borrower.collateral < encumberedCollateral || - borrower.collateral - encumberedCollateral < collateralAmountToPull_ - ) revert InsufficientCollateral(); + // prevent underflow + if (collateralAmountToPull_ > borrower.collateral) + revert InsufficientCollateral(); + + // check collateralization + borrower.collateral -= collateralAmountToPull_; + if (!_isCollateralized(vars.borrowerDebt, borrower.collateral, result_.newLup, poolState_.poolType)) + revert InsufficientCollateral(); // stamp borrower Np to Tp ratio when pull collateral action vars.stampNpTpRatio = true; - borrower.collateral -= collateralAmountToPull_; - result_.poolCollateral -= collateralAmountToPull_; } diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index 39f9e47e0..5f219118b 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -26,9 +26,11 @@ import { import { MAX_INFLATED_PRICE, + COLLATERALIZATION_FACTOR, _bondParams, - _bpf, + _borrowFeeRate, _claimableReserves, + _htp, _isCollateralized, _priceAt, _reserveAuctionPrice @@ -55,13 +57,16 @@ library KickerActions { /// @dev Struct used for `kick` function local vars. struct KickLocalVars { - uint256 borrowerDebt; // [WAD] the accrued debt of kicked borrower - uint256 borrowerCollateral; // [WAD] amount of kicked borrower collateral - uint256 neutralPrice; // [WAD] neutral price recorded in kick action - uint256 htp; // [WAD] highest threshold price in pool - uint256 referencePrice; // [WAD] used to calculate auction start price - uint256 bondFactor; // [WAD] bond factor of kicked auction - uint256 bondSize; // [WAD] bond size of kicked auction + uint256 borrowerDebt; // [WAD] the accrued debt of kicked borrower + uint256 borrowerCollateral; // [WAD] amount of kicked borrower collateral + uint256 t0ReserveSettleAmount; // [WAD] Amount of t0Debt that could be settled via reserves in an auction + uint256 borrowerNpTpRatio; // [WAD] borrower NP to TP ratio + uint256 neutralPrice; // [WAD] neutral price recorded in kick action + uint256 htp; // [WAD] highest threshold price (including the collateralization factor) in pool + uint256 referencePrice; // [WAD] used to calculate auction start price + uint256 bondFactor; // [WAD] bond factor of kicked auction + uint256 bondSize; // [WAD] bond size of kicked auction + uint256 debtToCollateral; // [WAD] borrower debt to collateral at kick time } /// @dev Struct used for `lenderKick` function local vars. @@ -77,10 +82,11 @@ library KickerActions { /**************/ // See `IPoolEvents` for descriptions + event BondWithdrawn(address indexed kicker, address indexed receiver, 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 ***/ @@ -90,8 +96,6 @@ library KickerActions { error AuctionActive(); error BorrowerOk(); error InsufficientLiquidity(); - error InsufficientLP(); - error InvalidAmount(); error NoReserves(); error PriceBelowLUP(); error ReserveAuctionTooSoon(); @@ -102,7 +106,7 @@ library KickerActions { /** * @notice See `IPoolKickerActions` for descriptions. - * @return The `KickResult` struct result of the kick action. + * @return kickResult_ The `KickResult` struct result of the kick action. */ function kick( AuctionsState storage auctions_, @@ -112,17 +116,20 @@ library KickerActions { address borrowerAddress_, uint256 limitIndex_ ) external returns ( - KickResult memory + KickResult memory kickResult_ ) { - return _kick( + uint256 curLup = Deposits.getLup(deposits_, poolState_.debt); + + kickResult_ = _kick( auctions_, - deposits_, loans_, poolState_, borrowerAddress_, limitIndex_, - 0 + curLup // proposed LUP is the current pool LUP ); + // return current LUP in pool + kickResult_.lup = curLup; } /** @@ -148,7 +155,8 @@ library KickerActions { vars.bucketPrice = _priceAt(index_); // revert if the bucket price is below current LUP - if (vars.bucketPrice < Deposits.getLup(deposits_, poolState_.debt)) revert PriceBelowLUP(); + uint256 curLup = Deposits.getLup(deposits_, poolState_.debt); + if (vars.bucketPrice < curLup) revert PriceBelowLUP(); Bucket storage bucket = buckets_[index_]; Lender storage lender = bucket.lenders[msg.sender]; @@ -172,16 +180,21 @@ library KickerActions { // revert if no entitled amount if (vars.entitledAmount == 0) revert InsufficientLiquidity(); + // add amount to remove to pool debt in order to calculate proposed LUP + // this simulates LUP movement with additional debt + uint256 proposedLup = Deposits.getLup(deposits_, poolState_.debt + vars.entitledAmount); + // kick top borrower kickResult_ = _kick( auctions_, - deposits_, loans_, poolState_, Loans.getMax(loans_).borrower, limitIndex_, - vars.entitledAmount + proposedLup ); + // return current LUP in pool + kickResult_.lup = curLup; } /*************************/ @@ -195,6 +208,7 @@ library KickerActions { * @dev update `reserveAuction.kicked` timestamp state * @dev === Reverts on === * @dev no reserves to claim `NoReserves()` + * @dev 5 days not passed `ReserveAuctionTooSoon()` * @dev === Emit events === * @dev - `KickReserveAuction` */ @@ -204,11 +218,10 @@ library KickerActions { KickReserveAuctionParams calldata params_ ) external { // retrieve timestamp of latest burn event and last burn timestamp - uint256 latestBurnEpoch = reserveAuction_.latestBurnEventEpoch; - uint256 lastBurnTimestamp = reserveAuction_.burnEvents[latestBurnEpoch].timestamp; + uint256 latestBurnEpoch = reserveAuction_.latestBurnEventEpoch; - // check that at least two weeks have passed since the last reserve auction completed, and that the auction was not kicked within the past 72 hours - if (block.timestamp < lastBurnTimestamp + 2 weeks || block.timestamp - reserveAuction_.kicked <= 72 hours) { + // check that at least five days have passed since the last reserve auction was kicked + if (block.timestamp < reserveAuction_.kicked + 120 hours) { revert ReserveAuctionTooSoon(); } @@ -226,8 +239,9 @@ library KickerActions { if (curUnclaimedAuctionReserve == 0) revert NoReserves(); - reserveAuction_.unclaimed = curUnclaimedAuctionReserve; - reserveAuction_.kicked = block.timestamp; + reserveAuction_.unclaimed = curUnclaimedAuctionReserve; + reserveAuction_.kicked = block.timestamp; + reserveAuction_.lastKickedReserves = curUnclaimedAuctionReserve; // increment latest burn event epoch and update burn event timestamp latestBurnEpoch += 1; @@ -237,11 +251,32 @@ library KickerActions { emit KickReserveAuction( curUnclaimedAuctionReserve, - _reserveAuctionPrice(block.timestamp), + _reserveAuctionPrice(block.timestamp, curUnclaimedAuctionReserve), latestBurnEpoch ); } + 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 ***/ /***************************/ @@ -262,22 +297,20 @@ library KickerActions { * @dev === Emit events === * @dev - `Kick` * @param auctions_ Struct for pool auctions state. - * @param deposits_ Struct for pool deposits state. * @param loans_ Struct for pool loans state. * @param poolState_ Current state of the pool. * @param borrowerAddress_ Address of the borrower to kick. * @param limitIndex_ Index of the lower bound of `NP` tolerated when kicking the auction. - * @param additionalDebt_ Additional debt to be used when calculating proposed `LUP`. + * @param proposedLup_ Proposed `LUP` in pool. * @return kickResult_ The `KickResult` struct result of the kick action. */ function _kick( AuctionsState storage auctions_, - DepositsState storage deposits_, LoansState storage loans_, PoolState calldata poolState_, address borrowerAddress_, uint256 limitIndex_, - uint256 additionalDebt_ + uint256 proposedLup_ ) internal returns ( KickResult memory kickResult_ ) { @@ -290,17 +323,14 @@ library KickerActions { kickResult_.t0KickedDebt = borrower.t0Debt; kickResult_.collateralPreAction = borrower.collateral; - // add amount to remove to pool debt in order to calculate proposed LUP - // for regular kick this is the currrent LUP in pool - // for provisional kick this simulates LUP movement with additional debt - kickResult_.lup = Deposits.getLup(deposits_, poolState_.debt + additionalDebt_); - KickLocalVars memory vars; - vars.borrowerDebt = Maths.wmul(kickResult_.t0KickedDebt, poolState_.inflator); - vars.borrowerCollateral = kickResult_.collateralPreAction; + vars.borrowerDebt = Maths.wmul(kickResult_.t0KickedDebt, poolState_.inflator); + vars.borrowerCollateral = kickResult_.collateralPreAction; + vars.t0ReserveSettleAmount = Maths.wmul(kickResult_.t0KickedDebt, _borrowFeeRate(poolState_.rate)) / 2; + vars.borrowerNpTpRatio = borrower.npTpRatio; // revert if kick on a collateralized borrower - if (_isCollateralized(vars.borrowerDebt, vars.borrowerCollateral, kickResult_.lup, poolState_.poolType)) { + if (_isCollateralized(vars.borrowerDebt, vars.borrowerCollateral, proposedLup_, poolState_.poolType)) { revert BorrowerOk(); } @@ -308,21 +338,24 @@ library KickerActions { // neutral price = Tp * Np to Tp ratio // neutral price is capped at 50 * max pool price vars.neutralPrice = Maths.min( - Math.mulDiv(vars.borrowerDebt, borrower.npTpRatio, vars.borrowerCollateral), + Math.mulDiv(Maths.wmul(vars.borrowerDebt, COLLATERALIZATION_FACTOR), + vars.borrowerNpTpRatio, vars.borrowerCollateral), MAX_INFLATED_PRICE ); // check if NP is not less than price at the limit index provided by the kicker - done to prevent frontrunning kick auction call with a large amount of loan // which will make it harder for kicker to earn a reward and more likely that the kicker is penalized _revertIfPriceDroppedBelowLimit(vars.neutralPrice, limitIndex_); - vars.htp = Maths.wmul(Loans.getMax(loans_).thresholdPrice, poolState_.inflator); + vars.htp = _htp(Loans.getMax(loans_).t0DebtToCollateral, poolState_.inflator); vars.referencePrice = Maths.min(Maths.max(vars.htp, vars.neutralPrice), MAX_INFLATED_PRICE); (vars.bondFactor, vars.bondSize) = _bondParams( vars.borrowerDebt, - borrower.npTpRatio + vars.borrowerNpTpRatio ); + vars.debtToCollateral = Maths.wdiv(vars.borrowerDebt, vars.borrowerCollateral); + // record liquidation info _recordAuction( auctions_, @@ -331,7 +364,9 @@ library KickerActions { vars.bondSize, vars.bondFactor, vars.referencePrice, - vars.neutralPrice + vars.neutralPrice, + vars.debtToCollateral, + vars.t0ReserveSettleAmount ); // update escrowed bonds balances and get the difference needed to cover bond (after using any kick claimable funds if any) @@ -385,13 +420,15 @@ library KickerActions { * @dev `borrower -> liquidation` mapping update * @dev increment auctions count accumulator * @dev updates auction queue state - * @param auctions_ Struct for pool auctions state. - * @param liquidation_ Struct for current auction state. - * @param borrowerAddress_ Address of the borrower that is kicked. - * @param bondSize_ Bond size to cover newly kicked auction. - * @param bondFactor_ Bond factor of the newly kicked auction. - * @param referencePrice_ Used to calculate auction start price. - * @param neutralPrice_ Current pool `Neutral Price`. + * @param auctions_ Struct for pool auctions state. + * @param liquidation_ Struct for current auction state. + * @param borrowerAddress_ Address of the borrower that is kicked. + * @param bondSize_ Bond size to cover newly kicked auction. + * @param bondFactor_ Bond factor of the newly kicked auction. + * @param referencePrice_ Used to calculate auction start price. + * @param neutralPrice_ Current pool `Neutral Price`. + * @param debtToCollateral_ Borrower debt to collateral at time of kick. + * @param t0ReserveSettleAmount_ Amount of t0Debt that could be settled via reserves in auction */ function _recordAuction( AuctionsState storage auctions_, @@ -400,15 +437,18 @@ library KickerActions { uint256 bondSize_, uint256 bondFactor_, uint256 referencePrice_, - uint256 neutralPrice_ + uint256 neutralPrice_, + uint256 debtToCollateral_, + uint256 t0ReserveSettleAmount_ ) internal { // 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_); + liquidation_.kicker = msg.sender; + liquidation_.kickTime = uint96(block.timestamp); + liquidation_.bondSize = SafeCast.toUint160(bondSize_); + liquidation_.bondFactor = SafeCast.toUint96(bondFactor_); + liquidation_.neutralPrice = SafeCast.toUint96(neutralPrice_); + liquidation_.debtToCollateral = debtToCollateral_; + liquidation_.t0ReserveSettleAmount = t0ReserveSettleAmount_; // increment number of active auctions ++auctions_.noOfAuctions; @@ -416,11 +456,14 @@ 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(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/external/LenderActions.sol b/src/libraries/external/LenderActions.sol index 97501bf83..bc4242072 100644 --- a/src/libraries/external/LenderActions.sol +++ b/src/libraries/external/LenderActions.sol @@ -16,7 +16,12 @@ import { PoolState } from '../../interfaces/pool/commons/IPoolState.sol'; -import { _depositFeeRate, _priceAt, MAX_FENWICK_INDEX } from '../helpers/PoolHelper.sol'; +import { + _depositFeeRate, + _htp, + _priceAt, + MAX_FENWICK_INDEX +} from '../helpers/PoolHelper.sol'; import { Deposits } from '../internal/Deposits.sol'; import { Buckets } from '../internal/Buckets.sol'; @@ -89,7 +94,6 @@ library LenderActions { error InsufficientLiquidity(); error InsufficientCollateral(); error MoveToSameIndex(); - error PriceBelowLUP(); /***************************/ /*** External Functions ***/ @@ -142,7 +146,6 @@ library LenderActions { * @dev same block when bucket becomes insolvent `BucketBankruptcyBlock()` * @dev no LP awarded in bucket `InsufficientLP()` * @dev calculated unscaled amount to add is 0 `InvalidAmount()` - * @dev deposit below `LUP` `PriceBelowLUP()` * @dev === Emit events === * @dev - `AddQuoteToken` */ @@ -151,7 +154,7 @@ library LenderActions { DepositsState storage deposits_, PoolState calldata poolState_, AddQuoteParams calldata params_ - ) external returns (uint256 bucketLP_, uint256 lup_) { + ) external returns (uint256 bucketLP_, uint256 addedAmount_, uint256 lup_) { // revert if no amount to be added if (params_.amount == 0) revert InvalidAmount(); // revert if adding to an invalid index @@ -168,23 +171,15 @@ library LenderActions { uint256 bucketScale = Deposits.scale(deposits_, params_.index); uint256 bucketDeposit = Maths.wmul(bucketScale, unscaledBucketDeposit); uint256 bucketPrice = _priceAt(params_.index); - uint256 addedAmount = params_.amount; - // charge unutilized deposit fee where appropriate - uint256 lupIndex = Deposits.findIndexOfSum(deposits_, poolState_.debt); - bool depositBelowLup = lupIndex != 0 && params_.index > lupIndex; - - if (depositBelowLup) { - if (params_.revertIfBelowLup) revert PriceBelowLUP(); - - addedAmount = Maths.wmul(addedAmount, Maths.WAD - _depositFeeRate(poolState_.rate)); - } + // calculate added amount charging deposit fee + addedAmount_ = Maths.wmul(params_.amount, Maths.WAD - _depositFeeRate(poolState_.rate)); bucketLP_ = Buckets.quoteTokensToLP( bucket.collateral, bucket.lps, bucketDeposit, - addedAmount, + addedAmount_, bucketPrice, Math.Rounding.Down ); @@ -192,11 +187,7 @@ library LenderActions { // revert if (due to rounding) the awarded LP is 0 if (bucketLP_ == 0) revert InsufficientLP(); - uint256 unscaledAmount = Maths.wdiv(addedAmount, bucketScale); - // revert if unscaled amount is 0 - if (unscaledAmount == 0) revert InvalidAmount(); - - Deposits.unscaledAdd(deposits_, params_.index, unscaledAmount); + Deposits.unscaledAdd(deposits_, params_.index, Maths.wdiv(addedAmount_, bucketScale)); // update lender LP Buckets.addLenderLP(bucket, bankruptcyTime, msg.sender, bucketLP_); @@ -204,16 +195,14 @@ library LenderActions { // update bucket LP bucket.lps += bucketLP_; - // only need to recalculate LUP if the deposit was above it - if (!depositBelowLup) { - lupIndex = Deposits.findIndexOfSum(deposits_, poolState_.debt); - } + // calculate new LUP + uint256 lupIndex = Deposits.findIndexOfSum(deposits_, poolState_.debt); lup_ = _priceAt(lupIndex); emit AddQuoteToken( msg.sender, params_.index, - addedAmount, + addedAmount_, bucketLP_, lup_ ); @@ -234,7 +223,7 @@ library LenderActions { * @dev dust amount `DustAmountNotExceeded()` * @dev invalid index `InvalidIndex()` * @dev no LP awarded in to bucket `InsufficientLP()` - * @dev move below `LUP` `PriceBelowLUP()` + * @dev calculated unscaled amount to move is 0 `InvalidAmount()` * @dev === Emit events === * @dev - `BucketBankruptcy` * @dev - `MoveQuoteToken` @@ -245,11 +234,9 @@ library LenderActions { PoolState calldata poolState_, MoveQuoteParams calldata params_ ) external returns (uint256 fromBucketRedeemedLP_, uint256 toBucketLP_, uint256 movedAmount_, uint256 lup_) { - if (params_.maxAmountToMove == 0) - revert InvalidAmount(); if (params_.fromIndex == params_.toIndex) revert MoveToSameIndex(); - if (params_.maxAmountToMove != 0 && params_.maxAmountToMove < poolState_.quoteTokenScale) + if (params_.maxAmountToMove < poolState_.quoteTokenScale) revert DustAmountNotExceeded(); if (params_.toIndex == 0 || params_.toIndex > MAX_FENWICK_INDEX) revert InvalidIndex(); @@ -287,11 +274,8 @@ library LenderActions { }) ); - lup_ = Deposits.getLup(deposits_, poolState_.debt); - // apply unutilized deposit fee if quote token is moved from above the LUP to below the LUP - if (vars.fromBucketPrice >= lup_ && vars.toBucketPrice < lup_) { - if (params_.revertIfBelowLup) revert PriceBelowLUP(); - + // apply deposit fee if moving to a lower-priced bucket + if (params_.fromIndex < params_.toIndex) { movedAmount_ = Maths.wmul(movedAmount_, Maths.WAD - _depositFeeRate(poolState_.rate)); } @@ -313,10 +297,9 @@ library LenderActions { Deposits.unscaledAdd(deposits_, params_.toIndex, Maths.wdiv(movedAmount_, vars.toBucketScale)); - // recalculate LUP after adding amount in to bucket only if to bucket price is greater than LUP - if (vars.toBucketPrice > lup_) lup_ = Deposits.getLup(deposits_, poolState_.debt); - - vars.htp = Maths.wmul(params_.thresholdPrice, poolState_.inflator); + // recalculate LUP and HTP + lup_ = Deposits.getLup(deposits_, poolState_.debt); + vars.htp = _htp(params_.maxT0DebtToCollateral, poolState_.inflator); // check loan book's htp against new lup, revert if move drives LUP below HTP if ( @@ -433,7 +416,7 @@ library LenderActions { lup_ = Deposits.getLup(deposits_, poolState_.debt); - uint256 htp = Maths.wmul(params_.thresholdPrice, poolState_.inflator); + uint256 htp = _htp(params_.maxT0DebtToCollateral, poolState_.inflator); if ( // check loan book's htp doesn't exceed new lup @@ -749,7 +732,7 @@ library LenderActions { * @dev update `values` array state * @dev === Reverts on === * @dev no `LP` redeemed `InsufficientLP()` - * @dev no unscaled amount removed` `InvalidAmount()` + * @dev no unscaled amount removed `InvalidAmount()` * @return removedAmount_ Amount of scaled deposit removed. * @return redeemedLP_ Amount of bucket `LP` corresponding for calculated scaled deposit amount. * @return unscaledRemaining_ Amount of unscaled deposit remaining. @@ -831,14 +814,15 @@ library LenderActions { unscaledRemovedAmount = unscaledDepositAvailable; } + scaledDepositAvailable -= removedAmount_; + if (scaledDepositAvailable != 0 && scaledDepositAvailable < params_.dustLimit) revert DustAmountNotExceeded(); + unscaledRemaining_ = unscaledDepositAvailable - unscaledRemovedAmount; // revert if (due to rounding) required LP is 0 if (redeemedLP_ == 0) revert InsufficientLP(); - // revert if calculated amount of quote to remove is 0 - if (unscaledRemovedAmount == 0) revert InvalidAmount(); // update FenwickTree Deposits.unscaledRemove(deposits_, params_.index, unscaledRemovedAmount); } -} +} \ No newline at end of file diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index 164dff91a..8abbecdb5 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -5,9 +5,27 @@ pragma solidity 0.8.18; import { PRBMathSD59x18 } from "@prb-math/contracts/PRBMathSD59x18.sol"; import { PRBMathUD60x18 } from "@prb-math/contracts/PRBMathUD60x18.sol"; -import { InterestState, EmaState, PoolState, DepositsState } from '../../interfaces/pool/commons/IPoolState.sol'; - -import { _dwatp, _indexOf, MAX_FENWICK_INDEX, MIN_PRICE, MAX_PRICE } from '../helpers/PoolHelper.sol'; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + + +import { + DepositsState, + EmaState, + InflatorState, + InterestState, + PoolBalancesState, + PoolState +} from '../../interfaces/pool/commons/IPoolState.sol'; +import { IERC3156FlashBorrower } from '../../interfaces/pool/IERC3156FlashBorrower.sol'; + +import { + _dwatp, + _htp, + _indexOf, + MAX_FENWICK_INDEX, + MIN_PRICE, MAX_PRICE +} from '../helpers/PoolHelper.sol'; import { Deposits } from '../internal/Deposits.sol'; import { Buckets } from '../internal/Buckets.sol'; @@ -21,6 +39,8 @@ import { Maths } from '../internal/Maths.sol'; - pool utilization */ library PoolCommons { + using SafeERC20 for IERC20; + /*****************/ /*** Constants ***/ @@ -40,9 +60,18 @@ library PoolCommons { /**************/ // See `IPoolEvents` for descriptions + event Flashloan(address indexed receiver, address indexed token, uint256 amount); event ResetInterestRate(uint256 oldRate, uint256 newRate); event UpdateInterestRate(uint256 oldRate, uint256 newRate); + /**************/ + /*** Errors ***/ + /**************/ + + // See `IPoolErrors` for descriptions + error FlashloanCallbackFailed(); + error FlashloanIncorrectBalance(); + /*************************/ /*** Local Var Structs ***/ /*************************/ @@ -209,19 +238,19 @@ library PoolCommons { * @dev === Write state === * @dev - `Deposits.mult` (scale `Fenwick` tree with new interest accrued): * @dev update `scaling` array state - * @param emaParams_ Struct for pool `EMA`s state. - * @param deposits_ Struct for pool deposits state. - * @param poolState_ Current state of the pool. - * @param thresholdPrice_ Current Pool Threshold Price. - * @param elapsed_ Time elapsed since last inflator update. - * @return newInflator_ The new value of pool inflator. - * @return newInterest_ The new interest accrued. + * @param emaParams_ Struct for pool `EMA`s state. + * @param deposits_ Struct for pool deposits state. + * @param poolState_ Current state of the pool. + * @param maxT0DebtToCollateral_ Max t0 debt to collateral in Pool. + * @param elapsed_ Time elapsed since last inflator update. + * @return newInflator_ The new value of pool inflator. + * @return newInterest_ The new interest accrued. */ function accrueInterest( EmaState storage emaParams_, DepositsState storage deposits_, PoolState calldata poolState_, - uint256 thresholdPrice_, + uint256 maxT0DebtToCollateral_, uint256 elapsed_ ) external returns (uint256 newInflator_, uint256 newInterest_) { // Scale the borrower inflator to update amount of interest owed by borrowers @@ -229,7 +258,7 @@ library PoolCommons { // calculate the highest threshold price newInflator_ = Maths.wmul(poolState_.inflator, pendingFactor); - uint256 htp = Maths.wmul(thresholdPrice_, poolState_.inflator); + uint256 htp = _htp(maxT0DebtToCollateral_, poolState_.inflator); uint256 accrualIndex; if (htp > MAX_PRICE) accrualIndex = 1; // if HTP is over the highest price bucket then no buckets earn interest @@ -259,6 +288,45 @@ library PoolCommons { } } + /** + * @notice Executes a flashloan from current pool. + * @dev === Reverts on === + * @dev - `FlashloanCallbackFailed()` if receiver is not an `ERC3156FlashBorrower` + * @dev - `FlashloanIncorrectBalance()` if pool balance after flashloan is different than initial balance + * @param receiver_ Address of the contract which implements the appropriate interface to receive tokens. + * @param token_ Address of the `ERC20` token caller wants to borrow. + * @param amount_ The denormalized amount (dependent upon token precision) of tokens to borrow. + * @param data_ User-defined calldata passed to the receiver. + */ + function flashLoan( + IERC3156FlashBorrower receiver_, + address token_, + uint256 amount_, + bytes calldata data_ + ) external { + IERC20 tokenContract = IERC20(token_); + + uint256 initialBalance = tokenContract.balanceOf(address(this)); + + tokenContract.safeTransfer( + address(receiver_), + amount_ + ); + + if (receiver_.onFlashLoan(msg.sender, token_, amount_, 0, data_) != + keccak256("ERC3156FlashBorrower.onFlashLoan")) revert FlashloanCallbackFailed(); + + tokenContract.safeTransferFrom( + address(receiver_), + address(this), + amount_ + ); + + if (tokenContract.balanceOf(address(this)) != initialBalance) revert FlashloanIncorrectBalance(); + + emit Flashloan(address(receiver_), token_, amount_); + } + /**************************/ /*** Internal Functions ***/ /**************************/ @@ -377,6 +445,35 @@ 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, + pendingInflator(inflator, inflatorState_.inflatorUpdate, interestState_.interestRate) + ), + 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. @@ -401,7 +498,7 @@ library PoolCommons { uint256 inflator_, uint256 inflatorUpdate, uint256 interestRate_ - ) external view returns (uint256) { + ) public view returns (uint256) { return Maths.wmul( inflator_, PRBMathUD60x18.exp((interestRate_ * (block.timestamp - inflatorUpdate)) / 365 days) diff --git a/src/libraries/external/PositionNFTSVG.sol b/src/libraries/external/PositionNFTSVG.sol index f9598ce14..b972f95ec 100644 --- a/src/libraries/external/PositionNFTSVG.sol +++ b/src/libraries/external/PositionNFTSVG.sol @@ -21,9 +21,7 @@ library PositionNFTSVG { string collateralTokenSymbol; // the symbol of collateral token of the pool string quoteTokenSymbol; // the symbol of quote token of the pool uint256 tokenId; // the ID of positions NFT token - address pool; // the address of pool tracked in positions NFT token address owner; // the owner of positions NFT token - uint256[] indexes; // the array of price buckets index with LP to be tracked by the NFT } /*******************************/ diff --git a/src/libraries/external/SettlerActions.sol b/src/libraries/external/SettlerActions.sol index 6f065d85f..1458c08d7 100644 --- a/src/libraries/external/SettlerActions.sol +++ b/src/libraries/external/SettlerActions.sol @@ -132,17 +132,33 @@ library SettlerActions { if (borrower.t0Debt != 0 && borrower.collateral == 0) { // 2. settle debt with pool reserves - uint256 assets = Maths.floorWmul(poolState_.t0Debt - result_.t0DebtSettled + borrower.t0Debt, poolState_.inflator) + params_.poolBalance; + uint256 assets = Maths.floorWmul(poolState_.t0Debt - result_.t0DebtSettled + borrower.t0Debt, poolState_.inflator) + params_.poolBalance; + uint256 deposits = Deposits.treeSum(deposits_); uint256 liabilities = // require 1.0 + 1e-9 deposit buffer (extra margin) for deposits - Maths.wmul(DEPOSIT_BUFFER, Deposits.treeSum(deposits_)) + + Maths.wmul(DEPOSIT_BUFFER, deposits) + auctions_.totalBondEscrowed + reserveAuction_.unclaimed; // settle debt from reserves (assets - liabilities) if reserves positive, round reserves down however + // capped at half of the origination fee rate, based on current book fees if (assets > liabilities) { - borrower.t0Debt -= Maths.min(borrower.t0Debt, Maths.floorWdiv(assets - liabilities, poolState_.inflator)); + uint256 t0ReserveSettleAmount = Maths.min(Maths.floorWdiv(assets - liabilities, poolState_.inflator), borrower.t0Debt); + + // if the settlement phase of 144 hours has not ended, settle up to the borrower reserve limit + if (deposits > 0 && block.timestamp - kickTime < 144 hours) { + // retrieve amount of debt that can be settled with reserves + uint256 reserveSettleLimit = auctions_.liquidations[params_.borrower].t0ReserveSettleAmount; + + // calculate reserve amount to be used when settling the auction + t0ReserveSettleAmount = Maths.min(t0ReserveSettleAmount, reserveSettleLimit); + reserveSettleLimit -= t0ReserveSettleAmount; + + // store remaining amount limit to settle + auctions_.liquidations[params_.borrower].t0ReserveSettleAmount = reserveSettleLimit; + } + borrower.t0Debt -= t0ReserveSettleAmount; } // 3. forgive bad debt from next HPB @@ -159,11 +175,9 @@ library SettlerActions { // complete result struct with debt settled result_.t0DebtSettled -= borrower.t0Debt; + result_.debtSettled = Maths.wmul(result_.t0DebtSettled, poolState_.inflator); - emit Settle( - params_.borrower, - result_.t0DebtSettled - ); + emit Settle(params_.borrower, result_.debtSettled); // if entire debt was settled then settle auction if (borrower.t0Debt == 0) { @@ -292,12 +306,12 @@ library SettlerActions { auctions_.head = address(0); auctions_.tail = address(0); } - else if(auctions_.head == borrower_) { + else if (auctions_.head == borrower_) { // liquidation is the head auctions_.liquidations[liquidation.next].prev = address(0); auctions_.head = liquidation.next; } - else if(auctions_.tail == borrower_) { + else if (auctions_.tail == borrower_) { // liquidation is the tail auctions_.liquidations[liquidation.prev].next = address(0); auctions_.tail = liquidation.prev; @@ -391,7 +405,8 @@ library SettlerActions { vars.hpbUnscaledDeposit -= vars.unscaledDeposit; // remove amount to settle debt from bucket (could be entire deposit or only the settled debt) - Deposits.unscaledRemove(deposits_, vars.index, vars.unscaledDeposit); + // when unscaledDeposit == 0 the amount of debt is very small and worth forgiving versus having settle revert + if (vars.unscaledDeposit != 0) Deposits.unscaledRemove(deposits_, vars.index, vars.unscaledDeposit); // check if bucket healthy - set bankruptcy if collateral is 0 and entire deposit was used to settle and there's still LP if (vars.hpbCollateral == 0 && vars.hpbUnscaledDeposit == 0 && vars.hpbLP != 0) { @@ -462,11 +477,12 @@ library SettlerActions { // no remaining debt to forgive remainingt0Debt_ = 0; - uint256 depositUsed = Maths.wdiv(debt, scale); - depositRemaining = unscaledDeposit - depositUsed; + uint256 depositUsed = Maths.min(Maths.wdiv(debt, scale), unscaledDeposit); + depositRemaining = unscaledDeposit - depositUsed; // Remove deposit used to forgive bad debt from bucket - Deposits.unscaledRemove(deposits_, index, depositUsed); + // when depositUsed == 0 the amount of debt is very small and worth forgiving versus having settle revert + if (depositUsed != 0) Deposits.unscaledRemove(deposits_, index, depositUsed); // 2) loan debt to settle exceeds bucket deposit, bucket deposit is the constraint } else { @@ -474,15 +490,17 @@ library SettlerActions { remainingt0Debt_ -= Maths.floorWdiv(depositToRemove, inflator_); // Remove all deposit from bucket - Deposits.unscaledRemove(deposits_, index, unscaledDeposit); + // when unscaledDeposit == 0 the amount of debt is very small and worth forgiving versus having settle revert + if (unscaledDeposit != 0) Deposits.unscaledRemove(deposits_, index, unscaledDeposit); } Bucket storage hpbBucket = buckets_[index]; uint256 bucketLP = hpbBucket.lps; + // If the remaining deposit and resulting bucket collateral is so small that the exchange rate // rounds to 0, then bankrupt the bucket. Note that lhs are WADs, so the // quantity is naturally 1e18 times larger than the actual product - if (depositRemaining * Maths.WAD + hpbBucket.collateral * _priceAt(index) <= bucketLP) { + if (depositRemaining * scale + hpbBucket.collateral * _priceAt(index) <= bucketLP) { // existing LP for the bucket shall become unclaimable hpbBucket.lps = 0; hpbBucket.bankruptcyTime = block.timestamp; diff --git a/src/libraries/external/TakerActions.sol b/src/libraries/external/TakerActions.sol index 04624aafa..3be037bab 100644 --- a/src/libraries/external/TakerActions.sol +++ b/src/libraries/external/TakerActions.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.18; import { PRBMathSD59x18 } from "@prb-math/contracts/PRBMathSD59x18.sol"; import { Math } from '@openzeppelin/contracts/utils/math/Math.sol'; +import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { PoolType } from '../../interfaces/pool/IPool.sol'; @@ -83,7 +84,6 @@ library TakerActions { uint256 bucketScale; // [WAD] The bucket scale. uint256 collateralAmount; // [WAD] The amount of collateral taken. uint256 excessQuoteToken; // [WAD] Difference of quote token that borrower receives after take (for fractional NFT only) - uint256 factor; // The take factor, calculated based on bond penalty factor. bool isRewarded; // True if kicker is rewarded (auction price lower than neutral price), false if penalized (auction price greater than neutral price). address kicker; // Address of auction kicker. uint256 quoteTokenAmount; // [WAD] Scaled quantity in Fenwick tree and before 1-bpf factor, paid for collateral @@ -117,9 +117,7 @@ library TakerActions { error InsufficientCollateral(); error InvalidAmount(); error NoAuction(); - error NoReserves(); error NoReservesAuction(); - error ReserveAuctionTooSoon(); /***************************/ /*** External Functions ***/ @@ -167,10 +165,10 @@ library TakerActions { // update borrower after take borrower.collateral -= vars.collateralAmount; - borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; + borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; // update pool params after take poolState_.t0Debt -= vars.t0RepayAmount; - poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); + poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); // update loan after take ( @@ -239,10 +237,10 @@ library TakerActions { // update borrower after take borrower.collateral -= vars.collateralAmount; - borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; + borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; // update pool params after take poolState_.t0Debt -= vars.t0RepayAmount; - poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); + poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); // update loan after take ( @@ -273,25 +271,29 @@ library TakerActions { * @dev === Write state === * @dev decrement `reserveAuction.unclaimed` accumulator * @dev === Reverts on === - * @dev not kicked or `72` hours didn't pass `NoReservesAuction()` + * @dev not kicked or `72` hours passed `NoReservesAuction()` + * @dev 0 take amount or 0 AJNA burned `InvalidAmount()` * @dev === Emit events === * @dev - `ReserveAuction` */ function takeReserves( ReserveAuctionState storage reserveAuction_, - uint256 maxAmount_ + uint256 maxAmount_, + uint256 quoteScale_ ) external returns (uint256 amount_, uint256 ajnaRequired_) { - // revert if no amount to be taken - if (maxAmount_ == 0) revert InvalidAmount(); - uint256 kicked = reserveAuction_.kicked; if (kicked != 0 && block.timestamp - kicked <= 72 hours) { uint256 unclaimed = reserveAuction_.unclaimed; - uint256 price = _reserveAuctionPrice(kicked); + uint256 price = _reserveAuctionPrice(kicked, reserveAuction_.lastKickedReserves); amount_ = Maths.min(unclaimed, maxAmount_); + // revert if no amount to be taken + if (amount_ / quoteScale_ == 0) revert InvalidAmount(); + ajnaRequired_ = Maths.ceilWmul(amount_, price); + // prevent 0-bid; must burn at least 1 wei of AJNA + if (ajnaRequired_ == 0) revert InvalidAmount(); unclaimed -= amount_; @@ -339,13 +341,10 @@ library TakerActions { ) internal returns (TakeLocalVars memory vars_) { Liquidation storage liquidation = auctions_.liquidations[params_.borrower]; - // Auction may not be taken in the same block it was kicked - if (liquidation.kickTime == block.timestamp) revert AuctionNotTakeable(); - vars_ = _prepareTake( liquidation, + 0, borrower_.t0Debt, - borrower_.collateral, params_.inflator ); @@ -372,14 +371,6 @@ library TakerActions { _rewardTake(auctions_, liquidation, vars_); - emit Take( - params_.borrower, - vars_.quoteTokenAmount, - vars_.collateralAmount, - vars_.bondChange, - vars_.isRewarded - ); - if (params_.poolType == uint8(PoolType.ERC721)) { // slither-disable-next-line divide-before-multiply uint256 collateralTaken = (vars_.collateralAmount / 1e18) * 1e18; // solidity rounds down, so if 2.5 it will be 2.5 / 1 = 2 @@ -400,6 +391,14 @@ library TakerActions { } } } + + emit Take( + params_.borrower, + vars_.quoteTokenAmount, + vars_.collateralAmount, + vars_.bondChange, + vars_.isRewarded + ); } /** @@ -422,13 +421,10 @@ library TakerActions { ) internal returns (TakeLocalVars memory vars_) { Liquidation storage liquidation = auctions_.liquidations[params_.borrower]; - // Auction may not be taken in the same block it was kicked - if (liquidation.kickTime == block.timestamp) revert AuctionNotTakeable(); - vars_= _prepareTake( liquidation, + _priceAt(params_.index), borrower_.t0Debt, - borrower_.collateral, params_.inflator ); @@ -437,8 +433,6 @@ library TakerActions { // revert if no quote tokens in arbed bucket if (vars_.unscaledDeposit == 0) revert InsufficientLiquidity(); - vars_.bucketPrice = _priceAt(params_.index); - // cannot arb with a price lower than the auction price if (vars_.auctionPrice > vars_.bucketPrice) revert AuctionPriceGtBucketPrice(); @@ -569,14 +563,14 @@ library TakerActions { ) internal { if (vars.isRewarded) { // take is below neutralPrice, Kicker is rewarded - liquidation_.bondSize += uint160(vars.bondChange); + liquidation_.bondSize += SafeCast.toUint160(vars.bondChange); auctions_.kickers[vars.kicker].locked += vars.bondChange; auctions_.totalBondEscrowed += vars.bondChange; } else { // take is above neutralPrice, Kicker is penalized vars.bondChange = Maths.min(liquidation_.bondSize, vars.bondChange); - liquidation_.bondSize -= uint160(vars.bondChange); + liquidation_.bondSize -= SafeCast.toUint160(vars.bondChange); auctions_.kickers[vars.kicker].locked -= vars.bondChange; auctions_.totalBondEscrowed -= vars.bondChange; } @@ -596,6 +590,8 @@ library TakerActions { * @dev - increment `bucket.collateral` and `bucket.lps` accumulator * @dev === Emit events === * @dev - `BucketTakeLPAwarded` + * @dev === Reverts on === + * @dev calculated unscaled amount to remove is 0 `InvalidAmount()` * @param auctions_ Struct for pool auctions state. * @param deposits_ Struct for pool deposits state. * @param buckets_ Struct for pool buckets state. @@ -653,7 +649,7 @@ library TakerActions { // take is above neutralPrice, Kicker is penalized vars.bondChange = Maths.min(liquidation_.bondSize, vars.bondChange); - liquidation_.bondSize -= uint160(vars.bondChange); + liquidation_.bondSize -= SafeCast.toUint160(vars.bondChange); auctions_.kickers[vars.kicker].locked -= vars.bondChange; auctions_.totalBondEscrowed -= vars.bondChange; @@ -680,20 +676,22 @@ library TakerActions { * @dev reverts on: * - loan is not in auction NoAuction() * @param liquidation_ Liquidation struct holding auction details. + * @param bucketPrice_ Price of the bucket, or 0 for non-bucket takes. * @param t0Debt_ Borrower t0 debt. - * @param collateral_ Borrower collateral. * @param inflator_ The pool's inflator, used to calculate borrower debt. * @return vars The prepared vars for take action. */ function _prepareTake( Liquidation memory liquidation_, + uint256 bucketPrice_, uint256 t0Debt_, - uint256 collateral_, uint256 inflator_ ) internal view returns (TakeLocalVars memory vars) { uint256 kickTime = liquidation_.kickTime; if (kickTime == 0) revert NoAuction(); + // Auction may not be taken in the same block it was kicked + if (kickTime == block.timestamp) revert AuctionNotTakeable(); vars.t0BorrowerDebt = t0Debt_; @@ -702,15 +700,14 @@ library TakerActions { uint256 neutralPrice = liquidation_.neutralPrice; vars.auctionPrice = _auctionPrice(liquidation_.referencePrice, kickTime); + vars.bucketPrice = bucketPrice_; vars.bondFactor = liquidation_.bondFactor; vars.bpf = _bpf( - vars.borrowerDebt, - collateral_, + liquidation_.debtToCollateral, neutralPrice, liquidation_.bondFactor, - vars.auctionPrice + bucketPrice_ == 0 ? vars.auctionPrice : bucketPrice_ ); - vars.factor = uint256(1e18 - Maths.maxInt(0, vars.bpf)); vars.kicker = liquidation_.kicker; vars.isRewarded = (vars.bpf >= 0); } @@ -764,7 +761,7 @@ library TakerActions { vars.t0RepayAmount = vars.t0BorrowerDebt; vars.unscaledQuoteTokenAmount = Math.mulDiv(vars.collateralAmount, netRewardedPrice, vars.bucketScale); - vars.quoteTokenAmount = Maths.wdiv(vars.borrowerDebt, Maths.WAD - takePenaltyFactor); + vars.quoteTokenAmount = Math.mulDiv(vars.collateralAmount, borrowerPrice, Maths.WAD - takePenaltyFactor); } else { // collateral available is constraint vars.collateralAmount = totalCollateral_; @@ -774,12 +771,15 @@ library TakerActions { vars.quoteTokenAmount = Maths.wmul(vars.collateralAmount, vars.auctionPrice); } + // repaid amount cannot exceed the borrower owned debt + vars.t0RepayAmount = Maths.min(vars.t0RepayAmount, vars.t0BorrowerDebt); + if (vars.isRewarded) { // take is below neutralPrice, Kicker is rewarded - vars.bondChange = Maths.wmul(vars.quoteTokenAmount, uint256(vars.bpf)); + vars.bondChange = Maths.floorWmul(vars.quoteTokenAmount, uint256(vars.bpf)); } else { // take is above neutralPrice, Kicker is penalized - vars.bondChange = Maths.wmul(vars.quoteTokenAmount, uint256(-vars.bpf)); + vars.bondChange = Maths.ceilWmul(vars.quoteTokenAmount, uint256(-vars.bpf)); } return vars; diff --git a/src/libraries/helpers/PoolHelper.sol b/src/libraries/helpers/PoolHelper.sol index 621001e82..6076d50ae 100644 --- a/src/libraries/helpers/PoolHelper.sol +++ b/src/libraries/helpers/PoolHelper.sol @@ -4,8 +4,10 @@ pragma solidity 0.8.18; import { PRBMathSD59x18 } from "@prb-math/contracts/PRBMathSD59x18.sol"; import { Math } from '@openzeppelin/contracts/utils/math/Math.sol'; +import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; -import { PoolType } from '../../interfaces/pool/IPool.sol'; +import { PoolType } from '../../interfaces/pool/IPool.sol'; +import { InflatorState, PoolState } from '../../interfaces/pool/commons/IPoolState.sol'; import { Buckets } from '../internal/Buckets.sol'; import { Maths } from '../internal/Maths.sol'; @@ -33,6 +35,9 @@ import { Maths } from '../internal/Maths.sol'; /// @dev step amounts in basis points. This is a constant across pools at `0.005`, achieved by dividing `WAD` by `10,000` int256 constant FLOAT_STEP_INT = 1.005 * 1e18; + /// @dev collateralization factor used to calculate borrrower HTP/TP/collateralization. + uint256 constant COLLATERALIZATION_FACTOR = 1.04 * 1e18; + /** * @notice Calculates the price (`WAD` precision) for a given `Fenwick` index. * @dev Reverts with `BucketIndexOutOfBounds` if index exceeds maximum constant. @@ -124,13 +129,57 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Calculates the unutilized deposit fee, charged to lenders who deposit below the `LUP`. * @param interestRate_ The current interest rate. - * @return Fee rate based upon the given interest rate, capped at 10%. + * @return Fee rate based upon the given interest rate */ function _depositFeeRate( uint256 interestRate_ ) pure returns (uint256) { - // current annualized rate divided by 365 (24 hours of interest), capped at 10% - return Maths.min(Maths.wdiv(interestRate_, 365 * 1e18), 0.1 * 1e18); + // current annualized rate divided by 365 * 3 (8 hours of interest) + return Maths.wdiv(interestRate_, 365 * 3e18); + } + + /** + * @notice Determines how the inflator state should be updated + * @param poolState_ State of the pool after updateInterestState was called. + * @param inflatorState_ Old inflator state. + * @return newInflator_ New inflator value. + * @return updateTimestamp_ `True` if timestamp of last update should be updated. + */ + function _determineInflatorState( + PoolState memory poolState_, + InflatorState memory inflatorState_ + ) view returns (uint208 newInflator_, bool updateTimestamp_) { + newInflator_ = inflatorState_.inflator; + + // update pool inflator + if (poolState_.isNewInterestAccrued) { + newInflator_ = SafeCast.toUint208(poolState_.inflator); + updateTimestamp_ = true; + // if the debt in the current pool state is 0, also update the inflator and inflatorUpdate fields in inflatorState + // slither-disable-next-line incorrect-equality + } else if (poolState_.debt == 0) { + newInflator_ = SafeCast.toUint208(Maths.WAD); + updateTimestamp_ = true; + // if the first loan has just been drawn, update the inflator timestamp + // slither-disable-next-line incorrect-equality + } else if (inflatorState_.inflator == Maths.WAD && inflatorState_.inflatorUpdate != block.timestamp){ + updateTimestamp_ = true; + } + } + + /** + * @notice Calculates `HTP` price. + * @param maxT0DebtToCollateral_ Max t0 debt to collateral in pool. + * @param inflator_ Pool's inflator. + */ + function _htp( + uint256 maxT0DebtToCollateral_, + uint256 inflator_ + ) pure returns (uint256) { + return Maths.wmul( + Maths.wmul(maxT0DebtToCollateral_, inflator_), + COLLATERALIZATION_FACTOR + ); } /** @@ -144,7 +193,13 @@ import { Maths } from '../internal/Maths.sol'; uint256 inflator_, uint256 t0Debt2ToCollateral_ ) pure returns (uint256) { - return t0Debt_ == 0 ? 0 : Maths.wdiv(Maths.wmul(inflator_, t0Debt2ToCollateral_), t0Debt_); + return t0Debt_ == 0 ? 0 : Maths.wdiv( + Maths.wmul( + Maths.wmul(inflator_, t0Debt2ToCollateral_), + COLLATERALIZATION_FACTOR + ), + t0Debt_ + ); } /** @@ -153,7 +208,7 @@ import { Maths } from '../internal/Maths.sol'; * @param collateral_ Collateral to calculate collateralization for. * @param price_ Price to calculate collateralization for. * @param type_ Type of the pool. - * @return `True` if collateralization calculated is equal or greater than `1`. + * @return `True` if value of collateral exceeds or equals debt. */ function _isCollateralized( uint256 debt_, @@ -161,12 +216,16 @@ import { Maths } from '../internal/Maths.sol'; uint256 price_, uint8 type_ ) pure returns (bool) { - if (type_ == uint8(PoolType.ERC20)) return Maths.wmul(collateral_, price_) >= debt_; - else { + // `False` if LUP = MIN_PRICE unless there is no debt + if (price_ == MIN_PRICE && debt_ != 0) return false; + + // Use collateral floor for NFT pools + if (type_ == uint8(PoolType.ERC721)) { //slither-disable-next-line divide-before-multiply collateral_ = (collateral_ / Maths.WAD) * Maths.WAD; // use collateral floor - return Maths.wmul(collateral_, price_) >= debt_; } + + return Maths.wmul(collateral_, price_) >= Maths.wmul(COLLATERALIZATION_FACTOR, debt_); } /** @@ -226,7 +285,6 @@ import { Maths } from '../internal/Maths.sol'; * @param bucketCollateral_ Amount of collateral in bucket. * @param deposit_ Current bucket deposit (quote tokens). Used to calculate bucket's exchange rate / `LP`. * @param lenderLPBalance_ The amount of `LP` to calculate quote token amount for. - * @param maxQuoteToken_ The max quote token amount to calculate `LP` for. * @param bucketPrice_ Bucket's price. * @return quoteTokenAmount_ Amount of quote tokens calculated for the given `LP` amount, capped at available bucket deposit. */ @@ -235,7 +293,6 @@ import { Maths } from '../internal/Maths.sol'; uint256 bucketCollateral_, uint256 deposit_, uint256 lenderLPBalance_, - uint256 maxQuoteToken_, uint256 bucketPrice_ ) pure returns (uint256 quoteTokenAmount_) { quoteTokenAmount_ = Buckets.lpToQuoteTokens( @@ -247,8 +304,7 @@ import { Maths } from '../internal/Maths.sol'; Math.Rounding.Down ); - if (quoteTokenAmount_ > deposit_) quoteTokenAmount_ = deposit_; - if (quoteTokenAmount_ > maxQuoteToken_) quoteTokenAmount_ = maxQuoteToken_; + if (quoteTokenAmount_ > deposit_) quoteTokenAmount_ = deposit_; } /** @@ -307,7 +363,7 @@ import { Maths } from '../internal/Maths.sol'; // calculate claimable reserves if there's quote token excess if (quoteTokenBalance_ > guaranteedFunds) { - claimable_ = Maths.wmul(0.995 * 1e18, debt_) + quoteTokenBalance_; + claimable_ = debt_ + quoteTokenBalance_; claimable_ -= Maths.min( claimable_, @@ -326,17 +382,20 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Calculates reserves auction price. * @param reserveAuctionKicked_ Time when reserve auction was started (kicked). + * @param lastKickedReserves_ Reserves to be auctioned when started (kicked). * @return price_ Calculated auction price. */ function _reserveAuctionPrice( - uint256 reserveAuctionKicked_ + uint256 reserveAuctionKicked_, + uint256 lastKickedReserves_ ) view returns (uint256 price_) { if (reserveAuctionKicked_ != 0) { uint256 secondsElapsed = block.timestamp - reserveAuctionKicked_; uint256 hoursComponent = 1e27 >> secondsElapsed / 3600; uint256 minutesComponent = Maths.rpow(MINUTE_HALF_LIFE, secondsElapsed % 3600 / 60); + uint256 initialPrice = lastKickedReserves_ == 0 ? 0 : Maths.wdiv(1_000_000_000 * 1e18, lastKickedReserves_); - price_ = Maths.rayToWad(1_000_000_000 * Maths.rmul(hoursComponent, minutesComponent)); + price_ = initialPrice * Maths.rmul(hoursComponent, minutesComponent) / 1e27; } } @@ -344,6 +403,11 @@ import { Maths } from '../internal/Maths.sol'; /*** Auction Utilities ***/ /*************************/ + /// @dev min bond factor. + uint256 constant MIN_BOND_FACTOR = 0.005 * 1e18; + /// @dev max bond factor. + uint256 constant MAX_BOND_FACTOR = 0.03 * 1e18; + /** * @notice Calculates auction price. * @param referencePrice_ Recorded at kick, used to calculate start price. @@ -372,32 +436,28 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Calculates bond penalty factor. * @dev Called in kick and take. - * @param debt_ Borrower debt. - * @param collateral_ Borrower collateral. - * @param neutralPrice_ `NP` of auction. - * @param bondFactor_ Factor used to determine bondSize. - * @param auctionPrice_ Auction price at the time of call. - * @return bpf_ Factor used in determining bond `reward` (positive) or `penalty` (negative). + * @param debtToCollateral_ Borrower debt to collateral at time of kick. + * @param neutralPrice_ `NP` of auction. + * @param bondFactor_ Factor used to determine bondSize. + * @param auctionPrice_ Auction price at the time of call or, for bucket takes, bucket price. + * @return bpf_ Factor used in determining bond `reward` (positive) or `penalty` (negative). */ function _bpf( - uint256 debt_, - uint256 collateral_, + uint256 debtToCollateral_, uint256 neutralPrice_, uint256 bondFactor_, uint256 auctionPrice_ ) pure returns (int256) { - int256 thresholdPrice = int256(Maths.wdiv(debt_, collateral_)); - int256 sign; - if (thresholdPrice < int256(neutralPrice_)) { - // BPF = BondFactor * min(1, max(-1, (neutralPrice - price) / (neutralPrice - thresholdPrice))) + if (debtToCollateral_ < neutralPrice_) { + // BPF = BondFactor * min(1, max(-1, (neutralPrice - price) / (neutralPrice - debtToCollateral))) sign = Maths.minInt( 1e18, Maths.maxInt( -1 * 1e18, PRBMathSD59x18.div( int256(neutralPrice_) - int256(auctionPrice_), - int256(neutralPrice_) - thresholdPrice + int256(neutralPrice_) - int256(debtToCollateral_) ) ) ); @@ -419,10 +479,13 @@ import { Maths } from '../internal/Maths.sol'; uint256 borrowerDebt_, uint256 npTpRatio_ ) pure returns (uint256 bondFactor_, uint256 bondSize_) { - // bondFactor = min((NP-to-TP-ratio - 1)/10, 0.03) - bondFactor_ = Maths.min( - 0.03 * 1e18, - (npTpRatio_ - 1e18) / 10 + // bondFactor = max(min(MAX_BOND_FACTOR, (NP/TP_ratio - 1) / 10), MIN_BOND_FACTOR) + bondFactor_ = Maths.max( + Maths.min( + MAX_BOND_FACTOR, + (npTpRatio_ - 1e18) / 10 + ), + MIN_BOND_FACTOR ); bondSize_ = Maths.wmul(bondFactor_, borrowerDebt_); diff --git a/src/libraries/helpers/RevertsHelper.sol b/src/libraries/helpers/RevertsHelper.sol index 499e870c9..e5e45e5a6 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'; @@ -18,11 +18,13 @@ import { Maths } from '../internal/Maths.sol'; // See `IPoolErrors` for descriptions error AuctionNotCleared(); + error AuctionActive(); error AmountLTMinDebt(); error DustAmountNotExceeded(); error LimitIndexExceeded(); error RemoveDepositLockedByAuctionDebt(); error TransactionExpired(); + error AddAboveAuctionPrice(); /** * @notice Called by `LP` removal functions assess whether or not `LP` is locked. @@ -75,6 +77,36 @@ 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 deposits and arbTakes. + * @dev Reverts with `AddAboveAuctionPrice` if price is above head of auction queue. + * @param auctions_ Auctions data. + * @param index_ Identifies bucket price to be compared with current auction price. + */ + function _revertIfAuctionPriceBelow( + AuctionsState storage auctions_, + uint256 index_ + ) view { + address head = auctions_.head; + if (head != address(0)) { + uint256 auctionPrice = _auctionPrice(auctions_.liquidations[head].referencePrice, auctions_.liquidations[head].kickTime); + if (_priceAt(index_) >= auctionPrice) revert AddAboveAuctionPrice(); + } + } + + /** + * @notice Check if there are still active / non settled auctions in pool. + * @notice Prevents kicking reserves auctions until all pending auctions are fully settled. + * @dev Reverts with `AuctionActive`. + * @param auctions_ Auctions data. + */ + function _revertIfActiveAuctions( + AuctionsState storage auctions_ + ) view { + if (auctions_.noOfAuctions != 0) revert AuctionActive(); + } + /** * @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. diff --git a/src/libraries/internal/Deposits.sol b/src/libraries/internal/Deposits.sol index 428997f05..6b2f0bedb 100644 --- a/src/libraries/internal/Deposits.sol +++ b/src/libraries/internal/Deposits.sol @@ -20,9 +20,18 @@ library Deposits { /// @dev Max index supported in the `Fenwick` tree uint256 internal constant SIZE = 8192; + /**************/ + /*** Errors ***/ + /**************/ + + // See `IPoolErrors` for descriptions + error InvalidAmount(); + /** * @notice Increase a value in the FenwickTree at an index. * @dev Starts at leaf/target and moved up towards root + * @dev === Reverts on === + * @dev unscaled amount to add is 0 `InvalidAmount()` * @param deposits_ Deposits state struct. * @param index_ The deposit index. * @param unscaledAddAmount_ The unscaled amount to increase deposit by. @@ -32,6 +41,10 @@ library Deposits { uint256 index_, uint256 unscaledAddAmount_ ) internal { + + // revert if 0 amount is added. + if (unscaledAddAmount_ == 0) revert InvalidAmount(); + // price buckets are indexed starting at 0, Fenwick bit logic is more elegant starting at 1 ++index_; @@ -289,6 +302,8 @@ library Deposits { /** * @notice Decrease a node in the `FenwickTree` at an index. * @dev Starts at leaf/target and moved up towards root. + * @dev === Reverts on === + * @dev unscaled amount to remove is 0 `InvalidAmount()` * @param deposits_ Deposits state struct. * @param index_ The deposit index. * @param unscaledRemoveAmount_ Unscaled amount to decrease deposit by. @@ -298,6 +313,10 @@ library Deposits { uint256 index_, uint256 unscaledRemoveAmount_ ) internal { + + // revert if 0 amount is removed. + if (unscaledRemoveAmount_ == 0) revert InvalidAmount(); + // price buckets are indexed starting at 0, Fenwick bit logic is more elegant starting at 1 ++index_; diff --git a/src/libraries/internal/Loans.sol b/src/libraries/internal/Loans.sol index 764b9ef20..8fac0872c 100644 --- a/src/libraries/internal/Loans.sol +++ b/src/libraries/internal/Loans.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.18; +import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { PRBMathSD59x18 } from "@prb-math/contracts/PRBMathSD59x18.sol"; import { @@ -20,10 +21,10 @@ import { Maths } from './Maths.sol'; /** @title Loans library @notice Internal library containing common logic for loans management. - @dev The `Loans` heap is a `Max Heap` data structure (complete binary tree), the root node is the loan with the highest threshold price (`TP`) + @dev The `Loans` heap is a `Max Heap` data structure (complete binary tree), the root node is the loan with the highest t0 threshold price (`TP`) at a given time. The heap is represented as an array, where the first element is a dummy element (`Loan(address(0), 0)`) and the first - value of the heap starts at index `1`, `ROOT_INDEX`. The threshold price of a loan's parent is always greater than or equal to the - threshold price of the loan. + value of the heap starts at index `1`, `ROOT_INDEX`. The t0 threshold price of a loan's parent is always greater than or equal to the + t0 threshold price of the loan. @dev This code was modified from the following source: https://github.com/zmitton/eth-heap/blob/master/contracts/Heap.sol */ library Loans { @@ -35,7 +36,7 @@ library Loans { /**************/ // See `IPoolErrors` for descriptions - error ZeroThresholdPrice(); + error ZeroDebtToCollateral(); /***********************/ /*** Initialization ***/ @@ -43,7 +44,7 @@ library Loans { /** * @notice Initializes Loans Max Heap. - * @dev Organizes loans so `Highest Threshold Price` can be retrieved easily. + * @dev Organizes loans so `Highest t0 threshold price` can be retrieved easily. * @param loans_ Holds Loan heap data. */ function init(LoansState storage loans_) internal { @@ -80,18 +81,18 @@ library Loans { bool activeBorrower = borrower_.t0Debt != 0 && borrower_.collateral != 0; - uint256 t0ThresholdPrice = activeBorrower ? Maths.wdiv(borrower_.t0Debt, borrower_.collateral) : 0; + uint256 t0DebtToCollateral = activeBorrower ? Maths.wdiv(borrower_.t0Debt, borrower_.collateral) : 0; - // loan not in auction, update threshold price and position in heap + // loan not in auction, update t0 threshold price and position in heap if (!inAuction_ ) { // get the loan id inside the heap uint256 loanId = loans_.indices[borrowerAddress_]; if (activeBorrower) { - // revert if threshold price is zero - if (t0ThresholdPrice == 0) revert ZeroThresholdPrice(); + // revert if t0 threshold price is zero + if (t0DebtToCollateral == 0) revert ZeroDebtToCollateral(); // update heap, insert if a new loan, update loan if already in heap - _upsert(loans_, borrowerAddress_, loanId, uint96(t0ThresholdPrice)); + _upsert(loans_, borrowerAddress_, loanId, SafeCast.toUint96(t0DebtToCollateral)); // if loan is in heap and borrwer is no longer active (no debt, no collateral) then remove loan from heap } else if (loanId != 0) { @@ -101,7 +102,7 @@ library Loans { // update Np to Tp ratio of borrower if (npTpRatioUpdate_) { - borrower_.npTpRatio = 1.04 * 1e18 + uint256(PRBMathSD59x18.sqrt(int256(poolRate_))) / 2; + borrower_.npTpRatio = 1e18 + uint256(PRBMathSD59x18.sqrt(int256(poolRate_))) / 2; } // save borrower state @@ -120,7 +121,7 @@ library Loans { */ function _bubbleUp(LoansState storage loans_, Loan memory loan_, uint index_) private { uint256 count = loans_.loans.length; - if (index_ == ROOT_INDEX || loan_.thresholdPrice <= loans_.loans[index_ / 2].thresholdPrice){ + if (index_ == ROOT_INDEX || loan_.t0DebtToCollateral <= loans_.loans[index_ / 2].t0DebtToCollateral){ _insert(loans_, loan_, index_, count); } else { _insert(loans_, loans_.loans[index_ / 2], index_, count); @@ -144,11 +145,11 @@ library Loans { } else { Loan memory largestChild = loans_.loans[cIndex]; - if (count > cIndex + 1 && loans_.loans[cIndex + 1].thresholdPrice > largestChild.thresholdPrice) { + if (count > cIndex + 1 && loans_.loans[cIndex + 1].t0DebtToCollateral > largestChild.t0DebtToCollateral) { largestChild = loans_.loans[++cIndex]; } - if (largestChild.thresholdPrice <= loan_.thresholdPrice) { + if (largestChild.t0DebtToCollateral <= loan_.t0DebtToCollateral) { _insert(loans_, loan_, index_, count); } else { _insert(loans_, largestChild, index_, count); @@ -190,31 +191,31 @@ library Loans { /** * @notice Performs an insert or an update dependent on borrowers existance. - * @param loans_ Holds loans heap data. - * @param borrower_ Borrower address that is being updated or inserted. - * @param index_ Index of `Loan` to be upserted. - * @param thresholdPrice_ `Threshold Price` that is updated or inserted. + * @param loans_ Holds loans heap data. + * @param borrower_ Borrower address that is being updated or inserted. + * @param index_ Index of `Loan` to be upserted. + * @param t0DebtToCollateral_ Borrower t0 debt to collateral that is updated or inserted. */ function _upsert( LoansState storage loans_, address borrower_, uint256 index_, - uint96 thresholdPrice_ + uint96 t0DebtToCollateral_ ) internal { // Loan exists, update in place. if (index_ != 0) { Loan memory currentLoan = loans_.loans[index_]; - if (currentLoan.thresholdPrice > thresholdPrice_) { - currentLoan.thresholdPrice = thresholdPrice_; + if (currentLoan.t0DebtToCollateral > t0DebtToCollateral_) { + currentLoan.t0DebtToCollateral = t0DebtToCollateral_; _bubbleDown(loans_, currentLoan, index_); } else { - currentLoan.thresholdPrice = thresholdPrice_; + currentLoan.t0DebtToCollateral = t0DebtToCollateral_; _bubbleUp(loans_, currentLoan, index_); } // New loan, insert it } else { - _bubbleUp(loans_, Loan(borrower_, thresholdPrice_), loans_.loans.length); + _bubbleUp(loans_, Loan(borrower_, t0DebtToCollateral_), loans_.loans.length); } } @@ -234,7 +235,7 @@ library Loans { } /** - * @notice Retreives `Loan` with the highest threshold price value. + * @notice Retreives `Loan` with the highest t0 threshold price value. * @param loans_ Holds loans heap data. * @return `Max Loan` in the heap. */ diff --git a/src/libraries/internal/Maths.sol b/src/libraries/internal/Maths.sol index f195ecf10..b7ed3175d 100644 --- a/src/libraries/internal/Maths.sol +++ b/src/libraries/internal/Maths.sol @@ -67,10 +67,6 @@ library Maths { } } - function rayToWad(uint256 x) internal pure returns (uint256) { - return (x + 10**9 / 2) / 10**9; - } - /*************************/ /*** Integer Functions ***/ /*************************/ diff --git a/tests/INVARIANTS.md b/tests/INVARIANTS.md index ee1a17b95..22ed7618e 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -25,10 +25,11 @@ - **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. -- **L2**: `Loan` in loans array (`LoansState.loans`) at index 0 has the corresponding address (`Loan.borrower`) equal with `0x` address and the threshold price (`Loan.thresholdPrice`) equal with 0 +- **L1**: for each `Loan` in loans array (`LoansState.loans`) starting from index 1, the corresponding address (`Loan.borrower`) is not `0x`, the borrower t0 debt to collateral (`Loan.t0DebtToCollateral`) is different than 0 and the id mapped in indices mapping (`LoansState.indices`) equals index of loan in loans array. +- **L2**: `Loan` in loans array (`LoansState.loans`) at index 0 has the corresponding address (`Loan.borrower`) equal with `0x` address and the borrower t0 debt to collateral (`Loan.t0DebtToCollateral`) equal with 0 - **L3**: Loans array (`LoansState.loans`) is a max-heap with respect to t0-threshold price: the t0TP of loan at index `i` is >= the t0-threshold price of the loans at index `2*i` and `2*i+1` ## Buckets @@ -63,33 +64,21 @@ - **R7**: Exchange rates are unchanged under depositTakes - **R8**: Exchange rates are unchanged under arbTakes -## Reserves (margin of 1e15 on comparisons) +## Reserves (margin of 1e13 on comparisons) - **RE1**: Reserves are unchanged by pledging collateral - **RE2**: Reserves are unchanged by removing collateral -- **RE3**: Reserves increase only when depositing quote token into a bucket below LUP. Reserves increase only when moving quote tokens into a bucket below LUP. +- **RE3**: Reserves increase upon every deposit and when moving quote tokens into a lower-priced bucket. - **RE4**: Reserves are unchanged by withdrawing deposit (quote token) from a bucket after the penalty period hes expired - **RE5**: Reserves are unchanged by adding collateral token into a bucket - **RE6**: Reserves are unchanged by removing collateral token from a bucket - **RE7**: Reserves increase by bond penalty/reward plus borrower penalty on take above TP. - **RE8**: Reserves increase by bond penalty/reward plus borrower penalty on bucket takes above TP. -- **RE9**: Reserves unchanges by takes and bucket takes below TP. +- **RE9**: Reserves unchanged by takes and bucket takes below TP (at the time of kick). - **RE10**: Reserves increase by origination fee: max(1 week interest, 0.05% of borrow amount), on draw debt - **RE11**: Reserves decrease by claimableReserves by kickReserveAuction - **RE12**: Reserves decrease by amount of reserve used to settle a auction - **RE13**: Reserves are unchanged by kick -## Rewards -- **RW1**: Staking rewards must be less than reward cap percentage multiplied by ajna burned (`newRewards < REWARD_CAP * totalBurnedInPeriod`) for any given time period (`epoch`) -- **RW2**: Updating (recording) rewards must be less than reward cap percentage multiplied by ajna burned (`newRewards < UPDATE_CAP * totalBurned`) for any given time period (`epoch`) -- **RW3**: If a bucket has had it's exchange rate updated bucketExchangeRates mapping should be non-zero (`bucketExchangeRates[pool_][bucketIndex_][burnEpoch_] != 0`) -- **RW4**: After staking, for each bucket in the staked position `lpsAtStakeTime` should equal the position's LP (`position.lps`) in the bucket and `rateAtStakeTime` should equal the bucket's exchange rate (`Buckets.getExchangeRate()`) -- **RW5**: After staking, the Reward's manager contract should be the new owner of the position (`ERC721.ownerOf()`). Upon unstaking, The caller of unstake should be the new owner of the position (`ERC721.ownerOf()`) -- **RW6**: After claiming rewards, `stakeInfo_.lastClaimedEpoch` should be equal to the epoch this position was staked in or the last epoch they claimed rewards for. After claiming or unstaking, `isEpochClaimed` should be equal to `true` for all epochs that the staker has claimed rewards for. -- **RW7**: Each time the bucket rate is updated the `updateRewardsClaimed` accumulator should be updated. Each time a user claims rewards from staking the `rewardsClaimed` accumulator should be updated. -- **RW8**: After unstaking or claiming rewards, if ajna has been burned over an epoch while the staker was staked they should have an increased amount in ajna balance `_ajna.balanceOf()` that matches the amount of ajna balance deducted from the contract `_ajna.balanceOf()`. -- **RW9**: After unstaking, stakeInfo's tokenId mapping should be deleted and all corrosponding values should therefore be zero'd out (`StakeInfo.owner`,`StakeInfo.ajnaPool`, `StakeInfo.lastClaimedEpoch`) -- **RW10**: a Staker can never claim rewards for the same epoch twice - ## Position Manager - **PM1**: LP balance of PositionManager in a Pool for a Bucket should be the sum of the positions[...][index].lps for all tokens/users - **PM2**: Sum of the LP balance of the PositionManager in a Pool across all buckets should be the sum of the positions[...].[...].lps across all indexes and tokens/users diff --git a/tests/README.md b/tests/README.md index 09f341cd6..1ec01f168 100644 --- a/tests/README.md +++ b/tests/README.md @@ -37,10 +37,7 @@ make test-regression-erc721 ```bash make test-regression-position ``` -- regression tests for Rewards Manager: -```bash -make test-regression-rewards -``` + #### Instruction to generate regression test from failing invariant sequence - copy the failing scenario steps from invariant failure in `trace.log` file in invariants dir @@ -75,14 +72,11 @@ Invariant test scenarios can be externally configured by customizing following e | MAX_POOL_DEBT | ERC20 ERC721 | 1e45 | The max amount of debt that can be taken from the pool. If debt goes above this amount, borrower debt will be repaid | | SKIP_TIME | ERC20 ERC721 | 24 hours | The upper limit of time that can be skipped after a pool action (fuzzed) | | SKIP_TIME_TO_KICK | ERC20 ERC721 | 200 days | The time to be skipped and drive a new loan undercollateralized. Use a big value to ensure a successful kick | -| MAX_EPOCH_ADVANCE | ERC20 ERC721 | 5 | The maximum number of epochs that will be created before an unstake or claimRewards call | -| MAX_AJNA_AMOUNT | ERC20 ERC721 | 100_000_000 | The maximum amount of ajna provided to the rewards contract | -| NO_OF_POOLS | Position Rewards | 10 | Number of pools to be used in position and rewards manager invariant testing | +| NO_OF_POOLS | Position | 10 | Number of pools to be used in position manager invariant testing | | FOUNDRY_INVARIANT_RUNS | ERC20 ERC721 | 10 | The number of runs for each scenario | | FOUNDRY_INVARIANT_DEPTH | ERC20 ERC721 | 200 | The number of actions performed in each scenario | | LOGS_VERBOSITY_POOL | ERC20 ERC721 | 0 |

Details to log

0 = No Logs

1 = pool State

2 = pool State, Auctions details

3 = pool State, Auctions details , Buckets details

4 = pool State, Auctions details , Buckets details, Lender details

5 = pool State, Auctions details , Buckets details, Lender details, Borrower details

Note - Log File with name `logFile.txt` will be generated in project directory| | LOGS_VERBOSITY_POSITION | ERC20 ERC721 | 0 |

Details to log

0 = No Logs

1 = positionManager details

Note - Log File with name `logFile.txt` will be generated in project directory| -| LOGS_VERBOSITY_REWARDS | ERC20 ERC721 | 0 |

Details to log

0 = No Logs

1 = rewardsManager details

Note - Log File with name `logFile.txt` will be generated in project directory| #### Invariant names The `` placeholder in commands below could take following values: @@ -158,10 +152,6 @@ make test-invariant-position-erc20 ```bash make test-invariant-position-erc721 ``` -- run all invariant tests for Rewards Manager: -```bash -make test-invariant-rewards -``` - run specific invariant test for both ERC20 and ERC721 pools: ```bash make test-invariant MT= @@ -210,10 +200,6 @@ make coverage brownie test ``` - to view `stdout` on long-running tests, use `brownie test -s`. -- run invariant tests (experimental, doesn't have full coverage): -```bash -brownie test --stateful true -``` ### Debugging Brownie integration tests - to drop into the console upon test failure: diff --git a/tests/brownie/conftest.py b/tests/brownie/conftest.py index 20c72aa62..7df387c4f 100644 --- a/tests/brownie/conftest.py +++ b/tests/brownie/conftest.py @@ -112,7 +112,7 @@ def availableLiquidity(self): return quoteBalance - reserves; def borrowerInfo(self, borrower_address): - # returns (debt, collateral, t0NeutralPrice) + # returns (debt, collateral, t0NeutralPrice, thresholdPrice) return self.pool_info_utils.borrowerInfo(self.pool.address, borrower_address) def bucketInfo(self, index): @@ -123,7 +123,7 @@ def collateralToken(self): return Contract(self.pool.collateralAddress()) def debt(self): - (debt, accruedDebt, debtInAuction) = self.pool.debtInfo() + (debt, accruedDebt, debtInAuction, t0Debt2ToCollateral) = self.pool.debtInfo() return debt def hpb(self): @@ -147,7 +147,7 @@ def lenderInfo(self, index, lender_address): def loansInfo(self): # returns (poolSize, loansCount, maxBorrower, pendingInflator, pendingInterestFactor) - # Not to be confused with pool.loansInfo which returns (maxBorrower, maxThresholdPrice, noOfLoans) + # Not to be confused with pool.loansInfo which returns (maxBorrower, maxT0DebtToCollateral, noOfLoans) return self.pool_info_utils.poolLoansInfo(self.pool.address) def lup(self): @@ -375,7 +375,7 @@ def validate_pool(pool_helper, borrowers): borrowers_with_debt = 0 for borrower in borrowers: - (debt, _, _) = pool_helper.borrowerInfo(borrower.address) + (debt, _, _, _) = pool_helper.borrowerInfo(borrower.address) if debt > 0: borrowers_with_debt += 1 assert borrowers_with_debt == loansCount diff --git a/tests/brownie/test_invariants.py b/tests/brownie/test_invariants.py deleted file mode 100644 index 5aadf6b7f..000000000 --- a/tests/brownie/test_invariants.py +++ /dev/null @@ -1,639 +0,0 @@ -import brownie -import pytest -from brownie.test import strategy -from brownie import Contract, chain -import hypothesis.strategies as st -from hypothesis.stateful import invariant -from hypothesis._settings import HealthCheck -from conftest import PoolHelper, MAX_PRICE - -############## Constants ############## - -MAX_BUCKET = 2690 -MIN_BUCKET = 2700 -NUM_LENDERS = 10 -NUM_BORROWERS = 15 -NUM_BIDDERS = 5 -NUM_KICKERS = 5 -NUM_TAKERS = 5 -MAX_LEND_AMOUNT = 10000*1e18 -MIN_LEND_AMOUNT = 1*1e18 -MAX_BORROW_AMOUNT = 1000*1e18 -MIN_BORROW_AMOUNT = 1*1e18 -MAX_BID_AMOUNT = 10*1e18 -MIN_BID_AMOUNT = 1*1e18 -MIN_TAKE_AMOUNT = 5*1e16 -MAX_TAKE_AMOUNT = 1*1e18 -MAX_NUMBER_OF_RULES = 1000 -MAX_NUMBER_OF_RUNS = 50 - -MAX_UINT256 = 2**256-1 - - -class _BasePoolStateMachine: - - """ - This base state machine class contains initialization and invariant - methods that are shared across multiple stateful tests. - """ - - ############## Strategies ############## - - st_sleep = st.integers(min_value=0, max_value=12 * 360) - st_index = st.integers(min_value=MAX_BUCKET, max_value=MIN_BUCKET) - st_lender = st.integers(min_value=0, max_value=NUM_LENDERS-1) - st_borrower = st.integers(min_value=0, max_value=NUM_BORROWERS-1) - st_bidder = st.integers(min_value=0, max_value=NUM_BIDDERS-1) - st_kicker = st.integers(min_value=0, max_value=NUM_KICKERS-1) - st_taker = st.integers(min_value=0, max_value=NUM_TAKERS-1) - - st_lend_amount = strategy("uint256", min_value=MIN_LEND_AMOUNT, max_value=MAX_LEND_AMOUNT) - st_borrow_amount = strategy("uint256", min_value=MIN_BORROW_AMOUNT, max_value=MAX_BORROW_AMOUNT) - st_bid_amount = strategy("uint256", min_value=MIN_BID_AMOUNT, max_value=MAX_BID_AMOUNT) - st_take_amount = strategy("uint256", min_value=MIN_TAKE_AMOUNT, max_value=MAX_TAKE_AMOUNT) - - - ############## Initialization ############## - - def __init__(self, ajna_protocol, scaled_pool, lenders, borrowers, bidders, kickers, takers): - self.pool = scaled_pool - self.lenders = lenders - self.borrowers = borrowers - self.bidders = bidders - self.kickers = kickers - self.takers = takers - self.pool_helper = PoolHelper(ajna_protocol, scaled_pool) - - - ############## Invariants ############## - - @invariant() - def pool_collateral_balance(self): - - # collateral inflows: - # - pledge collateral (borrower) - # - added collateral in bucket (bidder swap) - # collateral outflows: - # - pull collateral (borrower) - # - remove collateral from buckets (any actor with LP in bucket: lender, borrower, kicker, taker) - # - auction take - - buckets_collateral = 0 - - for index in range(MAX_BUCKET, MIN_BUCKET + 1): - (_, bucket_collateral, _, _, _) = self.pool.bucketInfo(index) - buckets_collateral += bucket_collateral - - # Invariant 1: Pool collateral token balance = sum of collateral across all borrowers + sum of claimable collateral across all buckets - assert self.pool_helper.collateralToken().balanceOf(self.pool) == self.pool.pledgedCollateral() + buckets_collateral - - borrowers_collateral = 0 - - for borrower in self.borrowers: - (_, borrower_collateral, _) = self.pool.borrowerInfo(borrower) - borrowers_collateral += borrower_collateral - - # Invariant 2: total pledged collateral in pool = sum of collateral pledged across all borrowers - assert borrowers_collateral == self.pool.pledgedCollateral() - - @invariant() - def pool_quote_balance(self): - - # quote inflows: - # - add quote tokens (lender) - # - repay debt (borrower) - # - kick loan (kicker, lender) - # quote outflows: - # - draw debt (borrower) - # - remove quote tokens from bucket (any actor with LP in bucket: lender, borrower, kicker, taker) - # - claim bonds (kicker, lender) - # - reward reserves auction - - liquidation_bonds = 0 - for kicker in self.kickers: - (claimable, locked) = self.pool.kickerInfo(kicker) - liquidation_bonds += claimable + locked - - # Invariant 3: Pool quote token balance (with penalties) >= liquidation bonds (locked + claimable) + pool deposit size - pool debt - assert self.pool_helper.quoteToken().balanceOf(self.pool) >= liquidation_bonds + self.pool_helper.pool.depositSize() - self.pool_helper.debt() - - @invariant() - def pool_global_debt(self): - borrowers_debt = 0 - - for borrower in self.borrowers: - (borrower_debt, _, _) = self.pool.borrowerInfo(borrower) - borrowers_debt += borrower_debt - - # Invariant 4: Global Debt Accumulator = sum of debt across all borrowers - assert self.pool.totalT0Debt() == borrowers_debt - - @invariant() - def pool_buckets(self): - for index in range(MAX_BUCKET, MIN_BUCKET + 1): - total_lenders_lps = 0 - - for lender in self.lenders: - (lender_lps, _) = self.pool.lenderInfo(index, lender) - total_lenders_lps += lender_lps - - for borrower in self.borrowers: - (borrower_lps, _) = self.pool.lenderInfo(index, borrower) - total_lenders_lps += borrower_lps - - for bidder in self.bidders: - (bidder_lps, _) = self.pool.lenderInfo(index, bidder) - total_lenders_lps += bidder_lps - - for kicker in self.kickers: - (kicker_lps, _) = self.pool.lenderInfo(index, kicker) - total_lenders_lps += kicker_lps - - for taker in self.takers: - (taker_lps, _) = self.pool.lenderInfo(index, taker) - total_lenders_lps += taker_lps - - (bucket_lps, bucket_collateral, _, bucket_deposit, _) = self.pool.bucketInfo(index) - # Invariant 5: sum of actors lps in bucket = bucket lps accumulator - assert bucket_lps == total_lenders_lps - - # Invariant 6: if no deposit / collateral in bucket then bucket LP should be 0 - if bucket_collateral == 0 and bucket_deposit == 0: - assert bucket_lps == 0 - - - @invariant() - def pool_debt_in_auction(self): - auctioned_borrowers_debt = 0 - for borrower in self.borrowers: - (_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrower) - if kick_time != 0: - (borrower_debt, _, _) = self.pool.borrowerInfo(borrower) - auctioned_borrowers_debt += borrower_debt - - # Invariant 7: debt in auction accumulator = sum of debt across all auctioned borrowers - assert self.pool.totalT0DebtInAuction() == auctioned_borrowers_debt - - @invariant() - def pool_auction_bonds(self): - (total_bond_escrowed, _, _, _) = self.pool.reservesInfo() - - kicker_bonds_locked = 0 - for kicker in self.kickers: - (_, locked) = self.pool.kickerInfo(kicker) - kicker_bonds_locked += locked - - auction_bonds_locked = 0 - for borrower in self.borrowers: - (_, _, bond_size, _, _, _, _, _, _, _) = self.pool.auctionInfo(borrower) - auction_bonds_locked += bond_size - - # Invariant 8: sum of bonds across all auctions = sum of locked balances across all kickers = total bond escrowed accumulator - assert total_bond_escrowed == kicker_bonds_locked == auction_bonds_locked - - @invariant() - def pool_loans_and_auctions(self): - (_, _, number_of_loans) = self.pool.loansInfo() - - number_of_auctions = 0 - borrowers_with_debt = 0 - for borrower in self.borrowers: - (borrower_debt, _, _) = self.pool.borrowerInfo(borrower) - if borrower_debt != 0: - borrowers_with_debt += 1 - - (_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrower) - if kick_time != 0: - number_of_auctions += 1 - - # Invariant 9: number of borrowers with debt = number of loans + number of auctioned borrowers - assert borrowers_with_debt == number_of_loans + number_of_auctions - - - ############## Teardown ############## - - def teardown(self): - print('Tear down') - - - ############## Utilities ############## - - @staticmethod - def _print_rule_result(message, success): - status = "succeeded" if success else "failed" - print(f"{message} {status}") - - -@pytest.fixture -def BasePoolStateMachine(): - yield _BasePoolStateMachine - - -@pytest.fixture -def borrowers(ajna_protocol, scaled_pool): - collateral_client = ajna_protocol.get_token(scaled_pool.collateralAddress()) - quote_client = ajna_protocol.get_token(scaled_pool.quoteTokenAddress()) - amount = int(150_000 * 10**18 / NUM_BORROWERS) - borrowers = [] - print("Initializing borrowers") - for _ in range(NUM_BORROWERS): - borrower = ajna_protocol.add_borrower() - collateral_client.top_up(borrower, amount) - collateral_client.approve_max(scaled_pool, borrower) - quote_client.top_up(borrower, 100_000 * 10**18) # for repayment of interest - quote_client.approve_max(scaled_pool, borrower) - assert collateral_client.get_contract().balanceOf(borrower) >= amount - borrowers.append(borrower) - return borrowers - - -@pytest.fixture -def lenders(ajna_protocol, scaled_pool): - quote_client = ajna_protocol.get_token(scaled_pool.quoteTokenAddress()) - amount = int(3_000_000_000 * 10**18 / NUM_LENDERS) - lenders = [] - print("Initializing lenders") - for _ in range(NUM_LENDERS): - lender = ajna_protocol.add_lender() - quote_client.top_up(lender, amount) - quote_client.approve_max(scaled_pool, lender) - lenders.append(lender) - return lenders - - -@pytest.fixture -def bidders(ajna_protocol, scaled_pool): - collateral_client = ajna_protocol.get_token(scaled_pool.collateralAddress()) - amount = int(100 * 10**18 / NUM_BIDDERS) - bidders = [] - print("Initializing bidders") - for _ in range(NUM_BIDDERS): - bidder = ajna_protocol.add_borrower() - collateral_client.top_up(bidder, amount) - collateral_client.approve_max(scaled_pool, bidder) - assert collateral_client.get_contract().balanceOf(bidder) >= amount - bidders.append(bidder) - return bidders - - -@pytest.fixture -def kickers(ajna_protocol, scaled_pool): - quote_client = ajna_protocol.get_token(scaled_pool.quoteTokenAddress()) - amount = int(3_000_000_000 * 10**18 / NUM_KICKERS) - kickers = [] - print("Initializing kickers") - for _ in range(NUM_KICKERS): - kicker = ajna_protocol.add_lender() - quote_client.top_up(kicker, amount) - quote_client.approve_max(scaled_pool, kicker) - kickers.append(kicker) - return kickers - - -@pytest.fixture -def takers(ajna_protocol, scaled_pool): - quote_client = ajna_protocol.get_token(scaled_pool.quoteTokenAddress()) - amount = int(3_000_000_000 * 10**18 / NUM_TAKERS) - takers = [] - print("Initializing takers") - for _ in range(NUM_TAKERS): - taker = ajna_protocol.add_lender() - quote_client.top_up(taker, amount) - quote_client.approve_max(scaled_pool, taker) - takers.append(taker) - return takers - -############## Tests ############## - - -def test_stateful_borrow_repay( - BasePoolStateMachine, - state_machine, - ajna_protocol, - scaled_pool, - lenders, - borrowers, - bidders, - kickers, - takers - ): - - """ - Stateful test that verifies draw debt / repay behavior - """ - - class PoolStateMachine(BasePoolStateMachine): - - - def setup(self): - # add some initial liquidity in the pool - self.pool.addQuoteToken(MAX_LEND_AMOUNT, MAX_BUCKET, chain.time() + 30, False, {"from": lenders[0]}) - - - ############## Lender rules ############## - - def rule_add_quote_token(self, st_lend_amount, st_index, st_lender, st_sleep): - # lend an arbitrary amount - lender = lenders[st_lender] - - lender_balance = self.pool_helper.quoteToken().balanceOf(lender) - - lend_amount = min(lender_balance, st_lend_amount) - - success = True - - try: - self.pool.addQuoteToken(lend_amount, st_index, chain.time() + 30, False, {"from": lenders[st_lender]}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"lender{st_lender}: add quote token {lend_amount} at index {st_index}", - success - ) - - - def rule_swap_quote_for_collateral(self, st_lend_amount, st_bid_amount, st_index, st_lender, st_bidder, st_sleep): - - success = True - - try: - (_, bucket_collateral, _, _, _) = self.pool.bucketInfo(st_index) - if bucket_collateral < st_bid_amount: - self.pool.addCollateral(st_bid_amount, st_index, chain.time() + 30, {"from": bidders[st_bidder]}) - - self.pool.addQuoteToken(st_lend_amount, st_index, chain.time() + 30, False, {"from": lenders[st_lender]}) - self.pool.removeCollateral(st_bid_amount, st_index, {"from": lenders[st_lender]}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"lender{st_lender}: swap quote {st_lend_amount} for collateral {st_bid_amount} from index {st_index}", - success - ) - - - ############## Borrower rules ############## - - def rule_draw_debt(self, st_borrow_amount, st_lender, st_borrower, st_sleep): - # borrow an arbitrary amount - - success = True - - try: - (min_debt, _, _, _) = self.pool_helper.utilizationInfo() - st_borrow_amount = max(st_borrow_amount, min_debt + 100*1e18) # borrow at least the min debt amount from pool - - pool_quote_on_deposit = self.pool_helper.pool.depositSize() - self.pool_helper.debt() - if pool_quote_on_deposit < st_borrow_amount: - self.pool.addQuoteToken(st_borrow_amount + 100*1e18, MAX_BUCKET, chain.time() + 30, False, {"from": lenders[st_lender]}) - - pool_price = self.pool_helper.lup() - if pool_price == MAX_PRICE: # if there is no LUP, - pool_price = self.pool_helper.hpb() # use the highest-priced bucket with deposit - - collateral_to_deposit = st_borrow_amount / pool_price * 2 * 10**18 - - self.pool.drawDebt(borrowers[st_borrower], st_borrow_amount, 7000, collateral_to_deposit, {"from": borrowers[st_borrower]}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"borrower{st_borrower}: draw debt {st_borrow_amount} and pledge {collateral_to_deposit}", - success - ) - - - def rule_repay_debt(self, st_borrow_amount, st_borrower, st_sleep): - # repay an arbitrary amount - borrower = borrowers[st_borrower] - - (debt, _, _) = self.pool_helper.borrowerInfo(borrower) - repay_amount = min(debt, st_borrow_amount) - - borrower_balance = self.pool_helper.quoteToken().balanceOf(borrower) - repay_amount = min(repay_amount, borrower_balance) - - success = True - - try: - self.pool.repayDebt(borrower, repay_amount, 0, borrower, 7000, {"from": borrower}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"borrower{st_borrower}: repay debt {repay_amount}", - success - ) - - - ############## Bidder rules ############## - - def rule_swap_collateral_for_quote(self, st_bid_amount, st_lend_amount, st_index, st_lender, st_bidder, st_sleep): - # bid an arbitrary amount - - success = True - - try: - (_, _, _, bucket_deposit, _) = self.pool.bucketInfo(st_index) - if bucket_deposit < st_lend_amount: - self.pool.addQuoteToken(st_lend_amount, st_index, chain.time() + 30, False, {"from": lenders[st_lender]}) - - self.pool.addCollateral(st_bid_amount, st_index, chain.time() + 30, {"from": bidders[st_bidder]}) - self.pool.removeQuoteToken(st_lend_amount, st_index, {"from": bidders[st_bidder]}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"bidder{st_bidder}: swap collateral {st_bid_amount} for quote {st_lend_amount} at index {st_index}", - success - ) - - - settings = {"stateful_step_count": MAX_NUMBER_OF_RULES, "max_examples": MAX_NUMBER_OF_RUNS} - state_machine( - PoolStateMachine, - ajna_protocol, - scaled_pool, - lenders, - borrowers, - bidders, - kickers, - takers, - settings=settings - ) - - -@pytest.mark.skip -def test_stateful_auctions( - BasePoolStateMachine, - state_machine, - ajna_protocol, - scaled_pool, - lenders, - borrowers, - bidders, - kickers, - takers - ): - - """ - Stateful test that verifies auctions behavior - """ - - class PoolStateMachine(BasePoolStateMachine): - - - def setup(self): - # add some initial liquidity in the pool - self.pool.addQuoteToken(MAX_BORROW_AMOUNT, MAX_BUCKET, chain.time() + 30, False, {"from": lenders[0]}) - self.pool.addQuoteToken(MAX_BORROW_AMOUNT, MIN_BUCKET, chain.time() + 30, False, {"from": lenders[0]}) - - - ############## Borrower rules ############## - - def rule_draw_debt(self, st_borrow_amount, st_lender, st_borrower, st_sleep): - # borrow an arbitrary amount - - success = True - - # make sure borrower doesn't have any debt or collateral pledged (to make sure kick and take actions succeed) - (debt, collateral_deposited, _) = self.pool_helper.borrowerInfo(borrowers[st_borrower]) - if debt != 0: - debt = MAX_UINT256 # make sure the entire debt is repaid - - self.pool.repayDebt(borrowers[st_borrower], debt, collateral_deposited, borrowers[st_borrower], 7000, {"from": borrowers[st_borrower]}) - - try: - (min_debt, _, _, _) = self.pool_helper.utilizationInfo() - st_borrow_amount = max(st_borrow_amount, min_debt + 100*1e18) # borrow at least the min debt amount from pool - - pool_quote_on_deposit = self.pool_helper.pool.depositSize() - self.pool_helper.debt() - if pool_quote_on_deposit < st_borrow_amount: - self.pool.addQuoteToken(st_borrow_amount + 100*1e18, MAX_BUCKET, chain.time() + 30, False, {"from": lenders[st_lender]}) - - pool_price = self.pool_helper.lup() - if pool_price == MAX_PRICE: # if there is no LUP, - pool_price = self.pool_helper.hpb() # use the highest-priced bucket with deposit - - collateral_to_deposit = st_borrow_amount / pool_price * 1.01 * 10**18 - - self.pool.drawDebt(borrowers[st_borrower], st_borrow_amount, 7000, collateral_to_deposit, {"from": borrowers[st_borrower]}) - - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"borrower{st_borrower}: draw debt {st_borrow_amount} and pledge {collateral_to_deposit}", - success - ) - - - def rule_repay_debt(self, st_borrow_amount, st_borrower, st_sleep): - # repay an arbitrary amount - borrower = borrowers[st_borrower] - - (debt, _, _) = self.pool_helper.borrowerInfo(borrower) - repay_amount = min(debt, st_borrow_amount) - - borrower_balance = self.pool_helper.quoteToken().balanceOf(borrower) - repay_amount = min(repay_amount, borrower_balance) - - success = True - - try: - self.pool.repayDebt(borrower, repay_amount, 0, borrower, 7000, {"from": borrower}) - - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"borrower{st_borrower}: repay debt {repay_amount}", - success - ) - - - ############## Kicker rules ############## - - def rule_kick_auction(self, st_borrow_amount, st_lender, st_borrower, st_kicker, st_sleep): - - # do not kick if already active - (_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower]) - if kick_time != 0: - return - - success = True - - try: - # execute borrow rule to ensure loan - self.rule_draw_debt(st_borrow_amount, st_lender, st_borrower, st_sleep) - - # do not kick if borrower does not have debt - (debt, _, _) = self.pool_helper.borrowerInfo(borrowers[st_borrower]) - if debt == 0: - return - - # skip to make loan kickable - chain.sleep(86400 * 200) - chain.mine(2) - - # kick borrower - self.pool.kick(borrowers[st_borrower], 7_388, {"from": kickers[st_kicker]}) - - chain.sleep(st_sleep) - chain.mine(2) - except: - success = False - - self._print_rule_result( - f"kicker{st_kicker}: kick borrower borrower{st_borrower}", - success - ) - - - ############## Taker rules ############## - - def rule_take_auction(self, st_borrow_amount, st_take_amount, st_lender, st_borrower, st_kicker, st_taker, st_sleep): - - success = True - - # kick if auction not kicked already - (_, _, _, kick_time, _, _, _, _, _, _) = self.pool.auctionInfo(borrowers[st_borrower]) - if kick_time == 0: - self.rule_kick_auction(st_borrow_amount, st_lender, st_borrower, st_kicker, st_sleep) - - try: - # skip to take from auction - chain.sleep(3600 * 3) - chain.mine(2) - - self.pool.take(borrowers[st_borrower], st_take_amount, takers[st_taker], bytes(), {"from": takers[st_taker]}) - chain.sleep(st_sleep) - except: - success = False - - self._print_rule_result( - f"taker{st_taker}: take collateral {st_take_amount} from borrower{st_borrower}", - success - ) - - - settings = {"stateful_step_count": MAX_NUMBER_OF_RULES, "max_examples": MAX_NUMBER_OF_RUNS} - state_machine( - PoolStateMachine, - ajna_protocol, - scaled_pool, - lenders, - borrowers, - bidders, - kickers, - takers, - settings=settings - ) \ No newline at end of file diff --git a/tests/brownie/test_scaled_pool.py b/tests/brownie/test_scaled_pool.py index 24a1a17d3..c926480d1 100644 --- a/tests/brownie/test_scaled_pool.py +++ b/tests/brownie/test_scaled_pool.py @@ -14,7 +14,7 @@ def test_quote_deposit_move_remove_scaled( with test_utils.GasWatcher(["addQuoteToken", "moveQuoteToken", "removeQuoteToken"]): add_txes = [] for i in range(2530, 2550): - tx = scaled_pool.addQuoteToken(100 * 10**18, i, chain.time() + 30, False, {"from": lenders[0]}) + tx = scaled_pool.addQuoteToken(100 * 10**18, i, chain.time() + 30, {"from": lenders[0]}) add_txes.append(tx) with capsys.disabled(): print("\n==================================") @@ -25,7 +25,7 @@ def test_quote_deposit_move_remove_scaled( move_txes = [] for i in range(2530, 2550): - tx = scaled_pool.moveQuoteToken(100 * 10**18, i, i + 30, chain.time() + 30, False, {"from": lenders[0]}) + tx = scaled_pool.moveQuoteToken(100 * 10**18, i, i + 30, chain.time() + 30, {"from": lenders[0]}) move_txes.append(tx) with capsys.disabled(): print("\n==================================") @@ -57,9 +57,9 @@ def test_borrow_repay_scaled( with test_utils.GasWatcher(["addQuoteToken", "drawDebt", "repayDebt"]): expiry = chain.time() + 30 - scaled_pool.addQuoteToken(100 * 10**18, 2550, expiry, False, {"from": lenders[0]}) - scaled_pool.addQuoteToken(100 * 10**18, 2560, expiry, False, {"from": lenders[0]}) - scaled_pool.addQuoteToken(100 * 10**18, 2570, expiry, False, {"from": lenders[0]}) + scaled_pool.addQuoteToken(100 * 10**18, 2550, expiry, {"from": lenders[0]}) + scaled_pool.addQuoteToken(100 * 10**18, 2560, expiry, {"from": lenders[0]}) + scaled_pool.addQuoteToken(100 * 10**18, 2570, expiry, {"from": lenders[0]}) col_txes = [] for i in range(10): diff --git a/tests/brownie/test_stable_volatile.py b/tests/brownie/test_stable_volatile.py index 20428fe2e..167533254 100644 --- a/tests/brownie/test_stable_volatile.py +++ b/tests/brownie/test_stable_volatile.py @@ -58,7 +58,7 @@ def lenders(ajna_protocol, scaled_pool): def borrowers(ajna_protocol, scaled_pool): collateral_client = ajna_protocol.get_token(scaled_pool.collateralAddress()) dai_client = ajna_protocol.get_token(scaled_pool.quoteTokenAddress()) - amount = int(150_000 * 10**18 / NUM_BORROWERS) + amount = int(100_000 * 10**18 / NUM_BORROWERS) borrowers = [] print("Initializing borrowers") for _ in range(NUM_BORROWERS): @@ -96,7 +96,7 @@ def add_initial_liquidity(lenders, pool_helper, chain): price_index = price_position + MAX_BUCKET log(f" lender {i} depositing {deposit_amount/1e18} into bucket {price_index} " f"({pool_helper.indexToPrice(price_index) / 1e18:.1f})") - pool_helper.pool.addQuoteToken(deposit_amount, price_index, chain.time() + 30, False, {"from": lenders[i]}) + pool_helper.pool.addQuoteToken(deposit_amount, price_index, chain.time() + 30, {"from": lenders[i]}) def draw_initial_debt(borrowers, pool_helper, test_utils, chain, target_utilization): @@ -152,7 +152,7 @@ def aggregate_borrower_debt(borrowers, pool_helper, debug=False): total_debt = 0 for i in range(0, len(borrowers) - 1): borrower = borrowers[i] - (debt, _, _) = pool_helper.borrowerInfo(borrower.address) + (debt, _, _, _) = pool_helper.borrowerInfo(borrower.address) if debug and debt > 0: log(f" borrower {i:>4} debt: {debt/1e18:>15.3f}") total_debt += debt @@ -177,7 +177,7 @@ def pledge_and_borrow(pool_helper, borrower, borrower_index, collateral_to_depos pool = pool_helper.pool # prevent invalid actions - (debt, pledged, _) = pool_helper.borrowerInfo(borrower.address) + (debt, pledged, _, _) = pool_helper.borrowerInfo(borrower.address) if not ensure_pool_is_funded(pool, borrow_amount, "borrow"): # ensure_pool_is_funded logs a message return @@ -294,7 +294,7 @@ def add_quote_token(lender, lender_index, pool_helper, chain): return None log(f" lender {lender_index:>4} adding {quantity / 10**18:.1f} liquidity at {deposit_price / 10**18:.1f}") - tx = pool_helper.pool.addQuoteToken(quantity, deposit_index, chain.time() + 15, False, {"from": lender}) + tx = pool_helper.pool.addQuoteToken(quantity, deposit_index, chain.time() + 15, {"from": lender}) return deposit_price @@ -320,7 +320,7 @@ def remove_quote_token(lender, lender_index, price, pool_helper) -> bool: def repay_debt(borrower, borrower_index, pool_helper, test_utils): dai = pool_helper.quoteToken() - (debt, collateral_deposited, _) = pool_helper.borrowerInfo(borrower) + (debt, collateral_deposited, _, _) = pool_helper.borrowerInfo(borrower) quote_balance = dai.balanceOf(borrower) (_, _, _, min_debt) = pool_helper.utilizationInfo() diff --git a/tests/forge/interactions/BalancerUniswapExample.sol b/tests/forge/interactions/BalancerUniswapExample.sol index d5b3ca405..6aa358e5a 100644 --- a/tests/forge/interactions/BalancerUniswapExample.sol +++ b/tests/forge/interactions/BalancerUniswapExample.sol @@ -53,7 +53,7 @@ contract BalancerUniswapTaker { // take auction from Ajna pool, give USDC, receive WETH IAjnaPool(decoded.ajnaPool).take(decoded.borrower, decoded.maxAmount, address(this), new bytes(0)); - uint256 usdcBalanceAfterTake = 81080126; + uint256 usdcBalanceAfterTake = 81253332; assert(tokens[0].balanceOf(address(this)) == usdcBalanceAfterTake); // USDC balance after Ajna take assert(tokens[1].balanceOf(address(this)) == 2000000000000000000); // WETH balance after Ajna take @@ -137,9 +137,9 @@ contract BalancerUniswapPurchaser { uint256 lps = IAjnaPool(decoded.ajnaPool).addCollateral(loanAmount, decoded.bucketIndex, block.timestamp + 5 minutes); (uint256 quoteAmount, ) = IAjnaPool(decoded.ajnaPool).removeQuoteToken(type(uint256).max, decoded.bucketIndex); assert(lps == 83008350.10362729922336157 * 1e18); // LPS in bucket - assert(quoteAmount == 5000 * 1e18); // Purchased quote amount - assert(quote.balanceOf(address(this)) == 5000 * 1e6); // USDC balance after Ajna purchase - assert(collateral.balanceOf(address(this)) == 0); // WETH balance after Ajna purchase + assert(quoteAmount == 4999.771689497716895 * 1e18); // Purchased quote amount + assert(quote.balanceOf(address(this)) == 4999.771689 * 1e6); // USDC balance after Ajna purchase + assert(collateral.balanceOf(address(this)) == 0); // WETH balance after Ajna purchase // swap USDC to WETH on Uniswap, approve router to spend USDC purchased from ajna quote.approve(address(router), quoteAmount); diff --git a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol index 74d4644f9..9430ba8b2 100644 --- a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol +++ b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol @@ -54,18 +54,18 @@ contract ERC20TakeWithExternalLiquidityTest is Test { // add liquidity to the Ajna pool vm.startPrank(_lender); usdc.approve(address(_ajnaPool), type(uint256).max); - _ajnaPool.addQuoteToken(2_000 * 1e18, 3696, type(uint256).max, false); - _ajnaPool.addQuoteToken(5_000 * 1e18, 3698, type(uint256).max, false); - _ajnaPool.addQuoteToken(11_000 * 1e18, 3700, type(uint256).max, false); - _ajnaPool.addQuoteToken(25_000 * 1e18, 3702, type(uint256).max, false); - _ajnaPool.addQuoteToken(30_000 * 1e18, 3704, type(uint256).max, false); + _ajnaPool.addQuoteToken(2_000 * 1e18, 3696, type(uint256).max); + _ajnaPool.addQuoteToken(5_000 * 1e18, 3698, type(uint256).max); + _ajnaPool.addQuoteToken(11_000 * 1e18, 3700, type(uint256).max); + _ajnaPool.addQuoteToken(25_000 * 1e18, 3702, type(uint256).max); + _ajnaPool.addQuoteToken(30_000 * 1e18, 3704, type(uint256).max); vm.stopPrank(); // borrower draws debt vm.startPrank(_borrower); weth.approve(address(_ajnaPool), type(uint256).max); usdc.approve(address(_ajnaPool), type(uint256).max); - _ajnaPool.drawDebt(_borrower, 19.25 * 1e18, 3696, 2 * 1e18); + _ajnaPool.drawDebt(_borrower, 19 * 1e18, 3696, 2 * 1e18); vm.stopPrank(); // borrower2 draws debt @@ -105,7 +105,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { }) ); vm.expectEmit(true, true, false, true); - emit Take(_borrower, 18.919873153126569032 * 1e18, 2.0 * 1e18, 0.287210105092827748 * 1e18, true); + emit Take(_borrower, 18.746667146330604216 * 1e18, 2.0 * 1e18, 0.209594110453786132 * 1e18, true); taker.take(tokens, amounts, data); assertGt(usdc.balanceOf(address(this)), 0); // could vary @@ -126,7 +126,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { // call take using taker contract bytes memory data = abi.encode(address(_ajnaPool)); vm.expectEmit(true, true, false, true); - emit Take(_borrower, 18.919873153126569032 * 1e18, 2.0 * 1e18, 0.287210105092827748 * 1e18, true); + emit Take(_borrower, 18.746667146330604216 * 1e18, 2.0 * 1e18, 0.209594110453786132 * 1e18, true); _ajnaPool.take(_borrower, takeAmount, address(taker), data); // confirm we earned some quote token @@ -136,7 +136,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { function testTakeCalleeDiffersFromSender() external { // _lender is msg.sender, QT & CT balances pre take - assertEq(usdc.balanceOf(_lender), 119_999.999999926999703463 * 1e18); + assertEq(usdc.balanceOf(_lender), 119_999.999999926999784436 * 1e18); assertEq(weth.balanceOf(_lender), 0); // callee, _lender1 QT & CT balances pre take @@ -148,7 +148,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { _ajnaPool.take(_borrower, 1_001 * 1e18, _lender1, new bytes(0)); // _lender is has QT deducted from balance - assertEq(usdc.balanceOf(_lender), 119_999.999999926980783589 * 1e18); + assertEq(usdc.balanceOf(_lender), 119_999.999999926981037768 * 1e18); assertEq(weth.balanceOf(_lender), 0); // callee, _lender1 receives CT from take diff --git a/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol b/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol index cbf94628c..5efad8bd7 100644 --- a/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol +++ b/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol @@ -50,7 +50,7 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract { _drawDebt({ from: _borrower, borrower: _borrower, - amountToBorrow: 1_999 * 1e18, + amountToBorrow: 1_930 * 1e18, limitIndex: 3232, tokenIds: tokenIdsToAdd, newLup: _p1004_98 @@ -80,14 +80,14 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract { // call take using taker contract bytes memory data = abi.encode(address(_pool)); vm.expectEmit(true, true, false, true); - uint256 quoteTokenPaid = 1_161.844718489711575688 * 1e18; + uint256 quoteTokenPaid = 1_126.096435871756057616 * 1e18; uint256 collateralPurchased = 2 * 1e18; - uint256 bondChange = 17.637197723169355130 * 1e18; + uint256 bondChange = 12.590140899147395432 * 1e18; emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true); _pool.take(_borrower, 2, address(taker), data); // confirm we earned some quote token - assertEq(_quote.balanceOf(address(taker)), 338.155281510288424312 * 1e18); + assertEq(_quote.balanceOf(address(taker)), 373.903564128243942384 * 1e18); } function testTakeNFTCalleeDiffersFromSender() external { @@ -103,21 +103,21 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract { _collateral.setApprovalForAll(address(marketPlace), true); // _lender is msg.sender, QT & CT balances pre take - assertEq(_quote.balanceOf(_lender), 49_969.374638518350819260 * 1e18); + assertEq(_quote.balanceOf(_lender), 49_978.222939913714312699 * 1e18); assertEq(_quote.balanceOf(address(taker)), 0); // call take using taker contract changePrank(_lender); bytes memory data = abi.encode(address(_pool)); vm.expectEmit(true, true, false, true); - uint256 quoteTokenPaid = 1_161.844718489711575688 * 1e18; + uint256 quoteTokenPaid = 1_126.096435871756057616 * 1e18; uint256 collateralPurchased = 2 * 1e18; - uint256 bondChange = 17.637197723169355130 * 1e18; + uint256 bondChange = 12.590140899147395432 * 1e18; emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true); _pool.take(_borrower, 2, address(taker), data); // _lender is msg.sender, QT & CT balances post take - assertEq(_quote.balanceOf(_lender), 48_807.529920028639243572 * 1e18); + assertEq(_quote.balanceOf(_lender), 48_852.126504041958255083 * 1e18); assertEq(_quote.balanceOf(address(taker)), 1_500.0 * 1e18); // QT is increased as NFTTakeExample contract sells the NFT } } diff --git a/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol b/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol index c1166eb6d..2582bebfa 100644 --- a/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol +++ b/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol @@ -28,7 +28,7 @@ contract PurchaseQuoteWithExternalLiquidityTest is Test { deal(USDC, _lender, 120_000 * 1e6); vm.startPrank(_lender); usdc.approve(address(_ajnaPool), type(uint256).max); - _ajnaPool.addQuoteToken(5_000 * 1e18, 500, type(uint256).max, false); + _ajnaPool.addQuoteToken(5_000 * 1e18, 500, type(uint256).max); vm.stopPrank(); } diff --git a/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol index 8f5bac357..59719c382 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol @@ -74,8 +74,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl numberOfCalls['BBasicHandler.pledgeCollateral']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _prePledgeCollateral(amountToPledge_); @@ -92,8 +91,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl numberOfCalls['BBasicHandler.pullCollateral']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _prePullCollateral(amountToPull_); @@ -110,8 +108,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl numberOfCalls['BBasicHandler.drawDebt']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _preDrawDebt(amountToBorrow_); @@ -128,8 +125,7 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl numberOfCalls['BBasicHandler.repayDebt']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _preRepayDebt(amountToRepay_); @@ -145,39 +141,49 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl function _preAddCollateral( uint256 amountToAdd_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToAdd_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToAdd_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } function _preRemoveCollateral( uint256 amountToRemove_ ) internal returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToRemove_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToRemove_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); // ensure actor has collateral to remove - (uint256 lpBalanceBefore, ) = _pool.lenderInfo(_lenderBucketIndex, _actor); - if (lpBalanceBefore == 0) _addCollateral(boundedAmount_, _lenderBucketIndex); + if (_getLenderInfo(_lenderBucketIndex, _actor).lpBalance == 0) { + _addCollateral(boundedAmount_, _lenderBucketIndex); + } } function _prePledgeCollateral( uint256 amountToPledge_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToPledge_, _erc20Pool.collateralScale(), MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToPledge_, _erc20Pool.collateralScale(), MAX_COLLATERAL_AMOUNT + ); } function _prePullCollateral( uint256 amountToPull_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToPull_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToPull_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } function _preDrawDebt( uint256 amountToBorrow_ ) internal override returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT); + boundedAmount_ = constrictToRange( + amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT + ); // borrower cannot make any action when in auction - (uint256 kickTime, uint256 collateral,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return boundedAmount_; + if (_getAuctionInfo(_actor).kickTime != 0) return boundedAmount_; // Pre Condition // 1. borrower's debt should exceed minDebt @@ -185,7 +191,6 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl // 3. drawDebt should not make borrower under collateralized // 1. borrower's debt should exceed minDebt - (uint256 debt,, ) = _poolInfo.borrowerInfo(address(_pool), _actor); (uint256 minDebt, , , ) = _poolInfo.poolUtilizationInfo(address(_pool)); if (boundedAmount_ < minDebt && minDebt < MAX_DEBT_AMOUNT) boundedAmount_ = minDebt + 1; @@ -202,27 +207,29 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl (uint256 currentPoolDebt, , , ) = _pool.debtInfo(); uint256 nextPoolDebt = currentPoolDebt + boundedAmount_; uint256 newLup = _priceAt(_pool.depositIndex(nextPoolDebt)); - (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(_actor); // repay debt if borrower becomes undercollateralized with new debt at new lup - if (!_isCollateralized(debt + boundedAmount_, collateral, newLup, _pool.poolType())) { + if (!_isCollateralized(borrowerInfo.debt + boundedAmount_, borrowerInfo.collateral, newLup, _pool.poolType())) { _repayDebt(type(uint256).max); - (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); - _pullCollateral(collateral); + borrowerInfo = _getBorrowerInfo(_actor); + _pullCollateral(borrowerInfo.collateral); - require(debt == 0, "borrower has debt"); + require(borrowerInfo.debt == 0, "borrower has debt"); } } function _preRepayDebt( uint256 amountToRepay_ ) internal returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToRepay_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT); + boundedAmount_ = constrictToRange( + amountToRepay_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT + ); // ensure actor has debt to repay - (uint256 debt, , ) = PoolInfoUtils(_poolInfo).borrowerInfo(address(_pool), _actor); - if (debt == 0) { + if (_getBorrowerInfo(_actor).debt == 0) { boundedAmount_ = _preDrawDebt(boundedAmount_); _drawDebt(boundedAmount_); } diff --git a/tests/forge/invariants/ERC20Pool/handlers/LiquidationERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/LiquidationERC20PoolHandler.sol index ee3a1ae06..eafd8e1be 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/LiquidationERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/LiquidationERC20PoolHandler.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.18; -import { LiquidationPoolHandler } from '../../base/handlers/LiquidationPoolHandler.sol'; -import { BasicERC20PoolHandler } from './BasicERC20PoolHandler.sol'; +import { LiquidationPoolHandler } from '../../base/handlers/LiquidationPoolHandler.sol'; +import { BasicERC20PoolHandler } from './BasicERC20PoolHandler.sol'; contract LiquidationERC20PoolHandler is LiquidationPoolHandler, BasicERC20PoolHandler { @@ -18,7 +18,9 @@ contract LiquidationERC20PoolHandler is LiquidationPoolHandler, BasicERC20PoolHa } function _constrictTakeAmount(uint256 amountToTake_) internal view override returns(uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToTake_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToTake_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } } \ No newline at end of file diff --git a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol index 9903290a0..9c3fc7822 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol @@ -42,7 +42,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded _setupLendersAndDeposits(LENDERS); _setupBorrowersAndLoans(LOANS_COUNT); - ( , , uint256 totalLoans) = _pool.loansInfo(); + uint256 totalLoans = _getLoansInfo().noOfLoans; require(totalLoans == LOANS_COUNT, "loans setup failed"); vm.warp(block.timestamp + 100_000 days); @@ -56,19 +56,22 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded uint256 borrowerIndex_, uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - borrowerIndex_ = constrictToRange(borrowerIndex_, 0, _activeBorrowers.values().length - 1); + borrowerIndex_ = constrictToRange( + borrowerIndex_, 0, _activeBorrowers.values().length - 1 + ); _actor = _borrowers[borrowerIndex_]; + changePrank(_actor); - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor); - if (block.timestamp > kickTime + 72 hours) { + if (block.timestamp > _getAuctionInfo(_actor).kickTime + 72 hours) { numberOfCalls['BPanicExitPoolHandler.settleDebt']++; _settleAuction(_actor, numberOfBuckets); } else { numberOfCalls['BPanicExitPoolHandler.repayLoan']++; _repayDebt(type(uint256).max); } - (, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + + uint256 collateral = _getBorrowerInfo(_actor).collateral; _pullCollateral(collateral); _resetSettledAuction(_actor, borrowerIndex_); @@ -98,7 +101,8 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded if (takeAuction_) { vm.warp(block.timestamp + 61 minutes); - ( , uint256 auctionedCollateral, ) = _pool.borrowerInfo(borrower); + + uint256 auctionedCollateral = _getBorrowerInfo(borrower).collateral; _takeAuction(borrower, auctionedCollateral, _actor); _resetSettledAuction(borrower, borrowerIndex_); } @@ -151,20 +155,18 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded ) external useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BPanicExitPoolHandler.withdrawBonds']++; - kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); - address kicker = _lenders[kickerIndex_]; - - (uint256 kickerClaimable, ) = _pool.kickerInfo(kicker); + kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); + address kicker = _lenders[kickerIndex_]; _actor = kicker; changePrank(_actor); - _withdrawBonds(kicker, kickerClaimable); + _withdrawBonds(kicker, _getKickerInfo(kicker).claimableBond); } function settleHeadAuction( uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); + address headAuction = _getAuctionInfo(address(0)).head; if (headAuction != address(0)) { _settleAuction(headAuction, 10); _resetSettledAuction(headAuction, 0); @@ -218,8 +220,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); - if (kickTime == 0) { + if (_getAuctionInfo(borrower_).kickTime == 0) { if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC20Pool/handlers/SettleERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/SettleERC20PoolHandler.sol index 65ef26888..64e8b2a4b 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/SettleERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/SettleERC20PoolHandler.sol @@ -43,7 +43,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas _setupLendersAndDeposits(LENDERS); _setupBorrowersAndLoans(LOANS_COUNT); - ( , , uint256 totalLoans) = _pool.loansInfo(); + uint256 totalLoans = _getLoansInfo().noOfLoans; require(totalLoans == LOANS_COUNT, "loans setup failed"); vm.warp(block.timestamp + 1_000 days); @@ -62,7 +62,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); address kicker = _lenders[kickerIndex_]; - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); + uint256 kickTime = _getAuctionInfo(borrower).kickTime; // Kick auction if not already kicked if (kickTime == 0) { @@ -71,7 +71,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas _kickAuction(borrower); } - (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); + kickTime = _getAuctionInfo(borrower).kickTime; if (kickTime == 0) return; @@ -82,171 +82,11 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas changePrank(borrower); _actor = borrower; - _settle(borrower, numberOfBuckets); + _settleAuction(borrower, numberOfBuckets); _resetSettledAuction(borrower, borrowerIndex_); } - function repayDebtByThirdParty( - uint256 actorIndex_, - uint256 kickerIndex_, - uint256 borrowerIndex_, - uint256 skippedTime_ - ) external useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['SettlePoolHandler.repayLoan']++; - - borrowerIndex_ = constrictToRange(borrowerIndex_, 0, _activeBorrowers.values().length - 1); - address borrower = _borrowers[borrowerIndex_]; - - kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); - address kicker = _lenders[kickerIndex_]; - - actorIndex_ = constrictToRange(actorIndex_, 0, LENDERS - 1); - address payer = _lenders[actorIndex_]; - - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); - - // Kick auction if not already kicked - if (kickTime == 0) { - changePrank(kicker); - _actor = kicker; - _kickAuction(borrower); - } - - (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); - - if (kickTime == 0) return; - - // skip time to make auction settleable - if (block.timestamp < kickTime + 72 hours) { - skip(kickTime + 73 hours - block.timestamp); - } - - // skip time to make auction settleable - if (block.timestamp < kickTime + 72 hours) { - skip(kickTime + 73 hours - block.timestamp); - } - - changePrank(payer); - _repayDebtByThirdParty(payer, borrower, type(uint256).max); - - _resetSettledAuction(borrower, borrowerIndex_); - } - - function _settle( - address borrower_, - uint256 maxDepth_ - ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBLiquidationHandler.settleAuction']++; - ( - uint256 borrowerT0Debt, - uint256 collateral, - ) = _pool.borrowerInfo(borrower_); - (uint256 reservesBeforeAction, , , , )= _poolInfo.poolReservesInfo(address(_pool)); - (uint256 inflator, ) = _pool.inflatorInfo(); - - _pool.settle(borrower_, maxDepth_); - // settle borrower debt with exchanging borrower collateral with quote tokens starting from hpb - while (maxDepth_ != 0 && borrowerT0Debt != 0 && collateral != 0) { - uint256 bucketIndex = fenwickIndexForSum(1); - uint256 maxSettleableDebt = Maths.floorWmul(collateral, _priceAt(bucketIndex)); - uint256 fenwickDeposit = fenwickDeposits[bucketIndex]; - uint256 borrowerDebt = Maths.wmul(borrowerT0Debt, inflator); - - if (fenwickDeposit == 0 && maxSettleableDebt != 0) { - collateral = 0; - // Deposits in the tree is zero, insert entire collateral into lowest bucket 7388 - // **B5**: when settle with collateral: record min bucket where collateral added - buckets.add(7388); - lenderDepositTime[borrower_][7388] = block.timestamp; - } else { - if (bucketIndex != MAX_FENWICK_INDEX) { - // enough deposit in bucket and collateral avail to settle entire debt - if (fenwickDeposit >= borrowerDebt && maxSettleableDebt >= borrowerDebt) { - fenwickDeposits[bucketIndex] -= borrowerDebt; - collateral -= Maths.ceilWdiv(borrowerDebt, _priceAt(bucketIndex)); - borrowerT0Debt = 0; - } - // enough collateral, therefore not enough deposit to settle entire debt, we settle only deposit amount - else if (maxSettleableDebt >= fenwickDeposit) { - fenwickDeposits[bucketIndex] = 0; - collateral -= Maths.ceilWdiv(fenwickDeposit, _priceAt(bucketIndex)); - borrowerT0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); - } - // exchange all collateral with deposit - else { - fenwickDeposits[bucketIndex] -= maxSettleableDebt; - collateral = 0; - borrowerT0Debt -= Maths.floorWdiv(maxSettleableDebt, inflator); - } - } else { - collateral = 0; - // **B5**: when settle with collateral: record min bucket where collateral added. - // Lender doesn't get any LP when settle bad debt. - buckets.add(7388); - } - } - - maxDepth_ -= 1; - } - - // if collateral becomes 0 and still debt is left, settle debt by reserves and hpb making buckets bankrupt - if (borrowerT0Debt != 0 && collateral == 0) { - - (uint256 reservesAfterAction, , , , )= _poolInfo.poolReservesInfo(address(_pool)); - if (reservesBeforeAction > reservesAfterAction) { - // **RE12**: Reserves decrease by amount of reserve used to settle a auction - decreaseInReserves = reservesBeforeAction - reservesAfterAction; - } else { - // Reserves might increase upto 2 WAD due to rounding issue - increaseInReserves = reservesAfterAction - reservesBeforeAction; - } - borrowerT0Debt -= Maths.min(Maths.wdiv(decreaseInReserves, inflator), borrowerT0Debt); - - while (maxDepth_ != 0 && borrowerT0Debt != 0) { - uint256 bucketIndex = fenwickIndexForSum(1); - uint256 fenwickDeposit = fenwickDeposits[bucketIndex]; - uint256 borrowerDebt = Maths.wmul(borrowerT0Debt, inflator); - - if (bucketIndex != MAX_FENWICK_INDEX) { - // debt is greater than bucket deposit - if (borrowerDebt > fenwickDeposit) { - fenwickDeposits[bucketIndex] = 0; - borrowerT0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); - } - // bucket deposit is greater than debt - else { - fenwickDeposits[bucketIndex] -= borrowerDebt; - borrowerT0Debt = 0; - } - } - - maxDepth_ -= 1; - } - } - // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); - if (kickTime == 0 && collateral % 1e18 != 0 && _pool.poolType() == 1) { - buckets.add(7388); - lenderDepositTime[borrower_][7388] = block.timestamp; - } - } - - function _repayDebtByThirdParty( - address payer_, - address borrower_, - uint256 amountToRepay_ - ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBBasicHandler.repayDebt']++; - - (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); - - // ensure actor always has amount of quote to repay - _ensureQuoteAmount(payer_, borrowerDebt + 10 * 1e18); - - _erc20Pool.repayDebt(borrower_, amountToRepay_, 0, borrower_, 7388); - } - function _setupLendersAndDeposits(uint256 count_) internal virtual { uint256[] memory buckets = buckets.values(); for (uint256 i; i < count_;) { @@ -294,8 +134,7 @@ contract SettleERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBas } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); - if (kickTime == 0) { + if (_getAuctionInfo(borrower_).kickTime == 0) { if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol index 32878fffe..d80340964 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol @@ -71,13 +71,12 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa changePrank(_actor); - uint256 rateBeforeSwap = _pool.bucketExchangeRate(_lenderBucketIndex); - (uint256 lpBeforeSwap, , , ,) = _pool.bucketInfo(_lenderBucketIndex); + BucketInfo memory bucketInfoBeforeSwap = _getBucketInfo(_lenderBucketIndex); _addQuoteToken(tradeAmount_, _lenderBucketIndex); _removeCollateral(type(uint256).max, _lenderBucketIndex); - (uint256 lpAfterSwap, , , ,) = _pool.bucketInfo(_lenderBucketIndex); + BucketInfo memory bucketInfoAfterSwap = _getBucketInfo(_lenderBucketIndex); printLine( string( @@ -85,10 +84,13 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa ) ); printLog("Trading price = ", _priceAt(_lenderBucketIndex)); - printLog("Bucket LP before = ", lpBeforeSwap); - printLog("Bucket LP after = ", lpAfterSwap); + printLog("Bucket LP before = ", bucketInfoBeforeSwap.lpBalance); + printLog("Bucket LP after = ", bucketInfoAfterSwap.lpBalance); - require (rateBeforeSwap == _pool.bucketExchangeRate(_lenderBucketIndex), "R1-R8: Exchange Rate Invariant"); + require ( + bucketInfoBeforeSwap.exchangeRate == bucketInfoAfterSwap.exchangeRate, + "R1-R8: Exchange Rate Invariant" + ); } function swapCollateralForQuote( @@ -104,13 +106,12 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa changePrank(_actor); - uint256 rateBeforeSwap = _pool.bucketExchangeRate(_lenderBucketIndex); - (uint256 lpBeforeSwap, , , ,) = _pool.bucketInfo(_lenderBucketIndex); + BucketInfo memory bucketInfoBeforeSwap = _getBucketInfo(_lenderBucketIndex); _addCollateral(tradeAmount_, _lenderBucketIndex); _removeQuoteToken(type(uint256).max, _lenderBucketIndex); - (uint256 lpAfterSwap, , , ,) = _pool.bucketInfo(_lenderBucketIndex); + BucketInfo memory bucketInfoAfterSwap = _getBucketInfo(_lenderBucketIndex); printLine( string( @@ -118,10 +119,13 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa ) ); printLog("Trading price = ", _priceAt(_lenderBucketIndex)); - printLog("Bucket LP before = ", lpBeforeSwap); - printLog("Bucket LP after = ", lpAfterSwap); + printLog("Bucket LP before = ", bucketInfoBeforeSwap.lpBalance); + printLog("Bucket LP after = ", bucketInfoAfterSwap.lpBalance); - require (rateBeforeSwap == _pool.bucketExchangeRate(_lenderBucketIndex), "R1-R8: Exchange Rate Invariant"); + require ( + bucketInfoBeforeSwap.exchangeRate == bucketInfoAfterSwap.exchangeRate, + "R1-R8: Exchange Rate Invariant" + ); } function _setupQuoteDeposits(uint256 count_) internal virtual { @@ -171,8 +175,7 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); - if (kickTime == 0) { + if (_getAuctionInfo(borrower_).kickTime == 0) { if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol index 49a2c3d28..0b3a4071b 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol @@ -8,7 +8,8 @@ import { PoolInfoUtils } from 'src/PoolInfoUtils.sol'; import { _borrowFeeRate, _depositFeeRate, - _roundToScale + _roundToScale, + COLLATERALIZATION_FACTOR } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; @@ -35,17 +36,24 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B // ensure actor always has amount of collateral to add _ensureCollateralAmount(_actor, amount_); - (uint256 lpBalanceBeforeAction, ) = _erc20Pool.lenderInfo(bucketIndex_, _actor); + uint256 lpBalanceBeforeAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; - try _erc20Pool.addCollateral(amount_, bucketIndex_, block.timestamp + 1 minutes) { + try _erc20Pool.addCollateral( + amount_, + bucketIndex_, + block.timestamp + 1 minutes + ) { // **B5**: when adding collateral: lender deposit time = timestamp of block when deposit happened lenderDepositTime[_actor][bucketIndex_] = block.timestamp; // **R5**: Exchange rates are unchanged by adding collateral token into a bucket exchangeRateShouldNotChange[bucketIndex_] = true; // Post action condition - (uint256 lpBalanceAfterAction, ) = _erc20Pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction > lpBalanceBeforeAction, "LP balance should increase"); + uint256 lpBalanceAfterAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + require( + lpBalanceAfterAction > lpBalanceBeforeAction, + "LP balance should increase" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -57,17 +65,21 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.removeCollateral']++; - (uint256 lpBalanceBeforeAction, ) = _erc20Pool.lenderInfo(bucketIndex_, _actor); - - try _erc20Pool.removeCollateral(amount_, bucketIndex_) { + uint256 lpBalanceBeforeAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + try _erc20Pool.removeCollateral( + amount_, + bucketIndex_ + ) { // **R6**: Exchange rates are unchanged by removing collateral token from a bucket exchangeRateShouldNotChange[bucketIndex_] = true; // Post action condition - (uint256 lpBalanceAfterAction, ) = _erc20Pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction < lpBalanceBeforeAction, "LP balance should decrease"); - + uint256 lpBalanceAfterAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + require( + lpBalanceAfterAction < lpBalanceBeforeAction, + "LP balance should decrease" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -90,7 +102,12 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B exchangeRateShouldNotChange[bucketIndex] = true; } - try _erc20Pool.drawDebt(_actor, 0, 0, amount_) { + try _erc20Pool.drawDebt( + _actor, + 0, + 0, + amount_ + ) { } catch (bytes memory err) { _ensurePoolError(err); } @@ -106,8 +123,13 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B exchangeRateShouldNotChange[bucketIndex] = true; } - try _erc20Pool.repayDebt(_actor, 0, amount_, _actor, 7388) { - + try _erc20Pool.repayDebt( + _actor, + 0, + amount_, + _actor, + 7388 + ) { } catch (bytes memory err) { _ensurePoolError(err); } @@ -126,14 +148,19 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B uint256 bucket = depositIndex - 1; uint256 price = _poolInfo.indexToPrice(bucket); - uint256 collateralToPledge = ((amount_ * 1e18 + price / 2) / price) * 101 / 100 + 1; + uint256 collateralToPledge = ((COLLATERALIZATION_FACTOR * amount_ + price / 2) / price) * 101 / 100 + 1; // ensure actor always has amount of collateral to pledge _ensureCollateralAmount(_actor, collateralToPledge); (uint256 interestRate, ) = _erc20Pool.interestRateInfo(); - try _erc20Pool.drawDebt(_actor, amount_, 7388, collateralToPledge) { + try _erc20Pool.drawDebt( + _actor, + amount_, + 7388, + collateralToPledge + ) { // amount is rounded by pool to token scale amount_ = _roundToScale(amount_, _pool.quoteTokenScale()); @@ -141,7 +168,6 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B increaseInReserves += Maths.wmul( amount_, _borrowFeeRate(interestRate) ); - } catch (bytes memory err) { _ensurePoolError(err); } @@ -152,13 +178,18 @@ abstract contract UnboundedBasicERC20PoolHandler is UnboundedBasicPoolHandler, B ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.repayDebt']++; - (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), _actor); + uint256 borrowerDebt = _getBorrowerInfo(_actor).debt; // ensure actor always has amount of quote to repay _ensureQuoteAmount(_actor, borrowerDebt + 10 * 1e18); - try _erc20Pool.repayDebt(_actor, amountToRepay_, 0, _actor, 7388) { - + try _erc20Pool.repayDebt( + _actor, + amountToRepay_, + 0, + _actor, + 7388 + ) { } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/ERC721Pool/BasicERC721PoolInvariants.t.sol b/tests/forge/invariants/ERC721Pool/BasicERC721PoolInvariants.t.sol index 50c65d9db..659b6bee7 100644 --- a/tests/forge/invariants/ERC721Pool/BasicERC721PoolInvariants.t.sol +++ b/tests/forge/invariants/ERC721Pool/BasicERC721PoolInvariants.t.sol @@ -105,10 +105,10 @@ contract BasicERC721PoolInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - borrowerTokens += _erc721pool.totalBorrowerTokens(borrower); + borrowerTokens += _erc721pool.getBorrowerTokenIds(borrower).length; } - uint256 bucketTokens = _erc721pool.totalBucketTokens(); + uint256 bucketTokens = _erc721pool.getBucketTokenIds().length; require(collateralBalance == borrowerTokens + bucketTokens, "Collateral Invariant CT3"); } @@ -117,7 +117,7 @@ contract BasicERC721PoolInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - uint256 borrowerTokens = _erc721pool.totalBorrowerTokens(borrower); + uint256 borrowerTokens = _erc721pool.getBorrowerTokenIds(borrower).length; (, uint256 borrowerCollateral, ) = _erc721pool.borrowerInfo(borrower); @@ -130,7 +130,7 @@ contract BasicERC721PoolInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - uint256 borrowerTokens = _erc721pool.totalBorrowerTokens(borrower); + uint256 borrowerTokens = _erc721pool.getBorrowerTokenIds(borrower).length; for (uint256 tokenIndex = 0; tokenIndex < borrowerTokens; tokenIndex++) { uint256 borrowerTokenId = _erc721pool.borrowerTokenIds(borrower, tokenIndex); @@ -139,7 +139,7 @@ contract BasicERC721PoolInvariants is BasicInvariants { } } - uint256 bucketTokens = _erc721pool.totalBucketTokens(); + uint256 bucketTokens = _erc721pool.getBucketTokenIds().length; for (uint256 tokenIndex = 0; tokenIndex < bucketTokens; tokenIndex++) { uint256 bucketTokenId = _erc721pool.bucketTokenIds(tokenIndex); @@ -152,7 +152,7 @@ contract BasicERC721PoolInvariants is BasicInvariants { uint256 actorCount = IBaseHandler(_handler).getActorsCount(); for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - uint256 borrowerTokens = _erc721pool.totalBorrowerTokens(borrower); + uint256 borrowerTokens = _erc721pool.getBorrowerTokenIds(borrower).length; for (uint256 tokenIndex = 0; tokenIndex < borrowerTokens; tokenIndex++) { uint256 borrowerTokenId = _erc721pool.borrowerTokenIds(borrower, tokenIndex); @@ -161,7 +161,7 @@ contract BasicERC721PoolInvariants is BasicInvariants { } } - uint256 bucketTokens = _erc721pool.totalBucketTokens(); + uint256 bucketTokens = _erc721pool.getBucketTokenIds().length; for (uint256 tokenIndex = 0; tokenIndex < bucketTokens; tokenIndex++) { uint256 bucketTokenId = _erc721pool.bucketTokenIds(tokenIndex); diff --git a/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol index d207cd2d1..88cf0dd1e 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol @@ -70,7 +70,10 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan numberOfCalls['BBasicHandler.mergeCollateral']++; // Prepare test phase - (uint256 NFTAmount, uint256[] memory bucketIndexes) = _preMergeCollateral(); + ( + uint256 NFTAmount, + uint256[] memory bucketIndexes + ) = _preMergeCollateral(); // Action phase _mergeCollateral(NFTAmount, bucketIndexes); @@ -88,8 +91,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan numberOfCalls['BBasicHandler.pledgeCollateral']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _prePledgeCollateral(amountToPledge_); @@ -106,8 +108,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan numberOfCalls['BBasicHandler.pullCollateral']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _prePullCollateral(amountToPull_); @@ -124,8 +125,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan numberOfCalls['BBasicHandler.drawDebt']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _preDrawDebt(amountToBorrow_); @@ -142,8 +142,7 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan numberOfCalls['BBasicHandler.repayDebt']++; // borrower cannot make any action when in auction - (uint256 kickTime,,,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return; + if (_getAuctionInfo(_actor).kickTime != 0) return; // Prepare test phase uint256 boundedAmount = _preRepayDebt(amountToRepay_); @@ -159,17 +158,22 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan function _preAddCollateral( uint256 amountToAdd_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToAdd_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToAdd_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } function _preRemoveCollateral( uint256 amountToRemove_ ) internal returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToRemove_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToRemove_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); // ensure actor has collateral to remove - (uint256 lpBalanceBefore, ) = _pool.lenderInfo(_lenderBucketIndex, _actor); - if (lpBalanceBefore == 0) _addCollateral(boundedAmount_, _lenderBucketIndex); + if (_getLenderInfo(_lenderBucketIndex, _actor).lpBalance == 0) { + _addCollateral(boundedAmount_, _lenderBucketIndex); + } } function _preMergeCollateral() internal returns(uint256 NFTAmount_, uint256[] memory bucketIndexes_) { @@ -179,12 +183,16 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan uint256 bucketIndex = bucketIndexes_[i]; // Add Quote token in each bucket such that user has enough lps in each bucket to merge collateral - uint256 price = _poolInfo.indexToPrice(bucketIndex); - _addQuoteToken(price, bucketIndex); + _addQuoteToken( + _poolInfo.indexToPrice(bucketIndex), + bucketIndex + ); + + uint256 collateralAmount = _poolInfo.lpToCollateral( + address(_erc721Pool), _getLenderInfo(bucketIndex, _actor).lpBalance, bucketIndex + ); - (uint256 lenderLps, ) = _erc721Pool.lenderInfo(bucketIndex, _actor); - uint256 collateralAmount =_poolInfo.lpToCollateral(address(_erc721Pool), lenderLps, bucketIndex); - NFTAmount_ += collateralAmount; + NFTAmount_ += collateralAmount; } // Round collateral amount @@ -194,23 +202,28 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan function _prePledgeCollateral( uint256 amountToPledge_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToPledge_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToPledge_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } function _prePullCollateral( uint256 amountToPull_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToPull_, 0, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToPull_, 0, MAX_COLLATERAL_AMOUNT + ); } function _preDrawDebt( uint256 amountToBorrow_ ) internal override returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT); + boundedAmount_ = constrictToRange( + amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT + ); // borrower cannot make any action when in auction - (uint256 kickTime, uint256 collateral, uint256 debt,,,) = _poolInfo.auctionStatus(address(_pool), _actor); - if (kickTime != 0) return boundedAmount_; + if (_getAuctionInfo(_actor).kickTime != 0) return boundedAmount_; // Pre Condition // 1. borrower's debt should exceed minDebt @@ -218,7 +231,6 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan // 3. drawDebt should not make borrower under collateralized // 1. borrower's debt should exceed minDebt - (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); (uint256 minDebt, , , ) = _poolInfo.poolUtilizationInfo(address(_pool)); if (boundedAmount_ < minDebt && minDebt < MAX_DEBT_AMOUNT) boundedAmount_ = minDebt + 1; @@ -235,27 +247,33 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan (uint256 currentPoolDebt, , , ) = _pool.debtInfo(); uint256 nextPoolDebt = currentPoolDebt + boundedAmount_; uint256 newLup = _priceAt(_pool.depositIndex(nextPoolDebt)); - (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(_actor); // repay debt if borrower becomes undercollateralized with new debt at new lup - if (!_isCollateralized(debt + boundedAmount_, collateral, newLup, _pool.poolType())) { + if (!_isCollateralized( + borrowerInfo.debt + boundedAmount_, borrowerInfo.collateral, newLup, _pool.poolType()) + ) { _repayDebt(type(uint256).max); - (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); - _pullCollateral(collateral); + borrowerInfo = _getBorrowerInfo(_actor); + _pullCollateral(borrowerInfo.collateral); - require(debt == 0, "borrower has debt"); + require( + borrowerInfo.debt == 0, + "borrower has debt" + ); } } function _preRepayDebt( uint256 amountToRepay_ ) internal returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToRepay_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT); + boundedAmount_ = constrictToRange( + amountToRepay_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT + ); // ensure actor has debt to repay - (uint256 debt, , ) = PoolInfoUtils(_poolInfo).borrowerInfo(address(_pool), _actor); - if (debt == 0) { + if (_getBorrowerInfo(_actor).debt == 0) { boundedAmount_ = _preDrawDebt(boundedAmount_); _drawDebt(boundedAmount_); } diff --git a/tests/forge/invariants/ERC721Pool/handlers/LiquidationERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/LiquidationERC721PoolHandler.sol index 176f2d2c1..dd3467a14 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/LiquidationERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/LiquidationERC721PoolHandler.sol @@ -18,7 +18,9 @@ contract LiquidationERC721PoolHandler is LiquidationPoolHandler, BasicERC721Pool } function _constrictTakeAmount(uint256 amountToTake_) internal view override returns(uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToTake_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT); + boundedAmount_ = constrictToRange( + amountToTake_, MIN_COLLATERAL_AMOUNT, MAX_COLLATERAL_AMOUNT + ); } } \ No newline at end of file diff --git a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol index 2051776b7..574a36007 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol @@ -40,7 +40,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde _setupLendersAndDeposits(LENDERS); _setupBorrowersAndLoans(LOANS_COUNT); - ( , , uint256 totalLoans) = _pool.loansInfo(); + uint256 totalLoans = _getLoansInfo().noOfLoans; require(totalLoans == LOANS_COUNT, "loans setup failed"); vm.warp(block.timestamp + 100_000 days); @@ -54,19 +54,20 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde uint256 borrowerIndex_, uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - borrowerIndex_ = constrictToRange(borrowerIndex_, 0, _activeBorrowers.values().length - 1); + borrowerIndex_ = constrictToRange( + borrowerIndex_, 0, _activeBorrowers.values().length - 1 + ); _actor = _borrowers[borrowerIndex_]; changePrank(_actor); - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor); - if (block.timestamp > kickTime + 72 hours) { + if (block.timestamp > _getAuctionInfo(_actor).kickTime + 72 hours) { numberOfCalls['BPanicExitPoolHandler.settleDebt']++; _settleAuction(_actor, numberOfBuckets); } else { numberOfCalls['BPanicExitPoolHandler.repayLoan']++; _repayDebt(type(uint256).max); } - (, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + uint256 collateral = _getBorrowerInfo(_actor).collateral; _pullCollateral(collateral); _resetSettledAuction(_actor, borrowerIndex_); @@ -96,7 +97,8 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde if (takeAuction_) { vm.warp(block.timestamp + 61 minutes); - ( , uint256 auctionedCollateral, ) = _pool.borrowerInfo(borrower); + uint256 auctionedCollateral = _getBorrowerInfo(borrower).collateral; + _takeAuction(borrower, auctionedCollateral, _actor); _resetSettledAuction(borrower, borrowerIndex_); } @@ -149,20 +151,18 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde ) external useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BPanicExitPoolHandler.withdrawBonds']++; - kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); - address kicker = _lenders[kickerIndex_]; - - (uint256 kickerClaimable, ) = _pool.kickerInfo(kicker); + kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); + address kicker = _lenders[kickerIndex_]; _actor = kicker; changePrank(_actor); - _withdrawBonds(kicker, kickerClaimable); + _withdrawBonds(kicker, _getKickerInfo(kicker).claimableBond); } function settleHeadAuction( uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); + address headAuction = _getAuctionInfo(address(0)).head; if (headAuction != address(0)) { _settleAuction(headAuction, 10); _resetSettledAuction(headAuction, 0); @@ -216,8 +216,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); - if (kickTime == 0) { + if (_getAuctionInfo(borrower_).kickTime == 0) { if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol index 09dd59ffd..daaa1b099 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol @@ -100,17 +100,22 @@ abstract contract BaseERC721PoolHandler is BaseHandler { uint256 kickTimeBefore, uint256 borrowerCollateralBefore, , , uint256 auctionPrice, + , , , ) = _poolInfo.auctionStatus(address(_erc721Pool), borrower_); - try _erc721Pool.repayDebt(borrower_, amount_, 0, borrower_, 7388) { - + try _erc721Pool.repayDebt( + borrower_, + amount_, + 0, + borrower_, + 7388 + ) { _recordSettleBucket( borrower_, borrowerCollateralBefore, kickTimeBefore, auctionPrice ); - } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/ERC721Pool/handlers/unbounded/UnboundedBasicERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/unbounded/UnboundedBasicERC721PoolHandler.sol index b3e2d4719..56a6ad876 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/unbounded/UnboundedBasicERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/unbounded/UnboundedBasicERC721PoolHandler.sol @@ -13,7 +13,8 @@ import { _indexOf, _roundToScale, MIN_PRICE, - MAX_PRICE + MAX_PRICE, + COLLATERALIZATION_FACTOR } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; @@ -39,7 +40,7 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.addCollateral']++; - (uint256 lpBalanceBeforeAction, ) = _erc721Pool.lenderInfo(bucketIndex_, _actor); + uint256 lpBalanceBeforeAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; _ensureCollateralAmount(_actor, amount_); uint256[] memory tokenIds = new uint256[](amount_); @@ -47,15 +48,22 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, tokenIds[i] = _collateral.tokenOfOwnerByIndex(_actor, i); } - try _erc721Pool.addCollateral(tokenIds, bucketIndex_, block.timestamp + 1 minutes) { + try _erc721Pool.addCollateral( + tokenIds, + bucketIndex_, + block.timestamp + 1 minutes + ) { // **B5**: when adding collateral: lender deposit time = timestamp of block when deposit happened lenderDepositTime[_actor][bucketIndex_] = block.timestamp; // **R5**: Exchange rates are unchanged by adding collateral token into a bucket exchangeRateShouldNotChange[bucketIndex_] = true; // Post action condition - (uint256 lpBalanceAfterAction, ) = _erc721Pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction > lpBalanceBeforeAction, "LP balance should increase"); + uint256 lpBalanceAfterAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + require( + lpBalanceAfterAction > lpBalanceBeforeAction, + "LP balance should increase" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -67,17 +75,21 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.removeCollateral']++; - (uint256 lpBalanceBeforeAction, ) = _erc721Pool.lenderInfo(bucketIndex_, _actor); - - try _erc721Pool.removeCollateral(amount_, bucketIndex_) { + uint256 lpBalanceBeforeAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + try _erc721Pool.removeCollateral( + amount_, + bucketIndex_ + ) { // **R6**: Exchange rates are unchanged by removing collateral token from a bucket exchangeRateShouldNotChange[bucketIndex_] = true; // Post action condition - (uint256 lpBalanceAfterAction, ) = _erc721Pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction < lpBalanceBeforeAction, "LP balance should decrease"); - + uint256 lpBalanceAfterAction = _getLenderInfo(bucketIndex_, _actor).lpBalance; + require( + lpBalanceAfterAction < lpBalanceBeforeAction, + "LP balance should decrease" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -89,14 +101,16 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.mergeCollateral']++; - try _erc721Pool.mergeOrRemoveCollateral(bucketIndexes_, amount_, 7388) { - + try _erc721Pool.mergeOrRemoveCollateral( + bucketIndexes_, + amount_, + 7388 + ) { for(uint256 i; i < bucketIndexes_.length; i++) { uint256 bucketIndex = bucketIndexes_[i]; // **R6**: Exchange rates are unchanged by removing collateral token from a bucket exchangeRateShouldNotChange[bucketIndex] = true; } - } catch (bytes memory err) { _ensurePoolError(err); } @@ -111,8 +125,8 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.pledgeCollateral']++; - (, uint256 borrowerCollateralBefore, ) = _pool.borrowerInfo(_actor); - (uint256 kickTimeBefore, , , , uint256 auctionPrice, ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); + uint256 borrowerCollateralBefore = _getBorrowerInfo(_actor).collateral; + (uint256 kickTimeBefore, , , , uint256 auctionPrice, , , , ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); // **R1**: Exchange rates are unchanged by pledging collateral for (uint256 bucketIndex = LENDER_MIN_BUCKET_INDEX; bucketIndex <= LENDER_MAX_BUCKET_INDEX; bucketIndex++) { @@ -125,15 +139,18 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, tokenIds[i] = _collateral.tokenOfOwnerByIndex(_actor, i); } - try _erc721Pool.drawDebt(_actor, 0, 0, tokenIds) { - + try _erc721Pool.drawDebt( + _actor, + 0, + 0, + tokenIds + ) { _recordSettleBucket( _actor, borrowerCollateralBefore, kickTimeBefore, auctionPrice ); - } catch (bytes memory err) { _ensurePoolError(err); } @@ -149,8 +166,13 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, exchangeRateShouldNotChange[bucketIndex] = true; } - try _erc721Pool.repayDebt(_actor, 0, amount_, _actor, 7388) { - + try _erc721Pool.repayDebt( + _actor, + 0, + amount_, + _actor, + 7388 + ) { } catch (bytes memory err) { _ensurePoolError(err); } @@ -174,7 +196,10 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, if (bucket > LENDER_MAX_BUCKET_INDEX) return; // calculates collateral required to borrow quote tokens, added 1 for roundup such that 0.8 NFT will become 1 - uint256 collateralToPledge = Maths.wdiv(amount_, price) / 1e18 + 1; + uint256 collateralToPledge = Maths.wdiv( + Maths.wmul(COLLATERALIZATION_FACTOR, amount_), + price + ) / 1e18 + 1; _ensureCollateralAmount(_actor, collateralToPledge); uint256[] memory tokenIds = new uint256[](collateralToPledge); @@ -184,10 +209,15 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, (uint256 interestRate, ) = _erc721Pool.interestRateInfo(); - (, uint256 borrowerCollateralBefore, ) = _pool.borrowerInfo(_actor); - (uint256 kickTimeBefore, , , , uint256 auctionPrice, ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); + uint256 borrowerCollateralBefore = _getBorrowerInfo(_actor).collateral; + (uint256 kickTimeBefore, , , , uint256 auctionPrice, , , , ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); - try _erc721Pool.drawDebt(_actor, amount_, 7388, tokenIds) { + try _erc721Pool.drawDebt( + _actor, + amount_, + 7388, + tokenIds + ) { // amount is rounded by pool to token scale amount_ = _roundToScale(amount_, _pool.quoteTokenScale()); @@ -202,7 +232,6 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, kickTimeBefore, auctionPrice ); - } catch (bytes memory err) { _ensurePoolError(err); } @@ -213,21 +242,25 @@ abstract contract UnboundedBasicERC721PoolHandler is UnboundedBasicPoolHandler, ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.repayDebt']++; - (uint256 borrowerDebt, uint256 borrowerCollateralBefore, ) = _poolInfo.borrowerInfo(address(_pool), _actor); - (uint256 kickTimeBefore, , , , uint256 auctionPrice, ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); + BorrowerInfo memory borrowerInfoBeforeAction = _getBorrowerInfo(_actor); + (uint256 kickTimeBefore, , , , uint256 auctionPrice, , , , ) =_poolInfo.auctionStatus(address(_erc721Pool), _actor); // ensure actor always has amount of quote to repay - _ensureQuoteAmount(_actor, borrowerDebt + 10 * 1e18); - - try _erc721Pool.repayDebt(_actor, amountToRepay_, 0, _actor, 7388) { - + _ensureQuoteAmount(_actor, borrowerInfoBeforeAction.debt + 10 * 1e18); + + try _erc721Pool.repayDebt( + _actor, + amountToRepay_, + 0, + _actor, + 7388 + ) { _recordSettleBucket( _actor, - borrowerCollateralBefore, + borrowerInfoBeforeAction.collateral, kickTimeBefore, auctionPrice ); - } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol b/tests/forge/invariants/PositionManager/ERC20PoolPositionsInvariants.t.sol similarity index 96% rename from tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol rename to tests/forge/invariants/PositionManager/ERC20PoolPositionsInvariants.t.sol index d2913169a..71410be55 100644 --- a/tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol +++ b/tests/forge/invariants/PositionManager/ERC20PoolPositionsInvariants.t.sol @@ -15,7 +15,7 @@ import { PositionManager } from 'src/PositionManager.sol'; import { Maths } from 'src/libraries/internal/Maths.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; -import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; +import { IPositionsHandler } from '../interfaces/IPositionsHandler.sol'; import { TokenWithNDecimals } from '../../utils/Tokens.sol'; import { ERC20PoolPositionHandler } from './handlers/ERC20PoolPositionHandler.sol'; diff --git a/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol b/tests/forge/invariants/PositionManager/ERC721PoolPositionsInvariants.t.sol similarity index 100% rename from tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol rename to tests/forge/invariants/PositionManager/ERC721PoolPositionsInvariants.t.sol diff --git a/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol b/tests/forge/invariants/PositionManager/PositionsInvariants.sol similarity index 93% rename from tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol rename to tests/forge/invariants/PositionManager/PositionsInvariants.sol index 4a3b6783d..7705eebda 100644 --- a/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol +++ b/tests/forge/invariants/PositionManager/PositionsInvariants.sol @@ -13,7 +13,7 @@ import { PositionManager } from 'src/PositionManager.sol'; import { Maths } from 'src/libraries/internal/Maths.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; -import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; +import { IPositionsHandler } from '../interfaces/IPositionsHandler.sol'; import { BaseInvariants } from '../base/BaseInvariants.sol'; import { TokenWithNDecimals } from '../../utils/Tokens.sol'; @@ -32,7 +32,7 @@ abstract contract PositionsInvariants is BaseInvariants { for (uint256 poolIndex = 0; poolIndex < _pools.length; poolIndex++) { address pool = _pools[poolIndex]; - uint256[] memory bucketIndexes = IPositionsAndRewardsHandler(_handler).getBucketIndexesWithPosition(pool); + uint256[] memory bucketIndexes = IPositionsHandler(_handler).getBucketIndexesWithPosition(pool); // loop over bucket indexes with positions for (uint256 i = 0; i < bucketIndexes.length; i++) { @@ -45,7 +45,7 @@ abstract contract PositionsInvariants is BaseInvariants { poolLpAccum += poolLp; // loop over tokenIds in bucket indexes - uint256[] memory tokenIds = IPositionsAndRewardsHandler(_handler).getTokenIdsByBucketIndex(pool, bucketIndex); + uint256[] memory tokenIds = IPositionsHandler(_handler).getTokenIdsByBucketIndex(pool, bucketIndex); for (uint256 k = 0; k < tokenIds.length; k++) { uint256 tokenId = tokenIds[k]; diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionPoolHandler.sol b/tests/forge/invariants/PositionManager/handlers/BasePositionPoolHandler.sol similarity index 77% rename from tests/forge/invariants/PositionsAndRewards/handlers/BasePositionPoolHandler.sol rename to tests/forge/invariants/PositionManager/handlers/BasePositionPoolHandler.sol index b9f3c10f4..116445f8a 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionPoolHandler.sol +++ b/tests/forge/invariants/PositionManager/handlers/BasePositionPoolHandler.sol @@ -29,23 +29,32 @@ abstract contract BasePositionPoolHandler is UnboundedPositionPoolHandler { uint256 bucketIndex = indexes_[i]; // ensure actor has a position - (uint256 lpBalanceBefore,) = _pool.lenderInfo(bucketIndex, _actor); - // add quote token if they don't have a position - if (lpBalanceBefore == 0) { + if (_getLenderInfo(bucketIndex, _actor).lpBalance == 0) { // bound amount - uint256 boundedAmount = constrictToRange(amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT); + uint256 boundedAmount = constrictToRange( + amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT + ); _ensureQuoteAmount(_actor, boundedAmount); - try _pool.addQuoteToken(boundedAmount, bucketIndex, block.timestamp + 1 minutes, false) { + + try _pool.addQuoteToken( + boundedAmount, + bucketIndex, + block.timestamp + 1 minutes + ) { } catch (bytes memory err) { _ensurePoolError(err); } } - (lpBalances[i], ) = _pool.lenderInfo(bucketIndex, _actor); + lpBalances[i] = _getLenderInfo(bucketIndex, _actor).lpBalance; } - _pool.increaseLPAllowance(address(_positionManager), indexes_, lpBalances); + _pool.increaseLPAllowance( + address(_positionManager), + indexes_, + lpBalances + ); // mint position NFT tokenId_ = _mint(); @@ -118,14 +127,19 @@ abstract contract BasePositionPoolHandler is UnboundedPositionPoolHandler { uint256 amountToAdd_ ) internal returns (uint256[] memory indexes_) { // ensure actor has a position - (uint256 lpBalanceBefore,) = _pool.lenderInfo(bucketIndex_, _actor); - // add quote token if they don't have a position - if (lpBalanceBefore == 0) { + if (_getLenderInfo(bucketIndex_, _actor).lpBalance == 0) { // bound amount - uint256 boundedAmount = constrictToRange(amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT); + uint256 boundedAmount = constrictToRange( + amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT + ); _ensureQuoteAmount(_actor, boundedAmount); - try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes, false) { + + try _pool.addQuoteToken( + boundedAmount, + bucketIndex_, + block.timestamp + 1 minutes + ) { } catch (bytes memory err) { _ensurePoolError(err); } @@ -136,11 +150,19 @@ abstract contract BasePositionPoolHandler is UnboundedPositionPoolHandler { uint256[] memory lpBalances = new uint256[](1); - (lpBalances[0], ) = _pool.lenderInfo(bucketIndex_, _actor); - _pool.increaseLPAllowance(address(_positionManager), indexes_, lpBalances); + lpBalances[0] = _getLenderInfo(bucketIndex_, _actor).lpBalance; + + _pool.increaseLPAllowance( + address(_positionManager), + indexes_, + lpBalances + ); } - function getRandomElements(uint256 noOfElements, uint256[] memory arr) internal returns (uint256[] memory randomBuckets_) { + function getRandomElements( + uint256 noOfElements, + uint256[] memory arr + ) internal returns (uint256[] memory randomBuckets_) { randomBuckets_ = new uint256[](noOfElements); for (uint256 i = 0; i < noOfElements; i++) { diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol b/tests/forge/invariants/PositionManager/handlers/ERC20PoolPositionHandler.sol similarity index 66% rename from tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol rename to tests/forge/invariants/PositionManager/handlers/ERC20PoolPositionHandler.sol index b1ab9eda6..7e39fc6d7 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol +++ b/tests/forge/invariants/PositionManager/handlers/ERC20PoolPositionHandler.sol @@ -2,10 +2,8 @@ pragma solidity 0.8.18; -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; import { PositionManager } from 'src/PositionManager.sol'; import { Pool } from 'src/base/Pool.sol'; import { ERC20Pool } from 'src/ERC20Pool.sol'; @@ -13,20 +11,19 @@ import { Maths } from 'src/libraries/internal/Maths.sol'; import { TokenWithNDecimals } from '../../../utils/Tokens.sol'; -import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; -import { UnboundedBasicERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol'; -import { BaseRewardsPoolHandler } from './BaseRewardsPoolHandler.sol'; +import { PositionPoolHandler } from './PositionPoolHandler.sol'; +import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; +import { UnboundedBasicPoolHandler } from '../../base/handlers/unbounded/UnboundedBasicPoolHandler.sol'; +import { UnboundedBasicERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/UnboundedBasicERC20PoolHandler.sol'; import { UnboundedLiquidationPoolHandler } from '../../base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol'; -import { UnboundedReservePoolHandler } from '../../base/handlers/unbounded/UnboundedReservePoolHandler.sol'; - -contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandler, UnboundedLiquidationPoolHandler, UnboundedReservePoolHandler, BaseRewardsPoolHandler { +contract ERC20PoolPositionHandler is PositionPoolHandler, BaseERC20PoolHandler, UnboundedBasicERC20PoolHandler, UnboundedLiquidationPoolHandler { using EnumerableSet for EnumerableSet.UintSet; address[] internal _lenders; address[] internal _borrowers; - uint16 internal constant LENDERS = 200; + uint16 internal constant LENDERS = 200; uint16 internal constant LOANS_COUNT = 500; uint16 nonce; uint256 numberOfBuckets; @@ -34,7 +31,6 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl EnumerableSet.UintSet internal _activeBorrowers; constructor( - address rewards_, address positions_, address[] memory pools_, address ajna_, @@ -48,10 +44,7 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl } // Position manager - _positionManager = PositionManager(positions_); - - // Rewards manager - _rewardsManager = RewardsManager(rewards_); + _positionManager = PositionManager(positions_); // pool hash for mint() call _poolHash = bytes32(keccak256("ERC20_NON_SUBSET_HASH")); @@ -66,12 +59,27 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl _setupLendersAndDeposits(LENDERS); _setupBorrowersAndLoans(LOANS_COUNT); - ( , , uint256 totalLoans) = _pool.loansInfo(); + uint256 totalLoans = _getLoansInfo().noOfLoans; require(totalLoans == LOANS_COUNT, "loans setup failed"); vm.warp(block.timestamp + 1_000 days); } + modifier useRandomPool(uint256 poolIndex) override { + poolIndex = bound(poolIndex, 0, _pools.length - 1); + updateTokenAndPoolAddress(_pools[poolIndex]); + + _; + } + + function updateTokenAndPoolAddress(address pool_) internal override { + _pool = Pool(pool_); + _erc20Pool = ERC20Pool(pool_); + + _quote = TokenWithNDecimals(_pool.quoteTokenAddress()); + _collateral = TokenWithNDecimals(_pool.collateralAddress()); + } + function lenderKickAuction( uint256 kickerIndex_, uint256 bucketIndex_, @@ -102,51 +110,6 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl _moveQuoteToken(boundedAmount, _lenderBucketIndex, toBucketIndex_); } - function stake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BPriceFall.stake']++; - // Pre action - (uint256 tokenId, ) = _preStake(_lenderBucketIndex, amountToAdd_); - - // Action phase - _stake(tokenId); - } - - function moveStakedLiquidity( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_, - uint256 numberOfEpochs_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BRewardsHandler.unstake']++; - // Pre action - (uint256 tokenId, uint256[] memory indexes) = _preUnstake( - _lenderBucketIndex, - amountToAdd_, - numberOfEpochs_ - ); - - // if rewards exceed contract balance tx will revert, return - uint256 reward = _rewardsManager.calculateRewards(tokenId, _pool.currentBurnEpoch()); - if (reward > _ajna.balanceOf(address(_rewardsManager))) return; - - // Action phase - _unstake(tokenId); - - // Move liquidity to lower index - uint256 toIndex_ = constrictToRange(_randomBucket(), indexes[0], 7388); - _moveLiquidity(tokenId, indexes[0], toIndex_); - - // re-stake Token - _positionManager.approve(address(_rewardsManager), tokenId); - _stake(tokenId); - } - function takeOrSettleAuction( uint256 borrowerIndex_, uint256 takerIndex_, @@ -154,7 +117,7 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl ) external useTimestamps useRandomActor(takerIndex_) skipTime(skippedTime_) writeLogs { address borrower = _borrowers[constrictToRange(borrowerIndex_, 0, _borrowers.length - 1)]; - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); // Kick borrower if not already kicked if (kickTime == 0) { @@ -249,29 +212,4 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl ) % 900 + 100; ++ nonce; } - - /*******************************/ - /*** Helper Functions ***/ - /*******************************/ - - function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); - if (kickTime == 0) { - if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); - } - } - - - function _advanceEpochRewardStakers( - uint256 amountToAdd_, - uint256[] memory indexes_, - uint256 numberOfEpochs_ - ) internal override {} - - modifier useRandomPool(uint256 poolIndex) override { - _; - } - - function updateTokenAndPoolAddress(address pool_) internal override {} - } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionManager/handlers/ERC721PoolPositionHandler.sol similarity index 100% rename from tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol rename to tests/forge/invariants/PositionManager/handlers/ERC721PoolPositionHandler.sol diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol b/tests/forge/invariants/PositionManager/handlers/PositionPoolHandler.sol similarity index 97% rename from tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol rename to tests/forge/invariants/PositionManager/handlers/PositionPoolHandler.sol index 1d7232e42..9990e917f 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol +++ b/tests/forge/invariants/PositionManager/handlers/PositionPoolHandler.sol @@ -20,6 +20,7 @@ abstract contract PositionPoolHandler is BasePositionPoolHandler { uint256 skippedTime_ ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) useRandomPool(skippedTime_) writeLogs writePositionLogs { numberOfCalls['BPositionHandler.memorialize']++; + // Pre action // (uint256 tokenId, uint256[] memory indexes) = _preMemorializePositions(noOfBuckets_, amountToAdd_); @@ -34,6 +35,7 @@ abstract contract PositionPoolHandler is BasePositionPoolHandler { uint256 skippedTime_ ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) useRandomPool(skippedTime_) writeLogs writePositionLogs { numberOfCalls['BPositionHandler.redeem']++; + // Pre action // (uint256 tokenId, uint256[] memory indexes) = _preRedeemPositions(noOfBuckets_, amountToAdd_); @@ -60,7 +62,8 @@ abstract contract PositionPoolHandler is BasePositionPoolHandler { uint256 skippedTime_, uint256 amountToAdd_ ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) useRandomPool(skippedTime_) writeLogs writePositionLogs { - numberOfCalls['BPositionHandler.burn']++; + numberOfCalls['BPositionHandler.burn']++; + // Pre action // (uint256 tokenId_) = _preBurn(_lenderBucketIndex, amountToAdd_); @@ -74,7 +77,8 @@ abstract contract PositionPoolHandler is BasePositionPoolHandler { uint256 amountToMove_, uint256 toIndex_ ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) useRandomPool(skippedTime_) writeLogs writePositionLogs { - numberOfCalls['BPositionHandler.moveLiquidity']++; + numberOfCalls['BPositionHandler.moveLiquidity']++; + // Pre action // ( uint256 tokenId, @@ -107,7 +111,8 @@ abstract contract PositionPoolHandler is BasePositionPoolHandler { uint256 skippedTime_, uint256 amountToAdd_ ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs { - numberOfCalls['BPositionHandler.transferPosition']++; + numberOfCalls['BPositionHandler.transferPosition']++; + // Pre action // (uint256 tokenId_, uint256[] memory indexes) = _getNFTPosition(_lenderBucketIndex, amountToAdd_); diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedBasePositionHandler.sol similarity index 83% rename from tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol rename to tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedBasePositionHandler.sol index 63dbf4c5c..7f5b71968 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol +++ b/tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -6,7 +6,6 @@ import '@std/Test.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; /** * @dev this contract manages multiple lenders @@ -16,31 +15,22 @@ import { RewardsManager } from 'src/RewardsManager.sol'; abstract contract UnboundedBasePositionHandler is Test { PositionManager internal _positionManager; - RewardsManager internal _rewardsManager; bytes32 internal _poolHash; - uint256 MAX_AJNA_AMOUNT = vm.envOr("MAX_AJNA_AMOUNT_ERC20", uint256(100_000_000 * 1e18)); - address[] internal _pools; - // positionManager & rewardsManager + // positionManager mapping(address => EnumerableSet.UintSet) internal bucketIndexesWithPosition; mapping(uint256 => EnumerableSet.UintSet) internal bucketIndexesByTokenId; - - // positionManager mapping(address => mapping(uint256 => EnumerableSet.UintSet)) internal tokenIdsByBucketIndex; mapping(address => EnumerableSet.UintSet) internal tokenIdsByActor; + // used to track changes in `_redeemPositions()` and `_memorializePositions()` mapping(address => mapping(uint256 => uint256)) internal actorLpsBefore; mapping(address => mapping(uint256 => uint256)) internal posManLpsBefore; mapping(address => mapping(uint256 => uint256)) internal bucketIndexToDepositTime; - // rewardsManager - mapping(address => EnumerableSet.UintSet) internal stakedTokenIdsByActor; - mapping(address => mapping(uint256 => uint256)) public rewardsClaimedPerEpoch; // staking rewards per epoch - mapping(address => mapping(uint256 => uint256)) public updateRewardsClaimedPerEpoch; // updating rewards per epoch - uint256 internal counter = 1; using EnumerableSet for EnumerableSet.UintSet; @@ -61,10 +51,6 @@ abstract contract UnboundedBasePositionHandler is Test { return tokenIdsByActor[actor_].values(); } - function getStakedTokenIdsByActor(address actor_) public view returns(uint256[] memory) { - return stakedTokenIdsByActor[actor_].values(); - } - function randomSeed() internal returns (uint256) { counter++; return uint256(keccak256(abi.encodePacked(block.number, block.prevrandao, counter))); @@ -90,7 +76,8 @@ abstract contract UnboundedBasePositionHandler is Test { err == keccak256(abi.encodeWithSignature("InvalidIndex()")) || err == keccak256(abi.encodeWithSignature("LUPBelowHTP()")) || err == keccak256(abi.encodeWithSignature("InsufficientLP()")) || - err == keccak256(abi.encodeWithSignature("AuctionNotCleared()")), + err == keccak256(abi.encodeWithSignature("AuctionNotCleared()")) || + err == keccak256(abi.encodeWithSignature("AddAboveAuctionPrice()")), "Unexpected revert error" ); } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol b/tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedPositionPoolHandler.sol similarity index 61% rename from tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol rename to tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedPositionPoolHandler.sol index 59df71bb8..68a50d684 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol +++ b/tests/forge/invariants/PositionManager/handlers/unbounded/UnboundedPositionPoolHandler.sol @@ -42,18 +42,22 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, for(uint256 i = 0; i < indexes_.length; i++) { // store vals pre action to check after memorializing: - (uint256 poolPreActionActorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); - (uint256 poolPreActionPosManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + LenderInfo memory lenderInfoBeforeAction = _getLenderInfo(indexes_[i], address(_actor)); + LenderInfo memory positionManagerInfoBeforeAction = _getLenderInfo(indexes_[i], address(_positionManager)); - actorLpsBefore[address(_pool)][indexes_[i]] = poolPreActionActorLps; - posManLpsBefore[address(_pool)][indexes_[i]] = poolPreActionPosManLps; + actorLpsBefore[address(_pool)][indexes_[i]] = lenderInfoBeforeAction.lpBalance; + posManLpsBefore[address(_pool)][indexes_[i]] = positionManagerInfoBeforeAction.lpBalance; // positionManager is assigned the most recent depositTime - bucketIndexToDepositTime[address(_pool)][indexes_[i]] = (actorDepositTime >= posManDepositTime) ? actorDepositTime : posManDepositTime; + bucketIndexToDepositTime[address(_pool)][indexes_[i]] = (lenderInfoBeforeAction.depositTime >= positionManagerInfoBeforeAction.depositTime) ? + lenderInfoBeforeAction.depositTime : positionManagerInfoBeforeAction.depositTime; } - try _positionManager.memorializePositions(address(_pool), tokenId_, indexes_) { - + try _positionManager.memorializePositions( + address(_pool), + tokenId_, + indexes_ + ) { // track created positions for ( uint256 i = 0; i < indexes_.length; i++) { uint256 bucketIndex = indexes_[i]; @@ -64,19 +68,28 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, // info used to tearDown buckets bucketIndexesByTokenId[tokenId_].add(bucketIndex); - (uint256 poolLps, uint256 poolDepositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + LenderInfo memory positionManagerInfoBeforeAction = _getLenderInfo(indexes_[i], address(_positionManager)); - require(poolDepositTime == bucketIndexToDepositTime[address(_pool)][bucketIndex], - "PM7: positionManager depositTime does not match most recent depositTime"); + require( + positionManagerInfoBeforeAction.depositTime == bucketIndexToDepositTime[address(_pool)][bucketIndex], + "PM7: positionManager depositTime does not match most recent depositTime" + ); // assert that the LP that now exists in the pool contract matches the amount added by the actor - require(poolLps == actorLpsBefore[address(_pool)][bucketIndex] + posManLpsBefore[address(_pool)][bucketIndex], - "PM7: pool contract lps do not match amount added by actor"); + require( + positionManagerInfoBeforeAction.lpBalance == actorLpsBefore[address(_pool)][bucketIndex] + posManLpsBefore[address(_pool)][bucketIndex], + "PM7: pool contract lps do not match amount added by actor" + ); // assert that the positionManager LP balance of the actor has increased - (uint256 posLps,) = _positionManager.getPositionInfo(tokenId_, bucketIndex); - require(posLps == actorLpsBefore[address(_pool)][bucketIndex], - "PM7: positionManager lps do not match amount added by actor"); + ( + uint256 posLps, + ) = _positionManager.getPositionInfo(tokenId_, bucketIndex); + + require( + posLps == actorLpsBefore[address(_pool)][bucketIndex], + "PM7: positionManager lps do not match amount added by actor" + ); delete actorLpsBefore[address(_pool)][bucketIndex]; delete posManLpsBefore[address(_pool)][bucketIndex]; @@ -85,7 +98,6 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, // info used track actors positions tokenIdsByActor[address(_actor)].add(tokenId_); - } catch (bytes memory err) { // cleanup buckets so they don't interfere with future calls @@ -103,22 +115,33 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, function _mint() internal returns (uint256 tokenIdResult) { numberOfCalls['UBPositionHandler.mint']++; - try _positionManager.mint(address(_pool), _actor, _poolHash) returns (uint256 tokenId) { - + try _positionManager.mint( + address(_pool), + _actor, + _poolHash + ) returns (uint256 tokenId) { tokenIdResult = tokenId; // Post Action Checks // // assert that the minter is the owner - require(_positionManager.ownerOf(tokenId) == _actor, "PM4: minter is not owner"); + require( + _positionManager.ownerOf(tokenId) == _actor, + "PM4: minter is not owner" + ); // assert that poolKey is returns correct pool address address poolAddress = _positionManager.poolKey(tokenId); - require(poolAddress == address(_pool), "PM4: poolKey does not match pool address"); + require( + poolAddress == address(_pool), + "PM4: poolKey does not match pool address" + ); // assert that no positions are associated with this tokenId uint256[] memory posIndexes = _positionManager.getPositionIndexes(tokenId); - require(posIndexes.length == 0, "PM4: positions are associated with tokenId"); - + require( + posIndexes.length == 0, + "PM4: positions are associated with tokenId" + ); } catch (bytes memory err) { _ensurePositionsManagerError(err); } @@ -134,17 +157,15 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, uint256 totalPositionIndexes = _positionManager.getPositionIndexes(tokenId_).length; for (uint256 i = 0; i < indexes_.length; i++) { - - (uint256 poolPreActionActorLps,) = _pool.lenderInfo(indexes_[i], preActionOwner); - (uint256 poolPreActionPosManLps,) = _pool.lenderInfo(indexes_[i], address(_positionManager)); - // store vals in mappings to check lps - actorLpsBefore[address(_pool)][indexes_[i]] = poolPreActionActorLps; - posManLpsBefore[address(_pool)][indexes_[i]] = poolPreActionPosManLps; + actorLpsBefore[address(_pool)][indexes_[i]] = _getLenderInfo(indexes_[i], preActionOwner).lpBalance; + posManLpsBefore[address(_pool)][indexes_[i]] = _getLenderInfo(indexes_[i], address(_positionManager)).lpBalance; } - try _positionManager.redeemPositions(address(_pool), tokenId_, indexes_) { - + try _positionManager.redeemPositions( + address(_pool), + tokenId_, + indexes_) { // remove tracked positions for ( uint256 i = 0; i < indexes_.length; i++) { uint256 bucketIndex = indexes_[i]; @@ -153,27 +174,40 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, // if no other positions exist for this bucketIndex, remove from bucketIndexesWithPosition if (getTokenIdsByBucketIndex(address(_pool), bucketIndex).length == 0) { - bucketIndexesWithPosition[address(_pool)].remove(bucketIndex); } - (uint256 poolActorLps,) = _pool.lenderInfo(bucketIndex, preActionOwner); - (uint256 poolPosLps,) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + uint256 poolActorLps = _getLenderInfo(bucketIndex, preActionOwner).lpBalance; + uint256 poolPosLps = _getLenderInfo(bucketIndex, address(_positionManager)).lpBalance; // assert PositionsMan LP in pool matches the amount redeemed by actor // positionMan has now == positionMan pre - actor's LP change - require(poolPosLps == posManLpsBefore[address(_pool)][bucketIndex] - (poolActorLps - actorLpsBefore[address(_pool)][bucketIndex]), - "PM8: positionManager's pool contract lps do not match amount redeemed by actor"); + require( + poolPosLps == posManLpsBefore[address(_pool)][bucketIndex] - (poolActorLps - actorLpsBefore[address(_pool)][bucketIndex]), + "PM8: positionManager's pool contract lps do not match amount redeemed by actor" + ); // assert actor LP in pool matches amount removed from the posMan's position // assert actor LP in pool = what actor LP had pre + what LP positionManager redeemed to actor - require(poolActorLps == actorLpsBefore[address(_pool)][bucketIndex] + (posManLpsBefore[address(_pool)][bucketIndex] - poolPosLps), - "PM8: actor's pool contract lps do not match amount redeemed by actor"); + require( + poolActorLps == actorLpsBefore[address(_pool)][bucketIndex] + (posManLpsBefore[address(_pool)][bucketIndex] - poolPosLps), + "PM8: actor's pool contract lps do not match amount redeemed by actor" + ); // assert that the underlying LP balance in PositionManager is zero - (uint256 posLps, uint256 posDepositTime) = _positionManager.getPositionInfo(tokenId_, bucketIndex); - require(posLps == 0, "PM8: tokenId has lps after redemption"); - require(posDepositTime == 0, "PM8: tokenId has depositTime after redemption"); + ( + uint256 posLps, + uint256 posDepositTime + ) = _positionManager.getPositionInfo(tokenId_, bucketIndex); + + require( + posLps == 0, + "PM8: tokenId has lps after redemption" + ); + require( + posDepositTime == 0, + "PM8: tokenId has depositTime after redemption" + ); // delete mappings for reuse delete actorLpsBefore[address(_pool)][bucketIndex]; @@ -183,27 +217,31 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, } // assert that the minter is still the owner - require(_positionManager.ownerOf(tokenId_) == preActionOwner, - 'PM8: previous owner is no longer owner on redemption'); + require( + _positionManager.ownerOf(tokenId_) == preActionOwner, + 'PM8: previous owner is no longer owner on redemption' + ); // assert that poolKey address matches pool address - require(_positionManager.poolKey(tokenId_) == address(_pool), - 'PM8: poolKey has changed on redemption'); + require( + _positionManager.poolKey(tokenId_) == address(_pool), + 'PM8: poolKey has changed on redemption' + ); // if all positions are redeemed if (totalPositionIndexes == indexes_.length) { - // assert that no positions are associated with this tokenId uint256[] memory posIndexes = _positionManager.getPositionIndexes(tokenId_); - require(posIndexes.length == 0, 'PM8: positions still exist after redemption'); + require( + posIndexes.length == 0, + "PM8: positions still exist after redemption" + ); // info for tear down delete bucketIndexesByTokenId[tokenId_]; tokenIdsByActor[address(_actor)].remove(tokenId_); } - } catch (bytes memory err) { - for ( uint256 i = 0; i < indexes_.length; i++) { uint256 bucketIndex = indexes_[i]; // delete mappings for reuse @@ -220,20 +258,14 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, uint256 index ) internal view returns (uint256 quoteAtIndex_) { // retrieve info of bucket from pool - ( - uint256 bucketLP, - uint256 bucketCollateral, - , - uint256 bucketDeposit, - ) = _pool.bucketInfo(index); + BucketInfo memory bucketInfo = _getBucketInfo(index); // calculate the max amount of quote tokens that can be moved, given the tracked LP quoteAtIndex_ = _lpToQuoteToken( - bucketLP, - bucketCollateral, - bucketDeposit, + bucketInfo.lpBalance, + bucketInfo.collateral, + bucketInfo.deposit, lp, - bucketDeposit, _priceAt(index) ); } @@ -256,12 +288,13 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, (uint256 preActionToLps,) = _positionManager.getPositionInfo(tokenId_, toIndex_); uint256 preActionToIndexQuote = _getQuoteAtIndex(preActionToLps, toIndex_); - /** - * @notice Struct holding parameters for moving the liquidity of a position. - */ - - try _positionManager.moveLiquidity(address(_pool), tokenId_, fromIndex_, toIndex_, block.timestamp + 30, false) { - + try _positionManager.moveLiquidity( + address(_pool), + tokenId_, + fromIndex_, + toIndex_, + block.timestamp + 30 + ) { bucketIndexesByTokenId[tokenId_].add(toIndex_); bucketIndexesByTokenId[tokenId_].remove(fromIndex_); @@ -279,15 +312,35 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, tokenIdsByBucketIndex[address(_pool)][toIndex_].add(tokenId_); // assert that fromIndex LP and deposit time are both zero - (uint256 fromLps, uint256 fromDepositTime) = _positionManager.getPositionInfo(tokenId_, fromIndex_); - require(fromLps == 0, "PM6: from bucket still has LPs after move"); - require(fromDepositTime == 0, "PM6: from bucket still has deposit time after move"); + ( + uint256 fromLps, + uint256 fromDepositTime + ) = _positionManager.getPositionInfo(tokenId_, fromIndex_); + + require( + fromLps == 0, + "PM6: from bucket still has LPs after move" + ); + require( + fromDepositTime == 0, + "PM6: from bucket still has deposit time after move" + ); // assert that toIndex LP is increased and deposit time matches positionManagers depositTime pre action - (uint256 toLps, uint256 toDepositTime) = _positionManager.getPositionInfo(tokenId_, toIndex_); - (,uint256 postActionDepositTime)= _pool.lenderInfo(toIndex_, address(_positionManager)); - require(toLps >= preActionToLps, "PM6: to bucket lps have not increased"); // difficult to estimate LPS, assert that it is greater than - require(toDepositTime == postActionDepositTime, "PM6: to bucket deposit time does not match positionManager"); + uint256 postActionDepositTime= _getLenderInfo(toIndex_, address(_positionManager)).depositTime; + ( + uint256 toLps, + uint256 toDepositTime + ) = _positionManager.getPositionInfo(tokenId_, toIndex_); + + require( + toLps >= preActionToLps, + "PM6: to bucket lps have not increased" + ); // difficult to estimate LPS, assert that it is greater than + require( + toDepositTime == postActionDepositTime, + "PM6: to bucket deposit time does not match positionManager" + ); // get post action QT represented in positionManager for tokenID uint256 postActionFromIndexQuote = _getQuoteAtIndex(fromLps, fromIndex_); @@ -301,7 +354,6 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, 1, "PM6: positiionManager QT balance has increased by `1` margin" ); - } catch (bytes memory err) { _ensurePositionsManagerError(err); } @@ -311,20 +363,33 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, uint256 tokenId_ ) internal { numberOfCalls['UBPositionHandler.burn']++; - try _positionManager.burn(address(_pool), tokenId_) { + + try _positionManager.burn( + address(_pool), + tokenId_ + ) { // Post Action Checks // // should revert if token id is burned vm.expectRevert("ERC721: invalid token ID"); - require(_positionManager.ownerOf(tokenId_) == address(0), "PM5: ownership is not zero address"); + + require( + _positionManager.ownerOf(tokenId_) == address(0), + "PM5: ownership is not zero address" + ); // assert that poolKey is returns zero address address poolAddress = _positionManager.poolKey(tokenId_); - require(poolAddress == address(0), "PM5: poolKey has not been reset on burn"); + require( + poolAddress == address(0), + "PM5: poolKey has not been reset on burn" + ); // assert that no positions are associated with this tokenId uint256[] memory posIndexes = _positionManager.getPositionIndexes(tokenId_); - require(posIndexes.length == 0, "PM5: positions still exist after burn"); - + require( + posIndexes.length == 0, + "PM5: positions still exist after burn" + ); } catch (bytes memory err) { _ensurePositionsManagerError(err); } @@ -335,14 +400,20 @@ abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, uint256 tokenId_ ) internal { numberOfCalls['UBPositionHandler.transferPosition']++; - try _positionManager.transferFrom(_actor, receiver_, tokenId_) { + try _positionManager.transferFrom( + _actor, + receiver_, + tokenId_ + ) { // actor should loses ownership, receiver gains it tokenIdsByActor[address(_actor)].remove(tokenId_); tokenIdsByActor[receiver_].add(tokenId_); - require(_positionManager.ownerOf(tokenId_) == receiver_, "new NFT owner should be receiver"); - + require( + _positionManager.ownerOf(tokenId_) == receiver_, + "new NFT owner should be receiver" + ); } catch (bytes memory err) { _ensurePositionsManagerError(err); } diff --git a/tests/forge/invariants/PositionsAndRewards/BucketBankruptcyERC20PoolRewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/BucketBankruptcyERC20PoolRewardsInvariants.t.sol deleted file mode 100644 index 9d972e619..000000000 --- a/tests/forge/invariants/PositionsAndRewards/BucketBankruptcyERC20PoolRewardsInvariants.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { ERC721Pool } from 'src/ERC721Pool.sol'; -import { ERC20PoolFactory } from 'src/ERC20PoolFactory.sol'; -import { ERC721PoolFactory } from 'src/ERC721PoolFactory.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; - -import { TokenWithNDecimals } from '../../utils/Tokens.sol'; - -import { BucketBankruptcyERC20PoolRewardsHandler } from './handlers/BucketBankruptcyERC20PoolRewardsHandler.sol'; -import { RewardsInvariants } from './RewardsInvariants.t.sol'; - -contract BucketBankruptcyERC20PoolRewardsInvariants is RewardsInvariants { - - BucketBankruptcyERC20PoolRewardsHandler internal _bucketBankruptcyerc20poolrewardsHandler; - - function setUp() public override virtual { - - super.setUp(); - - _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); - _erc20impl = _erc20poolFactory.implementation(); - _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); - _erc721impl = _erc721poolFactory.implementation(); - _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); - _rewardsManager = new RewardsManager(address(_ajna), _positionManager); - - uint256 noOfPools = vm.envOr("NO_OF_POOLS", uint256(10)); - - for (uint256 i = 0; i < noOfPools; ++i) { - address collateral = address(new TokenWithNDecimals(string(abi.encodePacked("Collateral", Strings.toString(i + 1))), "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18))))); - address quote = address(new TokenWithNDecimals(string(abi.encodePacked("Quote", Strings.toString(i + 1))), "Q", uint8(vm.envOr("QUOTE_PRECISION", uint256(18))))); - address pool = address(_erc20poolFactory.deployPool(collateral, quote, 0.05 * 10**18)); - - excludeContract(collateral); - excludeContract(quote); - excludeContract(pool); - _pools.push(pool); - } - - // fund the rewards manager with 100M ajna - _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); - - excludeContract(address(_ajna)); - excludeContract(address(_quote)); - excludeContract(address(_erc20poolFactory)); - excludeContract(address(_erc721poolFactory)); - excludeContract(address(_poolInfo)); - excludeContract(address(_erc20impl)); - excludeContract(address(_erc721impl)); - excludeContract(address(_positionManager)); - excludeContract(address(_rewardsManager)); - - _bucketBankruptcyerc20poolrewardsHandler = new BucketBankruptcyERC20PoolRewardsHandler( - address(_rewardsManager), - address(_positionManager), - _pools, - address(_ajna), - address(_poolInfo), - NUM_ACTORS, - address(this) - ); - - _handler = address(_bucketBankruptcyerc20poolrewardsHandler); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol deleted file mode 100644 index df5a27ca4..000000000 --- a/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import "@std/console.sol"; -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { ERC721Pool } from 'src/ERC721Pool.sol'; -import { ERC20PoolFactory } from 'src/ERC20PoolFactory.sol'; -import { ERC721PoolFactory } from 'src/ERC721PoolFactory.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; - -import { TokenWithNDecimals } from '../../utils/Tokens.sol'; - -import { ERC20PoolRewardsHandler } from './handlers/ERC20PoolRewardsHandler.sol'; -import { RewardsInvariants } from './RewardsInvariants.t.sol'; - -contract ERC20PoolRewardsInvariants is RewardsInvariants { - - ERC20PoolRewardsHandler internal _erc20poolrewardsHandler; - - function setUp() public override virtual { - - super.setUp(); - - _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); - _erc20impl = _erc20poolFactory.implementation(); - _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); - _erc721impl = _erc721poolFactory.implementation(); - _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); - _rewardsManager = new RewardsManager(address(_ajna), _positionManager); - - uint256 noOfPools = vm.envOr("NO_OF_POOLS", uint256(10)); - - for (uint256 i = 0; i < noOfPools; ++i) { - address collateral = address(new TokenWithNDecimals(string(abi.encodePacked("Collateral", Strings.toString(i + 1))), "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18))))); - address quote = address(new TokenWithNDecimals(string(abi.encodePacked("Quote", Strings.toString(i + 1))), "Q", uint8(vm.envOr("QUOTE_PRECISION", uint256(18))))); - address pool = address(_erc20poolFactory.deployPool(collateral, quote, 0.05 * 10**18)); - - excludeContract(collateral); - excludeContract(quote); - excludeContract(pool); - _pools.push(pool); - } - - // fund the rewards manager with 100M ajna - _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); - - excludeContract(address(_ajna)); - excludeContract(address(_quote)); - excludeContract(address(_erc20poolFactory)); - excludeContract(address(_erc721poolFactory)); - excludeContract(address(_poolInfo)); - excludeContract(address(_erc20impl)); - excludeContract(address(_erc721impl)); - excludeContract(address(_positionManager)); - excludeContract(address(_rewardsManager)); - - _erc20poolrewardsHandler = new ERC20PoolRewardsHandler( - address(_rewardsManager), - address(_positionManager), - _pools, - address(_ajna), - address(_poolInfo), - NUM_ACTORS, - address(this) - ); - - _handler = address(_erc20poolrewardsHandler); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol deleted file mode 100644 index 4008f6ebb..000000000 --- a/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import "@std/console.sol"; -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { ERC721Pool } from 'src/ERC721Pool.sol'; -import { ERC20PoolFactory } from 'src/ERC20PoolFactory.sol'; -import { ERC721PoolFactory } from 'src/ERC721PoolFactory.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; - -import { NFTCollateralToken, TokenWithNDecimals } from '../../utils/Tokens.sol'; - -import { ERC721PoolRewardsHandler } from './handlers/ERC721PoolRewardsHandler.sol'; -import { RewardsInvariants } from './RewardsInvariants.t.sol'; - -contract ERC721PoolRewardsInvariants is RewardsInvariants { - - ERC721PoolRewardsHandler internal _erc721poolrewardsHandler; - - function setUp() public override virtual { - - super.setUp(); - - uint256[] memory tokenIds; - _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); - _erc20impl = _erc20poolFactory.implementation(); - _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); - _erc721impl = _erc721poolFactory.implementation(); - _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); - _rewardsManager = new RewardsManager(address(_ajna), _positionManager); - - uint256 noOfPools = vm.envOr("NO_OF_POOLS", uint256(10)); - - for (uint256 i = 0; i < noOfPools; ++i) { - address collateral = address(new NFTCollateralToken()); - address quote = address(new TokenWithNDecimals(string(abi.encodePacked("Quote", Strings.toString(i + 1))), "Q", uint8(vm.envOr("QUOTE_PRECISION", uint256(18))))); - address pool = address(_erc721poolFactory.deployPool(collateral, quote, tokenIds, 0.05 * 10**18)); - - excludeContract(collateral); - excludeContract(quote); - excludeContract(pool); - _pools.push(pool); - } - - // fund the rewards manager with 100M ajna - _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); - - excludeContract(address(_ajna)); - excludeContract(address(_quote)); - excludeContract(address(_erc20poolFactory)); - excludeContract(address(_erc721poolFactory)); - excludeContract(address(_poolInfo)); - excludeContract(address(_erc20impl)); - excludeContract(address(_erc721impl)); - excludeContract(address(_positionManager)); - excludeContract(address(_rewardsManager)); - - _erc721poolrewardsHandler = new ERC721PoolRewardsHandler( - address(_rewardsManager), - address(_positionManager), - _pools, - address(_ajna), - address(_poolInfo), - NUM_ACTORS, - address(this) - ); - - _handler = address(_erc721poolrewardsHandler); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol deleted file mode 100644 index ba330ff6d..000000000 --- a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import "@std/console.sol"; - -import { Pool } from 'src/base/Pool.sol'; -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { RewardsManager, _getEpochInfo } from 'src/RewardsManager.sol'; - -import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; -import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; -import { PositionsInvariants } from './PositionsInvariants.sol'; - -abstract contract RewardsInvariants is PositionsInvariants { - - RewardsManager internal _rewardsManager; - - function invariant_rewards_RW1_RW2() public useCurrentTimestamp { - - for (uint256 poolIndex = 0; poolIndex < _pools.length; poolIndex++) { - address pool = _pools[poolIndex]; - uint256 epoch; // incremented every `kickReserve()` call - - while (epoch <= Pool(pool).currentBurnEpoch()) { - // get staking rewards that have been claimed - uint256 rewardsClaimed = IPositionsAndRewardsHandler(_handler).rewardsClaimedPerEpoch(pool, epoch); - - // get updating rewards that have been claimed - uint256 updateRewardsClaimed = IPositionsAndRewardsHandler(_handler).updateRewardsClaimedPerEpoch(pool, epoch); - - // total ajna burned by the pool over the epoch - (, uint256 totalBurnedInPeriod,) = _getEpochInfo(pool, epoch); - - // stake rewards cap is 80% of total burned - uint256 stakeRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.8 * 1e18); - - // update rewards cap is 10% of total burned - uint256 updateRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.1 * 1e18); - - // check claimed rewards <= rewards cap - if (stakeRewardsCap != 0) require(rewardsClaimed <= stakeRewardsCap, "Rewards invariant RW1"); - - // check update rewards <= rewards cap - if (updateRewardsCap != 0) require(updateRewardsClaimed <= updateRewardsCap, "Rewards invariant RW2"); - - epoch++; - } - } - } - - function invariant_call_summary() public virtual override useCurrentTimestamp { - console.log("\nCall Summary\n"); - console.log("--Rewards--------"); - console.log("UBRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.unstake")); - console.log("BRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake")); - console.log("UBRewardsHandler.emergencyUnstake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.emergencyUnstake")); - console.log("BRewardsHandler.emergencyUnstake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.emergencyUnstake")); - console.log("UBRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.stake")); - console.log("BRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake")); - console.log("UBRewardsHandler.updateExchangeRate ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.updateExchangeRate")); - console.log("BRewardsHandler.updateExchangeRate ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.updateExchangeRate")); - console.log("UBRewardsHandler.claimRewards ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.claimRewards")); - console.log("BRewardsHandler.claimRewards ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.claimRewards")); - console.log( - "Sum", - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.updateExchangeRate") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.claimRewards") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.emergencyUnstake") - ); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseRewardsPoolHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseRewardsPoolHandler.sol deleted file mode 100644 index 10d4d971a..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BaseRewardsPoolHandler.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { BasePositionPoolHandler } from './BasePositionPoolHandler.sol'; -import { UnboundedRewardsPoolHandler } from './unbounded/UnboundedRewardsPoolHandler.sol'; - -abstract contract BaseRewardsPoolHandler is UnboundedRewardsPoolHandler, BasePositionPoolHandler { - - /*******************************/ - /*** Prepare Tests Functions ***/ - /*******************************/ - - function _preStake( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - - // retreive or create a NFT position - (tokenId_, indexes_) = _getNFTPosition(bucketIndex_, amountToAdd_); - - // Approve rewards contract to transfer token - _positionManager.approve(address(_rewardsManager), tokenId_); - } - - function _preUnstake( - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 numberOfEpochs_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - (tokenId_, indexes_) = _getStakedPosition(bucketIndex_, amountToAdd_); - - if (indexes_.length != 0) { - _advanceEpochRewardStakers( - amountToAdd_, - indexes_, - numberOfEpochs_ - ); - } - } - - function _getStakedPosition( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - - // Check for exisiting staked positions in RewardsManager - uint256[] memory tokenIds = getStakedTokenIdsByActor(_actor); - - if (tokenIds.length != 0 ) { - // use existing position NFT - tokenId_ = tokenIds[0]; - indexes_ = getBucketIndexesByTokenId(tokenId_); - updateTokenAndPoolAddress(_positionManager.poolKey(tokenId_)); - - // create position in NFT if not already there - if (indexes_.length == 0) { - indexes_ = _getPosition(bucketIndex_, amountToAdd_); - _memorializePositions(tokenId_, indexes_); - } - - } else { - // retreive or create a NFT position - (tokenId_, indexes_) = _getNFTPosition(bucketIndex_, amountToAdd_); - updateTokenAndPoolAddress(_positionManager.poolKey(tokenId_)); - - // approve rewards contract to transfer token - _positionManager.approve(address(_rewardsManager), tokenId_); - - // stake the position - _stake(tokenId_); - } - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol deleted file mode 100644 index 06defde99..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { PositionManager } from 'src/PositionManager.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; - -import { TokenWithNDecimals } from '../../../utils/Tokens.sol'; - -import { PositionPoolHandler } from './PositionPoolHandler.sol'; -import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; - -contract ERC20PoolPositionHandler is PositionPoolHandler, BaseERC20PoolHandler { - - constructor( - address positions_, - address[] memory pools_, - address ajna_, - address poolInfoUtils_, - uint256 numOfActors_, - address testContract_ - ) BaseERC20PoolHandler(pools_[0], ajna_, poolInfoUtils_, numOfActors_, testContract_) { - - for (uint256 i = 0; i < pools_.length; i++) { - _pools.push(pools_[i]); - } - - // Position manager - _positionManager = PositionManager(positions_); - - // pool hash for mint() call - _poolHash = bytes32(keccak256("ERC20_NON_SUBSET_HASH")); - } - - modifier useRandomPool(uint256 poolIndex) override { - poolIndex = bound(poolIndex, 0, _pools.length - 1); - updateTokenAndPoolAddress(_pools[poolIndex]); - - _; - } - - function updateTokenAndPoolAddress(address pool_) internal override { - _pool = Pool(pool_); - _erc20Pool = ERC20Pool(pool_); - - _quote = TokenWithNDecimals(_pool.quoteTokenAddress()); - _collateral = TokenWithNDecimals(_pool.collateralAddress()); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol deleted file mode 100644 index e3c8cdafd..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol +++ /dev/null @@ -1,96 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { RewardsManager } from 'src/RewardsManager.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; - -import { TokenWithNDecimals } from '../../../utils/Tokens.sol'; - -import { RewardsPoolHandler } from './RewardsPoolHandler.sol'; -import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; - -contract ERC20PoolRewardsHandler is RewardsPoolHandler, ReserveERC20PoolHandler { - - constructor( - address rewards_, - address positions_, - address[] memory pools_, - address ajna_, - address poolInfoUtils_, - uint256 numOfActors_, - address testContract_ - ) ReserveERC20PoolHandler(pools_[0], ajna_, poolInfoUtils_, numOfActors_, testContract_) { - - for (uint256 i = 0; i < pools_.length; i++) { - _pools.push(pools_[i]); - } - - // Position manager - _positionManager = PositionManager(positions_); - - // Rewards manager - _rewardsManager = RewardsManager(rewards_); - - // pool hash for mint() call - _poolHash = bytes32(keccak256("ERC20_NON_SUBSET_HASH")); - } - - function _advanceEpochRewardStakers( - uint256 amountToAdd_, - uint256[] memory indexes_, - uint256 numberOfEpochs_ - ) internal override { - - numberOfEpochs_ = constrictToRange(numberOfEpochs_, 1, vm.envOr("MAX_EPOCH_ADVANCE", uint256(5))); - - for (uint256 epoch = 0; epoch <= numberOfEpochs_; epoch ++) { - // draw some debt and then repay after some times to increase pool earning / reserves - (, uint256 claimableReserves, , ) = _pool.reservesInfo(); - if (claimableReserves == 0) { - uint256 amountToBorrow = _preDrawDebt(amountToAdd_); - _drawDebt(amountToBorrow); - - skip(10 days); - - _repayDebt(type(uint256).max); - } - - // epochs are spaced a minimum of 14 days apart - uint256 timeToSkip = constrictToRange(randomSeed(), 15 days, 30 days); - - skip(timeToSkip); - - _kickReserveAuction(); - - // skip time for price to decrease, large price decrease reduces chances of rewards exceeding rewards contract balance - skip(30 hours); - - (, claimableReserves, , ) = _pool.reservesInfo(); - uint256 boundedTakeAmount = constrictToRange(amountToAdd_, claimableReserves / 2, claimableReserves); - _takeReserves(boundedTakeAmount); - - // exchange rates must be updated so that rewards can be claimed - if (indexes_.length != 0 && randomSeed() % 2 == 0) { _updateExchangeRate(indexes_); } - } - } - - modifier useRandomPool(uint256 poolIndex) override { - poolIndex = bound(poolIndex, 0, _pools.length - 1); - updateTokenAndPoolAddress(_pools[poolIndex]); - - _; - } - - function updateTokenAndPoolAddress(address pool_) internal override { - _pool = Pool(pool_); - _erc20Pool = ERC20Pool(pool_); - - _quote = TokenWithNDecimals(_pool.quoteTokenAddress()); - _collateral = TokenWithNDecimals(_pool.collateralAddress()); - } - -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol deleted file mode 100644 index 4be9fc90f..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { RewardsManager } from 'src/RewardsManager.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { Pool } from 'src/base/Pool.sol'; -import { ERC721Pool } from 'src/ERC721Pool.sol'; - -import { TokenWithNDecimals, NFTCollateralToken } from '../../../utils/Tokens.sol'; - -import { RewardsPoolHandler } from './RewardsPoolHandler.sol'; -import { ReserveERC721PoolHandler } from '../../ERC721Pool/handlers/ReserveERC721PoolHandler.sol'; - -contract ERC721PoolRewardsHandler is RewardsPoolHandler, ReserveERC721PoolHandler { - - constructor( - address rewards_, - address positions_, - address[] memory pools_, - address ajna_, - address poolInfo_, - uint256 numOfActors_, - address testContract_ - ) ReserveERC721PoolHandler(pools_[0], ajna_, poolInfo_, numOfActors_, testContract_) { - - for (uint256 i = 0; i < pools_.length; i++) { - _pools.push(pools_[i]); - } - - // Position manager - _positionManager = PositionManager(positions_); - - // Rewards manager - _rewardsManager = RewardsManager(rewards_); - - // pool hash for mint() call - _poolHash = bytes32(keccak256("ERC721_NON_SUBSET_HASH")); - } - - function _advanceEpochRewardStakers( - uint256 amountToAdd_, - uint256[] memory indexes_, - uint256 numberOfEpochs_ - ) internal override { - - numberOfEpochs_ = constrictToRange(numberOfEpochs_, 1, vm.envOr("MAX_EPOCH_ADVANCE", uint256(2))); - - for (uint256 epoch = 0; epoch <= numberOfEpochs_; epoch ++) { - // draw some debt and then repay after some times to increase pool earning / reserves - (, uint256 claimableReserves, , ) = _pool.reservesInfo(); - if (claimableReserves == 0) { - uint256 amountToBorrow = _preDrawDebt(amountToAdd_); - _drawDebt(amountToBorrow); - - _repayDebt(type(uint256).max); - } - - // epochs are spaced a minimum of 14 days apart - uint256 timeToSkip = constrictToRange(randomSeed(), 15 days, 30 days); - - skip(timeToSkip); - - (, claimableReserves, , ) = _pool.reservesInfo(); - - _kickReserveAuction(); - - // skip time for price to decrease, large price decrease reduces chances of rewards exceeding rewards contract balance - skip(60 hours); - - uint256 boundedTakeAmount = constrictToRange(amountToAdd_, claimableReserves / 2, claimableReserves); - _takeReserves(boundedTakeAmount); - - // exchange rates must be updated so that rewards can be claimed - if (indexes_.length != 0 && randomSeed() % 2 == 0) { _updateExchangeRate(indexes_); } - } - } - - modifier useRandomPool(uint256 poolIndex) override { - poolIndex = bound(poolIndex, 0, _pools.length - 1); - updateTokenAndPoolAddress(_pools[poolIndex]); - - _; - } - - function updateTokenAndPoolAddress(address pool_) internal override { - _pool = Pool(pool_); - _erc721Pool = ERC721Pool(pool_); - - _quote = TokenWithNDecimals(_pool.quoteTokenAddress()); - _collateral = NFTCollateralToken(_pool.collateralAddress()); - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol deleted file mode 100644 index e1c991aa9..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol +++ /dev/null @@ -1,189 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { Pool } from 'src/base/Pool.sol'; - -import { PositionPoolHandler } from './PositionPoolHandler.sol'; -import { BaseRewardsPoolHandler } from './BaseRewardsPoolHandler.sol'; - -abstract contract RewardsPoolHandler is BaseRewardsPoolHandler, PositionPoolHandler { - - /*******************************/ - /*** Rewards Test Functions ***/ - /*******************************/ - - function stake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs writeRewardsLogs { - numberOfCalls['BRewardsHandler.stake']++; - // Pre action - (uint256 tokenId, uint256[] memory indexes) = _preStake(_lenderBucketIndex, amountToAdd_); - - // NFT doesn't have a position associated with it, return - if (indexes.length == 0) return; - - // Action phase - _stake(tokenId); - } - - function unstake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_, - uint256 numberOfEpochs_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs writeRewardsLogs { - numberOfCalls['BRewardsHandler.unstake']++; - // Pre action - (uint256 tokenId, uint256[] memory indexes) = _preUnstake( - _lenderBucketIndex, - amountToAdd_, - numberOfEpochs_ - ); - - // NFT doesn't have a position associated with it, return - if (indexes.length == 0) return; - - // if rewards exceed contract balance tx will revert, return - uint256 reward = _rewardsManager.calculateRewards(tokenId, _pool.currentBurnEpoch()); - if (reward > _ajna.balanceOf(address(_rewardsManager))) return; - - // Action phase - _unstake(tokenId); - } - - function emergencyUnstake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_, - uint256 numberOfEpochs_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs writeRewardsLogs { - numberOfCalls['BRewardsHandler.emergencyUnstake']++; - - // Pre action - (uint256 tokenId, uint256[] memory indexes) = _preUnstake( - _lenderBucketIndex, - amountToAdd_, - numberOfEpochs_ - ); - - // NFT doesn't have a position associated with it, return - if (indexes.length == 0) return; - - // Action phase - _emergencyUnstake(tokenId); - } - - function updateExchangeRate( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs writeRewardsLogs { - numberOfCalls['BRewardsHandler.updateRate']++; - - // Pre action // - uint256[] memory indexes = getBucketIndexesWithPosition(address(_pool)); - - // if there are no existing positions, create a position at a a random index - if (indexes.length == 0) { - (, indexes) = _getStakedPosition(_lenderBucketIndex, amountToAdd_); - - // NFT doesn't have a position associated with it, return - if (indexes.length == 0) return; - } - - // Action phase - _updateExchangeRate(indexes); - } - - function claimRewards( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_, - uint256 numberOfEpochs_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs writePositionLogs writeRewardsLogs { - numberOfCalls['BRewardsHandler.claimRewards']++; - - // Pre action // - (uint256 tokenId, uint256[] memory indexes) = _preUnstake( - _lenderBucketIndex, - amountToAdd_, - numberOfEpochs_ - ); - - // NFT doesn't have a position associated with it, return - if (indexes.length == 0) return; - - // Action phase - _claimRewards(tokenId, _pool.currentBurnEpoch()); - } - - /********************************/ - /*** Logging Helper Functions ***/ - /********************************/ - - modifier writeRewardsLogs() { - // Verbosity of Log file for rewardsManager - logVerbosity = uint256(vm.envOr("LOGS_VERBOSITY_REWARDS", uint256(0))); - - if (logVerbosity != 0) logToFile = true; - - _; - - if (logVerbosity > 0) { - printInNextLine("== RewardsManager Details =="); - writeStakedActorLogs(); - writeEpochRewardLogs(); - printInNextLine("======================="); - } - } - - function writeStakedActorLogs() internal { - - for (uint256 i = 0; i < actors.length; i++) { - - uint256[] memory tokenIds = getStakedTokenIdsByActor(actors[i]); - - if (tokenIds.length != 0) { - string memory actorStr = string(abi.encodePacked("Actor ", Strings.toString(i), " staked tokenIds: ")); - - string memory tokenIdStr; - for (uint256 k = 0; k < tokenIds.length; k++) { - tokenIdStr = string(abi.encodePacked(tokenIdStr, " ", Strings.toString(tokenIds[k]))); - } - - printLine(string.concat(actorStr,tokenIdStr)); - } - } - } - - function writeEpochRewardLogs() internal { - // loop over pools - for (uint256 i = 0; i < _pools.length; i++) { - address pool = _pools[i]; - printLine(string.concat("Pool: ", Strings.toHexString(uint160(pool), 20))); - uint256 epoch = 0; - uint256 currentPoolEpoch = Pool(pool).currentBurnEpoch(); - if (currentPoolEpoch != 0) { - while (epoch <= currentPoolEpoch) { - printLine(""); - printLog("Epoch = ", epoch); - printLog("Claimed Staking Rewards = ", rewardsClaimedPerEpoch[pool][epoch]); - printLog("Claimed Updating Rewards = ", updateRewardsClaimedPerEpoch[pool][epoch]); - - epoch++; - } - } - } - - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol deleted file mode 100644 index 194dcb947..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol +++ /dev/null @@ -1,305 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import '../../../../utils/DSTestPlus.sol'; -import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; -import { - _depositFeeRate, - _lpToQuoteToken, - _priceAt - } from 'src/libraries/helpers/PoolHelper.sol'; -import { Maths } from "src/libraries/internal/Maths.sol"; - -import { BaseERC20PoolHandler } from '../../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; -import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; - -import { BaseHandler } from '../../../base/handlers/unbounded/BaseHandler.sol'; - -import { UnboundedPositionPoolHandler } from './UnboundedPositionPoolHandler.sol'; - -/** - * @dev this contract manages multiple lenders - * @dev methods in this contract are called in random order - * @dev randomly selects a lender contract to make a txn - */ -abstract contract UnboundedRewardsPoolHandler is UnboundedPositionPoolHandler { - - using EnumerableSet for EnumerableSet.UintSet; - - /********************************/ - /*** Rewards Helper Functions ***/ - /********************************/ - - function _stake( - uint256 tokenId_ - ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBRewardsHandler.stake']++; - - require(_positionManager.ownerOf(tokenId_) == address(_actor), "the actor calling `stake()` is not the owner"); - - try _rewardsManager.stake(tokenId_) { - // actor should loses ownership, positionManager gains it - tokenIdsByActor[address(_rewardsManager)].add(tokenId_); - tokenIdsByActor[address(_actor)].remove(tokenId_); - - // staked position is tracked - stakedTokenIdsByActor[address(_actor)].add(tokenId_); - - require(_positionManager.ownerOf(tokenId_) == address(_rewardsManager), "RW5: owner should be rewardsManager"); - - } catch (bytes memory err) { - _ensureRewardsManagerError(err); - } - } - - function _unstake( - uint256 tokenId_ - ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBRewardsHandler.unstake']++; - - // track balances - uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); - uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); - - (,,uint256 preActionLastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - - // loop over all epochs that are going to be - uint256 totalRewardsEarnedPreAction; - - uint256[] memory rewardsEarnedInEpochPreAction = new uint256[](_pool.currentBurnEpoch() + 1); - - for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // for epochs already claimed by the staker, `rewardsClaimed()` should go unchanged - if (_rewardsManager.isEpochClaimed(tokenId_, epoch)) { - rewardsEarnedInEpochPreAction[epoch] = _rewardsManager.getRewardsClaimed(address(_pool), epoch); - } - - // total the rewards earned pre action - totalRewardsEarnedPreAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - try _rewardsManager.unstake(tokenId_) { - - // actor should receive tokenId, positionManager loses ownership - tokenIdsByActor[address(_actor)].add(tokenId_); - tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); - - // staked position is no longer tracked - stakedTokenIdsByActor[address(_actor)].remove(tokenId_); - - // balance changes - uint256 actorAjnaGain = _ajna.balanceOf(_actor) - actorAjnaBalanceBeforeClaim; - - // loop over all epochs that were claimed - uint256 totalRewardsEarnedPostAction; - for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // if lastClaimed is the same as epoch staked isEpochClaimed will return false - if (epoch != preActionLastClaimedEpoch) { - require(_rewardsManager.isEpochClaimed(tokenId_, epoch) == true, - "RW6: epoch after claim rewards is not claimed"); - } - - if (rewardsEarnedInEpochPreAction[epoch] > 0) { - require(rewardsEarnedInEpochPreAction[epoch] == _rewardsManager.getRewardsClaimed(address(_pool), epoch), - "RW10: staker has claimed rewards from the same epoch twice"); - } - - // total rewards earned across all actors in epoch post action - totalRewardsEarnedPostAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - - // reset staking and updating rewards earned in epoch - rewardsClaimedPerEpoch[address(_pool)][epoch] = _rewardsManager.getRewardsClaimed(address(_pool), epoch); - updateRewardsClaimedPerEpoch[address(_pool)][epoch] = _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - require(_positionManager.ownerOf(tokenId_) == address(_actor), - "RW5: caller of unstake is not owner of NFT"); - - require(actorAjnaGain <= totalRewardsEarnedPostAction - totalRewardsEarnedPreAction, - "RW7: actor's total claimed is greater than rewards earned"); - - require(actorAjnaGain == contractAjnaBalanceBeforeClaim - _ajna.balanceOf(address(_rewardsManager)), - "RW8: ajna deducted from rewardsManager doesn't equal ajna gained by actor"); - - (address owner, address pool, uint256 lastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - require(owner == address(0) && pool == address(0) && lastClaimedEpoch == 0, - "RW9: stake info is not reset after unstake"); - - } catch (bytes memory err) { - _ensureRewardsManagerError(err); - } - } - - function _emergencyUnstake( - uint256 tokenId_ - ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBRewardsHandler.emergencyUnstake']++; - - uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); - uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); - - // loop over all epochs that have occured - uint256 totalRewardsEarnedPreAction; - for (uint256 epoch = 0; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // total rewards earned across all actors in epoch pre action - totalRewardsEarnedPreAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - try _rewardsManager.emergencyUnstake(tokenId_) { - - // actor should receive tokenId, positionManager loses ownership - tokenIdsByActor[address(_actor)].add(tokenId_); - tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); - - // staked position is no longer tracked - stakedTokenIdsByActor[address(_actor)].remove(tokenId_); - - // loop over all epochs that have occured - uint256 totalRewardsEarnedPostAction; - for (uint256 epoch = 0; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // total rewards earned across all actors in epoch post action - totalRewardsEarnedPostAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - require(totalRewardsEarnedPreAction == totalRewardsEarnedPostAction, - "rewards were earned on emergency unstake"); - - require(_positionManager.ownerOf(tokenId_) == address(_actor), - "RW5: caller of unstake is not owner of NFT"); - - require(contractAjnaBalanceBeforeClaim == _ajna.balanceOf(address(_rewardsManager)), - "RW8: ajna balance of rewardsManager changed"); - - require(actorAjnaBalanceBeforeClaim == _ajna.balanceOf(_actor), - "RW8: ajna balance of actor changed"); - - } catch (bytes memory err) { - _ensureRewardsManagerError(err); - } - } - - function _updateExchangeRate( - uint256[] memory indexes_ - ) internal { - numberOfCalls['UBRewardsHandler.updateExchangeRate']++; - - // track balances - uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); - uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); - - // total the rewards earned pre action - uint256 totalRewardsEarnedPreAction = _rewardsManager.getUpdateRewardsClaimed(address(_pool), _pool.currentBurnEpoch()); - - try _rewardsManager.updateBucketExchangeRatesAndClaim(address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), indexes_) { - - // balance changes - uint256 actorAjnaGain = _ajna.balanceOf(_actor) - actorAjnaBalanceBeforeClaim; - - require(actorAjnaGain <= _rewardsManager.getUpdateRewardsClaimed(address(_pool), _pool.currentBurnEpoch()) - totalRewardsEarnedPreAction, - "RW7: actor's total claimed is greater than update rewards earned"); - - require(actorAjnaGain == contractAjnaBalanceBeforeClaim - _ajna.balanceOf(address(_rewardsManager)), - "RW8: ajna deducted from rewardsManager doesn't equal ajna gained by actor"); - - } catch (bytes memory err) { - _ensureRewardsManagerError(err); - } - } - - function _claimRewards( - uint256 tokenId_, - uint256 epoch_ - ) internal { - numberOfCalls['UBRewardsHandler.claimRewards']++; - - // track balances - uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); - uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); - - (,,uint256 preActionLastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - - // loop over all epochs that are going to be - uint256 totalRewardsEarnedPreAction; - - uint256[] memory rewardsEarnedInEpochPreAction = new uint256[](_pool.currentBurnEpoch() + 1); - for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // track epochs that have already been claimed - if (_rewardsManager.isEpochClaimed(tokenId_, epoch)) { - rewardsEarnedInEpochPreAction[epoch] = _rewardsManager.getRewardsClaimed(address(_pool), epoch); - } - // total the rewards earned pre action - totalRewardsEarnedPreAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - try _rewardsManager.claimRewards(tokenId_, epoch_, 0) { - - // balance changes - uint256 actorAjnaGain = _ajna.balanceOf(_actor) - actorAjnaBalanceBeforeClaim; - - // loop over all epochs that were claimed - uint256 totalRewardsEarnedPostAction; - for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { - - // if lastClaimed is the same as epoch staked isEpochClaimed will return false - if (epoch != preActionLastClaimedEpoch) { - require(_rewardsManager.isEpochClaimed(tokenId_, epoch) == true, - "RW6: epoch after claim rewards is not claimed"); - } - - if (rewardsEarnedInEpochPreAction[epoch] > 0) { - require(rewardsEarnedInEpochPreAction[epoch] == _rewardsManager.getRewardsClaimed(address(_pool), epoch), - "RW10: staker has claimed rewards from the same epoch twice"); - } - - // total rewards earned across all actors in epoch post action - totalRewardsEarnedPostAction += _rewardsManager.getRewardsClaimed(address(_pool), epoch) + _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - - // reset staking and updating rewards earned in epoch - rewardsClaimedPerEpoch[address(_pool)][epoch] = _rewardsManager.getRewardsClaimed(address(_pool), epoch); - updateRewardsClaimedPerEpoch[address(_pool)][epoch] = _rewardsManager.getUpdateRewardsClaimed(address(_pool), epoch); - } - - (, , uint256 lastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - require(lastClaimedEpoch == _pool.currentBurnEpoch(), - "RW6: lastClaimed is not current epoch"); - - require(actorAjnaGain <= totalRewardsEarnedPostAction - totalRewardsEarnedPreAction, - "RW7: actor's total claimed is greater than rewards earned"); - - require(actorAjnaGain == contractAjnaBalanceBeforeClaim - _ajna.balanceOf(address(_rewardsManager)), - "RW8: ajna deducted from rewardsManager doesn't equal ajna gained by actor"); - - } catch (bytes memory err) { - _ensureRewardsManagerError(err); - } - } - - function _advanceEpochRewardStakers( - uint256 amountToAdd_, - uint256[] memory indexes_, - uint256 numberOfEpochs_ - ) internal virtual; - - function _ensureRewardsManagerError(bytes memory err_) internal pure { - bytes32 err = keccak256(err_); - - require( - err == keccak256(abi.encodeWithSignature("AlreadyClaimed()")) || - err == keccak256(abi.encodeWithSignature("EpochNotAvailable()")) || - err == keccak256(abi.encodeWithSignature("InsufficientLiquidity()")) || - err == keccak256(abi.encodeWithSignature("MoveStakedLiquidityInvalid()")) || - err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) || - err == keccak256(abi.encodeWithSignature("NotOwnerOfDeposit()")) || - err == keccak256(abi.encodeWithSignature("DeployWithZeroAddress()")), - "Unexpected revert error" - ); - } -} \ No newline at end of file diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index ad199a7ea..0528f7dd6 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -145,7 +145,7 @@ abstract contract BasicInvariants is BaseInvariants { ( uint256 totalBondEscrowed, uint256 unClaimed, - , + , , ) = _pool.reservesInfo(); uint256 assets = poolBalance + poolDebt; @@ -186,7 +186,7 @@ abstract contract BasicInvariants is BaseInvariants { ( uint256 totalBondEscrowed, uint256 unClaimed, - , + , , ) = _pool.reservesInfo(); require( @@ -241,27 +241,27 @@ abstract contract BasicInvariants is BaseInvariants { /************************/ function _invariant_L1_L2_L3() internal view { - (address borrower, uint256 tp) = _pool.loanInfo(0); + (address borrower, uint256 t0Tp) = _pool.loanInfo(0); // first loan in loan heap should be 0 require(borrower == address(0), "Loan Invariant L2"); - require(tp == 0, "Loan Invariant L2"); + require(t0Tp == 0, "Loan Invariant L2"); ( , , uint256 totalLoans) = _pool.loansInfo(); for (uint256 loanId = 1; loanId < totalLoans; loanId++) { - (borrower, tp) = _pool.loanInfo(loanId); + (borrower, t0Tp) = _pool.loanInfo(loanId); - // borrower address and threshold price should not 0 + // borrower address and t0 threshold price should not 0 require(borrower != address(0), "Loan Invariant L1"); - require(tp != 0, "Loan Invariant L1"); + require(t0Tp != 0, "Loan Invariant L1"); - // tp of a loan at index 'i' in loan array should be greater than equals to loans at index '2i' and '2i+1' - (, uint256 tp1) = _pool.loanInfo(2 * loanId); - (, uint256 tp2) = _pool.loanInfo(2 * loanId + 1); + // t0Tp of a loan at index 'i' in loan array should be greater than equals to loans at index '2i' and '2i+1' + (, uint256 t0Tp1) = _pool.loanInfo(2 * loanId); + (, uint256 t0Tp2) = _pool.loanInfo(2 * loanId + 1); - require(tp >= tp1, "Loan Invariant L3"); - require(tp >= tp2, "Loan Invariant L3"); + require(t0Tp >= t0Tp1, "Loan Invariant L3"); + require(t0Tp >= t0Tp2, "Loan Invariant L3"); } } @@ -286,7 +286,7 @@ abstract contract BasicInvariants is BaseInvariants { /// @dev reserve.totalInterestEarned should only update once per block function _invariant_I2() internal { - (, , , uint256 totalInterestEarned) = _pool.reservesInfo(); + (, , , , uint256 totalInterestEarned) = _pool.reservesInfo(); if (previousTotalInterestEarnedUpdate == block.number) { require( @@ -321,7 +321,7 @@ abstract contract BasicInvariants is BaseInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); if (kickTime == 0) { (uint256 borrowerT0Debt, uint256 borrowerCollateral, ) = _pool.borrowerInfo(borrower); @@ -478,11 +478,6 @@ abstract contract BasicInvariants is BaseInvariants { console.log("UBReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("UBReserveHandler.takeReserves")); console.log("BReserveHandler.kickReserves ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.kickReserves")); console.log("UBReserveHandler.kickReserves ", IBaseHandler(_handler).numberOfCalls("UBReserveHandler.kickReserves")); - console.log("--Rewards--------"); - console.log("BRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake")); - console.log("UBRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.stake")); - console.log("BRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake")); - console.log("UBRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.unstake")); console.log("--Positions--------"); console.log("UBPositionHandler.mint ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.mint")); console.log("BPositionHandler.mint ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.mint")); @@ -517,8 +512,6 @@ abstract contract BasicInvariants is BaseInvariants { IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction") + IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves") + IBaseHandler(_handler).numberOfCalls("BReserveHandler.kickReserves") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake") + - IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake") + IBaseHandler(_handler).numberOfCalls("BPositionHandler.mint") + IBaseHandler(_handler).numberOfCalls("BPositionHandler.burn") + IBaseHandler(_handler).numberOfCalls("BPositionHandler.memorialize") + diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index 4788bcd48..851aad546 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(); } /// @dev checks sum of all borrower's t0debt is equals to total pool t0debtInAuction @@ -30,7 +31,7 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , ,) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); if (kickTime != 0) { (uint256 t0debt, , ) = _pool.borrowerInfo(borrower); @@ -55,14 +56,14 @@ abstract contract LiquidationInvariants is BasicInvariants { kickerClaimableBond += claimable; } - (uint256 totalBondEscrowed, , , ) = _pool.reservesInfo(); + (uint256 totalBondEscrowed, , , , ) = _pool.reservesInfo(); require(totalBondEscrowed == kickerClaimableBond + kickerLockedBond, "A2: total bond escrowed != kicker bonds"); uint256 lockedBonds; for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , uint256 bond, , , , , , ) = _pool.auctionInfo(borrower); + (, , uint256 bond, , , , , , , ) = _pool.auctionInfo(borrower); lockedBonds += bond; } require(lockedBonds == kickerLockedBond, "A2: bonds in auctions != than kicker locked bonds"); @@ -94,7 +95,7 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); if (kickTime != 0) borrowersKicked += 1; } @@ -108,7 +109,7 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (address kicker, , uint256 bondSize, , , , , , ) = _pool.auctionInfo(borrower); + (address kicker, , uint256 bondSize, , , , , , , ) = _pool.auctionInfo(borrower); (, uint256 lockedAmount) = _pool.kickerInfo(kicker); require(lockedAmount >= bondSize, "Auction Invariant A5"); @@ -120,7 +121,7 @@ abstract contract LiquidationInvariants is BasicInvariants { uint256 previousTotalBondEscrowed = IBaseHandler(_handler).previousTotalBonds(); uint256 increaseInBonds = IBaseHandler(_handler).increaseInBonds(); uint256 decreaseInBonds = IBaseHandler(_handler).decreaseInBonds(); - (uint256 currentTotalBondEscrowed, , , ) = _pool.reservesInfo(); + (uint256 currentTotalBondEscrowed, , , ,) = _pool.reservesInfo(); requireWithinDiff( currentTotalBondEscrowed, @@ -140,6 +141,17 @@ 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 referencePrice; + (,,,, uint256 lastReferencePrice,,, address nextBorrower,,) = _pool.auctionInfo(address(0)); + while (nextBorrower != address(0)) { + (,,,, referencePrice,,,, nextBorrower,) = _pool.auctionInfo(nextBorrower); + require(lastReferencePrice <= referencePrice, "Auction Invariant A9"); + lastReferencePrice = referencePrice; + } + } function invariant_call_summary() public virtual override useCurrentTimestamp { console.log("\nCall Summary\n"); diff --git a/tests/forge/invariants/base/ReserveInvariants.t.sol b/tests/forge/invariants/base/ReserveInvariants.t.sol index f1314e013..efa9754d9 100644 --- a/tests/forge/invariants/base/ReserveInvariants.t.sol +++ b/tests/forge/invariants/base/ReserveInvariants.t.sol @@ -14,21 +14,23 @@ abstract contract ReserveInvariants is LiquidationInvariants { function invariant_reserves() public useCurrentTimestamp { - uint256 previousReserves = IBaseHandler(_handler).previousReserves(); - uint256 increaseInReserves = IBaseHandler(_handler).increaseInReserves(); - uint256 decreaseInReserves = IBaseHandler(_handler).decreaseInReserves(); + uint256 previousReserves = IBaseHandler(_handler).previousReserves(); + uint256 increaseInReserves = IBaseHandler(_handler).increaseInReserves(); + uint256 decreaseInReserves = IBaseHandler(_handler).decreaseInReserves(); + uint256 reservesErrorMargin = Maths.max(IBaseHandler(_handler).reservesErrorMargin(), 1e13); (uint256 currentReserves, , , , ) = _poolInfo.poolReservesInfo(address(_pool)); console.log("Previous Reserves -->", previousReserves); console.log("Increase in Reserves -->", increaseInReserves); console.log("Decrease in Reserves -->", decreaseInReserves); console.log("Current Reserves -->", currentReserves); + console.log("Reserves Error margin -->", reservesErrorMargin); console.log("Required Reserves -->", previousReserves + increaseInReserves - decreaseInReserves); requireWithinDiff( currentReserves, previousReserves + increaseInReserves - decreaseInReserves, - Maths.max(_pool.quoteTokenScale(), 1e13), + Maths.max(_pool.quoteTokenScale(), reservesErrorMargin), "Incorrect Reserves change" ); } diff --git a/tests/forge/invariants/base/handlers/BasicPoolHandler.sol b/tests/forge/invariants/base/handlers/BasicPoolHandler.sol index 82c7db254..2fea74e0d 100644 --- a/tests/forge/invariants/base/handlers/BasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/BasicPoolHandler.sol @@ -29,7 +29,10 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { uint256 boundedAmount = _preAddQuoteToken(amountToAdd_); // Action phase - _addQuoteToken(boundedAmount, _lenderBucketIndex); + _addQuoteToken( + boundedAmount, + _lenderBucketIndex + ); } function removeQuoteToken( @@ -44,7 +47,10 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { uint256 boundedAmount = _preRemoveQuoteToken(amountToRemove_); // Action phase - _removeQuoteToken(boundedAmount, _lenderBucketIndex); + _removeQuoteToken( + boundedAmount, + _lenderBucketIndex + ); } function moveQuoteToken( @@ -64,7 +70,11 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { ) = _preMoveQuoteToken(amountToMove_, fromIndex_, toIndex_); // Action phase - _moveQuoteToken(boundedAmount, boundedFromIndex, boundedToIndex); + _moveQuoteToken( + boundedAmount, + boundedFromIndex, + boundedToIndex + ); } function transferLps( @@ -77,11 +87,22 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { numberOfCalls['BBasicHandler.transferLps']++; // Prepare test phase - (address receiver, uint256 boundedLps) = _preTransferLps(toActorIndex_, lpsToTransfer_); + ( + address receiver, + uint256 boundedLps + ) = _preTransferLps(toActorIndex_, lpsToTransfer_); // Action phase - _increaseLPAllowance(receiver, _lenderBucketIndex, boundedLps); - _transferLps(_actor, receiver, _lenderBucketIndex); + _increaseLPAllowance( + receiver, + _lenderBucketIndex, + boundedLps + ); + _transferLps( + _actor, + receiver, + _lenderBucketIndex + ); } function stampLoan( @@ -89,6 +110,7 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { uint256 skippedTime_ ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { numberOfCalls['BBasicHandler.stampLoan']++; + _stampLoan(); } @@ -99,18 +121,25 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { function _preAddQuoteToken( uint256 amountToAdd_ ) internal view returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT); + boundedAmount_ = constrictToRange( + amountToAdd_, Maths.max(_pool.quoteTokenScale(), MIN_QUOTE_AMOUNT), MAX_QUOTE_AMOUNT + ); } function _preRemoveQuoteToken( uint256 amountToRemove_ ) internal returns (uint256 boundedAmount_) { - boundedAmount_ = constrictToRange(amountToRemove_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); + boundedAmount_ = constrictToRange( + amountToRemove_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT + ); // ensure actor has quote tokens to remove - (uint256 lpBalanceBefore, ) = _pool.lenderInfo(_lenderBucketIndex, _actor); - if (lpBalanceBefore == 0) { - _addQuoteToken(boundedAmount_, _lenderBucketIndex); + LenderInfo memory lenderInfo = _getLenderInfo(_lenderBucketIndex, _actor); + if (lenderInfo.lpBalance == 0) { + _addQuoteToken( + boundedAmount_, + _lenderBucketIndex + ); } } @@ -119,17 +148,27 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { uint256 fromIndex_, uint256 toIndex_ ) internal returns (uint256 boundedFromIndex_, uint256 boundedToIndex_, uint256 boundedAmount_) { - boundedFromIndex_ = constrictToRange(fromIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); - boundedToIndex_ = constrictToRange(toIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); - boundedAmount_ = constrictToRange(amountToMove_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); - - // ensure actor has LP to move - (uint256 lpBalance, ) = _pool.lenderInfo(boundedFromIndex_, _actor); - if (lpBalance == 0) _addQuoteToken(boundedAmount_, boundedToIndex_); + boundedFromIndex_ = constrictToRange( + fromIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX + ); + boundedToIndex_ = constrictToRange( + toIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX + ); + boundedAmount_ = constrictToRange( + amountToMove_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT + ); + + LenderInfo memory lenderInfo = _getLenderInfo(boundedFromIndex_, _actor); + if (lenderInfo.lpBalance == 0) { + _addQuoteToken( + boundedAmount_, + boundedToIndex_ + ); + } + lenderInfo = _getLenderInfo(boundedFromIndex_, _actor); - (uint256 lps, ) = _pool.lenderInfo(boundedFromIndex_, _actor); // restrict amount to move by available deposit inside bucket - uint256 availableDeposit = _poolInfo.lpToQuoteTokens(address(_pool), lps, boundedFromIndex_); + uint256 availableDeposit = _lpToQuoteTokens(lenderInfo.lpBalance, boundedFromIndex_); boundedAmount_ = Maths.min(boundedAmount_, availableDeposit); } @@ -138,14 +177,17 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { uint256 lpsToTransfer_ ) internal returns (address receiver_, uint256 boundedLps_) { // ensure actor has LP to transfer - (uint256 senderLpBalance, ) = _pool.lenderInfo(_lenderBucketIndex, _actor); - if (senderLpBalance == 0) _addQuoteToken(1e24, _lenderBucketIndex); - - (senderLpBalance, ) = _pool.lenderInfo(_lenderBucketIndex, _actor); - - boundedLps_ = constrictToRange(lpsToTransfer_, 0, senderLpBalance); + LenderInfo memory senderInfo = _getLenderInfo(_lenderBucketIndex, _actor); + if (senderInfo.lpBalance == 0) { + _addQuoteToken( + 1e24, + _lenderBucketIndex + ); + } + senderInfo = _getLenderInfo(_lenderBucketIndex, _actor); - receiver_ = actors[constrictToRange(toActorIndex_, 0, actors.length - 1)]; + boundedLps_ = constrictToRange(lpsToTransfer_, 0, senderInfo.lpBalance); + receiver_ = actors[constrictToRange(toActorIndex_, 0, actors.length - 1)]; } function _preDrawDebt( diff --git a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol index e2446cede..5c4960c1b 100644 --- a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol @@ -20,7 +20,12 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.kickAuction']++; - _kickAuction(borrowerIndex_, amount_, kickerIndex_); + + _kickAuction( + borrowerIndex_, + amount_, + kickerIndex_ + ); } function lenderKickAuction( @@ -29,6 +34,7 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas uint256 skippedTime_ ) external useRandomActor(kickerIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.lenderKickAuction']++; + _lenderKickAuction(_lenderBucketIndex); } @@ -38,7 +44,11 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas uint256 skippedTime_ ) external useRandomActor(kickerIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.withdrawBonds']++; - _withdrawBonds(_actor, maxAmount_); + + _withdrawBonds( + _actor, + maxAmount_ + ); } /****************************/ @@ -53,29 +63,38 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas ) external useRandomActor(takerIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.takeAuction']++; - address borrower; // try to take from head auction if any - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); - if (headAuction != address(0)) { - (, uint256 auctionedCollateral, ) = _poolInfo.borrowerInfo(address(_pool), headAuction); - borrower = headAuction; - amount_ = auctionedCollateral / 2; + AuctionInfo memory auctionInfo = _getAuctionInfo(address(0)); - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); - // skip to make auction takeable - if (block.timestamp - kickTime < 1 hours) { + address borrower; + if (auctionInfo.head != address(0)) { + borrower = auctionInfo.head; + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(borrower); + amount_ = borrowerInfo.collateral / 2; + + auctionInfo = _getAuctionInfo(borrower); + // TODO: eliminate this unnecessary skip, perhaps advance by single block instead + if (block.timestamp - auctionInfo.kickTime < 1 hours) { vm.warp(block.timestamp + 61 minutes); } - } else { address taker = _actor; // no head auction, prepare take action - (amount_, borrower) = _preTake(amount_, borrowerIndex_, takerIndex_); + ( + amount_, + borrower + ) = _preTake(amount_, borrowerIndex_, takerIndex_); + _actor = taker; changePrank(taker); } - _takeAuction(borrower, amount_, _actor); + _takeAuction( + borrower, + amount_, + _actor + ); } function bucketTake( @@ -87,20 +106,22 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas ) external useRandomActor(takerIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.bucketTake']++; - bucketIndex_ = constrictToRange(bucketIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + bucketIndex_ = constrictToRange( + bucketIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX + ); - address borrower; // try to take from head auction if any - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); - if (headAuction != address(0)) { - borrower = headAuction; + AuctionInfo memory auctionInfo = _getAuctionInfo(address(0)); + + address borrower; + if (auctionInfo.head != address(0)) { + borrower = auctionInfo.head; - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); + auctionInfo = _getAuctionInfo(borrower); // skip to make auction takeable - if (block.timestamp - kickTime < 1 hours) { + if (block.timestamp - auctionInfo.kickTime < 1 hours) { vm.warp(block.timestamp + 61 minutes); } - } else { address taker = _actor; // no head auction, prepare take action @@ -109,7 +130,12 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas changePrank(taker); } - _bucketTake(_actor, borrower, depositTake_, bucketIndex_); + _bucketTake( + _actor, + borrower, + depositTake_, + bucketIndex_ + ); } /******************************/ @@ -124,11 +150,12 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BLiquidationHandler.settleAuction']++; - address borrower; // try to settle head auction if any - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); - if (headAuction != address(0)) { - borrower = headAuction; + AuctionInfo memory auctionInfo = _getAuctionInfo(address(0)); + + address borrower; + if (auctionInfo.head != address(0)) { + borrower = auctionInfo.head; } else { address settler = _actor; // no head auction, prepare take action @@ -137,7 +164,10 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas changePrank(settler); } - _settleAuction(borrower, LENDER_MAX_BUCKET_INDEX - LENDER_MIN_BUCKET_INDEX); + _settleAuction( + borrower, + LENDER_MAX_BUCKET_INDEX - LENDER_MIN_BUCKET_INDEX + ); } @@ -146,48 +176,65 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas /*******************************/ function _preKick(uint256 borrowerIndex_, uint256 amount_) internal returns(address borrower_, bool borrowerKicked_) { - borrowerIndex_ = constrictToRange(borrowerIndex_, 0, actors.length - 1); - borrower_ = actors[borrowerIndex_]; - amount_ = constrictToRange(amount_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); + amount_ = constrictToRange( + amount_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT + ); + borrowerIndex_ = constrictToRange( + borrowerIndex_, 0, actors.length - 1 + ); - ( , , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); + borrower_ = actors[borrowerIndex_]; - borrowerKicked_ = kickTime != 0; + AuctionInfo memory auctionInfo = _getAuctionInfo(borrower_); + borrowerKicked_ = auctionInfo.kickTime != 0; if (!borrowerKicked_) { // if borrower not kicked then check if it is undercollateralized / kickable - uint256 lup = _poolInfo.lup(address(_pool)); - (uint256 debt, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(borrower_); - if (_isCollateralized(debt, collateral, lup, _pool.poolType())) { + if (_isBorrowerCollateralized(borrowerInfo)) { changePrank(borrower_); _actor = borrower_; uint256 drawDebtAmount = _preDrawDebt(amount_); _drawDebt(drawDebtAmount); // skip to make borrower undercollateralized - (debt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); - if (debt != 0) vm.warp(block.timestamp + _getKickSkipTime()); + borrowerInfo = _getBorrowerInfo(borrower_); + if (borrowerInfo.debt != 0) vm.warp(block.timestamp + _getKickSkipTime()); } } } function _preTake(uint256 amount_, uint256 borrowerIndex_, uint256 kickerIndex_) internal returns(uint256 boundedAmount_, address borrower_){ boundedAmount_ = _constrictTakeAmount(amount_); - borrower_ = _kickAuction(borrowerIndex_, boundedAmount_ * 100, kickerIndex_); + + borrower_ = _kickAuction( + borrowerIndex_, + boundedAmount_ * 100, + kickerIndex_ + ); // skip time to make auction takeable vm.warp(block.timestamp + 61 minutes); } function _preBucketTake(uint256 borrowerIndex_, uint256 kickerIndex_) internal returns(address borrower_) { - borrower_ = _kickAuction(borrowerIndex_, 1e24, kickerIndex_); + borrower_ = _kickAuction( + borrowerIndex_, + 1e24, + kickerIndex_ + ); + // skip time to make auction takeable vm.warp(block.timestamp + 61 minutes); } function _preSettleAuction(uint256 borrowerIndex_, uint256 kickerIndex_) internal returns(address borrower_) { - borrower_ = _kickAuction(borrowerIndex_, 1e24, kickerIndex_); + borrower_ = _kickAuction( + borrowerIndex_, + 1e24, + kickerIndex_ + ); // skip time to make auction clearable vm.warp(block.timestamp + 73 hours); @@ -206,7 +253,10 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas // Prepare test phase address kicker = _actor; bool borrowerKicked; - (borrower_, borrowerKicked)= _preKick(borrowerIndex_, amount_); + ( + borrower_, + borrowerKicked + )= _preKick(borrowerIndex_, amount_); // Action phase _actor = kicker; diff --git a/tests/forge/invariants/base/handlers/ReservePoolHandler.sol b/tests/forge/invariants/base/handlers/ReservePoolHandler.sol index 7535a5cf4..1e65a882e 100644 --- a/tests/forge/invariants/base/handlers/ReservePoolHandler.sol +++ b/tests/forge/invariants/base/handlers/ReservePoolHandler.sol @@ -19,8 +19,7 @@ abstract contract ReservePoolHandler is UnboundedReservePoolHandler, Liquidation numberOfCalls['BReserveHandler.kickReserveAuction']++; // take all reserves if available - (, , uint256 claimableReservesRemaining, , ) = _poolInfo.poolReservesInfo(address(_pool)); - _takeReserves(claimableReservesRemaining); + _takeReserves(_getReservesInfo().claimableReservesRemaining); // Action phase _kickReserveAuction(); @@ -34,15 +33,17 @@ abstract contract ReservePoolHandler is UnboundedReservePoolHandler, Liquidation numberOfCalls['BReserveHandler.takeReserves']++; // kick reserve auction if claimable reserves available - (, uint256 claimableReserves, , , ) = _poolInfo.poolReservesInfo(address(_pool)); - if (claimableReserves != 0) { + if (_getReservesInfo().claimableReserves != 0) { _kickReserveAuction(); } // take reserve auction if remaining claimable reserves - (, , uint256 claimableReservesRemaining, , ) = _poolInfo.poolReservesInfo(address(_pool)); + uint256 claimableReservesRemaining = _getReservesInfo().claimableReservesRemaining; if (claimableReservesRemaining != 0) { - uint256 boundedAmount = constrictToRange(amountToTake_, claimableReservesRemaining / 2, claimableReservesRemaining); + uint256 boundedAmount = constrictToRange( + amountToTake_, claimableReservesRemaining / 2, claimableReservesRemaining + ); + _takeReserves(boundedAmount); } } diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index d4f3fe302..a146a9325 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -13,7 +13,9 @@ import { MAX_FENWICK_INDEX, MAX_PRICE, MIN_PRICE, - _indexOf + _indexOf, + _htp, + _isCollateralized } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from 'src/libraries/internal/Maths.sol'; @@ -28,6 +30,62 @@ abstract contract BaseHandler is Test { using EnumerableSet for EnumerableSet.UintSet; + struct BorrowerInfo { + uint256 t0Debt; + uint256 debt; + uint256 collateral; + uint256 npTpRatio; + uint256 t0Np; + uint256 thresholdPrice; + } + + struct BucketInfo { + uint256 lpBalance; + uint256 collateral; + uint256 deposit; + uint256 scale; + uint256 bankruptcyTime; + uint256 exchangeRate; + } + + struct AuctionInfo { + address kicker; + uint256 bondFactor; + uint256 bondSize; + uint256 kickTime; + uint256 referencePrice; + uint256 neutralPrice; + uint256 debtToCollateral; + uint256 auctionPrice; + uint256 auctionPriceIndex; + address head; + } + + struct KickerInfo { + uint256 claimableBond; + uint256 lockedBond; + uint256 totalBond; + } + + struct LenderInfo { + uint256 lpBalance; + uint256 depositTime; + } + + struct LoansInfo { + address maxBorrower; + uint256 maxT0DebtToCollateral; + uint256 noOfLoans; + } + + struct ReservesInfo { + uint256 reserves; + uint256 claimableReserves; + uint256 claimableReservesRemaining; + uint256 auctionPrice; + uint256 timeRemaining; + } + // Tokens TokenWithNDecimals internal _quote; BurnableToken internal _ajna; @@ -75,6 +133,7 @@ abstract contract BaseHandler is Test { uint256 public previousReserves; // reserves before action uint256 public increaseInReserves; // amount of reserve increase uint256 public decreaseInReserves; // amount of reserve decrease + uint256 public reservesErrorMargin; // change in reserve error acceptance margin // Auction bond invariant test state uint256 public previousTotalBonds; // total bond before action @@ -135,11 +194,11 @@ abstract contract BaseHandler is Test { address currentActor = _actor; // clear head auction if more than 72 hours passed - (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); + address headAuction = _getAuctionInfo(address(0)).head; if (headAuction != address(0)) { - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(headAuction); + uint256 kickTime = _getAuctionInfo(headAuction).kickTime; if (block.timestamp - kickTime > 72 hours) { - (uint256 auctionedDebt, , ) = _poolInfo.borrowerInfo(address(_pool), headAuction); + uint256 auctionedDebt = _getBorrowerInfo(headAuction).debt; try vm.startPrank(headAuction) { } catch { @@ -163,10 +222,10 @@ abstract contract BaseHandler is Test { uint256 maxLoansRepayments = 5; while (maxPoolDebt < poolDebt && maxLoansRepayments > 0) { - (address borrower, , ) = _pool.loansInfo(); + address borrower = _getLoansInfo().maxBorrower; if (borrower != address(0)) { - (uint256 debt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower); + uint256 debt = _getBorrowerInfo(borrower).debt; try vm.startPrank(borrower) { } catch { @@ -223,7 +282,9 @@ abstract contract BaseHandler is Test { if (lenderBucketIndexes.length < 3) { // if actor has touched less than three buckets, add a new bucket - _lenderBucketIndex = constrictToRange(bucketIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + _lenderBucketIndex = constrictToRange( + bucketIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX + ); lenderBucketIndexes.push(_lenderBucketIndex); } else { @@ -243,7 +304,15 @@ abstract contract BaseHandler is Test { if (logToFile == true) { if (numberOfCalls["Write logs"]++ == 0) vm.writeFile(path, ""); - printInNextLine(string(abi.encodePacked("================= Handler Call : ", Strings.toString(numberOfCalls["Write logs"]), " =================="))); + printInNextLine( + string( + abi.encodePacked( + "================= Handler Call : ", + Strings.toString(numberOfCalls["Write logs"]), + " ==================" + ) + ) + ); } if (logVerbosity > 0) { @@ -259,6 +328,106 @@ abstract contract BaseHandler is Test { /*** Pool Helper Functions ***/ /*****************************/ + function _getAuctionInfo(address borrower_) internal view returns (AuctionInfo memory auctionInfo_) { + ( + auctionInfo_.kicker, + auctionInfo_.bondFactor, + auctionInfo_.bondSize, + auctionInfo_.kickTime, + auctionInfo_.referencePrice, + auctionInfo_.neutralPrice, + auctionInfo_.debtToCollateral, + auctionInfo_.head, + , + ) = _pool.auctionInfo(borrower_); + + (,,,, auctionInfo_.auctionPrice,,,, ) = _poolInfo.auctionStatus(address(_pool), borrower_); + + auctionInfo_.auctionPriceIndex = auctionInfo_.auctionPrice < MIN_PRICE ? 7388 : (auctionInfo_.auctionPrice > MAX_PRICE ? 0 : _indexOf(auctionInfo_.auctionPrice)); + } + + function _getBorrowerInfo(address borrower_) internal view returns (BorrowerInfo memory borrowerInfo_) { + ( + borrowerInfo_.debt, + borrowerInfo_.collateral, + borrowerInfo_.t0Np, + borrowerInfo_.thresholdPrice + ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + + ( + borrowerInfo_.t0Debt, + , + borrowerInfo_.npTpRatio + ) = _pool.borrowerInfo(borrower_); + } + + function _getBucketInfo(uint256 index_) internal view returns (BucketInfo memory bucketInfo_) { + ( + bucketInfo_.lpBalance, + bucketInfo_.collateral, + bucketInfo_.bankruptcyTime, + bucketInfo_.deposit, + bucketInfo_.scale + ) = _pool.bucketInfo(index_); + + bucketInfo_.exchangeRate = _pool.bucketExchangeRate(index_); + } + + function _getLenderInfo( + uint256 index_, + address lender_ + ) internal view returns (LenderInfo memory lenderInfo_) { + ( + lenderInfo_.lpBalance, + lenderInfo_.depositTime + ) = _pool.lenderInfo(index_, lender_); + } + + function _getLoansInfo() internal view returns (LoansInfo memory loansInfo_) { + ( + loansInfo_.maxBorrower, + loansInfo_.maxT0DebtToCollateral, + loansInfo_.noOfLoans + ) = _pool.loansInfo(); + } + + function _getKickerInfo(address kicker_) internal view returns (KickerInfo memory kickerInfo_) { + ( + kickerInfo_.claimableBond, + kickerInfo_.lockedBond + ) = _pool.kickerInfo(kicker_); + kickerInfo_.totalBond = kickerInfo_.claimableBond + kickerInfo_.lockedBond; + } + + function _getReservesInfo() internal view returns (ReservesInfo memory reservesInfo_) { + ( + reservesInfo_.reserves, + reservesInfo_.claimableReserves, + reservesInfo_.claimableReservesRemaining, + reservesInfo_.auctionPrice, + reservesInfo_.timeRemaining + ) = _poolInfo.poolReservesInfo(address(_pool)); + } + + function _getLup() internal view returns (uint256) { + return _poolInfo.lup(address(_pool)); + } + + function _getPoolQuoteBalance() internal view returns (uint256) { + return _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); + } + + function _isBorrowerCollateralized(BorrowerInfo memory borrowerInfo_) internal view returns (bool) { + return _isCollateralized(borrowerInfo_.debt, borrowerInfo_.collateral, _getLup(), _pool.poolType()); + } + + function _lpToQuoteTokens( + uint256 lp_, + uint256 index_ + ) internal view returns (uint256) { + return _poolInfo.lpToQuoteTokens(address(_pool), lp_, index_); + } + function _getKickSkipTime() internal returns (uint256) { return vm.envOr("SKIP_TIME_TO_KICK", uint256(200 days)); } @@ -318,8 +487,9 @@ abstract contract BaseHandler is Test { err == keccak256(abi.encodeWithSignature("AuctionNotClearable()")) || err == keccak256(abi.encodeWithSignature("ReserveAuctionTooSoon()")) || err == keccak256(abi.encodeWithSignature("NoReserves()")) || - err == keccak256(abi.encodeWithSignature("ZeroThresholdPrice()")) || - err == keccak256(abi.encodeWithSignature("NoReservesAuction()")), + err == keccak256(abi.encodeWithSignature("ZeroDebtToCollateral()")) || + err == keccak256(abi.encodeWithSignature("NoReservesAuction()")) || + err == keccak256(abi.encodeWithSignature("AddAboveAuctionPrice()")), "Unexpected revert error" ); } @@ -346,7 +516,7 @@ abstract contract BaseHandler is Test { increaseInReserves = 0; decreaseInReserves = 0; // record reserves before each action - (previousReserves, , , , ) = _poolInfo.poolReservesInfo(address(_pool)); + previousReserves = _getReservesInfo().reserves; // reset penalties before each action borrowerPenalty = 0; @@ -356,7 +526,7 @@ abstract contract BaseHandler is Test { increaseInBonds = 0; decreaseInBonds = 0; // record totalBondEscrowed before each action - (previousTotalBonds, , , ) = _pool.reservesInfo(); + (previousTotalBonds, , , , ) = _pool.reservesInfo(); } /********************************/ @@ -379,8 +549,9 @@ abstract contract BaseHandler is Test { if (pendingFactor == 1e18) return; // get TP of worst loan - (, uint256 htp,) = _pool.loansInfo(); - + (uint256 inflator, ) = _pool.inflatorInfo(); + uint256 htp = _htp(_getLoansInfo().maxT0DebtToCollateral, inflator); + uint256 accrualIndex; if (htp > MAX_PRICE) accrualIndex = 1; // if HTP is over the highest price bucket then no buckets earn interest @@ -426,8 +597,7 @@ abstract contract BaseHandler is Test { // update local fenwick to pool fenwick before each action function _updateLocalFenwick() internal { for (uint256 bucketIndex = LENDER_MIN_BUCKET_INDEX; bucketIndex <= LENDER_MAX_BUCKET_INDEX; bucketIndex++) { - (, , , uint256 deposits, ) = _pool.bucketInfo(bucketIndex); - fenwickDeposits[bucketIndex] = deposits; + fenwickDeposits[bucketIndex] = _getBucketInfo(bucketIndex).deposit; } } @@ -435,21 +605,22 @@ abstract contract BaseHandler is Test { /*** Auctions Helper Functions ***/ /*********************************/ - function _getKickerBond(address kicker_) internal view returns (uint256 bond_) { - (uint256 claimableBond, uint256 lockedBond) = _pool.kickerInfo(kicker_); - bond_ = claimableBond + lockedBond; - } - function _recordSettleBucket( address borrower_, uint256 borrowerCollateralBefore_, uint256 kickTimeBefore_, uint256 auctionPrice_ ) internal { - (uint256 kickTimeAfter, , , , , ) = _poolInfo.auctionStatus(address(_pool), borrower_); + uint256 kickTimeAfter = _getAuctionInfo(borrower_).kickTime; // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - if (kickTimeBefore_ != 0 && kickTimeAfter == 0 && borrowerCollateralBefore_ % 1e18 != 0) { + if ( + kickTimeBefore_ != 0 + && + kickTimeAfter == 0 + && + borrowerCollateralBefore_ % 1e18 != 0 + ) { if (auctionPrice_ < MIN_PRICE) { buckets.add(7388); lenderDepositTime[borrower_][7388] = block.timestamp; @@ -479,7 +650,7 @@ abstract contract BaseHandler is Test { ( uint256 totalBond, - uint256 reserveUnclaimed, , + uint256 reserveUnclaimed, , , uint256 totalInterest ) = _pool.reservesInfo(); @@ -491,7 +662,7 @@ abstract contract BaseHandler is Test { ) = _poolInfo.poolLoansInfo(address(_pool)); ( - , , , , , , + , , , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); @@ -544,7 +715,11 @@ abstract contract BaseHandler is Test { uint256 bucketIndex = buckets.at(j); (uint256 lenderLps, ) = _pool.lenderInfo(bucketIndex, actors[i]); if (lenderLps != 0) { - data = string(abi.encodePacked("Lps at ", Strings.toString(bucketIndex), " = ", Strings.toString(lenderLps))); + data = string( + abi.encodePacked( + "Lps at ", Strings.toString(bucketIndex), " = ", Strings.toString(lenderLps) + ) + ); printLine(data); } } @@ -557,10 +732,14 @@ abstract contract BaseHandler is Test { for (uint256 i = 0; i < actors.length; i++) { printLine(""); printLog("Actor ", i + 1); - (uint256 debt, uint256 pledgedCollateral, ) = _poolInfo.borrowerInfo(address(_pool), actors[i]); - if (debt != 0 || pledgedCollateral != 0) { - printLog("Debt = ", debt); - printLog("Pledged collateral = ", pledgedCollateral); + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(actors[i]); + if (borrowerInfo.debt != 0 || borrowerInfo.collateral != 0) { + printLog("Debt = ", borrowerInfo.debt); + printLog("Pledged collateral = ", borrowerInfo.collateral); + printLog("t0 Neutral Price = ", borrowerInfo.t0Np); + printLog("Threshold Price = ", borrowerInfo.thresholdPrice); + } } printInNextLine("======================="); @@ -599,11 +778,11 @@ abstract contract BaseHandler is Test { uint256 bondFactor; uint256 bondSize; uint256 neutralPrice; - (,,,,,, nextBorrower,,) = _pool.auctionInfo(address(0)); + (,,,,,,, nextBorrower,,) = _pool.auctionInfo(address(0)); while (nextBorrower != address(0)) { data = string(abi.encodePacked("Borrower ", Strings.toHexString(uint160(nextBorrower), 20), " Auction Details :")); printInNextLine(data); - (, bondFactor, bondSize, kickTime, referencePrice, neutralPrice,, nextBorrower,) = _pool.auctionInfo(nextBorrower); + (, bondFactor, bondSize, kickTime, referencePrice, neutralPrice,,, nextBorrower,) = _pool.auctionInfo(nextBorrower); printLog("Bond Factor = ", bondFactor); printLog("Bond Size = ", bondSize); diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol index 4bff808a3..3b9a00164 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol @@ -27,43 +27,36 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.addQuoteToken']++; - (uint256 lpBalanceBeforeAction, ) = _pool.lenderInfo(bucketIndex_, _actor); - - (uint256 inflator, ) = _pool.inflatorInfo(); - uint256 poolDebt = Maths.wmul(_pool.totalT0Debt(), inflator); - uint256 lupIndex = _pool.depositIndex(poolDebt); - (uint256 interestRate, ) = _pool.interestRateInfo(); - // ensure actor always has amount of quote to add _ensureQuoteAmount(_actor, amount_); - try _pool.addQuoteToken(amount_, bucketIndex_, block.timestamp + 1 minutes, false) { + LenderInfo memory lenderInfoBeforeAdd = _getLenderInfo(bucketIndex_, _actor); + try _pool.addQuoteToken( + amount_, + bucketIndex_, + block.timestamp + 1 minutes + ) returns (uint256, uint256 addedAmount_) { // amount is rounded in pool to token scale amount_ = _roundToScale(amount_, _pool.quoteTokenScale()); + + // **RE3**: Reserves increase when depositing quote token + increaseInReserves += amount_ - addedAmount_; // **B5**: when adding quote tokens: lender deposit time = timestamp of block when deposit happened lenderDepositTime[_actor][bucketIndex_] = block.timestamp; + // **R3**: Exchange rates are unchanged by depositing quote token into a bucket exchangeRateShouldNotChange[bucketIndex_] = true; - bool depositBelowLup = lupIndex != 0 && bucketIndex_ > lupIndex; - if (depositBelowLup) { - uint256 intialAmount = amount_; - amount_ = Maths.wmul( - amount_, - Maths.WAD - _depositFeeRate(interestRate) - ); - // **RE3**: Reserves increase only when depositing quote token into a bucket below LUP - increaseInReserves += intialAmount - amount_; - } - - _fenwickAdd(amount_, bucketIndex_); + _fenwickAdd(addedAmount_, bucketIndex_); + LenderInfo memory lenderInfoAfterAdd = _getLenderInfo(bucketIndex_, _actor); // Post action condition - (uint256 lpBalanceAfterAction, ) = _pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction > lpBalanceBeforeAction, "LP balance should increase"); - + require( + lenderInfoAfterAdd.lpBalance > lenderInfoBeforeAdd.lpBalance, + "LP balance should increase" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -75,12 +68,15 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.removeQuoteToken']++; - (uint256 lpBalanceBeforeAction, ) = _pool.lenderInfo(bucketIndex_, _actor); + // record fenwick tree state before action + fenwickDeposits[bucketIndex_] = _getBucketInfo(bucketIndex_).deposit; - ( , , , uint256 deposit, ) = _pool.bucketInfo(bucketIndex_); - fenwickDeposits[bucketIndex_] = deposit; + LenderInfo memory lenderInfoBeforeRemove = _getLenderInfo(bucketIndex_, _actor); - try _pool.removeQuoteToken(amount_, bucketIndex_) returns (uint256 removedAmount_, uint256) { + try _pool.removeQuoteToken( + amount_, + bucketIndex_ + ) returns (uint256 removedAmount_, uint256) { // **R4**: Exchange rates are unchanged by withdrawing deposit (quote token) from a bucket exchangeRateShouldNotChange[bucketIndex_] = true; @@ -89,10 +85,12 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { // rounding in favour of pool goes to reserves increaseInReserves += removedAmount_ - _roundToScale(removedAmount_, _pool.quoteTokenScale()); + LenderInfo memory lenderInfoAfterRemove = _getLenderInfo(bucketIndex_, _actor); // Post action condition - (uint256 lpBalanceAfterAction, ) = _pool.lenderInfo(bucketIndex_, _actor); - require(lpBalanceAfterAction < lpBalanceBeforeAction, "LP balance should decrease"); - + require( + lenderInfoAfterRemove.lpBalance < lenderInfoBeforeRemove.lpBalance, + "LP balance should decrease" + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -105,23 +103,22 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.moveQuoteToken']++; - ( , , , uint256 fromDeposit, ) = _pool.bucketInfo(fromIndex_); - fenwickDeposits[fromIndex_] = fromDeposit; + // record fenwick tree state before action + fenwickDeposits[fromIndex_] = _getBucketInfo(fromIndex_).deposit; try _pool.moveQuoteToken( amount_, fromIndex_, toIndex_, - block.timestamp + 1 minutes, - false + block.timestamp + 1 minutes ) returns (uint256, uint256, uint256 movedAmount_) { - - (, uint256 fromBucketDepositTime) = _pool.lenderInfo(fromIndex_, _actor); - (, uint256 toBucketDepositTime) = _pool.lenderInfo(toIndex_, _actor); - // **B5**: when moving quote tokens: lender deposit time = timestamp of block when move happened - lenderDepositTime[_actor][toIndex_] = Maths.max(fromBucketDepositTime, toBucketDepositTime); - // **RE3**: Reserves increase only when moving quote tokens into a bucket below LUP. + lenderDepositTime[_actor][toIndex_] = Maths.max( + _getLenderInfo(fromIndex_, _actor).depositTime, + _getLenderInfo(toIndex_, _actor).depositTime + ); + + // **RE3**: Reserves increase only when moving quote tokens into a lower-priced bucket // movedAmount_ can be greater than amount_ in case when bucket gets empty by moveQuoteToken if (amount_ > movedAmount_) increaseInReserves += amount_ - movedAmount_; @@ -149,7 +146,12 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { buckets[0] = bucketIndex_; uint256[] memory amounts = new uint256[](1); amounts[0] = amount_; - _pool.increaseLPAllowance(receiver_, buckets, amounts); + + _pool.increaseLPAllowance( + receiver_, + buckets, + amounts + ); } function _transferLps( @@ -164,14 +166,16 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { changePrank(receiver_); - try _pool.transferLP(sender_, receiver_, buckets) { - - (, uint256 senderDepositTime) = _pool.lenderInfo(bucketIndex_, sender_); - (, uint256 receiverDepositTime) = _pool.lenderInfo(bucketIndex_, receiver_); - + try _pool.transferLP( + sender_, + receiver_, + buckets + ) { // **B6**: when receiving transferred LP : receiver deposit time (`Lender.depositTime`) = max of sender and receiver deposit time - lenderDepositTime[receiver_][bucketIndex_] = Maths.max(senderDepositTime, receiverDepositTime); - + lenderDepositTime[receiver_][bucketIndex_] = Maths.max( + _getLenderInfo(bucketIndex_, sender_).depositTime, + _getLenderInfo(bucketIndex_, receiver_).depositTime + ); } catch (bytes memory err) { _ensurePoolError(err); } @@ -179,6 +183,7 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { function _stampLoan() internal updateLocalStateAndPoolInterest { numberOfCalls['UBBasicHandler.stampLoan']++; + try _pool.stampLoan() { } catch (bytes memory err) { _ensurePoolError(err); diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index 6e4f6af74..3a647542a 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.18; +import '../../../../utils/DSTestPlus.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import { Math } from '@openzeppelin/contracts/utils/math/Math.sol'; @@ -11,17 +12,20 @@ import { MAX_FENWICK_INDEX } from 'src/libraries/helpers/ import { Buckets } from 'src/libraries/internal/Buckets.sol'; import { BaseHandler } from './BaseHandler.sol'; +import '@std/Vm.sol'; abstract contract UnboundedLiquidationPoolHandler is BaseHandler { using EnumerableSet for EnumerableSet.UintSet; - struct LocalBucketTakeVars { + struct LocalTakeVars { uint256 kickerLps; uint256 takerLps; uint256 deposit; uint256 kickerBond; uint256 borrowerLps; + uint256 borrowerCollateral; + uint256 borrowerDebt; } /*******************************/ @@ -33,21 +37,22 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.kickAuction']++; - (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(borrower_); + KickerInfo memory kickerInfoBeforeKick = _getKickerInfo(_actor); // ensure actor always has the amount to pay for bond - _ensureQuoteAmount(_actor, borrowerDebt); + _ensureQuoteAmount(_actor, borrowerInfo.debt); - uint256 kickerBondBefore = _getKickerBond(_actor); - - try _pool.kick(borrower_, 7388) { + try _pool.kick( + borrower_, + 7388 + ) { numberOfActions['kick']++; - uint256 kickerBondAfter = _getKickerBond(_actor); + KickerInfo memory kickerInfoAfterKick = _getKickerInfo(_actor); // **A7**: totalBondEscrowed should increase when auctioned kicked with the difference needed to cover the bond - increaseInBonds += kickerBondAfter - kickerBondBefore; - + increaseInBonds += kickerInfoAfterKick.totalBond - kickerInfoBeforeKick.totalBond; } catch (bytes memory err) { _ensurePoolError(err); } @@ -58,28 +63,33 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.lenderKickAuction']++; - (address maxBorrower, , ) = _pool.loansInfo(); - (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), maxBorrower); - ( , , , uint256 depositBeforeAction, ) = _pool.bucketInfo(bucketIndex_); - fenwickDeposits[bucketIndex_] = depositBeforeAction; + address maxBorrower = _getLoansInfo().maxBorrower; + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(maxBorrower); + if (borrowerInfo.debt == 0) return; + + BucketInfo memory bucketInfoBeforeKick = _getBucketInfo(bucketIndex_); + KickerInfo memory kickerInfoBeforeKick = _getKickerInfo(_actor); - uint256 kickerBondBefore = _getKickerBond(_actor); + // record fenwick tree state before action + fenwickDeposits[bucketIndex_] = bucketInfoBeforeKick.deposit; // ensure actor always has the amount to add for kick - _ensureQuoteAmount(_actor, borrowerDebt); + _ensureQuoteAmount(_actor, borrowerInfo.debt); - try _pool.lenderKick(bucketIndex_, 7388) { + try _pool.lenderKick( + bucketIndex_, + 7388 + ) { numberOfActions['lenderKick']++; - ( , , , uint256 depositAfterAction, ) = _pool.bucketInfo(bucketIndex_); - - uint256 kickerBondAfter = _getKickerBond(_actor); + BucketInfo memory bucketInfoAfterKick = _getBucketInfo(bucketIndex_); + KickerInfo memory kickerInfoAfterKick = _getKickerInfo(_actor); // **A7**: totalBondEscrowed should increase when auctioned kicked with the difference needed to cover the bond - increaseInBonds += kickerBondAfter - kickerBondBefore; - - _fenwickRemove(depositBeforeAction - depositAfterAction, bucketIndex_); + increaseInBonds += kickerInfoAfterKick.totalBond - kickerInfoBeforeKick.totalBond; + _fenwickRemove(bucketInfoBeforeKick.deposit - bucketInfoAfterKick.deposit, bucketIndex_); } catch (bytes memory err) { _ensurePoolError(err); } @@ -91,23 +101,24 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.withdrawBonds']++; - uint256 balanceBeforeWithdraw = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); - (uint256 claimableBondBeforeWithdraw, ) = _pool.kickerInfo(_actor); + KickerInfo memory kickerInfoBeforeWithdraw = _getKickerInfo(_actor); + uint256 poolBalanceBeforeWithdraw = _getPoolQuoteBalance(); - try _pool.withdrawBonds(kicker_, maxAmount_) { - - uint256 balanceAfterWithdraw = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); - (uint256 claimableBondAfterWithdraw, ) = _pool.kickerInfo(_actor); + try _pool.withdrawBonds( + kicker_, + maxAmount_ + ) { + KickerInfo memory kickerInfoAfterWithdraw = _getKickerInfo(_actor); + uint256 poolBalanceAfterWithdraw = _getPoolQuoteBalance(); // **A7** Claimable bonds should be available for withdrawal from pool at any time (bonds are guaranteed by the protocol). require( - claimableBondAfterWithdraw < claimableBondBeforeWithdraw, + kickerInfoAfterWithdraw.claimableBond < kickerInfoBeforeWithdraw.claimableBond, "A7: claimable bond not available to withdraw" ); // **A7**: totalBondEscrowed should decrease only when kicker bonds withdrawned - decreaseInBonds += balanceBeforeWithdraw - balanceAfterWithdraw; - + decreaseInBonds += poolBalanceBeforeWithdraw - poolBalanceAfterWithdraw; } catch (bytes memory err) { _ensurePoolError(err); } @@ -124,62 +135,88 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.takeAuction']++; - (address kicker, , , , , , , , ) = _pool.auctionInfo(borrower_); - - ( - uint256 borrowerDebtBeforeTake, - uint256 borrowerCollateralBeforeTake, - ) = _poolInfo.borrowerInfo(address(_pool), borrower_); - uint256 totalBondBeforeTake = _getKickerBond(kicker); - uint256 totalBalanceBeforeTake = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); + AuctionInfo memory auctionInfo = _getAuctionInfo(borrower_); + LocalTakeVars memory beforeTakeVars = _getTakeInfo( + auctionInfo.auctionPriceIndex, + auctionInfo.kicker, + _actor, + auctionInfo.auctionPriceIndex, + borrower_ + ); - (uint256 kickTimeBefore, , , , uint256 auctionPrice, ) = _poolInfo.auctionStatus(address(_pool), borrower_); + uint256 totalBalanceBeforeTake = _getPoolQuoteBalance(); // ensure actor always has the amount to take collateral _ensureQuoteAmount(taker_, 1e45); - try _pool.take(borrower_, amount_, taker_, bytes("")) { + try _pool.take( + borrower_, + amount_, + taker_, + bytes("") + ) { numberOfActions['take']++; - (uint256 borrowerDebtAfterTake, uint256 borrowerCollateralAfterTake, ) = _poolInfo.borrowerInfo(address(_pool), borrower_); - uint256 totalBondAfterTake = _getKickerBond(kicker); - uint256 totalBalanceAfterTake = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); + uint256 totalBalanceAfterTake = _getPoolQuoteBalance(); + + LocalTakeVars memory afterTakeVars = _getTakeInfo( + auctionInfo.auctionPriceIndex, + auctionInfo.kicker, + _actor, + auctionInfo.auctionPriceIndex, + borrower_ + ); // **RE7**: Reserves decrease with debt covered by take. - decreaseInReserves += borrowerDebtBeforeTake - borrowerDebtAfterTake; - + decreaseInReserves += beforeTakeVars.borrowerDebt - afterTakeVars.borrowerDebt; + // **A8**: kicker reward <= Borrower penalty - borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, auctionPrice) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); + // Borrower penalty is difference between borrower collateral taken at auction price to amount of borrower debt reduced. + borrowerPenalty = Maths.ceilWmul(beforeTakeVars.borrowerCollateral - afterTakeVars.borrowerCollateral, auctionInfo.auctionPrice) - (beforeTakeVars.borrowerDebt - afterTakeVars.borrowerDebt); + + if (afterTakeVars.borrowerLps > beforeTakeVars.borrowerLps) { + // Borrower gets Lps at auction price against fractional collateral added to the bucket. + borrowerPenalty -= _rewardedLpToQuoteToken(afterTakeVars.borrowerLps - beforeTakeVars.borrowerLps, auctionInfo.auctionPriceIndex); + } - if (totalBondBeforeTake > totalBondAfterTake) { + if (beforeTakeVars.kickerBond > afterTakeVars.kickerBond) { // **RE7**: Reserves increase by bond penalty on take. - increaseInReserves += totalBondBeforeTake - totalBondAfterTake; + increaseInReserves += beforeTakeVars.kickerBond - afterTakeVars.kickerBond; // **A7**: Total Bond decrease by bond penalty on take. - decreaseInBonds += totalBondBeforeTake - totalBondAfterTake; + decreaseInBonds += beforeTakeVars.kickerBond - afterTakeVars.kickerBond; } else { // **RE7**: Reserves decrease by bond reward on take. - decreaseInReserves += totalBondAfterTake - totalBondBeforeTake; + decreaseInReserves += afterTakeVars.kickerBond - beforeTakeVars.kickerBond; // **A7**: Total Bond increase by bond penalty on take. - increaseInBonds += totalBondAfterTake - totalBondBeforeTake; + increaseInBonds += afterTakeVars.kickerBond - beforeTakeVars.kickerBond; // **A8**: kicker reward <= Borrower penalty - kickerReward += totalBondAfterTake - totalBondBeforeTake; + kickerReward += afterTakeVars.kickerBond - beforeTakeVars.kickerBond; } + // Reserves can increase by up to 2e-18 (1/5e17) due to rounding error in inflator value multiplied with t0Debt + (uint256 inflator, ) = _pool.inflatorInfo(); + reservesErrorMargin = Math.max(reservesErrorMargin, inflator/5e17); + // **RE7**: Reserves increase with the quote token paid by taker. increaseInReserves += totalBalanceAfterTake - totalBalanceBeforeTake; + // **RE9**: Reserves unchanged by takes and bucket takes below TP(at the time of kick) + if (auctionInfo.auctionPrice < Maths.min(auctionInfo.debtToCollateral, auctionInfo.neutralPrice)) { + increaseInReserves = 0; + decreaseInReserves = 0; + } + if (_pool.poolType() == 1) { _recordSettleBucket( borrower_, - borrowerCollateralBeforeTake, - kickTimeBefore, - auctionPrice + beforeTakeVars.borrowerCollateral, + auctionInfo.kickTime, + auctionInfo.auctionPrice ); } - } catch (bytes memory err) { _ensurePoolError(err); } @@ -193,47 +230,50 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.bucketTake']++; - ( uint256 borrowerDebtBeforeTake, uint256 borrowerCollateralBeforeTake,) = _poolInfo.borrowerInfo(address(_pool), borrower_); + AuctionInfo memory auctionInfo = _getAuctionInfo(borrower_); + LocalTakeVars memory beforeTakeVars = _getTakeInfo( + bucketIndex_, + auctionInfo.kicker, + _actor, + auctionInfo.auctionPriceIndex, + borrower_ + ); - (address kicker, , , , , , , , ) = _pool.auctionInfo(borrower_); - ( , , , , uint256 auctionPrice, ) = _poolInfo.auctionStatus(address(_pool), borrower_); - uint256 auctionBucketIndex = auctionPrice < MIN_PRICE ? 7388 : (auctionPrice > MAX_PRICE ? 0 : _indexOf(auctionPrice)); - - LocalBucketTakeVars memory beforeBucketTakeVars = getBucketTakeInfo(bucketIndex_, kicker, _actor, auctionBucketIndex, borrower_); + // Record event emitted in bucketTake method call to calculate `borrowerPenalty` and `kickerReward` + vm.recordLogs(); - try _pool.bucketTake(borrower_, depositTake_, bucketIndex_) { + try _pool.bucketTake( + borrower_, + depositTake_, + bucketIndex_ + ) { numberOfActions['bucketTake']++; - LocalBucketTakeVars memory afterBucketTakeVars = getBucketTakeInfo(bucketIndex_, kicker, _actor, auctionBucketIndex, borrower_); + LocalTakeVars memory afterTakeVars = _getTakeInfo( + bucketIndex_, + auctionInfo.kicker, + _actor, + auctionInfo.auctionPriceIndex, + borrower_ + ); // **B7**: when awarded bucket take LP : taker deposit time = timestamp of block when award happened - if (afterBucketTakeVars.takerLps > beforeBucketTakeVars.takerLps) lenderDepositTime[taker_][bucketIndex_] = block.timestamp; - - (uint256 borrowerDebtAfterTake, uint256 borrowerCollateralAfterTake, ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + if (afterTakeVars.takerLps > beforeTakeVars.takerLps) lenderDepositTime[taker_][bucketIndex_] = block.timestamp; - if (afterBucketTakeVars.kickerLps > beforeBucketTakeVars.kickerLps) { + if (afterTakeVars.kickerLps > beforeTakeVars.kickerLps) { // **B7**: when awarded bucket take LP : kicker deposit time = timestamp of block when award happened - lenderDepositTime[kicker][bucketIndex_] = block.timestamp; - - // when kicker and taker are same, kicker Reward = total Reward (lps) - taker Reward (Collateral Price * difference of bucket used and auction price) - if (!depositTake_ && kicker == _actor) { - uint256 totalReward = lpToQuoteToken(afterBucketTakeVars.kickerLps - beforeBucketTakeVars.kickerLps, bucketIndex_); - uint256 takerReward = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, _priceAt(bucketIndex_) - auctionPrice); - - // **A8**: kicker reward <= Borrower penalty - kickerReward = totalReward - takerReward; - } else { - // **A8**: kicker reward <= Borrower penalty - kickerReward = lpToQuoteToken(afterBucketTakeVars.kickerLps - beforeBucketTakeVars.kickerLps, bucketIndex_); - } + lenderDepositTime[auctionInfo.kicker][bucketIndex_] = block.timestamp; } - // **A8**: kicker reward <= Borrower penalty - if (depositTake_) { - borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, _priceAt(bucketIndex_)) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); - } else { - borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, auctionPrice) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); - } + // Get emitted events logs in bucketTake + Vm.Log[] memory entries = vm.getRecordedLogs(); + (borrowerPenalty, kickerReward) = _getBorrowerPenaltyAndKickerReward( + entries, + bucketIndex_, + beforeTakeVars.borrowerDebt - afterTakeVars.borrowerDebt, + depositTake_, + auctionInfo.auctionPrice + ); // reserves are increased by take penalty of borrower (Deposit used from bucket - Borrower debt reduced) increaseInReserves += borrowerPenalty; @@ -241,30 +281,54 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // reserves are decreased by kicker reward decreaseInReserves += kickerReward; - if (beforeBucketTakeVars.kickerBond > afterBucketTakeVars.kickerBond) { + if (beforeTakeVars.kickerBond > afterTakeVars.kickerBond) { // **RE7**: Reserves increase by bond penalty on take. - increaseInReserves += beforeBucketTakeVars.kickerBond - afterBucketTakeVars.kickerBond; + increaseInReserves += beforeTakeVars.kickerBond - afterTakeVars.kickerBond; // **A7**: Total Bond decrease by bond penalty on take. - decreaseInBonds += beforeBucketTakeVars.kickerBond - afterBucketTakeVars.kickerBond; + decreaseInBonds += beforeTakeVars.kickerBond - afterTakeVars.kickerBond; } + // **R7**: Exchange rates are unchanged under depositTakes // **R8**: Exchange rates are unchanged under arbTakes exchangeRateShouldNotChange[bucketIndex_] = true; + // Reserves can increase with roundings in deposit calculations when auction Price is very small + if (auctionInfo.auctionPrice != 0 && auctionInfo.auctionPrice < 100) { + reservesErrorMargin = (beforeTakeVars.deposit - afterTakeVars.deposit) / auctionInfo.auctionPrice; + } + + // Reserves can increase by up to 2e-18 (1/5e17) due to rounding error in inflator value multiplied with t0Debt + (uint256 inflator, ) = _pool.inflatorInfo(); + reservesErrorMargin = Math.max(reservesErrorMargin, inflator/5e17); + + // In case of bucket take, collateral is taken at bucket price. + uint256 takePrice = _priceAt(bucketIndex_); + + // **RE9**: Reserves unchanged by takes and bucket takes below TP(at the time of kick) + if (takePrice < auctionInfo.debtToCollateral) { + increaseInReserves = 0; + decreaseInReserves = 0; + } + // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); - if (kickTime == 0 && _pool.poolType() == 1) { - buckets.add(auctionBucketIndex); - if (beforeBucketTakeVars.borrowerLps < afterBucketTakeVars.borrowerLps) { - lenderDepositTime[borrower_][auctionBucketIndex] = block.timestamp; + if ( + _getAuctionInfo(borrower_).kickTime == 0 + && + _pool.poolType() == 1 + ) { + buckets.add(auctionInfo.auctionPriceIndex); + if (beforeTakeVars.borrowerLps < afterTakeVars.borrowerLps) { + lenderDepositTime[borrower_][auctionInfo.auctionPriceIndex] = block.timestamp; } } // assign value to fenwick tree to mitigate rounding error that could be created in a _fenwickRemove call - fenwickDeposits[bucketIndex_] = afterBucketTakeVars.deposit; - + fenwickDeposits[bucketIndex_] = afterTakeVars.deposit; } catch (bytes memory err) { + // Reset event Logs + vm.getRecordedLogs(); + _ensurePoolError(err); } } @@ -278,25 +342,27 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { uint256 maxDepth_ ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.settleAuction']++; - ( - uint256 borrowerT0Debt, - uint256 collateral, - ) = _pool.borrowerInfo(borrower_); - (uint256 reservesBeforeAction, , , , )= _poolInfo.poolReservesInfo(address(_pool)); + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(borrower_); + + uint256 reservesBeforeAction = _getReservesInfo().reserves; (uint256 inflator, ) = _pool.inflatorInfo(); - try _pool.settle(borrower_, maxDepth_) { + try _pool.settle( + borrower_, + maxDepth_ + ) { numberOfActions['settle']++; // settle borrower debt with exchanging borrower collateral with quote tokens starting from hpb - while (maxDepth_ != 0 && borrowerT0Debt != 0 && collateral != 0) { + while (maxDepth_ != 0 && borrowerInfo.t0Debt != 0 && borrowerInfo.collateral != 0) { uint256 bucketIndex = fenwickIndexForSum(1); - uint256 maxSettleableDebt = Maths.floorWmul(collateral, _priceAt(bucketIndex)); + uint256 maxSettleableDebt = Maths.floorWmul(borrowerInfo.collateral, _priceAt(bucketIndex)); uint256 fenwickDeposit = fenwickDeposits[bucketIndex]; - uint256 borrowerDebt = Maths.wmul(borrowerT0Debt, inflator); + uint256 borrowerDebt = Maths.wmul(borrowerInfo.t0Debt, inflator); if (fenwickDeposit == 0 && maxSettleableDebt != 0) { - collateral = 0; + borrowerInfo.collateral = 0; // Deposits in the tree is zero, insert entire collateral into lowest bucket 7388 // **B5**: when settle with collateral: record min bucket where collateral added buckets.add(7388); @@ -306,23 +372,26 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // enough deposit in bucket and collateral avail to settle entire debt if (fenwickDeposit >= borrowerDebt && maxSettleableDebt >= borrowerDebt) { fenwickDeposits[bucketIndex] -= borrowerDebt; - collateral -= Maths.ceilWdiv(borrowerDebt, _priceAt(bucketIndex)); - borrowerT0Debt = 0; + + borrowerInfo.collateral -= Maths.ceilWdiv(borrowerDebt, _priceAt(bucketIndex)); + borrowerInfo.t0Debt = 0; } // enough collateral, therefore not enough deposit to settle entire debt, we settle only deposit amount else if (maxSettleableDebt >= fenwickDeposit) { fenwickDeposits[bucketIndex] = 0; - collateral -= Maths.ceilWdiv(fenwickDeposit, _priceAt(bucketIndex)); - borrowerT0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); + + borrowerInfo.collateral -= Maths.ceilWdiv(fenwickDeposit, _priceAt(bucketIndex)); + borrowerInfo.t0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); } // exchange all collateral with deposit else { fenwickDeposits[bucketIndex] -= maxSettleableDebt; - collateral = 0; - borrowerT0Debt -= Maths.floorWdiv(maxSettleableDebt, inflator); + + borrowerInfo.collateral = 0; + borrowerInfo.t0Debt -= Maths.floorWdiv(maxSettleableDebt, inflator); } } else { - collateral = 0; + borrowerInfo.collateral = 0; // **B5**: when settle with collateral: record min bucket where collateral added. // Lender doesn't get any LP when settle bad debt. buckets.add(7388); @@ -333,9 +402,10 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { } // if collateral becomes 0 and still debt is left, settle debt by reserves and hpb making buckets bankrupt - if (borrowerT0Debt != 0 && collateral == 0) { + if (borrowerInfo.t0Debt != 0 && borrowerInfo.collateral == 0) { + + uint256 reservesAfterAction = _getReservesInfo().reserves; - (uint256 reservesAfterAction, , , , )= _poolInfo.poolReservesInfo(address(_pool)); if (reservesBeforeAction > reservesAfterAction) { // **RE12**: Reserves decrease by amount of reserve used to settle a auction decreaseInReserves = reservesBeforeAction - reservesAfterAction; @@ -343,23 +413,28 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // Reserves might increase upto 2 WAD due to rounding issue increaseInReserves = reservesAfterAction - reservesBeforeAction; } - borrowerT0Debt -= Maths.min(Maths.wdiv(decreaseInReserves, inflator), borrowerT0Debt); + borrowerInfo.t0Debt -= Maths.min( + Maths.wdiv(decreaseInReserves, inflator), + borrowerInfo.t0Debt + ); - while (maxDepth_ != 0 && borrowerT0Debt != 0) { + while (maxDepth_ != 0 && borrowerInfo.t0Debt != 0) { uint256 bucketIndex = fenwickIndexForSum(1); uint256 fenwickDeposit = fenwickDeposits[bucketIndex]; - uint256 borrowerDebt = Maths.wmul(borrowerT0Debt, inflator); + uint256 borrowerDebt = Maths.wmul(borrowerInfo.t0Debt, inflator); if (bucketIndex != MAX_FENWICK_INDEX) { // debt is greater than bucket deposit if (borrowerDebt > fenwickDeposit) { fenwickDeposits[bucketIndex] = 0; - borrowerT0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); + + borrowerInfo.t0Debt -= Maths.floorWdiv(fenwickDeposit, inflator); } // bucket deposit is greater than debt else { fenwickDeposits[bucketIndex] -= borrowerDebt; - borrowerT0Debt = 0; + + borrowerInfo.t0Debt = 0; } } @@ -367,8 +442,13 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { } } // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); - if (kickTime == 0 && collateral % 1e18 != 0 && _pool.poolType() == 1) { + if ( + _getAuctionInfo(borrower_).kickTime == 0 + && + borrowerInfo.collateral % 1e18 != 0 + && + _pool.poolType() == 1 + ) { buckets.add(7388); lenderDepositTime[borrower_][7388] = block.timestamp; } @@ -377,26 +457,63 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { } } - function getBucketTakeInfo(uint256 bucketIndex_, address kicker_, address taker_, uint256 auctionBucketIndex_, address borrower_) internal view returns(LocalBucketTakeVars memory bucketTakeVars) { - (bucketTakeVars.kickerLps, ) = _pool.lenderInfo(bucketIndex_, kicker_); - (bucketTakeVars.takerLps, ) = _pool.lenderInfo(bucketIndex_, taker_); - ( , , , bucketTakeVars.deposit, ) = _pool.bucketInfo(bucketIndex_); - bucketTakeVars.kickerBond = _getKickerBond(kicker_); - (bucketTakeVars.borrowerLps, ) = _pool.lenderInfo(auctionBucketIndex_, borrower_); + function _getTakeInfo( + uint256 bucketIndex_, + address kicker_, + address taker_, + uint256 auctionBucketIndex_, + address borrower_ + ) internal view returns(LocalTakeVars memory takeVars) { + takeVars.kickerLps = _getLenderInfo(bucketIndex_, kicker_).lpBalance; + takeVars.takerLps = _getLenderInfo(bucketIndex_, taker_).lpBalance; + takeVars.borrowerLps = _getLenderInfo(auctionBucketIndex_, borrower_).lpBalance; + + takeVars.deposit = _getBucketInfo(bucketIndex_).deposit; + takeVars.kickerBond = _getKickerInfo(kicker_).totalBond; + + BorrowerInfo memory borrowerInfo = _getBorrowerInfo(borrower_); + takeVars.borrowerDebt = borrowerInfo.debt; + takeVars.borrowerCollateral = borrowerInfo.collateral; } - // Helper function to calculate quote tokens from lps in a bucket irrespective of deposit available. - function lpToQuoteToken(uint256 lps_, uint256 bucketIndex_) internal view returns(uint256 quoteTokens_) { - (uint256 bucketLP, uint256 bucketCollateral , , uint256 bucketDeposit, ) = _pool.bucketInfo(bucketIndex_); + // Helper function to calculate borrower penalty and kicker reward in bucket take through events emitted. + function _getBorrowerPenaltyAndKickerReward( + Vm.Log[] memory entries, + uint256 bucketIndex_, + uint256 borrowerDebtRepaid_, + bool depositTake_, + uint256 auctionPrice_ + ) internal view returns(uint256 borrowerPenalty_, uint256 kickerReward_) { + // Kicker lp reward read from `BucketTakeLPAwarded(taker, kicker, lpAwardedTaker, lpAwardedKicker)` event. + (, uint256 kickerLpAward) = abi.decode(entries[0].data, (uint256, uint256)); + kickerReward_ = _rewardedLpToQuoteToken(kickerLpAward, bucketIndex_); + + // Collateral Taken calculated from `BucketTake(borrower, index, amount, collateral, bondChange, isReward)` event. + (, , uint256 collateralTaken, ,) = abi.decode(entries[1].data, (uint256, uint256, uint256, uint256, bool)); + + if (depositTake_) { + borrowerPenalty_ = Maths.ceilWmul(collateralTaken, _priceAt(bucketIndex_)); + } else { + borrowerPenalty_ = Maths.ceilWmul(collateralTaken, auctionPrice_); + } + + borrowerPenalty_ -= borrowerDebtRepaid_; + } - quoteTokens_ = Buckets.lpToQuoteTokens( - bucketCollateral, - bucketLP, - bucketDeposit, + // Helper function to calculate quote tokens from lps in a bucket irrespective of deposit available. + // LP rewarded -> quote token rounded up (as LP rewarded are calculated as rewarded quote token -> LP rounded down) + function _rewardedLpToQuoteToken( + uint256 lps_, + uint256 bucketIndex_ + ) internal view returns(uint256 quoteTokens_) { + BucketInfo memory bucketInfo = _getBucketInfo(bucketIndex_); + quoteTokens_ = Buckets.lpToQuoteTokens( + bucketInfo.collateral, + bucketInfo.lpBalance, + bucketInfo.deposit, lps_, _priceAt(bucketIndex_), - Math.Rounding.Down + Math.Rounding.Up ); } - -} +} \ No newline at end of file diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol index c6493c439..758fc33fa 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol @@ -17,11 +17,10 @@ abstract contract UnboundedReservePoolHandler is BaseHandler { function _kickReserveAuction() internal updateLocalStateAndPoolInterest { numberOfCalls['UBReserveHandler.kickReserveAuction']++; - (, uint256 claimableReserves, , , ) = _poolInfo.poolReservesInfo(address(_pool)); + uint256 claimableReserves = _getReservesInfo().claimableReserves; if (claimableReserves == 0) return; try _pool.kickReserveAuction() { - // **RE11**: Reserves increase by claimableReserves by kickReserveAuction decreaseInReserves += claimableReserves; } catch (bytes memory err) { @@ -41,17 +40,17 @@ abstract contract UnboundedReservePoolHandler is BaseHandler { // ensure actor always has the amount to take reserves _ensureAjnaAmount(_actor, 1e45); - (, uint256 claimableReservesBeforeAction, ,) = _pool.reservesInfo(); - - try _pool.takeReserves(amount_) { + uint256 claimableReservesBeforeTake = _getReservesInfo().claimableReservesRemaining; - (, uint256 claimableReservesAfterAction, ,) = _pool.reservesInfo(); + try _pool.takeReserves( + amount_ + ) { + uint256 claimableReservesAfterTake = _getReservesInfo().claimableReservesRemaining; // reserves are guaranteed by the protocol) require( - claimableReservesAfterAction < claimableReservesBeforeAction, + claimableReservesAfterTake < claimableReservesBeforeTake, "QT1: claimable reserve not avaialble to take" ); - } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/interfaces/IBaseHandler.sol b/tests/forge/invariants/interfaces/IBaseHandler.sol index 4f8e365bb..f14fb1023 100644 --- a/tests/forge/invariants/interfaces/IBaseHandler.sol +++ b/tests/forge/invariants/interfaces/IBaseHandler.sol @@ -27,6 +27,7 @@ interface IBaseHandler { function previousReserves() external view returns(uint256); function increaseInReserves() external view returns(uint256); function decreaseInReserves() external view returns(uint256); + function reservesErrorMargin() external view returns(uint256); function borrowerPenalty() external view returns(uint256); function kickerReward() external view returns(uint256); diff --git a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol b/tests/forge/invariants/interfaces/IPositionsHandler.sol similarity index 52% rename from tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol rename to tests/forge/invariants/interfaces/IPositionsHandler.sol index 1988f2a7b..57fb47cae 100644 --- a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol +++ b/tests/forge/invariants/interfaces/IPositionsHandler.sol @@ -2,17 +2,10 @@ pragma solidity 0.8.18; -interface IPositionsAndRewardsHandler { - // positionManager & rewardsManager +interface IPositionsHandler { function getBucketIndexesWithPosition(address) external view returns(uint256[] memory); function getBucketIndexesByTokenId(uint256) external view returns(uint256[] memory); - // positionManager function getTokenIdsByActor() external view returns(uint256[] memory); function getTokenIdsByBucketIndex(address, uint256) external view returns(uint256[] memory); - - // rewardsManager - function rewardsClaimedPerEpoch(address, uint256) external view returns(uint256); - function updateRewardsClaimedPerEpoch(address, uint256) external view returns(uint256); - function getStakedTokenIdsByActor() external view returns(uint256[] memory); } \ No newline at end of file diff --git a/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol index d9ad7e9a4..d1b93a976 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol @@ -3,6 +3,8 @@ pragma solidity 0.8.18; import { BasicERC20PoolInvariants } from "../../invariants/ERC20Pool/BasicERC20PoolInvariants.t.sol"; +import { _depositFeeRate } from "src/libraries/helpers/PoolHelper.sol"; +import { Maths } from "src/libraries/internal/Maths.sol"; contract RegressionTestBasicERC20Pool is BasicERC20PoolInvariants { @@ -228,9 +230,13 @@ contract RegressionTestBasicERC20Pool is BasicERC20PoolInvariants { _basicERC20PoolHandler.addQuoteToken(1, depositAt2570, 2570, 0); _basicERC20PoolHandler.addQuoteToken(1, depositAt2571, 2571, 0); _basicERC20PoolHandler.addQuoteToken(1, depositAt2572, 2572, 0); + (uint256 interestRate, ) = _pool.interestRateInfo(); + depositAt2570 = Maths.wmul(depositAt2570, Maths.WAD - _depositFeeRate(interestRate)); + depositAt2571 = Maths.wmul(depositAt2571, Maths.WAD - _depositFeeRate(interestRate)); + depositAt2572 = Maths.wmul(depositAt2572, Maths.WAD - _depositFeeRate(interestRate)); assertEq(_pool.depositIndex(depositAt2570), 2570); assertEq(_pool.depositIndex(depositAt2570 + depositAt2571), 2571); - if (depositAt2572 != 0) { + if (depositAt2572 > scale) { assertEq(_pool.depositIndex(depositAt2570 + depositAt2571 + depositAt2572), 2572); } } diff --git a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol index 50da1a654..90a5ad920 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol @@ -565,6 +565,25 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { _liquidationERC20PoolHandler.bucketTake(437995719506453073927178171450999258981540842, 1, false, 10505745254535225521787303755428772101316447294490000685852, 1); invariant_auction(); } + + /* + Test was failing in bucket take due to kicker reward calculated 1 unit more than borrower penalty due to rounding in invariant handler. + Fixed by rounding up borrower penalty calculations. + */ + function test_regression_failure_A8_5() external { + _liquidationERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC20PoolHandler.transferLps(1000000723349964869, 788851800116510692513009799204, 999999998987189766687331, 1999999999999999999996779233486571999676542926, 17578572791586479054160852518); + _liquidationERC20PoolHandler.pullCollateral(245127557453865308850344, 29075872215974757772618544502249112026637573331041, 320926102985372314407801867544337409222117895231322939819); + _liquidationERC20PoolHandler.moveQuoteToken(3251769792, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 105206693738956439744956997581001974547690524037387997795061, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.removeCollateral(2, 1503807476050804044708293765108412212021375967876200308856270774431709, 3, 2016143937953654763718116642678378945337231563); + _liquidationERC20PoolHandler.kickAuction(20039169419373110383609479377, 1724901769, 709527059171478980285358094387900703425179029953176145265918012141182596, 28813093304904246843464); + _liquidationERC20PoolHandler.stampLoan(113260412868390240841, 1); + _liquidationERC20PoolHandler.stampLoan(0, 3); + _liquidationERC20PoolHandler.addCollateral(62058676330172980020738666, 1000000000038455964, 3123151313420689462484, 311810622805541359080687896812); + _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.bucketTake(57735102665284417941269, 1000000000000000000000999997966378072510645569, false, 144674580308375297229175702508, 2105345777576680966242023933); + invariant_auction(); + } } contract RegressionTestLiquidationWith10BucketsERC20Pool is LiquidationERC20PoolInvariants { @@ -707,7 +726,6 @@ contract RegressionTestLiquidationWith10BucketsERC20Pool is LiquidationERC20Pool } - contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20PoolInvariants { function setUp() public override { @@ -2147,8 +2165,8 @@ contract RegressionTestReserveEvmRevertERC720Pool is LiquidationERC20PoolInvaria invariant_auction(); } } -contract RegressionTestLiquidationWith18QuotePrecision4CollateralPrecisionERC20Pool is LiquidationERC20PoolInvariants { +contract RegressionTestLiquidationWith18QuotePrecision4CollateralPrecisionERC20Pool is LiquidationERC20PoolInvariants { function setUp() public override { vm.setEnv("QUOTE_PRECISION", "18"); vm.setEnv("COLLATERAL_PRECISION", "4"); @@ -2174,5 +2192,60 @@ contract RegressionTestLiquidationWith18QuotePrecision4CollateralPrecisionERC20P invariant_exchange_rate(); } +} +contract RegressionTestLiquidationWith8CollateralPrecisionERC20Pool is LiquidationERC20PoolInvariants { + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "8"); + super.setUp(); + } + + function test_regression_exchange_rate_failure() external { + _liquidationERC20PoolHandler.kickAuction(0, 17104183949941796511, 0, 280417724462859438244277310225109843561163957492078708458152152913172346); + _liquidationERC20PoolHandler.pledgeCollateral(0, 140265038788604003138859102577, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.bucketTake(5683872789780248582962257270041, 1, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + + invariant_exchange_rate(); + } } + +contract RegressionTestLiquidationWith12QuotePrecisionERC20Pool is LiquidationERC20PoolInvariants { + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "12"); + vm.setEnv("COLLATERAL_PRECISION", "18"); + super.setUp(); + } + + /** + Test was failing with underflow. Resolved by invariant improvements in PR#955. + */ + function test_regression_take_exchange_rate_underflow() external { + _liquidationERC20PoolHandler.pullCollateral(1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 45909730277988842415738220537184944537676, 1, 0, 0); + _liquidationERC20PoolHandler.kickAuction(70010871234460820744715912936890564712867991293425383626279454116593850533, 6499767, 28762655686049589541294942431851230420669838142, 1571345); + _liquidationERC20PoolHandler.addQuoteToken(181090242960530, 2377505175853220826817239127143875084418686811649475368310406086770995769749, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 72033836997607978984292992820571); + _liquidationERC20PoolHandler.withdrawBonds(695237110902130656531864435588814770662540280753085713853371273119165032, 76187813332501807831094303, 12572696008628451448752492); + _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 2, 9); + _liquidationERC20PoolHandler.kickAuction(1999999999999999999999043403500806748920639352, 3061195076792591263023058803418546501128, 2379220920797631821002222390458479008558342658478194460908722057821, 31903477196625138712736675); + _liquidationERC20PoolHandler.takeAuction(2, 885557492487161046, 1558101439297927368671261, 1292998037045564783449417757876861668872); + + invariant_exchange_rate(); + } + + /* + Test was failing because invariant logic for interest accrual was using the pending inflator to calculate HTP. + Fixed by calculating HTP using current pool inflator. + */ + function test_regression_failure_deposits_on_kick_1() external { + _liquidationERC20PoolHandler.drawDebt(2, 3221259065514816790487893458767898964, 4116413047421407597131232320880820919452009); + _liquidationERC20PoolHandler.withdrawBonds(1011868801812554352, 787959216853107061817696631727, 787949941098203131552111773821); + _liquidationERC20PoolHandler.lenderKickAuction(1013350938108023449, 709545743875727362579966764062968642140163108918930414591019589180725257, 1000019286889406901); + _liquidationERC20PoolHandler.pledgeCollateral(702496096288315654151051035260624996909623141681685150581265170070799900, 1025766506493781142223686516002, 1882017544514540473); + _liquidationERC20PoolHandler.addQuoteToken(184116457409845008802273399124418717054, 425420151153612354346298303754178903917488200526, 1524671197004160260571450442257224437845065293837405292129734683, 18328493294); + _liquidationERC20PoolHandler.pledgeCollateral(4184073188804616272013253095810669088604050280846044378968594414041510976844, 15476914321184942485933234133477, 999999999999999999999999999999999999999962315); + _liquidationERC20PoolHandler.kickAuction(2748385666284590326694, 1985130059088839548857545717, 2650077542301436190503272880334, 962354226098822); + + invariant_fenwick(); + } +} \ No newline at end of file diff --git a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol index 38238fc7f..b4b50dc29 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -1103,6 +1103,65 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { invariant_reserves(); } + /** + Test was failing in bucket take because of total reward calculated 1 unit less than taker reward due to rounding. + Fixed by calculating kicker reward only when total reward is greater than taker reward. + */ + function test_regression_bucket_take_arithmetic_over_underflow() external { + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1644755755592, 1959341507995549485252446); + _reserveERC20PoolHandler.transferLps(978535271576710676299781512516, 16098465890038718399935149108, 1448369905976755312991, 2000000437612435879631304211889, 2334526172727163946751610); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1957944, 350546778875546746949203120839869581644186, 1909020541887755559056550203807280332183167182459, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(240639932869060867937218082568651310505928854172964882670536199212801389, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 91142045672818924549776487045969516692421, 2); + _reserveERC20PoolHandler.takeAuction(847775274135304201693442802951942471956040628099463426658, 15437905983783, 3021853142853682116706828163678513643058264678516883895459894928, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(218829779082276597765702846551699258628317130832421, 280724425438786478945154682490650546683941835815462758599200198161, 111914756, 123107726091484989021093274023272769706926424743574450590, 179575236363434987440104); + _reserveERC20PoolHandler.addQuoteToken(4297946054336748243086707072598519007417628445, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6197979715556281575155572087704038006338731777143760188196); + _reserveERC20PoolHandler.moveQuoteToken(167613418362075128105108939402493441018698866633227, 262828624041670935140279333927912328409007891154917147, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.lenderKickAuction(12197725906791943334871217668864585709165849216409181, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 70725521863129038810985623968851609237); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 300752541693626254472549156222621163034080128650748453137); + _reserveERC20PoolHandler.bucketTake(34340038744157012785217068122223542629705265691484769346092334880775572, 3, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5); + _reserveERC20PoolHandler.transferLps(155227010272947024654, 3979, 14910698722141667014830239878, 32292219746171378696382686750905, 702470039723650472853373511323619201264376740059252842873620476391647153); + _reserveERC20PoolHandler.pledgeCollateral(15009631535641755367315249199883042255, 1242103542388660490644157825722210605939946175860408653463311, 138153650027265703842616); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 139465, 2365279393851601839489146993905474629987024, 254016223957851329609435735073288789372943399004393360105510319); + _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.settleAuction(2746, 14910898275941098990574623223, 250991308245266349, 391872544809136150711089553100); + _reserveERC20PoolHandler.kickReserveAuction(6316151018785827280299720335, 20172452359986642426397928979); + _reserveERC20PoolHandler.drawDebt(1058746730185409946, 688007029214871145227109798489438459916415067825650097323246830710161407, 1024414730660373408); + _reserveERC20PoolHandler.addCollateral(1690145554, 519988602335840889977616288107, 1741768576, 1000033915538988948); + _reserveERC20PoolHandler.bucketTake(3, 185058816859586233891008435707544391368868631160914389, false, 4530135247013654, 15691707183130113816464097191168520076563613870282071594338041203); + } + + /** + Test was failing because rewards differ by 1 gwei. + Fixed by updating TakerActions to round in favor of the protocol. + **/ + function test_regression_equivalent_rewards_on_take_A8() external { + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 186, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(702555080221925111442235101208458356417149500340156719083570911869585030, 1000032244817342892, 5728, 5907050982353226005633690); + _reserveERC20PoolHandler.moveQuoteToken(688008771392821209054006930063060492511262218297247835920927151049965569, 1000259178895617557, 7180441242553988447746122786, 216450160307007747500389357, 999970054977710845412932917383); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 18694763467974013375909729483405538071349537050941877688230901475624371810, 3063772036798766170756187646253602, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 4461285713774321097323261260815305817048191133452574325); + _reserveERC20PoolHandler.removeQuoteToken(187125087688063596684224028224017465563990405145, 1, 3, 0); + _reserveERC20PoolHandler.takeAuction(126553, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 6092025869035498002801041293341729609328640575790487069100672274, 111933338551295177700896412130593678998178179083162406077575); + invariant_auction(); + } + + /** + Test was failing because kicker reward went negative. + Fixed by updating calculation in UnboundedLiquidationPoolHandler._bucketTake. + **/ + function test_regression_fenwick_overflow_on_bucketTake() external { + _reserveERC20PoolHandler.pledgeCollateral(6350058051515749101632494, 394728019280243247197391935, 1000226947060929945); + _reserveERC20PoolHandler.lenderKickAuction(551739522123447953718609926799, 29959904068493160226, 695277117643056667684065838815807991886030299764502895676394782692460545); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 346390061016453699097263788381540543801879524975, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(11301737, 355771, 2, 2); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.kickReserveAuction(3, 2231676212031384998427); + _reserveERC20PoolHandler.removeCollateral(2999999999999999999999999998988019665354522083, 1035322182001286518, 695165544206547503308377521130384690735039945359133611786714594690651433, 1004661270349627628); + _reserveERC20PoolHandler.bucketTake(447001332907764750034625708199, 1020546679384387976, true, 1012523217442524004724156, 18158702416679488818029017510144); + _reserveERC20PoolHandler.bucketTake(402642984652752865557170717473, 0, false, 2372112862459332523316520992118272, 15759742); + invariant_fenwick(); + } + } contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvariants { @@ -1368,6 +1427,21 @@ contract RegressionTestReserveWith8CollateralPrecisionERC20Pool is ReserveERC20P invariant_reserves(); } + + /* + Test failed because RE9 was incorrectly implemented that take below tp (at time of take) doesn't change reserves. + Fixed by updating RE9 implementation to `Reserves are unchanged by take below tp (at time of kick)`. + */ + function test_regression_failure_reserves_on_bucketTake() external { + _reserveERC20PoolHandler.bucketTake(21318, 17209, false, 7256, 2112895574); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.removeQuoteToken(134507693871374985842462, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3133413913960740507); + _reserveERC20PoolHandler.bucketTake(2198, 20978, true, 9160, 2602); + _reserveERC20PoolHandler.takeAuction(19082, 7296, 22883, 1795); + _reserveERC20PoolHandler.bucketTake(3048, 3562, true, 11832, 12708); + + invariant_reserves(); + } } contract RegressionTestReservesWith18QuotePrecision4CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { @@ -1397,3 +1471,3790 @@ contract RegressionTestReservesWith18QuotePrecision4CollateralPrecisionERC20Pool } } + +contract RegressionTestReservesWith8QuotePrecision12CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "8"); + vm.setEnv("COLLATERAL_PRECISION", "12"); + super.setUp(); + } + + /** + Test was failing in bucket take below tp due to Reserves increase with roundings in deposit calculations when auction Price is very small. + Fixed by adding a reserves error acceptance margin of quoteToken/auctionPrice. + */ + function test_regression_bucket_take_re9_failure() external { + _reserveERC20PoolHandler.drawDebt(24508, 6004, 12873); + _reserveERC20PoolHandler.settleAuction(1622320951432348052667116641401087769239742492942, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 3); + _reserveERC20PoolHandler.drawDebt(24503, 7132, 8782); + _reserveERC20PoolHandler.bucketTake(202710807569127533859817400773714809979026059631061598064177268, 2385357505634384043709761419393984920, true,694050224651817452208361345174057184524500415461429528395753834136733358928, 139804506994); + _reserveERC20PoolHandler.pullCollateral(9052366115474232323230371391544137674838932567014847098128822449097, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(1672372126, 2686, 4981, 3704, 22645); + _reserveERC20PoolHandler.moveQuoteToken(3096, 8668, 1318, 4257, 33952); + _reserveERC20PoolHandler.kickAuction(3968, 6743, 3857, 463); + _reserveERC20PoolHandler.settleAuction(12887, 8185, 10534, 7613); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 50125298687992691, 6426773705941355197739888078198041158818108804992591704360862); + _reserveERC20PoolHandler.addCollateral(12853, 17657, 499654491, 20120); + _reserveERC20PoolHandler.bucketTake(10738, 1583, false, 37901, 8140); + invariant_reserves(); + } + +} + +contract RegressionTestReservesWith18QuotePrecision6CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "6"); + vm.setEnv("NO_OF_BUCKETS", "30"); + vm.setEnv("NO_OF_ACTORS", "50"); + super.setUp(); + } + /** + Test was failing in moveQuoteToken due to Lps getting added to toBucket without any deposit being added. + This situation arises when toBucketScale is large enough to make unscaled amount to move 0. moveQuoteToken did not have unscaledAmount == 0 check. + */ + function test_regression_B2_failure_moveQuote() external { + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(37642562402173750010, 2904559723264204341469701706, 10656653005746874933472811298, 1331491774496795422259020499820184178725565528690773573301367964081480684, 1999999999999999999); + _reserveERC20PoolHandler.moveQuoteToken(49046620449355538574108822723048473721226797556007972061207479861126558122005, 23784, 19123881933102896477378198103061, 1000414154273075144, 619264012354860144763880256225); + _reserveERC20PoolHandler.withdrawBonds(1004883798352154948, 11947170379806477397732457006311, 1477952512257156998936012715837); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 3); + _reserveERC20PoolHandler.stampLoan(34268240363921090802, 2803486243230681708692); + _reserveERC20PoolHandler.repayDebt(335178484623288505236146247200177153211434750469, 1000304350203678961561749662328, 1116826706101508024); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 265665595536910455721419627680330128971263024672346167033455279634443, 2); + _reserveERC20PoolHandler.moveQuoteToken(1657691958460652257817721055, 128072191243841582442294925179764165397182820830493893418841, 4694922462231054608489220624937610780, 2, 0); + _reserveERC20PoolHandler.drawDebt(1008192421263265380, 4517225061142593990014708057357, 24141); + _reserveERC20PoolHandler.removeCollateral(1001129709185447992, 3220690943477987049807033010837445643371744885401272976673118302376935, 3412186810, 111979); + _reserveERC20PoolHandler.kickAuction(3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.kickAuction(468454966848660, 0, 30126653398953890458934504947574, 0); + _reserveERC20PoolHandler.takeAuction(3, 730026890361279402974108678930380999203467765412415979, 628041607447162342701529524618502585069671378829099310, 52037600594867); + _reserveERC20PoolHandler.takeAuction(3, 9093784184160867955, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 49426735425491859878574883153968); + _reserveERC20PoolHandler.takeAuction(999999999999999999000000000002, 8787640851723169, 67635, 1079264131468941241); + _reserveERC20PoolHandler.takeReserves(115699975290581306710287262372735, 4108, 3926293078); + _reserveERC20PoolHandler.pullCollateral(4855, 45164, 552702555689170837845113726412); + _reserveERC20PoolHandler.kickAuction(31543111575, 206641648502291266814166441135001345683324218028137, 2, 270860970868659); + _reserveERC20PoolHandler.stampLoan(158717467331416019238731332649, 1000001343893597087); + _reserveERC20PoolHandler.kickReserveAuction(97983926411679345474877640016, 798876146163542422425948018); + _reserveERC20PoolHandler.kickAuction(1, 302963010203563217045817940832058, 1018385263215619388112308840704950032215637115163284158368967134127049893, 859382230981419552422); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1, 2250829479793965043112393498212445003681726733267413737114608); + _reserveERC20PoolHandler.pullCollateral(3550, 2699, 2999999999999999999999999998212019379567521146); + _reserveERC20PoolHandler.pledgeCollateral(7654031896205520683367911145188232047526991468011916645644996268959881, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(1242909492826417758811595914240, 33679, true, 110541095857117588638158761720577, 15090945451208801725994427988659); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1206649867156059110626296550961611770411460037634181640022, 734256886560207259070567292421738811835983360067867745873368356977, 17036220675); + _reserveERC20PoolHandler.lenderKickAuction(45662835087424134003642092876268526009069159, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(3429551819, 28974, true, 1014624400228610056, 260202225170683118622930860078); + _reserveERC20PoolHandler.addQuoteToken(0, 0, 368643525370126122865174898240876890193114741888, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(805173009076241759333109768105647925108786848870165244419235965052322, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(9102494126705912136391635961552, 3783032520536094598000000000001, 5517466683162027208627184808741); + _reserveERC20PoolHandler.drawDebt(8698646, 9601730769805593290860718038343291222144, 3); + _reserveERC20PoolHandler.bucketTake(0, 1130076866133441653066968291313836924919464218002922083969963093118603, true, 1453951219834897560228, 1); + _reserveERC20PoolHandler.removeQuoteToken(30482178350208701079706415428092, 783745149037624386585550186429, 2795441907963653198291, 1423930419712560391149071321229601042172357165885); + _reserveERC20PoolHandler.takeAuction(16385, 23002506274057403217924980440245, 1001755824294256451, 206598265514633648164257454674); + _reserveERC20PoolHandler.moveQuoteToken(808115637510339346987980910484201554880049403535211888190553939708394, 21172862412434827254487486033637085907171942794544723144205227622806764660184, 13128073886717853735365553573950572258, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(3437495112021185144385124595850567190038499942, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1040266413224669020577137878616); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.removeCollateral(3393789201, 9608831946164913767718400489, 999999999999999999999999999201, 1605448412177742017393657805308134475240492878800451229462083898729962615); + _reserveERC20PoolHandler.settleAuction(4947397177099301994545275559682766421540051743403377838144943962898171, 7077350928441221692629041404760, 606953422376098533486721405816942628, 32655172178692766299189013481534823734255); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 64730736141699810042774821578321223102332167752990, 8976690007292448925274126127498162327370402409); + _reserveERC20PoolHandler.settleAuction(10883036741901438467671283079619319366495184230539472516244, 3185905162002335798, 563955895685323566436, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.transferLps(73747, 114611474448027634600235153839231428197375546068683912824050264275057755995777, 12311, 10619131837839703049437348328893, 22012); + _reserveERC20PoolHandler.repayDebt(19490886905839046258464553234529721528219501433787277461396, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 570007); + _reserveERC20PoolHandler.addQuoteToken(1265313062124193198383171657268, 1243001927474216841017985775689, 985089034643502570822661366260662125519262487346007265687326441378381025, 7307508186654514697178579174800087908573304337235669764959155204); + _reserveERC20PoolHandler.transferLps(102323218402893140170627926756610, 35031638351875250549314648274754, 13201805297746991487306948870425, 65506, 1004959814542778579); + _reserveERC20PoolHandler.lenderKickAuction(32135, 32730, 107470); + _reserveERC20PoolHandler.addQuoteToken(1327002774761628913, 242093659266990, 9154582369034587240099145864183, 161236133566149516607); + _reserveERC20PoolHandler.kickAuction(148557178105758739342827405062, 8948708374796104827009952068367, 752169688703724029254139174841, 1000000756439655791); + _reserveERC20PoolHandler.addQuoteToken(435381640401452025213453281633010, 66767, 1009448195722588492, 999999086799978261); + _reserveERC20PoolHandler.bucketTake(42312, 65701, true, 7447, 2811304608608972325004825982661); + _reserveERC20PoolHandler.settleAuction(12956816065578107839247440075762, 999999086757990867999999, 1000001211168019496, 23698725416021562432343); + _reserveERC20PoolHandler.settleAuction(19991245651642183268611022153239, 1011591174700694233, 3814303885, 1000000000000063210); + _reserveERC20PoolHandler.stampLoan(16539192824490576482748390831, 8281296564376035766467088646693); + _reserveERC20PoolHandler.takeReserves(14565095858257663638699725926166, 1000000000000000000041718611022505469277808624, 911321890203952912632825386082); + _reserveERC20PoolHandler.removeCollateral(5779366742256304708421587141374585525761955778578667, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 5155301903333177813187407445257, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addCollateral(849780763312488485060831590510943022473868827588529262994477515, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(62666, 9088, 208020036141733040205661275829730, 999999999999998271017861409466459208446109031); + _reserveERC20PoolHandler.repayDebt(7868577833854263930192586982, 3563002411641593701328959, 10891865741082687010180273565300653035242); + _reserveERC20PoolHandler.kickReserveAuction(1879907284943600302271676779538912202678430602361590080741174876821, 248895193586379677219567192); + _reserveERC20PoolHandler.removeCollateral(133680764873922822756190603948146, 110660, 1019592565429153066, 7148285978104482052351783146738); + _reserveERC20PoolHandler.removeQuoteToken(1013329759075270666, 23603, 28338, 1656577080148706243515945988903227336335290961084842538604814590319019397); + _reserveERC20PoolHandler.takeAuction(38894353378845987341618976303304, 60765031729827910697264621403588316182529570832670969853587621380681188599459, 6930913201466847726605195767, 535787026336045316158); + _reserveERC20PoolHandler.pledgeCollateral(29327, 11568561597607592499663512289, 1009574318481086187); + _reserveERC20PoolHandler.takeReserves(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 32875608929003656732409563256255270173000690756790604154154765902089); + _reserveERC20PoolHandler.addCollateral(57066391561490679429183, 2620549433, 25199, 2721998507640457551634); + _reserveERC20PoolHandler.drawDebt(1519078156999656, 813579973302756680480149516, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.addCollateral(528, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 12649531341451027788733775487531317052733264410855707776259774028839721891245); + _reserveERC20PoolHandler.lenderKickAuction(22870134816715254542, 1000495951970901317, 2731098368592330690347); + _reserveERC20PoolHandler.pledgeCollateral(10480041655596534477067348276, 999999999999999999, 5105785804282851597299358); + _reserveERC20PoolHandler.settleAuction(1002307562575186330, 1000001513653347112, 22326, 8765023676929777074842298717063); + _reserveERC20PoolHandler.stampLoan(471092998655196430928608440551563, 1001482550522661429); + _reserveERC20PoolHandler.kickReserveAuction(61278, 110219346685965629431127252685990); + _reserveERC20PoolHandler.addQuoteToken(63315346304, 3, 449278986525604713461838959729536350729891841560390803014266023140, 1); + _reserveERC20PoolHandler.addQuoteToken(3331177199897255798180870934121854726320588161, 200561952950447534563084340465571467859975897154594701937434473315, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.addQuoteToken(107313943396321279, 4354, 2960676613341336214750882016916372955814956783131838494492275121780237281586, 801430277); + _reserveERC20PoolHandler.lenderKickAuction(513000690732841263173137480623008926431091, 612966676564642387450372950135290335931056463540439818292804211041478264, 0); + _reserveERC20PoolHandler.addQuoteToken(0, 9412483891784853232140403482147173715844914735605, 113105, 34040953374575350554885607936359418782220944521168475597499828913950); + _reserveERC20PoolHandler.settleAuction(23692408661812949240509199833019908544561567, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 95678290146660062092521468854715429169198101799256228142450663789287286); + _reserveERC20PoolHandler.transferLps(39696749383364, 65408921622587276955158111476109032153487, 13230439651832198145925122897082692199902791266240664101309010456783, 0, 1); + _reserveERC20PoolHandler.addCollateral(4866571773599597323073280738491957842303226836355542297, 39507803870579064094886642393054041886729837330651058635864834772657192, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.kickAuction(3, 1640393408711571831278012374245309190272560588971969114725903019391379479508, 1, 49099713126206153766918915302778488708409121398864970); + _reserveERC20PoolHandler.repayDebt(2310750510964915051772069797, 26749642396964445071760299012097834124871951554895328004511, 157364102255400017021090902636532); + _reserveERC20PoolHandler.settleAuction(1005004639975889978, 26484756821432353403, 50934, 1598); + _reserveERC20PoolHandler.bucketTake(36723352870165744101490067551753, 29999999999999999996992153671023349590036929699, false, 1244218290121641516566129454299, 182347436658528950166783055164); + _reserveERC20PoolHandler.stampLoan(321283919923302127827651535692360833, 19060753360392311487367913649547993834974770); + _reserveERC20PoolHandler.drawDebt(21303948393223722113894409624126011458800457027465268380346, 8555879868757976, 22679772829915516); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1227942203380083748950489549470399962062293398243381, 1155799463349376169508034099912612302653); + _reserveERC20PoolHandler.takeReserves(237577795, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(20506545835752511071357364287303845120702130358586552335616349704230610, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 20413550225262709567690483231485411759438345326437); + _reserveERC20PoolHandler.pledgeCollateral(52259880980899591075, 3039187888688329424622223400, 46397); + _reserveERC20PoolHandler.takeAuction(266191614232983735273531424042748544828814887992188925425709627500, 0, 52734024458083523376939533786, 1); + _reserveERC20PoolHandler.settleAuction(9581048927186226716462701011669838112662249515723843361767313929, 2, 2, 159241700633030894736691560839636343000081781140081957140); + _reserveERC20PoolHandler.stampLoan(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(162091225819886074282265645406479, 1113764505660524106059049549, 25484631824974318792552030396188); + _reserveERC20PoolHandler.moveQuoteToken(440285, 6707171850224462230981678560180266, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 2089092911515627639225770981079750247211708444515815583794292384886193439876); + _reserveERC20PoolHandler.removeCollateral(3, 2, 129227258927295388987248866788, 1464862990398809085970946208982073492262649291597626); + _reserveERC20PoolHandler.takeReserves(151825533062943134678968467797, 1005805586963047391, 60474); + _reserveERC20PoolHandler.transferLps(2, 57761224243784787561344570225552824510000512389305957022924835597, 33366272169494077962065618389905493264940838073091749686335991280255328480, 1226818929467483340591540834562215, 1332961435155); + _reserveERC20PoolHandler.lenderKickAuction(61901, 828690949286925292619996904703, 15889); + _reserveERC20PoolHandler.withdrawBonds(2, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(874805045645121022161038807764265009368600282240241857, 0, 17720312084534551378860430555493350986496361679747065); + _reserveERC20PoolHandler.kickAuction(20934389433568744551682743208671428341, 132784861374357203627, 3539655290530870770641134323909153551, 201842449063661854271887456681588482628926830153205022946646067036422639280); + _reserveERC20PoolHandler.stampLoan(217243868418377587294947853288, 40567); + _reserveERC20PoolHandler.bucketTake(15715, 1554725875711707770767950505583153845856543474257580574701613959727947300, false, 132216000022272890670522990538803, 93482255546821967179368472644093); + _reserveERC20PoolHandler.bucketTake(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 2, 170621813772); + _reserveERC20PoolHandler.removeCollateral(87490533647440741978588420437, 25562824512819651455981106, 1140, 31458102413749128203168669442379583768342123816499442600768499782045907262955); + _reserveERC20PoolHandler.lenderKickAuction(41948, 165626280612697807445299649001, 63600); + _reserveERC20PoolHandler.repayDebt(4031580380570000000000000, 27119208480505162084295542925794, 8149813563845175705473886410959); + _reserveERC20PoolHandler.moveQuoteToken(7265906890149654301553923086986081269601, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.removeQuoteToken(1002794652257663592, 66427, 331289518930283463063659, 1081147448723587352998723800314); + _reserveERC20PoolHandler.stampLoan(300627896167326717360449894904635, 885074771731775037716699045323); + _reserveERC20PoolHandler.stampLoan(16403964070271, 0); + _reserveERC20PoolHandler.settleAuction(0, 168077, 0, 1); + _reserveERC20PoolHandler.removeQuoteToken(3457977281120486778631088697804834975942780262, 1790328617839458354922133029, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3023292620685400832968761508412468627255105608696139783807140885579903, true, 4289025951144843502085586, 22319015879820); + _reserveERC20PoolHandler.moveQuoteToken(51691035972005835021466812008782954569123243552460976272387667840500936753, 247484642356638951512311, 13158202699308040253526828, 180235146753, 3209645578481866603); + _reserveERC20PoolHandler.settleAuction(7352, 64468, 105511, 14014498020178142167331212366990); + _reserveERC20PoolHandler.moveQuoteToken(102307567027383396996945386526120, 1000000000000000000011005443597518796068450771, 1830932055144360344882198952, 5062177514995020730630162831, 42115); + _reserveERC20PoolHandler.kickAuction(6269365082754440092150371671065279083767901414, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 2); + _reserveERC20PoolHandler.takeReserves(14, 33025669033967679085337134805565432952424673935025527829, 19); + _reserveERC20PoolHandler.removeQuoteToken(1248373319972090440955060850468, 5148171369684007845147895, 31639, 1477761581075761248195590384780); + _reserveERC20PoolHandler.withdrawBonds(2566642505619323625452, 1000496764916959457, 45462967837399988873); + _reserveERC20PoolHandler.pledgeCollateral(3185, 1076614429971412031, 45848); + _reserveERC20PoolHandler.pledgeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(320544368494042163789501884158905807856035129761, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 201725855268263696016334502905780987923701378953573255817596); + _reserveERC20PoolHandler.kickAuction(1000336252515461664061178680418, 1000388912084206393, 1011107483287844312, 8647554820919410630913313); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 50516976808537535276520446862304273644178309499903228413903745364358581683643, 2709945513107189127374088721782); + _reserveERC20PoolHandler.pledgeCollateral(3, 1, 0); + _reserveERC20PoolHandler.takeReserves(45133607575449095221162705762361305703977888819293869079201865091516795206737, 67924, 37831519418663083787231971931191); + _reserveERC20PoolHandler.lenderKickAuction(21504, 25904012845427761905660936435078, 703796362287742271184012329235); + _reserveERC20PoolHandler.bucketTake(0, 923157514371, true, 15939348515356431548564813731594466613300344692, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addCollateral(311493687718760788907972546738070, 1003382908177787998, 25483683918669391252516475347431, 24095534617878564822985881587326); + _reserveERC20PoolHandler.repayDebt(1000000195838638578, 62700607572090009959044442730, 1013743625667428849); + _reserveERC20PoolHandler.moveQuoteToken(42243698908707807441142106725951938117714223383204145877705, 1, 344271984601285246088324004893632267232258416064, 226798177494562158840374418128613468952892815953691457, 69091831791289); + _reserveERC20PoolHandler.repayDebt(70825, 14311, 1000018060925952915); + _reserveERC20PoolHandler.settleAuction(27902, 1002315564201303771, 1410727007152286014988461060895632509636857067929492447640832835235947347, 1076279560591369416); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 7337531939039374587624013433241677478892187); + _reserveERC20PoolHandler.stampLoan(9766504153929369500501, 0); + _reserveERC20PoolHandler.addQuoteToken(196612, 316754078648004981429079537060114, 515586298794801886086389215830, 10771); + _reserveERC20PoolHandler.moveQuoteToken(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(999999999999999983610855053382054071431657002, 782869510780044216, 147904853523810421167973112497, 1002307562575186332); + _reserveERC20PoolHandler.settleAuction(6152000316526416423777116062445, 8067, 1082752700483537290, 8392332001693122074120278752); + _reserveERC20PoolHandler.transferLps(0, 209280954247275939967640, 5681831508296658455609949266639286507386343604, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(256567610969183668446, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 45170453239180066788622436771378006982965484086762); + _reserveERC20PoolHandler.bucketTake(3, 457088375466998054138001988676565293909861727929272636081353670143559736, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 835976); + _reserveERC20PoolHandler.withdrawBonds(248815858138124671995198568086, 9539107926198722622144144750, 1121791448779424628); + _reserveERC20PoolHandler.withdrawBonds(785459014183016041080171388548, 4207753022934017992685049010435169736822549657056613192716, 819781724580373785897549492928263221293701171572180914318064930); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 28286868439485262801881579577300838); + _reserveERC20PoolHandler.removeQuoteToken(788075175180922013605003676684, 1768883582671251530427600188, 185172084216812873727314557153, 250099953452202106808943824181); + _reserveERC20PoolHandler.repayDebt(6869632414, 17725816229298487260494994916246610858103139, 1); + _reserveERC20PoolHandler.removeQuoteToken(64412, 206729188359503517697120877766, 4042, 51145); + _reserveERC20PoolHandler.takeAuction(702328495478510399361134893568247096170626256348510874367812337395998722, 80682, 8548501529095673, 25464396258606087115516263003); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 17190); + _reserveERC20PoolHandler.settleAuction(1168116, 16273236328583616777187303799280033699882910875418772142057668443193, 1, 95907608729712974033845641730550030873983681581863381934000446); + _reserveERC20PoolHandler.pledgeCollateral(1, 2, 76395220357970578660528990579202996); + _reserveERC20PoolHandler.bucketTake(176323869261540227, 1095857549145040623196306462960190874722398, false, 512016453946223100396062517108676400709, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(10426618351812971479895053579369315415, 5995484015394200729390334915003256603209905896738288, 1, 1937185812841271108950898153859296435919250286257258264239); + _reserveERC20PoolHandler.settleAuction(88343, 1000265629002775292, 231199676786891224341929645591039, 180570412974716531429860573824); + _reserveERC20PoolHandler.kickAuction(10332259793965506937787795115299, 1265751175713444793974412761641, 40036, 2999999999999999999999999998791516656669546344); + _reserveERC20PoolHandler.lenderKickAuction(1619938437346215026589817086810127556251032478854444047863517962733924299, 2839873154970308008234296806, 46946); + _reserveERC20PoolHandler.takeReserves(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(1532, 120941509555693416, 528179580389567238); + _reserveERC20PoolHandler.withdrawBonds(1925993008253225052386425605002958154500588089050593030286768082511958863, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 8220097918269); + _reserveERC20PoolHandler.repayDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 500656100541793027148256947969126414091417128156899777791044630627, 3, 1243401316126576, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(86942, 1265750446449220436328574557536, 1000413802927987948, 1095070231982735282, 680241183587742519486963119369); + _reserveERC20PoolHandler.kickAuction(1403160938973468662433328512684493640631441203426254, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1278671339437257582264011126928523351192550123453283116381962, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(858334688744263212517969720651, 1502114183356369806990088864306140636000206456355426700120405923606, 1002316954421934877, 521284031086467773149282088859153); + _reserveERC20PoolHandler.withdrawBonds(85440, 5829558243977283653706875843, 1004564639911162661); + _reserveERC20PoolHandler.repayDebt(1013926692820087722, 43885, 1005066474529536345); + _reserveERC20PoolHandler.addQuoteToken(17068621575404744873408466497490, 8174119886589104431536733128383526304274022365823554547283207377401020731580, 1726403099, 14362146246559834); + _reserveERC20PoolHandler.kickAuction(36021074946477834952556604650090188025165083141525898485882, 2, 1783014443306263471138234076064783875497601074416025, 20040917666669467911411967548879194898758435694121); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 0); + _reserveERC20PoolHandler.pullCollateral(3377305976, 1074951622983408273, 139300); + _reserveERC20PoolHandler.withdrawBonds(317671201421223616359609830, 107996983368437750089608313, 695313403486802436259104419118737155300690926564443914559798964544353279); + _reserveERC20PoolHandler.bucketTake(1227285541857866039, 37634845416349922903265732298955, false, 2045, 1678564923759951382809566858230352269477920505053496482024116495452246765); + _reserveERC20PoolHandler.addQuoteToken(61225, 4727824468742766134130739439, 1000612048935576642, 33999999999999999997378823527212266014901212612); + _reserveERC20PoolHandler.repayDebt(0, 3, 3); + _reserveERC20PoolHandler.kickAuction(7148337669010547658102894777428, 1832269711415118445953104329272, 83641212795071297144657292158, 11453); + _reserveERC20PoolHandler.transferLps(361066307962041057839371068891113210433188379775487, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2647891532951931849301096779287103964639222095103318115680174, 453); + _reserveERC20PoolHandler.stampLoan(561851286928478301651777396627094, 26136925387601172257176572093); + _reserveERC20PoolHandler.removeCollateral(1357911508, 40669226675172648967649613275638505482481605391973065, 10114, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickReserveAuction(5698628467688021004693473709553685, 737503206173290832007003921); + _reserveERC20PoolHandler.removeCollateral(26362, 111681, 421432787363630303958429504176614, 3009846230); + _reserveERC20PoolHandler.settleAuction(1163322980549754391906331783, 2471, 746055792553944623905408808008163043479145321569849473122862140185736161, 2182934151); + _reserveERC20PoolHandler.removeQuoteToken(194393439, 239, 87794916794198497504518085799777021196157872904632158883258484838161107050625, 1); + _reserveERC20PoolHandler.stampLoan(4323714631672351967941377588805351316488618339, 1); + _reserveERC20PoolHandler.addQuoteToken(4, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 3); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 142396890438868895911322645915413100162); + _reserveERC20PoolHandler.settleAuction(2, 3, 1, 0); + _reserveERC20PoolHandler.withdrawBonds(1000494930413731302, 854, 1092240860809360803); + _reserveERC20PoolHandler.transferLps(1007676985037977280, 5293258438020529061018764950, 1248335723118177042950426359461, 12776645595352149080460901309030, 78596); + _reserveERC20PoolHandler.addQuoteToken(1, 7451696, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.takeAuction(758870, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 15259711926701774562354058076); + _reserveERC20PoolHandler.takeAuction(68300521005251880246452791586826171749687841469, 24841240213455985834065941206835974642248317233510365559867572506411668, 229846574968679831347910311874661214380742, 3); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3043377535935618555168921421700797787592); + _reserveERC20PoolHandler.takeReserves(18768478360894681510639123648408, 46465, 25709); + _reserveERC20PoolHandler.kickAuction(0, 2, 2480583108832384988850663758126095532, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(2999999999999999999999999998832944857863450655000000000000, 45771, 62164652039633627497761335594, 1000412999688154238); + _reserveERC20PoolHandler.removeQuoteToken(364124028237392395823485921795702436499240256094033384013569265, 766794, 209920245295243436357988601, 0); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 787329402, 1257696470804019100618795990194408990721); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 4053656901589611, 1088323855928526383948658326959621445942462247919947474977085118384548552); + _reserveERC20PoolHandler.removeCollateral(43746300961571560222695335, 1, 73104762038534377972956331144940063380731, 32005289702807842917); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 53640541721121094535786842282666422); + _reserveERC20PoolHandler.addQuoteToken(17930, 65364, 21424201609023557872897895, 65169); + _reserveERC20PoolHandler.addQuoteToken(11129136906090464421688409, 1004882573745034412, 566740377654384793379900958627, 697909370195495554682103581227); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 670812358273298997332299658489574541630814267702641469872828); + _reserveERC20PoolHandler.kickReserveAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.addQuoteToken(3, 3, 52994323227034722517026788793221, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(356658, 4002645144088, 283607950439582862, 17575592972854422142521200722802988130147471569026817571); + _reserveERC20PoolHandler.stampLoan(5292118026705223940621493194469609859902, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 5637719028705938094613057980003920632228362239960818596087167581698, 149663380017310880799301848750329729135678); + _reserveERC20PoolHandler.repayDebt(84646, 17068973606930406543461471864112, 1658169940155884404636872799202); + _reserveERC20PoolHandler.withdrawBonds(45848, 22902933191168752524363784035744, 243370212847735416119340093428313); + _reserveERC20PoolHandler.lenderKickAuction(3, 0, 18693740270024255256353128200198867720368767039990324141528978069657609363); + _reserveERC20PoolHandler.moveQuoteToken(1077932344807860496661023241385451544061536009765871866009027124302947793, 15404321346282745254837437752201, 212021975738761452000000000001, 45733, 27372); + _reserveERC20PoolHandler.lenderKickAuction(10772, 25684490465543465598622839641963, 3516562160); + _reserveERC20PoolHandler.removeCollateral(2, 0, 1261110872917145498336054997256195374298813780262635957388146, 1); + _reserveERC20PoolHandler.settleAuction(308790479427827097093414287795563613099418796787330813476570771124147369521, 41937512108748567561271878845283173549273450225213447793727, 2594009395137, 1108985995010584891692958476338544269229253321282932512058479830315); + _reserveERC20PoolHandler.kickReserveAuction(104304, 40121); + _reserveERC20PoolHandler.addQuoteToken(27254769792208, 14728135472046120105947691358953727973, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 414074603574257187594813653314786085248036044181296); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 26819261768520169880354, true, 1024207814034120719023254733992264446908751020948981602359162, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(225449455045750393516697802271623587, 379395147962784744929851461809016976230202517958726242337, true, 14987615034806441423318840327422929530625185827, 4040179615492931169152063238091551429323738126497584396033880382607073752); + _reserveERC20PoolHandler.removeQuoteToken(187043526874134524125439, 364361703638417027207762019617, 3029381477, 334920009); + _reserveERC20PoolHandler.bucketTake(49283, 31996, true, 187319881898299587936593602479, 71364); + _reserveERC20PoolHandler.settleAuction(6724766265165202572707125761304, 45950, 20619937592141215250617270925845, 8731769574088027342937595963); + _reserveERC20PoolHandler.takeAuction(459529748357880933295684526074722294936591580127441009, 8034022, 1621613887985455559486663220302841631472, 531511394625370522269062968138110073240611995289300121605); + _reserveERC20PoolHandler.withdrawBonds(0, 10273410149368262918604204407481270728310441147521355069800363529006222351977, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(110927, 1100805399391925133, 48003, 1000000000000000000322692305421796163426770896); + _reserveERC20PoolHandler.withdrawBonds(20669874709518817084117328704566, 124388, 8470); + _reserveERC20PoolHandler.repayDebt(3, 282686084833603209384994385410506337825847396, 8415832879083357414309353687053); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 0, 3); + _reserveERC20PoolHandler.moveQuoteToken(34188901757821696207622661946833363324866106317905452880060918, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1035617650014072675852318, 3); + _reserveERC20PoolHandler.takeReserves(274406664943235117086784513592956983012372, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 8617136832384491533658272711596966111860464992224748656538834); + _reserveERC20PoolHandler.addQuoteToken(1000001224098999069, 2839679941389620469279570145, 80563, 605292630262187992982164189513291); + _reserveERC20PoolHandler.pullCollateral(16525315361870218541662910573, 26668098136978149102200185881746, 23908693653862604245305948749918); + _reserveERC20PoolHandler.withdrawBonds(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 9720113484669977941275495814081336554741668476427922839); + _reserveERC20PoolHandler.removeCollateral(9975223748825412976, 137666747966811415336537241598848, 102232, 3760225786814919945871494487); + _reserveERC20PoolHandler.kickAuction(39873320586386381747935560, 122531174816258389940952633077, 312754648700940034189150358845, 197015248597177779732041103971); + _reserveERC20PoolHandler.takeReserves(550327587341396418113442426482473368172354202166467605515597, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5378414617282011); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 76704223007645381848533964, 2989295166587199630472259289574023115102072081091076628344373, 2); + _reserveERC20PoolHandler.removeQuoteToken(37181118954123498058827724728759540431280774160109, 162880783811840809576544019999565668848599601292232504, 3, 3); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(63951, 698042199636437701613021151659, 181193326967639420601532109916979, 1942388279439325804845541280672085); + _reserveERC20PoolHandler.lenderKickAuction(217069806720235164462828155661559288363505001, 2507854891533295798525218167479041183901856349455, 33684000194086958010952090942433215994263524578705); + _reserveERC20PoolHandler.transferLps(1046441305387625662597463052593463024805405659909488160299287852636012362440, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 426990, 386339339861320912379163548255847692504955581827202199771033590, 4264502); + _reserveERC20PoolHandler.takeReserves(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1244380445815265300290424909629); + _reserveERC20PoolHandler.kickAuction(3868815119376793321270432, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.transferLps(81038991567309101942298831064504506635316972004340312, 728263367831447802663022419452107983820867884908287984997, 3, 14616673771250365029336653135294799951, 3610659149201249); + _reserveERC20PoolHandler.removeCollateral(1008659107280896015, 25684565925806238885960863252889, 1246907430534059181649793719220, 1453760141959572198809329243504752204044784772340654024539144126852327869); + _reserveERC20PoolHandler.kickReserveAuction(3079448458, 27020); + _reserveERC20PoolHandler.addCollateral(67504, 2999999999999999999999999998395666292593104303000000000000, 304789501076683498785500565544, 26655); + _reserveERC20PoolHandler.addCollateral(33070607865448996391677382450092, 4817, 64303091678591619398658692, 165545431690605441445193617915); + _reserveERC20PoolHandler.settleAuction(219272121391720049052785912887, 202372, 107539, 1259222536371095951704122248256); + _reserveERC20PoolHandler.moveQuoteToken(4226339283529880005235081977497059176318, 2, 3, 80573667099614927968070749098246587002614583772646796960009837605869456, 56206763583062125365650269926); + _reserveERC20PoolHandler.settleAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 4259808685362135412510, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.kickAuction(3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.removeCollateral(2424, 5815844568382205718572605055779, 1000415121112551425, 22707); + _reserveERC20PoolHandler.removeQuoteToken(2478362699497177756823438308987, 4524, 2097753911867000000000001, 302535661762914815953425538); + _reserveERC20PoolHandler.pullCollateral(1000000647930848959, 1079265096880598286, 999999999999999787978178697424804260644670040); + _reserveERC20PoolHandler.addCollateral(3, 3, 15464016793217984080619500455673, 2096321054298263505191806691575828); + _reserveERC20PoolHandler.settleAuction(0, 69884254105117009237169950473721157747344125822667100354376139072094743, 11157280518427, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(23023482542025090509697110475415, 193310468519771436229827928905398, 1004959814542778578); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 635612452667334223889532538208728714915569502); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8849866460938602434954923491789552498321462002); + _reserveERC20PoolHandler.removeCollateral(112354727, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 46824672475304343660747922541, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(15161544393497970544694448330117, 148508071034, 0); + _reserveERC20PoolHandler.settleAuction(214595417689583821821708243244, 10767774944191314417, 1480468673499319982280444215130, 1830418325320784729570014184990413); + _reserveERC20PoolHandler.takeReserves(42779, 680615193576865714993949811771, 1247595155467516918356465863266); + _reserveERC20PoolHandler.pledgeCollateral(3, 14221, 2); + _reserveERC20PoolHandler.takeReserves(8149943126032542426363686555808, 5156487572628113916240950987395, 5398158092292792042301424552); + _reserveERC20PoolHandler.drawDebt(3, 324909647022423772446029338722506866264064563831446516797108357819670803, 155736824835024377724150678558200858678828068298678257654499875); + _reserveERC20PoolHandler.addCollateral(1000000046957399279, 2229, 1030678810626900139, 1000913771878549061); + _reserveERC20PoolHandler.takeReserves(1, 1, 1); + _reserveERC20PoolHandler.pullCollateral(1000000000000000000000724154850294891711106750, 4517289146388704965100937630716, 182175782142048266405241356619888); + _reserveERC20PoolHandler.addQuoteToken(212793583610236286407085218364, 1000004617338661820, 1000415356282146006, 1063412126048251293638411074775); + _reserveERC20PoolHandler.pullCollateral(187043526874134524125438, 2758444253116117714950, 27317869685263531832910082); + _reserveERC20PoolHandler.removeQuoteToken(24394251342143757423523068060, 999999999999998770927144311811858149952877220, 12958212858061802986037998930618, 757631288446767689778895838135); + _reserveERC20PoolHandler.addQuoteToken(159153929464331243860907639134526, 83647, 24837823711160238249644417238137, 23747); + _reserveERC20PoolHandler.drawDebt(2, 53479616970447100318317956235652287630486308915492071519718315723240625619109, 21220844398222577293228960174226516159228602863693732551515446937186055); + _reserveERC20PoolHandler.stampLoan(1, 12360611860611904401132514090390808941842387183929599585514434048630953396); + _reserveERC20PoolHandler.addQuoteToken(70453061646243781023137540415052790969222547, 0, 45704328117538080181603751285195, 239069960298218131643444639395312566342717); + _reserveERC20PoolHandler.transferLps(99849106210251962292217516890134324060406114483530688447605087058686161977344, 213261225223039492594928345286, 54371896216364216315144, 1641, 235110167985618229737971491639); + _reserveERC20PoolHandler.kickReserveAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 84477341561364564797927, 3); + _reserveERC20PoolHandler.moveQuoteToken(13222037868358691772417333476592, 42658, 797503568287196479551833978311921703885323190872455505548800131652942311, 7307508186654514651052143348725931723414803985536627394412473519, 181742790038400985603263544582); + _reserveERC20PoolHandler.addQuoteToken(213331870056339802732459268202, 37160, 555432583631581335779854870431033, 66700); + _reserveERC20PoolHandler.settleAuction(2999999999999999999999999999999999926505306290, 27343, 73500, 175685770571166520057630591832891); + _reserveERC20PoolHandler.kickAuction(1434984569798987926389026614, 2308606772406874338782701906048, 1094569861733533410, 3166357129); + _reserveERC20PoolHandler.removeCollateral(3861629492987822375044724005525, 23898378975206453320824142624212, 21684, 112309); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 594328637173348223726873919565); + _reserveERC20PoolHandler.lenderKickAuction(556590835820984707504310, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 17038721957146518819845918158812396506); + _reserveERC20PoolHandler.withdrawBonds(2, 357815, 40173321747036321479114210026353); + _reserveERC20PoolHandler.repayDebt(1001301038492587188167215, 25922595819627310095875789985928, 4768); + _reserveERC20PoolHandler.kickReserveAuction(364361788568438744169425873609, 1919941759989464784736612817); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 25916706075052986, 0, 490939888498923310604409636113244364021768873931875738523928957340042264); + _reserveERC20PoolHandler.takeAuction(0, 3207930927813510360899004243613, 0, 0); + _reserveERC20PoolHandler.drawDebt(3, 0, 1283667111418718087796291966876565887433874593); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 257114171049142); + _reserveERC20PoolHandler.kickAuction(121185233046284138765747851798394, 80956, 25456841541876740591638385692388, 22903399683611245794465726923382); + _reserveERC20PoolHandler.kickAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3146087493362025485456634570388991892138960559065528250867987, 3); + _reserveERC20PoolHandler.kickAuction(27917, 33, 1076624857584926170, 5156487716742719175950734057963); + _reserveERC20PoolHandler.takeAuction(670849153287343969214678211759060818715541995, 0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.lenderKickAuction(3722334349747999999999999, 48343, 50000000000000007504303752959825611976512280598); + _reserveERC20PoolHandler.takeAuction(1000340529300183112, 47710206376465708889933240, 5018, 181126239049979700687565631484); + _reserveERC20PoolHandler.bucketTake(2409366757, 23002954912918706766198791036354, false, 50939, 1000412061623064483); + _reserveERC20PoolHandler.stampLoan(10038642563730541577199535612742778051, 9698534279298534305147337931389984356900229360077831); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.removeQuoteToken(71094324159498917522013718702335135089513235, 13141568091044380048587864726819017200440542469173020977587, 0, 3); + _reserveERC20PoolHandler.bucketTake(110085366235979786081204608033485736878, 83745251865189916065501826746505425924697254154156675779668050990766503442806, false, 702354538163824341119229886114778021838386542029996, 18495950251378053046); + _reserveERC20PoolHandler.pledgeCollateral(5830151280553770893151673901, 90422, 23260271307333828048688045213089); + _reserveERC20PoolHandler.bucketTake(1, 54165140633945936323260, false, 31729524913428508011369928804179107971239289, 1); + _reserveERC20PoolHandler.bucketTake(350, 172028884179301626986812297349147, true, 155068527509982663351982944, 391213332076953784547440999366343275433278579); + _reserveERC20PoolHandler.removeQuoteToken(19238831902045882735062513727701, 44929, 24555887753064651927618422994581, 4949); + _reserveERC20PoolHandler.takeAuction(13426756550166227675159765290117636083703358051860562648971, 285136459782859427135537456836, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(1009956823385802949, 5341); + _reserveERC20PoolHandler.transferLps(184633414508257339692296072860122, 203671446610984328294118107730201, 34642553713628299033, 135339917753179699999999764236, 110220424372011764574622562304641); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3829549741322560625, true, 194146934987766163254349730117507128335504831810102719534851677221, 4732480241160878860425351979843049115515657935334802409699209074); + _reserveERC20PoolHandler.drawDebt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 195015028747880205316); + _reserveERC20PoolHandler.repayDebt(1480868866677973373563266629413, 302535661762914815953425538, 289604); + _reserveERC20PoolHandler.repayDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(2, 17153443478984101453401473025503395950732154159263, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 105284856040705965826, 6, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pledgeCollateral(2, 40372681414098997932695643926645341076, 1); + _reserveERC20PoolHandler.drawDebt(45397, 29188809947358369997448329265, 1007827835052967256); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1148463503258880063377287873, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 1107871027141048045133446387536639399931); + _reserveERC20PoolHandler.repayDebt(210935835279891127479743655755, 31863663357592309638107226236833, 1264267125038486463229116936428); + _reserveERC20PoolHandler.removeQuoteToken(8111140262636269, 8879830156995870052991830976146, 45007, 7923268532088155483236204599548); + _reserveERC20PoolHandler.takeReserves(1823429416922747175532290196335891742112593527337518, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.kickReserveAuction(58970, 9783579015620699457012557129966); + _reserveERC20PoolHandler.transferLps(99813174211410456412845501360406, 1004698353172002056, 1004737060669881051, 1029316220890589580896344985, 1920398515164486257491273481); + _reserveERC20PoolHandler.addQuoteToken(1000002042017559293, 22001942759548186429207367283122, 32995, 122996746994842049905607927396792); + _reserveERC20PoolHandler.lenderKickAuction(42112388736146970996063877372687611472797385160773, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1830101812163257760035167237765727934453589369140548201538682896591); + _reserveERC20PoolHandler.pledgeCollateral(873997526269342972853729445, 212700214750724126705590695253, 699261128069635571950161724125); + _reserveERC20PoolHandler.stampLoan(20779858960809402604253349649621298456956778212692456138360400488091592818, 2); + _reserveERC20PoolHandler.withdrawBonds(89, 3, 270488841223974585568668370825700061196236645569024596625414266); + _reserveERC20PoolHandler.pledgeCollateral(4810686267623913331987481056958474436468823, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.removeQuoteToken(243059034441394937316222229163, 20155, 10598, 105237); + _reserveERC20PoolHandler.takeAuction(353095914745614344874854296826074246381784484285761170, 108676431757798502254327317752387019137928469130723472373786313872276353, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(82533955199386265420994751578339381566578590, 2, 46326290204754911406110575716876805); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1190965943378146, 120136135420991, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(3867328119, 964830386728456017255972493047, true, 200885187904806267189995644375, 1078427058759624748642471453711568385622119423127247172852269821812293567); + _reserveERC20PoolHandler.moveQuoteToken(2743718832, 22536, 1020443781884248669, 45444, 8948708199492119143187143781099); + invariant_bucket(); + } + +} + + + + +contract RegressionTestReservesWith18QuotePrecision18CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "18"); + vm.setEnv("NO_OF_BUCKETS", "30"); + vm.setEnv("NO_OF_ACTORS", "50"); + super.setUp(); + } + + /** + * Test was failing due to reserve imprecision due to t0debt rounding. Fixed by allowing reserve + * fluctuation up to ~2e-18th of the current inflator value in test harness bucketTake function. + Previous Reserves --> 41560434780897465224488579965 + Increase in Reserves --> 0 + Decrease in Reserves --> 0 + Current Reserves --> 41560434780897988234548290380 + Reserves Error margin --> 10000000000000 + Required Reserves --> 41560434780897465224488579965 + */ + function test_regression_failure_reserves_bucketTake_18precision() external { + _reserveERC20PoolHandler.withdrawBonds(1313160713349781589838246857071183042175798818623, 243608303726369371177003852941, 97001243185680629456207455042270488289225799387788972543024769916735273482822); + _reserveERC20PoolHandler.takeAuction(19626260194676342496347624680337, 190546780460648958969224270861321, 724414674030724914597533433314979360940095942366811113079544320264376867, 14477380972404753142149122); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3074943, 1338076649924567893410649915470); + _reserveERC20PoolHandler.lenderKickAuction(3756050, 19, 1951633346120599314824236424372864572505); + _reserveERC20PoolHandler.removeCollateral(1024560350146693393, 3488932012, 85294050264131672119628574691, 20144044128209203218490074875008); + _reserveERC20PoolHandler.withdrawBonds(35999999999999999994066572658251009643479608687, 149154487027323228402881697694176, 1005112508155603217); + _reserveERC20PoolHandler.pledgeCollateral(1012568732300604255, 127516645959162972418691444333720, 807665861263516809124750306976); + _reserveERC20PoolHandler.drawDebt(95995475335296983359694851567915401729188714318130, 888183696470081880744089322036301330978632, 86399459688794127730999484108338); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 8961408297694214805576481589216293267484597251015541593463242703134568796292, 577572495008453831747823839160926194009); + _reserveERC20PoolHandler.kickAuction(1000000018260314868, 81872, 1260994006901600840823120120145939418900019444870666411125752520053572792, 23250148961720181795263850602230); + _reserveERC20PoolHandler.pullCollateral(96577316124178831846592548691941255877029374641825275566984, 414192, 768550420751754107205420268803); + _reserveERC20PoolHandler.stampLoan(1337387978345739823916045152184552435676, 23094); + _reserveERC20PoolHandler.pledgeCollateral(22738, 408929405372329703863780748, 49159); + _reserveERC20PoolHandler.addCollateral(5064803276010586533556588670799661, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 24562342840084557138264518351946048348175802252, 2); + _reserveERC20PoolHandler.withdrawBonds(0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(14954132599503656619339415902, 79780, 3079, 1190695402177277499, 3738985552053468863469903); + _reserveERC20PoolHandler.kickReserveAuction(10973205117420246353343960862285808530809008524, 5081233381514057703841175142665483734971945323030058610342613338); + _reserveERC20PoolHandler.drawDebt(105810623447041815605251840934754, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(41178083514314818848783089908784944368233037842176423327246661050, 323687262857079054128208618554740, 41232588988949623428768490563118978543289927670890946396838772257949680, 3, 422208898890940124528662991855951094375512552556308662991); + _reserveERC20PoolHandler.pullCollateral(2573120913220314955261848288030767, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 228409113525992); + _reserveERC20PoolHandler.drawDebt(3, 325276464690270137265001181789630651, 903); + _reserveERC20PoolHandler.bucketTake(317256352574527620185773670490, 2806632291843638772314, false, 73840127111168979644, 19650215624480090491208800262699); + _reserveERC20PoolHandler.takeAuction(108304, 39392827409071222845130329382, 131210350036331080062728204414, 67570); + _reserveERC20PoolHandler.bucketTake(13999059473523741238192303156810323997, 745591727950442, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.settleAuction(30452121859821247684748780461425, 18446756267687738523, 97102983618368938544926765665075, 1000736542601590255); + _reserveERC20PoolHandler.kickAuction(1068696378245438561, 412598435056532855673303217318786, 12965, 74476); + _reserveERC20PoolHandler.repayDebt(16463086380181081259951324823861, 166229311393273120716672361260, 14864236705617826706212); + _reserveERC20PoolHandler.removeCollateral(54638881909472438350314560288203769840701397562, 2100728639040643140270154215254489444884213572760739318203492572957, 3396953888595311700450612849, 650325706218566268081512056186524970655230161720133711909791); + _reserveERC20PoolHandler.pullCollateral(11561580, 183899796013815520873724053, 105495); + _reserveERC20PoolHandler.stampLoan(4673, 2025664898059480443007525567); + _reserveERC20PoolHandler.bucketTake(153405316444154745788426926556, 70240, false, 3753345286, 1736914071142698641); + _reserveERC20PoolHandler.settleAuction(747853666640920773923023337927549166017861759783954178997188, 3, 5060520857176247898884359170946376732667, 3); + _reserveERC20PoolHandler.withdrawBonds(174124764660355333547934429328096, 12905255264339378086530979388796, 1523844729521026278900276); + _reserveERC20PoolHandler.repayDebt(23250134816786629323591971126996, 68508285147824475365791479906, 1861347394316483778715114552573); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 12554534877830976929838848023952056975, 10414313395308164775954490530595141599114, 1); + _reserveERC20PoolHandler.takeReserves(34, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 258241003343575); + _reserveERC20PoolHandler.addQuoteToken(12123164745318936702183806056087294358246678396500891696171861722484645976, 228567957003264204676296719904731948541204, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.moveQuoteToken(4944064687, 2954463520254020624398313158414797312500031, 2, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(21437470410879992894389347789850, 1000679089974032651, 183915320275673958037058468374); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 97809165602404930268545370649783948084197, 35, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(141277153071223065644210281663, 118815150407941630074003072801, 88313, 129567765994138837374827736438, 1044060635310510048); + _reserveERC20PoolHandler.lenderKickAuction(47934, 4907559259104025762695859208150, 20143729137789266290463852222004); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1290308581691070564150485275032427, true, 6067282040672972775786008840787906103796833251212798937000235132346290704371, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(8403388711352389444652708249623277286500826863852424355586, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 16796278714665665835736957701210723912127941453518097544874539006); + _reserveERC20PoolHandler.kickAuction(956721976422470546470374099936, 999996280483142532, 545592538598724720795673884777046, 187236868324058362267423721904985); + _reserveERC20PoolHandler.stampLoan(49276, 3066198512721517327934922059332); + _reserveERC20PoolHandler.bucketTake(6132737, 11640908437720570848423350765542523986760125216154630229459604927562228526503, false, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pullCollateral(12494714613428429213196, 0, 0); + _reserveERC20PoolHandler.addQuoteToken(46078264530917097478219911666273, 11066794161664926076795378050700493138694114681308445296572372985, 988631149389579059106898376917, 8511787781481978); + _reserveERC20PoolHandler.repayDebt(939585194151520082524745245267851864719403272247155215, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.bucketTake(15453533353143413956848031710387, 2425741604214535074889438, true, 5508705821096371661309231517652, 197076225879219688128857236376951); + _reserveERC20PoolHandler.bucketTake(1005973181704872051079262649089, 1013657019122139416, false, 64196, 3068415198340358442625437553327); + _reserveERC20PoolHandler.removeCollateral(314201797381946902354139115864439796420920512274, 31414950233780689458508874722238658381815041372917666207529470727, 46752381873630862311783905, 1); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 18959977846556659721057064458651948214, true, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(63705, 5760440648167352677944427443390, 66671); + _reserveERC20PoolHandler.repayDebt(88159696077984351346022739436195777976246237495213917881, 64837618622353548095090678430306, 0); + _reserveERC20PoolHandler.takeReserves(227363206733285599517, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(1000113969800114688, 6116474331978007906932453457497, 999998960696062639, 126727046200276957173156233926727); + _reserveERC20PoolHandler.pledgeCollateral(1346071958087106887300222768766914, 157638192109809914344925381504042269351, 9052444687150896978116177652727068); + _reserveERC20PoolHandler.withdrawBonds(0, 32574329921750076384, 5145000820798117795859758); + _reserveERC20PoolHandler.kickAuction(17589937191369063371683174, 3288186568404671522947690521, 206495327672819118529554934114, 27016); + _reserveERC20PoolHandler.stampLoan(53143226429187540263622922315210688, 0); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 54706502255431373912803447386729104799292223109884594668, 756857243716641271760946601256469102084582700371080961493707564570); + _reserveERC20PoolHandler.drawDebt(1, 910052915197002596125759558497337574914909546047909298950465, 318183129869151169845171843145857229803018049658134); + _reserveERC20PoolHandler.removeCollateral(978805123424592564286065473444906134624891488735202521496741907565732820, 81114, 1707158355427330625, 15625575281672432809213692); + _reserveERC20PoolHandler.pledgeCollateral(6204942788129376359836295664408, 49605853260093, 0); + _reserveERC20PoolHandler.takeReserves(999999999999998212003326843530863247854219050, 6169697918739139432369681994, 1003390638680555473); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(2921322906, 32224, 1281363200757183049590284404127); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 337836460933253590433610, 749, 627922303709149876625892393776814055141103724, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(44299290393089814123432003388956099508327943925, 1588615611457114, 1038738684578491046936956745287941566213846058841533, 754708130767116758896880589158486739012555, 130467556347174231); + _reserveERC20PoolHandler.takeReserves(1000010977258987132, 333737878388249388576700779, 143908122468870821977622); + _reserveERC20PoolHandler.addCollateral(2999999999999999300379492804584593729619777602, 88254867508873949164062562380292183589278158337108842429966637074844283408725, 1005236892001476567, 1042882318498388095); + _reserveERC20PoolHandler.lenderKickAuction(43016059093882643474997821339150710791003904119, 28261123033229572, 2); + _reserveERC20PoolHandler.settleAuction(32870277066034038103296547061344, 31264056215423335280008295551346, 158589921642095768186097371318507, 818); + _reserveERC20PoolHandler.pledgeCollateral(64416, 75210, 1701500633047647916805401704406); + _reserveERC20PoolHandler.removeCollateral(210586112228359164166727897050, 33680, 14258290749459954708848521614252, 14861684363741140486146810269628); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 961284600486812935025369762291888698438664026836); + _reserveERC20PoolHandler.withdrawBonds(86607, 15622156717875871584254794764800, 118162970592265645915138603333); + _reserveERC20PoolHandler.kickReserveAuction(188274849503737825566885214565, 1191402898373670594); + _reserveERC20PoolHandler.addQuoteToken(85725, 32327623175605600609341705279467, 13930, 1000000000000000001845640564443670600161376027); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 328417293175114991547858083, 0); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 35790000792332387374646687836130800848546419820363182933544692, true, 169287054949585645772854539091891568806570, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 14545176942586, 3); + _reserveERC20PoolHandler.stampLoan(43029, 98587079845710180553603910455462); + _reserveERC20PoolHandler.takeReserves(81033643860589999087886741700, 7283168618528060814584056506017, 1003660379332759684); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 105221736439, 142307592080715858007, 2); + _reserveERC20PoolHandler.bucketTake(2, 305654110049115317954, false, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addQuoteToken(486, 12193238774265054590312503304341058278661587097301939213560116358611204577640, 319509396583239870491377496207534, 39911); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.moveQuoteToken(14859987477615822181582485813, 1012898660666364713, 1001686229898268595, 7624158324670965819183359, 3049865491110357417140566072465); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 2, 20853528722861757941946898130023848785614978798666); + _reserveERC20PoolHandler.repayDebt(2, 1230, 1); + _reserveERC20PoolHandler.takeAuction(223845220356227868348395049196537, 856751248566633650755388956573219858748489493455783418424670122118, 16099325705992211271653081341589, 29716056875819433575098039590038); + _reserveERC20PoolHandler.takeReserves(37062893470735070370032375, 11427654449249351686457918104577, 1376410642605376005965814); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 7849868953531792171715820946981968, 12185166000244133480578451385272395958453270531987456005); + _reserveERC20PoolHandler.bucketTake(693550833687216333632891404296659594506064138, 2, true, 9090910659740, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(6826318979908857960453779, 1, 2941417009172784701197752138104247990, 6099673335660); + _reserveERC20PoolHandler.addQuoteToken(75122809490921535427172481531459, 2043537929, 2999999999999999510843810754774412689339354373, 304445086385040132026798381184); + _reserveERC20PoolHandler.removeCollateral(25985398568480771548020635735287560831580954129713275882714029936218747, 61236742135198376703837762755246961779334328357030807294, 0, 0); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 473689368490154987287514512873709499363729395673, 686494911307); + _reserveERC20PoolHandler.withdrawBonds(3, 1155498283382904677394066274370105926893325540151, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeQuoteToken(0, 68504051491634437, 5321772785922494000876006959949850629074, 26971104); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 150085774663419494471042180121345934738380746562681037970460254053623619); + _reserveERC20PoolHandler.takeAuction(1984876563783221945304382045, 40021543831777996448402901423566, 1070732065984121535, 29595650257269782307521832684657); + _reserveERC20PoolHandler.removeQuoteToken(69509, 731755391216895917190532359767344915147423669540172604376200358198769075, 16411426623949828176368000046874, 3717955445); + _reserveERC20PoolHandler.takeAuction(0, 72505998070338784483906326229670761251900472703970126, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.stampLoan(1000000000000000000398667239656035429776614264, 90971416692237753017882378665); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 31146277361213116, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.transferLps(40659048, 25087115166122247711172, 15467043192175365581979790523045, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(1231959118580558994699051057312, 45491, 126133612409614627893254394921, 109387); + _reserveERC20PoolHandler.removeQuoteToken(2, 41990574, 672, 2645159324693672280); + _reserveERC20PoolHandler.removeQuoteToken(4304547430933817, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 419776803314); + _reserveERC20PoolHandler.moveQuoteToken(115353466808250303128501914385629, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 155202199039057644401735802442984422, 2); + _reserveERC20PoolHandler.kickAuction(1000603105720624956, 16610068924212058205470914645933, 1001710830079987695, 28187536373604017123206636052949); + _reserveERC20PoolHandler.bucketTake(2, 11165742808286926503752859882402059585240978636218, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(64244769947485319099069408188859495430023939075, 11140879061221207814701713, 20332064945748159111069410852340443223713343078, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(225785210944561939564761768429, 285457834146874632195321460846339, 93825437115237757926686279334269554609368528469243773039035757457295259063342); + _reserveERC20PoolHandler.lenderKickAuction(14477067640164830836239575080509, 2485317373719194524451977249400087260909051201664294145188760093602999, 0); + _reserveERC20PoolHandler.takeAuction(28654, 1003082652872475657, 1011576393383520282, 34679757158376518430925836683760); + _reserveERC20PoolHandler.takeAuction(1711047290696609827050, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 265274500939567187, 29984815458832815414324428541958621298284419930482333064633761641718824071461); + _reserveERC20PoolHandler.pledgeCollateral(996028371910983630919179649734, 18200, 866704060549177703012414324); + _reserveERC20PoolHandler.addCollateral(1, 0, 2, 3); + _reserveERC20PoolHandler.removeCollateral(0, 4794026247945354920286994318457624080106698680832921701183756580, 31142593675471308946241689866736225313131, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(18892118254419163824624583, 587630284377125431855588179264156, 32881206662486469206478848872349, 87990, 127946188261807479794554484889); + _reserveERC20PoolHandler.pullCollateral(1886125258156007374380993733162831, 1581899785202093579764232390491, 223442925975656677231160783691127); + _reserveERC20PoolHandler.transferLps(70899748797508326495916219864, 782537217269011143521446055725684564066755733284701869087000375091529816, 1001292893482173747, 1746334530885289223359074260968, 8266); + _reserveERC20PoolHandler.withdrawBonds(134541446392596212952304316715421256392207, 281478030849615415680815886242151391953, 863607949653695912432789473576005131411875210493388076945205357); + _reserveERC20PoolHandler.pledgeCollateral(93972232769017128383208098279289239299517671525737429452091000476766866295, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.kickReserveAuction(1, 3); + _reserveERC20PoolHandler.moveQuoteToken(339951141435951933164865, 3, 0, 263960732476535, 868296057807486003); + _reserveERC20PoolHandler.kickAuction(2358420, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 19742083754892904940554666293102951550647570138669336639945623720946123591); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.removeCollateral(165995817922473652518905414629, 47001, 3019101925072431289293002927063, 7653055070315015065222310512771); + _reserveERC20PoolHandler.settleAuction(289503362597406149790427741243, 473687694326, 316003954664603415833732722829137, 26596737157575446261178464177362); + _reserveERC20PoolHandler.lenderKickAuction(458374840666866553510662051, 2772852390514232007829, 594941625987070056706728102380870); + _reserveERC20PoolHandler.kickAuction(2999999999999999999754012532465975984297763485, 60520267886409580670768237, 21225297245626439428852880154976, 51555872363261828660540447473183); + _reserveERC20PoolHandler.removeCollateral(509402786193883212442354758393593866, 1122417893437336944855510, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 8476568036305); + _reserveERC20PoolHandler.drawDebt(144343091359980199241548570028, 79515371650204835834696871938273, 60424); + _reserveERC20PoolHandler.addCollateral(1001908270207919265, 519120549498149948557298744, 284800715283673093206393599525, 105465); + _reserveERC20PoolHandler.kickAuction(35961960588810973619552161357075309845553645617614058365390431994955847, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2026493379333418680067448989848865359789031911398546855993); + _reserveERC20PoolHandler.takeReserves(8681, 90990587573928582395803341521, 954709046031488666987018101611); + _reserveERC20PoolHandler.kickReserveAuction(1877716632633166338764021763611, 2026); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 6417868763328144274441536001088452057580594293534547162920730, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(6832450493597117706110199496763616669581926722628909338, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3166946665101505850469295159459095840); + _reserveERC20PoolHandler.kickReserveAuction(5871589318184893082217008913403700189012396035983468484162994, 819136017190676646329839822258382321388486821562267712); + _reserveERC20PoolHandler.pledgeCollateral(5743818999762928577590772434, 1291961914149075056852630142021, 35802607365587979308319505663671); + _reserveERC20PoolHandler.kickAuction(76137851735953261282202977166942513898491, 122021138020144990418398002844732104092460333687937673613128889, 3, 23724096835351281065267867476194283); + _reserveERC20PoolHandler.pledgeCollateral(78205599038945119207449254421, 1, 3); + _reserveERC20PoolHandler.pledgeCollateral(162196244186663820036156878182, 179497704039621283300812628430208, 40452); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2130265553); + _reserveERC20PoolHandler.removeCollateral(786118254040717290643964601459384546450694487287769445353866, 1, 30834830168748054761431893081390609073, 19098382563151740786990520993204305579370); + _reserveERC20PoolHandler.kickAuction(25712, 999937258335917696307362296777, 53867682294054042917860919, 21970465775456583755173692); + _reserveERC20PoolHandler.lenderKickAuction(11399379394538954719150514234483478911540118214508711316929916968812914, 3350350892086992411541633423391, 233844809296127932196037894119076617123440818328778583); + _reserveERC20PoolHandler.withdrawBonds(238602109141784062224712941984890948600925416534177139782314185, 0, 422370693763625505794); + _reserveERC20PoolHandler.addQuoteToken(1003519854588118019, 17034329381891023981931, 10395485668247196931162212754355, 2183858015149258361612471197); + _reserveERC20PoolHandler.removeCollateral(1001513217144301302, 20157068181094697269688394513183, 30024190, 47176); + _reserveERC20PoolHandler.transferLps(24621845301548361847992121, 27172142536188477043541737972383, 289500258810820891302938465111, 446656565090239800145380785, 826017646289104836138341139297760457947751884820746891410232243389819017); + _reserveERC20PoolHandler.repayDebt(112763776509441409056240295967311831298132213091857, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 21768484085); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 806229153659423029662111896489314178404, 1); + _reserveERC20PoolHandler.moveQuoteToken(1004920509154363155, 30450666053080364818985338375546, 1000000, 30668, 1954367808237681163232472544913); + _reserveERC20PoolHandler.stampLoan(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addQuoteToken(5695749629001313164214759934650, 818583374578947518623895751420, 1000010864226374804, 818528613948249119025078686887); + _reserveERC20PoolHandler.addQuoteToken(0, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.removeCollateral(1000000031868341450, 22994, 799758195294668360574365419808, 1003506979965290361); + _reserveERC20PoolHandler.takeReserves(88601598767866928184529474834223065352051177924606515955053637107674, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(105572711, 38445024174667936097, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(30452123558886317123371986692014, 3656255296478427970857217347, 1189882029626961491); + _reserveERC20PoolHandler.takeReserves(2521748786336871266174927473598, 13962890705710981245839302201544, 1692281267863168662659342413261); + _reserveERC20PoolHandler.moveQuoteToken(44637236172891555536017683423, 1529355871083619689841917544450531038551400192395750632130757291767646754, 5697408695264158654344483595948, 479814420829182676700458628857025, 1000735663909006188); + _reserveERC20PoolHandler.takeAuction(764265442068336947000613812353728185413049995, 554486579807106298, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 255211168976368092); + _reserveERC20PoolHandler.kickReserveAuction(734737112688186589069840978427990157399489, 561181220531963583889062544); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 22299610723150091608641337869356581723935128146488523299023324932229929); + _reserveERC20PoolHandler.addQuoteToken(90708273505471459842204615011, 1581206123038223956974806234277, 1187594007652974296, 41787510335983635291055666992129); + _reserveERC20PoolHandler.repayDebt(3, 3, 3); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(1001938080408985907, 75892); + _reserveERC20PoolHandler.removeCollateral(893907948982186, 417198501694969585713, 207145564963530430048985633858868679830329524197913482012168660743179808, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(2515261442, 1242734225453263068, 111842, 1000000103627605571); + _reserveERC20PoolHandler.moveQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 24329921925938249296965, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.takeAuction(15882899258328281282252091322583322533509184405771, 1, 2452199183077554215570481519130841636204328485854513771525159, 25890322285863681897240017620360518945591319004); + _reserveERC20PoolHandler.withdrawBonds(108378, 10239772879538335225538739190367, 90724406499707409847615714828); + _reserveERC20PoolHandler.removeCollateral(203131201342162854704751, 40461043612796742959666165411023, 164809343344601825935849438315031, 17345131361591341481711797829); + _reserveERC20PoolHandler.removeQuoteToken(5614956089759304493015724733499881489579491366518, 123079750161, 13510631893684, 380374499); + _reserveERC20PoolHandler.kickAuction(79521079663432823670447846549317590333024159783654662722513, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1676411); + _reserveERC20PoolHandler.withdrawBonds(346679207651908788605977937189549272274186, 27077, 1427276697627175516769979382142687833299108655589625089899808937266355); + _reserveERC20PoolHandler.moveQuoteToken(2714411610139598115527, 30593, 1003193724629183788, 44378902394094733092691749930, 32166311861427320484957545214971); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 386750294508868614428663194159059468260618315962973492124405, 175623609594010995123, 1); + _reserveERC20PoolHandler.drawDebt(16466370739820302383780524199335, 103341, 32746819660942078207516026122697); + _reserveERC20PoolHandler.settleAuction(1070732065984121537, 1002890412016994378, 10180, 1799132133); + _reserveERC20PoolHandler.addQuoteToken(0, 1581272199956173729870018779015252717949122706484258735790572234900378, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(3, 539392610193406998495237624396478656703548059248344220, 1, 2); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 11839702651359691822175706174, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2528636929383); + _reserveERC20PoolHandler.pledgeCollateral(17083993140, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 15256110201332552446502862577063575678082405075211216, 2076210235678804651587398731798422356893929367, 1580195718640362787723044387905814464717518433597571349100983213018623503); + _reserveERC20PoolHandler.drawDebt(1011767229401861063, 2167202559, 846326018297286849859991958045); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14654806779820925722080990295679796166951856538323467169, 3); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2558206803660920980571410399141875347663612794329351991); + _reserveERC20PoolHandler.settleAuction(63848336761685444294366407, 0, 44616318546503135111594183772632624349290074, 10800653277160513436956972134907292015289335738705); + _reserveERC20PoolHandler.drawDebt(993020270883971128318344077743180417428983279870489842, 0, 177293891323371672895610346144762305308261671417); + _reserveERC20PoolHandler.stampLoan(69595115, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(153465816851, 32875, 178039630163669210943764467585, 2676488665697809243704361454); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 2021944937943431988894560290461042588124978493274166500, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1560866985219934186343475689031363510547499606843049014384395542, 132794113097198891828528904471276935731849733045935217186640); + _reserveERC20PoolHandler.pledgeCollateral(3641135333168250388978190615128601192454367453435, 1, 328673473716876556880415673480012811711188690821361420842); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 469594831361884822026168233869305641832454554297887471991, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(23664869645583592108398799036467699623197503042051905560699, 1191622918749192298720632238839411358979561723589946088); + _reserveERC20PoolHandler.removeCollateral(40753966250297795215003899792515, 8630218901254689956132385031, 1582171362282714732201145284289, 10237); + _reserveERC20PoolHandler.repayDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 6728710880343977453773606); + _reserveERC20PoolHandler.settleAuction(39190152584546417999584352057749, 459698406744350623411926274979, 54258885703773274955122577755393, 15909960914939267992721489728607); + _reserveERC20PoolHandler.takeReserves(2593118620648188244177, 2459987060206448880956459327675, 1144693410974291709410668819594124622984764775423193617990436768899274516); + _reserveERC20PoolHandler.pledgeCollateral(1, 67186305870143658045366141754910442709518583145622705, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(2, 78097903524530476033132063517592414722827967485830668554624764, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(1000000000000000000269856654976993517723765488, 6429252327279707157654948628, 3179409307, 1000034670414497588); + _reserveERC20PoolHandler.repayDebt(25, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(0, 737661487264165828649324, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 290589); + _reserveERC20PoolHandler.addCollateral(40352, 999998881992400041, 1961293045937084281446493599048, 1005236764714570763); + _reserveERC20PoolHandler.repayDebt(8229216906965578438711557162658, 29803424331097947596069014241873, 23254450544396469722926108333101); + _reserveERC20PoolHandler.drawDebt(1000507358595057205, 48266383348925046816848235123, 1461002806216490558322296298188); + _reserveERC20PoolHandler.stampLoan(9900753803700598801030989, 97212); + _reserveERC20PoolHandler.repayDebt(3, 172669951473451730864797026655728314784741984523209623468503077, 4332428432793065753244); + _reserveERC20PoolHandler.pullCollateral(80488067796509514217232454466566876042431, 1, 3); + _reserveERC20PoolHandler.pullCollateral(146247926104180632418290252582208, 25240192111914575847356814291579, 8727); + _reserveERC20PoolHandler.removeQuoteToken(1955027806185132239998146523197970, 1004629885584181216, 22957812803192472772657122882199, 275414895586219516364957937); + _reserveERC20PoolHandler.drawDebt(107407, 322479151421857635961556500649, 22665); + _reserveERC20PoolHandler.settleAuction(49682, 1088778141030985131, 1004655556879802861, 1002044493803448807); + _reserveERC20PoolHandler.drawDebt(13159, 20143795919805289029820574248534, 982500782537120761015236940998); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 66607577121); + _reserveERC20PoolHandler.stampLoan(1031349982634654288734972859158, 998303646565402420308167385056); + _reserveERC20PoolHandler.bucketTake(0, 297900610476656141760153960817875472951661287051757001, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5562422739892253871027983990523978796723867465052556145243707357111307643); + _reserveERC20PoolHandler.kickAuction(0, 160420259145466178497648021338301750739739236543498903333563257272297215, 2354, 21459711847487828147486135729424914194849162579672582647); + _reserveERC20PoolHandler.withdrawBonds(800867771572810833386764907748020069734729476582837934020173065097224609622, 40628861884509005800636651060346097594038796292575981593216137453216122, 0); + _reserveERC20PoolHandler.removeCollateral(1000944346251588702, 874522958489709364351651044803, 4577245750286241810591279, 1000000669013415062); + _reserveERC20PoolHandler.pullCollateral(1, 2198697769933, 1359370038280329134705400115143558369943414); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 236891952794); + _reserveERC20PoolHandler.moveQuoteToken(1970060187617891261410061344974277699975747159091421858915655452888559856, 184182086969637900612294944050440490577000974718810323056288151351188, 1131279377382968909438007577017141651677634153407270656027965649594170, 727226270706841454823082962353491, 280442696352035553188709338314859407675749610311980009618622); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 29103284489109168); + _reserveERC20PoolHandler.stampLoan(3, 271383786297110388659455473823765522716); + _reserveERC20PoolHandler.settleAuction(2, 3, 0, 1); + _reserveERC20PoolHandler.drawDebt(18750778043934623908352795104428886583563406677377762437145, 95251144587848324264548558054688159109, 8281487296761203206510812702927); + _reserveERC20PoolHandler.pledgeCollateral(7605943798908107, 579815, 6); + _reserveERC20PoolHandler.takeReserves(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(8807, 3098766212704010576629271497726, 1002638408519177773, 350578227481545122238264922); + _reserveERC20PoolHandler.addCollateral(1323641599350316803, 1057570505606844097, 1021226766034996215, 244661731655967760993543226310795); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2468030400077840155822753504740668854907845, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1652509326829420416); + _reserveERC20PoolHandler.takeReserves(198, 818532579038358, 0); + _reserveERC20PoolHandler.pullCollateral(49677330164534764368814217546, 2370187728790397611644755480732, 4762621156222323434548475860676); + _reserveERC20PoolHandler.withdrawBonds(40947908860970705174814440394186127863796003061, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3996, 24750948229041744360360073227535006848157293192466886387, 664); + _reserveERC20PoolHandler.addCollateral(94451234354786244339625315388765, 129109887661868743362223119964, 1005237306190124104, 231473602518262892964697249156665); + _reserveERC20PoolHandler.pullCollateral(4977450675110644274064792781984067044, 674241408325830963271159256220912782, 229481608275666600966785456266021754703994251407120931054304833276039384335); + _reserveERC20PoolHandler.pledgeCollateral(9377905647794299163596, 1977934398057985, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(1323641599350316801, 2041971193, 2534038337); + _reserveERC20PoolHandler.transferLps(196453696679920372766722605727123, 40021498577295123432476999736897, 12397725745250461535125829880363, 453359139277339155017330551068963, 78904415576750364219614985788); + _reserveERC20PoolHandler.bucketTake(60071668692008425337655398, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1302721229759271194979249739891738263622540238021240); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 7527693672230251820628897884212929467393247324519160, false, 62304071, 1206133591676907527208124); + _reserveERC20PoolHandler.settleAuction(1000001289764910893, 1000000580289361669, 9177756810343987323056433397128, 798797540670525372174242771707); + _reserveERC20PoolHandler.addQuoteToken(3, 17881, 640951655164679459136027403, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickReserveAuction(0, 32262329473904436386778697543077872429890116817248375172); + _reserveERC20PoolHandler.removeQuoteToken(2, 2818399609530743652725542618857834734278554355600862406474693441, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.lenderKickAuction(33419088425165, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pledgeCollateral(1887810507253894275142761816783, 111910008932893684902293943787, 9414511908332977605248610875519); + _reserveERC20PoolHandler.pledgeCollateral(139140745126353797625201389207960140293601576534358117546217449484275314480, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 405616452164761373514562412942102332042011961960255248615739); + _reserveERC20PoolHandler.removeQuoteToken(2007410431, 8058370611409588329446663809964, 2534555659, 64859); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 437795915043, 1929906415731347689148951); + _reserveERC20PoolHandler.stampLoan(740983357862470587246184787196351607011363016245957799445889049456113, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(0, 18543332097188021147209515453582590, 7330392319592460868555162307111222386361694696660259041062323651); + _reserveERC20PoolHandler.moveQuoteToken(25258004253638607431574154359651, 3045359175781691864658920744031, 67779, 258304719966085623533092733543, 20924159476411627633921846004288); + _reserveERC20PoolHandler.withdrawBonds(83398821674391534657621560879358089539293104988891463007109, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1634742388392417718612546015868); + _reserveERC20PoolHandler.drawDebt(1579000511918697907639220693762010, 172133335811040710984789674, 23254011570496074332269690813811); + _reserveERC20PoolHandler.kickAuction(2, 9394714, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(48130075994672278974872817, 39358191735267750161240071573516, 64071740283202592482042626331158022961, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(807666529410719657002048893345, 1746786851755927105948631166094, 111003, 65386543839702078844023375500788); + _reserveERC20PoolHandler.kickReserveAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(3474188945960014570603781234273, 182282815115168055032977659368272488686441105254765014, 1); + _reserveERC20PoolHandler.removeCollateral(109923685568233024268797207908, 22879517165678110938523266767614, 14144322486758418449589910172040, 61920258378051030240077152); + _reserveERC20PoolHandler.removeCollateral(66193137722195180159355193940465844036919607227789133575241109805054601192327, 26404512592818336711370267461009, 9290, 29099); + _reserveERC20PoolHandler.moveQuoteToken(22003473681084181424388341215231, 42298578052628289385579000055055, 1000456323355310314, 98618625287986140446548624363098, 2115); + _reserveERC20PoolHandler.withdrawBonds(2041391127, 2521748785997300174592824377831, 3060464548340719530367669234586); + _reserveERC20PoolHandler.removeQuoteToken(420485471231703316984456011927480467363790736555736842110, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 73289844592364558632724543970855572867610, 121110194287653186571); + _reserveERC20PoolHandler.addCollateral(17444398545932716442609587476921, 999168718631791372108219508910, 94450992448698106930915513668390, 1503374833330724355618670439300); + _reserveERC20PoolHandler.transferLps(47280, 237674642214740738429852671, 3034231622457042137958658891570, 94407916397170568921034662456511, 1015633420475139622); + _reserveERC20PoolHandler.addQuoteToken(2, 3156740680813600510963925806730237564980026703017132120787376, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 183087003403563899171435752361345491701350910372301673456); + _reserveERC20PoolHandler.removeQuoteToken(172482203088290264312227240055, 25188584456895035543729951702722, 115638054, 1586680203920965482872268402557830818029675180394892589238040260382339453); + _reserveERC20PoolHandler.kickAuction(2890306510919995649385884131702897691243318939446995088362122, 7989340041480698845446428561608263236993447, 14753619408682402355263205967971291770599849979744373052122013888180755400, 42659472034311118294852255293); + _reserveERC20PoolHandler.removeCollateral(1, 3, 35, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(2731383956, 129241, 25490183602612189604690899798626, 12355620334868948403423684979); + _reserveERC20PoolHandler.withdrawBonds(2591352086, 21847345287222288331894224960190, 1045573891143100744); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 221219011790504830170941232890025, 2); + _reserveERC20PoolHandler.addQuoteToken(581669925589917850545582142005, 548768875791661009873676087853, 17841, 1000650450391191242); + _reserveERC20PoolHandler.addCollateral(204032710184306565544852275235831, 484887807051282606263656437690838, 5601326568325366346210593463, 999998503932618327); + _reserveERC20PoolHandler.drawDebt(50245, 66697, 7839); + _reserveERC20PoolHandler.lenderKickAuction(8847688626, 9345899547406982924, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(499679590737450514180996640345, 47292297365514981672191351685177, 6255486236634427718468290); + _reserveERC20PoolHandler.transferLps(3260572408749589507377858830309066283607684173713402868037318511665873372, 987161468143, 1443099719654036, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2857866925477753048684669713131952072083154421105719788693764948351360, 43845748552690493459907568342565045570723665990441003343583); + _reserveERC20PoolHandler.transferLps(272304337952, 911084997904961261052091805635512, 1, 2, 2); + _reserveERC20PoolHandler.kickAuction(6722098608454967, 43616697508847561127379224493320, 1001139067643775188, 11135110980384403942987153590993); + _reserveERC20PoolHandler.lenderKickAuction(0, 506849628539776, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(8603651419444664625563535329909, 115968966570143165994380847178); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3); + _reserveERC20PoolHandler.settleAuction(4632011794316134294752803447312381, 203075765019819747645, 224853260315948194201357136382039355324068197735407978995, 2); + _reserveERC20PoolHandler.pullCollateral(240580, 38418677, 290474537897373410165545776522254252578803839203378193491845604722622054300); + _reserveERC20PoolHandler.removeCollateral(2734148453327722584336602359240, 9493399166884227706253897558, 24662, 127054169569839553349814159206); + _reserveERC20PoolHandler.moveQuoteToken(157861283323178192768787193368, 2526278173681235724642, 1000033434039610001, 4446232817311655303915647533, 14712945229039674306747516109); + _reserveERC20PoolHandler.removeQuoteToken(224641275930544798939215934012429, 2957600292, 1002277084944008190, 317259458520215471487621036115); + _reserveERC20PoolHandler.transferLps(13192201293847315013066344754419, 20390, 19368949026654718384648432120401, 62693, 3451966933933251199737383579946); + _reserveERC20PoolHandler.addQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 10553875828660566498704663866287003591158076680546616778360108691071967781); + _reserveERC20PoolHandler.transferLps(152032452844559849308281912014077792192722510414412509, 10900744912102607179877924, 1212413132176222101104666098941092771924732134328955805018491168231, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(106055487906963199347919428644449, 126276892286099194828530984065994, 22354034078384858216659582649673, 1001118654817032832); + _reserveERC20PoolHandler.pledgeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 18942919795201199613772631255741473); + _reserveERC20PoolHandler.repayDebt(2, 15276235126519722493271281608284529970097003948778508585, 2535168663550099298249705451319121808949405637358397138); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1518189233704957642342031806481909783036956073742627613, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.settleAuction(3393684818916483471678263472181734682907306254644221838513037094897580, 5132170858344698, 477447124954253456174671649437499, 6392); + _reserveERC20PoolHandler.takeAuction(396043632494144, 115008652500333583491631188011091, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickReserveAuction(1000173439454110463, 46065924909988081292239275709920); + _reserveERC20PoolHandler.kickAuction(8402996351967786971852339, 16995232833963492722718628732093, 1004429044742122499, 1138102485217461966223441247476967742387212734165734657525444672873969806); + _reserveERC20PoolHandler.moveQuoteToken(75730334670, 463258080664292285548, 259632898338777559032574140661399634557986962, 2, 122609865273565215); + _reserveERC20PoolHandler.kickReserveAuction(78546926321841351556726848, 297546891203712644955099496724912); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickReserveAuction(0, 25437115628029554271902316652); + _reserveERC20PoolHandler.addCollateral(125468371322623189395191762014, 3283705477019267983994954, 26224495800456325881448428624900, 4451704112898246226894400265); + _reserveERC20PoolHandler.stampLoan(7886531442498321410167752845, 514843265670233017184161833); + _reserveERC20PoolHandler.addQuoteToken(96040418247880516222800461792063, 7280365512102745621080479910484, 345800805808111552840807251, 702449314593751012263272569486764891434766482501025186913462082091769663); + _reserveERC20PoolHandler.transferLps(153890826098076982425443440352, 102696485328335330418455646626, 5699, 265853531882935704196696482, 14011486633744151633328541074152); + _reserveERC20PoolHandler.bucketTake(54066288031218195520851017311742778985382003499039160243292712255597496490835, 185481087680, true, 229634, 4); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(24106, 988463687792172861526073937184, true, 77680, 877189835798729511508936769134020482766718629240364376063295188864141912); + _reserveERC20PoolHandler.withdrawBonds(5920044030000718666924645042885, 1358864052482099519113093996500755916581932053409917160957183667787139896, 17058463172956477907407704850483175153839352432); + _reserveERC20PoolHandler.removeCollateral(3675394456555211586961475581389202244845803170245, 38196389744550433906156431026125371343775556063368440582590, 14991828766631150270573659975663589124392686654607997938324, 2); + _reserveERC20PoolHandler.pullCollateral(10213994943105161366013426535719, 22957731850314468092810582315714, 97105490776722319080956); + _reserveERC20PoolHandler.moveQuoteToken(2970816251493144105676212130258520150687772756694764336277943, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3); + _reserveERC20PoolHandler.kickAuction(407303464681716706726709, 1276782759301668034641366044374, 19684, 24439); + _reserveERC20PoolHandler.removeQuoteToken(13684506920877259660416098827692158951817746984280706946, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 52162185274740468641712643026251421054557199786323984835103729903, 1315082472764375031827850923); + _reserveERC20PoolHandler.takeReserves(1001145517904302901, 25601724655609802572139770986475, 1001022384926723983447289630730432396132276230720978964255166015358289118); + _reserveERC20PoolHandler.kickAuction(19842, 991343861574442718, 322870372116984809122416263, 23944902375185947078739915437240); + _reserveERC20PoolHandler.kickAuction(23980984876761331286558838957233854844294, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(0, 2, 2, 402438249343264428010644257446805986621356087324780663342457166346056); + _reserveERC20PoolHandler.drawDebt(3568337688932542575590564759, 27288, 992642451141294131228120589018); + _reserveERC20PoolHandler.transferLps(6133833985714200174134195845747143324395755006836070416473853633512, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(111716093696960185825127316280280182243, 35024840214, 1746210486667196461056, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 7559849472385); + _reserveERC20PoolHandler.withdrawBonds(3632738929098987, 16134199819141754465423502, 5391851861921217681970916197190148758245629811697335577631147382); + _reserveERC20PoolHandler.kickReserveAuction(4061538995323810204459755, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(1972272795, 1923320489225557056083582592988, 1075418018603229454, 85951481511201659336910552584462556066508423403276452852972802124644321970181); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 268793054583598763814963367414209110598020756735018139323395868); + _reserveERC20PoolHandler.kickAuction(10974089573056208404475720643723, 34900753842629502741046832141124130052932668216144965457151667002, 397057104633211080847767267789477, 3346); + _reserveERC20PoolHandler.addQuoteToken(0, 2520139424799174636310227203895853390313822330, 162378577134223706221486072504498796248282149999422660952, 1); + _reserveERC20PoolHandler.transferLps(34374488005582387305443388097594, 190540230121177892554366657581138, 46602, 819105400389110145065452903115871829681066107256701862755069226241285694, 51847294276519277694620110027); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 2, 1); + _reserveERC20PoolHandler.withdrawBonds(512851139770225679508142248, 18658456618012396957565244122479, 1000663087395200503); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.pledgeCollateral(1005236692199974685, 8201320006028250506882063666571, 2459864756549377036116323571014); + _reserveERC20PoolHandler.bucketTake(3, 4458731784069365424610607518812867133961482575123, true, 3, 2769938391424196142444171302562201785740809732578293659160863); + _reserveERC20PoolHandler.kickReserveAuction(7339609873968608372916486350204700098124580114193837283149792965210482523494, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(2999999999999998027929014233821754708735050481, 39056, 27666); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.withdrawBonds(3864325047480308814153859184962047656384073356119493444222921129425042, 81, 2); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 2); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 33561917067982, 2); + _reserveERC20PoolHandler.kickAuction(806061795907417717508634268684198804780564344387528320269882561727, 168639406703859425132377839390654856823063, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(988461478248562076638934393253, 106534, 2403587343860145884582, 22344107370366493921582660630, 2024118056925161807501892); + _reserveERC20PoolHandler.addQuoteToken(57276748646446991334522703, 106108713442237441743225077405556980113422049960765423168794101181632523958082, 1004182892556728215, 1001182059838156584); + _reserveERC20PoolHandler.repayDebt(3, 89632924168784806708978689137692640270837030940240067, 272684135774490949196835289201751486568202067511530); + _reserveERC20PoolHandler.bucketTake(2736179655426399487855754929896, 110862138396884940593684646613, false, 1359586396520620890883020427072954942931431447193872336317129092457431066, 5015980780524755); + _reserveERC20PoolHandler.takeReserves(378245130855823787, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2151982074507655226378573062301872130551729225851405772186402751741529258925); + _reserveERC20PoolHandler.lenderKickAuction(1452635446174219046191530546444073341752921173212249311578218026100093, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(64979, 101726541050469933514118543135, 336380378210560812302138846347, 2711853670419630060394, 247270969178227086173973947); + _reserveERC20PoolHandler.pledgeCollateral(20159403724770279404831367203831, 512108158635939058273878650431, 1000507915338149553); + _reserveERC20PoolHandler.pledgeCollateral(622579755237528, 196947936337661546279039869333817057510610544771541950771361945, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(223845220356227868348395049196538, 86579, 61920, 26972); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(1002934667884567612, 90956, 208023155486680879438762062731); + _reserveERC20PoolHandler.takeAuction(3, 2474491290046996032676409009313467389208407780351558, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(1027859133378048088156664774752, 1014582801619234878, 2995560189, 16078731544565918276582688542607, 111287910229449452378); + _reserveERC20PoolHandler.lenderKickAuction(22879576175607053514271330459976, 441762948192897558002104261371515, 367687078702797286270751453811942); + _reserveERC20PoolHandler.takeReserves(3593369, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 238898901040198078474680935477942362457244487764330090058942103295169637); + _reserveERC20PoolHandler.lenderKickAuction(167253543561450600855346633087860450204429539232810017806517980414721246026, 3273983, 15540989); + _reserveERC20PoolHandler.bucketTake(15453488832569176531580538848466, 9427568027969318460943309053, false, 5192388110704796352905882393, 78228); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1141527674880112673291, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.drawDebt(1000150970965001024, 9772, 205621143105409076826770040619); + _reserveERC20PoolHandler.lenderKickAuction(25856084474962278141161903429587331224171165, 6476231727198686069674965718504034289350938632989599, 2); + _reserveERC20PoolHandler.bucketTake(1142702514140543754046023894228931775, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6953124388542199107907452756634128543); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4692693361255998581105668987895356944933209825223978779660, 3, 3022929271268684971696971370482952283825295297700551039323312960452989526); + _reserveERC20PoolHandler.addQuoteToken(2, 1, 3, 31673073277747024036785537462311208659240583417196); + _reserveERC20PoolHandler.kickReserveAuction(1000000150837002188, 202718905565954209165307498); + _reserveERC20PoolHandler.pullCollateral(1000000000000000000562735687238676467600107065, 242219553590484677938257593947, 31869740932541785086640403393414); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1114446788, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(1711525088056642692321781895818, 1004055327091443162, 813, 136449739888070426189422609512); + _reserveERC20PoolHandler.addQuoteToken(21369225134816701247677489209969, 81960, 4490747798524370421209167245327935723340657030712552833845489963651188, 1000634814676024885); + _reserveERC20PoolHandler.removeCollateral(139916772927186942756220566424463785068849110236844736955254, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8751122214901989135362253535619502); + _reserveERC20PoolHandler.drawDebt(86506, 269430024928494061119931805300, 1015774869655334277); + _reserveERC20PoolHandler.withdrawBonds(1201274749743949596, 33867319080590716120046851591173, 1748564039732896174); + _reserveERC20PoolHandler.lenderKickAuction(45944283336576143985566904562363, 1001453721022250782, 1708118686882591639); + _reserveERC20PoolHandler.kickReserveAuction(196407373639459784221736, 3); + _reserveERC20PoolHandler.bucketTake(46971, 1003846801634538425, false, 174456710315335099602991529775497, 10377219311777000170019581775917); + _reserveERC20PoolHandler.transferLps(6760221946343264365542727939162, 1000262994721493099484309159445, 519992178893469263, 1003191130772174080, 9566716622364178713411100228); + _reserveERC20PoolHandler.pullCollateral(266050472923634231030735, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(659089822863412, 2, 27249920252078367099075134983518876283720980937251119524756628737); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5483500681537684476441450379968101, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3, 4572054204358575291734641879454728342406); + _reserveERC20PoolHandler.repayDebt(2402305453554148482683527700012634286923548202, 106386976028723461889853293836, 293284232744326642856965564191297534153430847809); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 174749646737, 21347512850804451733329066641314976607999, 42744154661110715413993179921471600152871721849650200999706124475628407071087); + _reserveERC20PoolHandler.addCollateral(72468, 2363278265243265452695406588, 71487, 675093730075531984290857571606012); + _reserveERC20PoolHandler.moveQuoteToken(259603270745, 18778353770475371, 3, 233798733212260469650873227616527796454572046229357511073618087000365015, 46312805798904705413008795957873807190978240266001801547874297081196808555); + _reserveERC20PoolHandler.kickReserveAuction(33563397170342369695829456751165510082634915628, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(45301, 7648942772157821858347722769067, 939249737442594830026580437284, 1123188025698350731943769649); + _reserveERC20PoolHandler.repayDebt(21226963358607883897817052955353, 7626825895511785767595788262480613598, 1003219094936049195); + _reserveERC20PoolHandler.transferLps(21839534310580396589447046708373, 23576887588733312594403281138616, 31689717874618616231084654, 7864490504889360854240538048, 6346385622404268350682864243611); + _reserveERC20PoolHandler.withdrawBonds(187776540825805903012231801264587518793542725561955403871, 1334459942983933932190837137865592442005278926817476077984, 23453643556159547838202473669141304446745188853023309109261419022688950778); + _reserveERC20PoolHandler.takeReserves(2, 177278438051488159862593283123706022116095, 0); + _reserveERC20PoolHandler.kickReserveAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(1006242490206816222, 317258912163456070246243500192, 82691, 8300190740736235278194026876863915486, 1961161323973216488205803654405); + _reserveERC20PoolHandler.addCollateral(1005236968449156003, 2381717668256189819443698513753978, 257705635465010558215267148700, 2164199768); + _reserveERC20PoolHandler.transferLps(29505591521846827125015, 1522719165486237072869056, 60, 16390499475256482, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 350195575491952220889492772392486887371392989421, 2); + _reserveERC20PoolHandler.kickReserveAuction(156605726165297478903214532525, 1983); + _reserveERC20PoolHandler.bucketTake(19345533007468127177369078146774271950651764, 115650297759179760970186404179767015677827137748967794685330836402692683, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(211783685559670776082342956968525309535695754212244, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeQuoteToken(6261567720611589014856233485791422450451505043381704992078367489008851439461, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 6168826725109294973418172814775392982649549656392224661); + _reserveERC20PoolHandler.takeAuction(23379972, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 852792921716222779898742, 1474480232626671696465943161655788368754327535939542517, 11460919140495); + _reserveERC20PoolHandler.bucketTake(336551244348140050634259954618, 375148409695862317093276272, false, 25857871814405647751578024933105, 788083879171319090585267986498); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 27816781094419); + _reserveERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 2); + _reserveERC20PoolHandler.lenderKickAuction(27172080337908095189867295718167, 96868906639327415378187682149959, 36587825538357715749970610678719567617342051509510080338465901801162122005001); + _reserveERC20PoolHandler.addCollateral(2, 2349422199351753490895535885234441465350244963519, 244808054752111580316375422325176281374888912520183062, 1); + _reserveERC20PoolHandler.removeCollateral(367514187458456143139043045, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 10119379570622733697078); + _reserveERC20PoolHandler.takeReserves(294415247008688926032522685768971244909886781354470, 70235335805323564296918364176134578880945673, 2); + _reserveERC20PoolHandler.drawDebt(49261551623613566920010552752543107774618191309482843751869005543694379, 13035016119916224, 444070980087); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 11, 3, 2); + _reserveERC20PoolHandler.removeQuoteToken(7964751705469545859590894278, 2742103240185530625364, 3564989509593009054804379381276, 1008077831265303366); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 116505794155979165, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(327106696801299434333787351521359374115377627, 9330962353067087769775067061572807, 4970030377183, 2); + _reserveERC20PoolHandler.takeAuction(402221499291, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 162); + _reserveERC20PoolHandler.kickAuction(13111612682534827773996163640199, 1726423829063211777855841102869, 3565139334034490554278559434128, 294651358107032831742671227525326); + _reserveERC20PoolHandler.kickReserveAuction(341710635704706470101329225372715754035587183155, 3); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 839); + _reserveERC20PoolHandler.moveQuoteToken(184342864988154682798580129924213499209, 20914784928221653828470296, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 110214056184197982489154); + _reserveERC20PoolHandler.takeAuction(128899414824149212842887767485, 34867447821807006553025250693706, 33127225858086527115495280376628, 40999999999999999993133559593271336661925811039); + _reserveERC20PoolHandler.settleAuction(27290779790898886383, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 110784780165, 3); + _reserveERC20PoolHandler.takeAuction(182272200120801058566397765229887, 86382, 3068419412839090839618689381903, 1000017307820875094); + _reserveERC20PoolHandler.kickReserveAuction(477079188709778, 0); + _reserveERC20PoolHandler.repayDebt(5592274435481746491892793097240758426326775955505201873, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1037764559372184986686543959641549704620399589325298874997179); + _reserveERC20PoolHandler.removeQuoteToken(1631756857420786168418321408519, 235589927492397289553100506365407, 819323818682669084297640036975006983402619597688060233131486494895002989, 10114845312902282058202113037698453480680889888); + _reserveERC20PoolHandler.transferLps(50643, 39190157772044372073447826912455, 69827872017106087488747303093181, 118159524657180261871845194258, 19841); + _reserveERC20PoolHandler.stampLoan(38, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(3, 1097698697657086, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 37611653896771464240112846970, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.addQuoteToken(5992822236695715763697263, 8575420410060605859213215006971, 1789055717585009949328231895430, 1311744726335564467075012918566852003665405314976391738660611301830404147); + _reserveERC20PoolHandler.pullCollateral(468323940503066920528204114, 50644, 25356024512677283290238661519527); + _reserveERC20PoolHandler.drawDebt(2718920517987810685293, 1060898017980950929320442, 310891824891964688215717234122452); + _reserveERC20PoolHandler.transferLps(7116505522618098330942020, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 138722655519827846296306440605468222894150418771148719797); + _reserveERC20PoolHandler.removeCollateral(348339942387922015864199828840750451304293001, 45, 36591499349325970095997811043563061302729864950409801967426313060440162343749, 1); + _reserveERC20PoolHandler.pledgeCollateral(205399211108453612883245899374292701358178623337, 3, 1822981425810171901648742029577); + _reserveERC20PoolHandler.pullCollateral(33103030467883232992823536062243460771799, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(150369905538856063402434645968190116130135829184479379, 918931364602093989949540724550, 1, 0, 747106490571424436215116862561106278510524437390154493817); + _reserveERC20PoolHandler.transferLps(6371120284762295472086753217592, 16202048849788603832332790628, 13658867252121201287775393, 97816053883603231152962419367362, 62198); + _reserveERC20PoolHandler.removeQuoteToken(80509729424188606450340837417157198, 3, 7557442, 9264739057811436601549923513769229456427719); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 16788868396706615285852073225751, 1953001200); + _reserveERC20PoolHandler.settleAuction(1, 1708843442190974694511673448163980263370154299426963031432265054030790, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(1986352918557608833587120856631076, 431973862049162451642727068, 802320008277487440165308981, 11868601064713346696829533828, 284800768857943366831818711888); + _reserveERC20PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.addCollateral(445495215956232823636365710462, 89394292327670045897134156838997404291068383735440919929886485736836724411749, 1992121087052880, 110797044786042427374626418645917401249115586023001); + _reserveERC20PoolHandler.addCollateral(988546785004485220168621678229, 1743578025, 60212, 2999999999999999252586562972971983764267033336); + _reserveERC20PoolHandler.removeQuoteToken(267232607094392536073141929456, 45145313700426665178967237014640465711144116818480, 17984025061020100486538233626178886200622794140565, 3); + _reserveERC20PoolHandler.withdrawBonds(50400, 807970927202559606280130259612, 86380); + _reserveERC20PoolHandler.stampLoan(47809080336562285713531800329, 826017646289104836138341139297760457947751884820746889743561759120050941); + _reserveERC20PoolHandler.repayDebt(30304960855078848021012718732742538383473003799210616369701789564571014397955, 101775076728778279359400183993, 1017491445787793287); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, false, 74112450910440379888471280350106120418, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 330056439925111863098323975925830106923031558889110478, 5333); + _reserveERC20PoolHandler.settleAuction(1, 1341268565475941716391459236846185320874314051443873138582642663, 30974633000861574, 3); + _reserveERC20PoolHandler.addQuoteToken(26589, 23150020124321080739969486229899, 45942796567480269438832889279169, 667); + _reserveERC20PoolHandler.transferLps(3, 2690060713878172718721204349679, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 287817696834326616508359932528324481708048, 1314387445551534135766); + _reserveERC20PoolHandler.kickAuction(67470345421450536967780770439, 41256, 732881733738492471432467799169155578256695211046307227006766147905723079, 819974893402620564093491734854718605804); + _reserveERC20PoolHandler.transferLps(2715153566871988574928712881556, 24352441380499669242371801302272, 10179392780061706553662358923555, 598786627476769936884514321427, 30594804556836422088347448968283); + _reserveERC20PoolHandler.kickAuction(2699227540314835856648238147997428749992733321012080815, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 30803522759172552926926793031); + _reserveERC20PoolHandler.kickAuction(362574467123448233672112010785600036155243418294975957608533159, 18325198731647484706, 2, 45586822704909918173253139357319841610267425362067530288600314788483530383); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 147735782388683637345691); + _reserveERC20PoolHandler.transferLps(2264205447, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 393435736817328888513196889409069202313277470807170, 645057209092811458717227249, 3); + _reserveERC20PoolHandler.kickReserveAuction(476482467241773568563805525281362, 3692874315336219851341367034126309586991576696866737747605799375405473535827); + _reserveERC20PoolHandler.settleAuction(2, 3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 53798152365912960630096307114590693246806329937675296492552809260877803, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.withdrawBonds(6224124036453864462000261832792, 2237458553, 2506371647687967686684284143286); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 67116680157, 2); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4664706711307747338587515329547790691178297810); + _reserveERC20PoolHandler.kickAuction(61433562444509870162212939634626980751444, 481057855082330582776588199473910365880707339841008704, 43801950311943285007399734305453935252931464173463691177711723808037153534, 12029649680917625208754169187150778840929441857018437964681987608597951293); + _reserveERC20PoolHandler.pullCollateral(167400433147115097027304303601520, 1000000674530922573, 6081457492260906419111834046864); + _reserveERC20PoolHandler.lenderKickAuction(7684504846162682619, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(317403999172841283000478524565545, 148463663909998606078648026309448, 915763434852258807357882900456, 695838161060774258820470296872189128966794314717253960306303707835103538, 56844); + _reserveERC20PoolHandler.moveQuoteToken(2805331082887084113896, 54564098083611201279731569252, 22792989559884870790283930473892, 208052359866592111178407903370329, 7920439679693492812774700578); + _reserveERC20PoolHandler.drawDebt(703520517900206366034371071762382203913929842473642794845612639406155045658, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.lenderKickAuction(0, 246903877493460413884875643, 0); + _reserveERC20PoolHandler.kickAuction(1500107724561233212931570348080, 982628983780387543350174363564, 569860181825493368606731891492, 1057430988415221594); + _reserveERC20PoolHandler.addQuoteToken(364568165061753196674690625547564, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 7193546025907807067316997); + _reserveERC20PoolHandler.transferLps(280711337925777617253, 0, 12173517929353581579097048236569531, 2703874233182151441900519110457, 2); + _reserveERC20PoolHandler.bucketTake(2, 11965269237113341, true, 85614588, 1); + _reserveERC20PoolHandler.lenderKickAuction(903289873395895577278541304, 10475, 28926089520153352022929888860530); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 43748076708607405118829969337753299953667864705); + _reserveERC20PoolHandler.kickReserveAuction(5128006214067564324981865563184988382269057542191708, 1712878829799242442931337644485859686482000128598); + _reserveERC20PoolHandler.lenderKickAuction(5242565040668786, 45157, 1000887541336322162); + _reserveERC20PoolHandler.addQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1225739994615102252413656363207721, 124413549515473600973843193384); + _reserveERC20PoolHandler.removeQuoteToken(102576, 927681204379780767164414949090874134043650786626519430863261884267170304, 87935868159230147849535604462732525937369558587914819723016226351352954578995, 25471077093173596162318848038); + _reserveERC20PoolHandler.settleAuction(0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 412773); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.lenderKickAuction(1956471885139081807534704895489, 3926141909, 552588401139081202541513102000590782); + _reserveERC20PoolHandler.withdrawBonds(38299, 1986098039255264190912005659909831, 8847082044524306387767767273839); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 15574973998169535649192859685); + _reserveERC20PoolHandler.stampLoan(1000544750646957388, 9170709463720744483211026029); + _reserveERC20PoolHandler.settleAuction(839374462262295, 48118871777291619860353109, 257778961834, 1394285027710542829268835859749490433578911606035167813); + _reserveERC20PoolHandler.moveQuoteToken(34678856474499912794875972, 2763716201669360350481, 3259030237327949393021560, 2735997380788718385716, 21225385770256430507205419036151); + _reserveERC20PoolHandler.addCollateral(200663108663594777518088819831977027879022749243260908, 0, 1559338178580052981285396878545402428278846811503833, 36956309841581242277556760393172); + _reserveERC20PoolHandler.withdrawBonds(2041847789, 280735741183132716639099646, 260642030639967555712752); + _reserveERC20PoolHandler.transferLps(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 12571148948218713209708716079065970590862303793710839831586385240, 8985229960381851700231026687651954479177653063084883868393685911891); + _reserveERC20PoolHandler.lenderKickAuction(1820279038540906857134812623195289987632775762099060813491376603712, 2725175259927455191880725216561, 1215766578394714764959432152); + _reserveERC20PoolHandler.moveQuoteToken(15705085547050583254782053381002779613529983, 411957176040456570456053377502979013102089798362422915341007867028189, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 19061849669957514138127954572796); + _reserveERC20PoolHandler.withdrawBonds(4113284945053689071879393427460149361657756086191980024, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 346238957374846183322071114123330102082234294393878667); + _reserveERC20PoolHandler.settleAuction(18115767088951726479402660351319086601684440901844348228, 56697125197014072193287091118573812663830, 26978516975777738298746301, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(80350350801064858, 7790790740943162351070334912774192989, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(80600, 1011308356596843114, 1359556027911263249364909436039206255749186738312104135783958522759711534); + _reserveERC20PoolHandler.pullCollateral(1027274972223200254, 789447283286843523326629947112148599483360034969408899593944555711848876, 3565062481148676948826555795235); + _reserveERC20PoolHandler.moveQuoteToken(143786749316716894075412731, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 1, 264478127933405); + _reserveERC20PoolHandler.kickReserveAuction(23021992029679188592094632157548, 91308406578568193802156893488146877426); + _reserveERC20PoolHandler.moveQuoteToken(3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2808920283567261771904, 2088030250816610135619759654874313); + _reserveERC20PoolHandler.lenderKickAuction(269474745704351988529530852483, 24352445052450104135372493606811, 178141707779577031150725694552); + _reserveERC20PoolHandler.moveQuoteToken(2999999999999999859257928160605724280749795461, 140974710538378112562872727543, 8008420489085183429134143658, 62227, 39969831059712783267462269224210); + _reserveERC20PoolHandler.bucketTake(1760117868, 2386635145082944087732944376907, false, 26404391419005500878396407711062, 111715); + _reserveERC20PoolHandler.takeAuction(8330778907929066, 3770632702157887826526408292845, 1000001577454516056, 10010483694025542888740102217); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.bucketTake(1870036496685129519800435909, 350504372675313383341882442876208, true, 1689685326, 21523735904858803318994512218404); + _reserveERC20PoolHandler.bucketTake(842836862353542415425885177967544754506694949358685043008064, 34262429388892035381868225777268442670331780, false, 150847278442100946994355499791409167435155566504581126104, 3); + _reserveERC20PoolHandler.settleAuction(1006315531623665639591921693201471379816, 1541, 40099906937229727627901296073699, 102703613715571978862281506037); + _reserveERC20PoolHandler.addQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 3146569663504987); + _reserveERC20PoolHandler.repayDebt(2985622560, 801424357658677182851944293183595918900022070747390179871248272949933088, 2999999999999999999999119677371929836614844529); + _reserveERC20PoolHandler.bucketTake(2, 237475892719237749826107080524240213866681732930201441644063067464387011, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.kickAuction(2999999999999999724978876439698711413550871839, 11099, 830440021756408054899922030365, 2794288949996531606155355230); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 1); + _reserveERC20PoolHandler.settleAuction(62945600558, 0, 1651062986345731737263544038177471752192767533327323524569257778393, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(226537472890505507253565261340357, 6346149426300083112621755911353, 4258169554933561168115425514); + _reserveERC20PoolHandler.kickAuction(2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(3856159637310680279594301236273451123812652016657266411904586581357604294477, 1272510591849626532517099784954128339062020, 900064083519817318302540521870639720006394887444155998535016171595193438674, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(153806108742551661036358540179669, 702758915864834857849802516399720761292941358008460179551371701335995639, 29944615526726819080134513021792001416706176197525309751396272312470562787354); + _reserveERC20PoolHandler.addCollateral(1, 183045448361113179192021127174264995714003264523, 1, 0); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 68331380259981218785, 13885667744886548130642239413537766384855125935236, 2); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, false, 26299285015788709333346085034246957519815544470703, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeQuoteToken(2, 113613072, 3, 0); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 82204074729714276350999123150118550283, 3); + _reserveERC20PoolHandler.removeCollateral(7264395503931736407428882391227243279804219950503, 4855364748374321771092340703312725753554958887794114477554672, 1, 5657212105618); + _reserveERC20PoolHandler.repayDebt(0, 514, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(111777, 1029909385351990943, 6436259376094226132004247131545); + _reserveERC20PoolHandler.drawDebt(47292297907134482057975649350948, 18658456966701881884347073373913, 130799823513632340986198912255588); + _reserveERC20PoolHandler.transferLps(335573051427923797094308366479062225970, 5523421925780057037, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 3); + _reserveERC20PoolHandler.moveQuoteToken(2269466079, 20865222292015371330170253, 2097190307, 29140190333364638982914889, 62194994739283749427245795337065138906247013207910224300391802800990463348559); + _reserveERC20PoolHandler.repayDebt(48474939077965061732673069678169288280917408498939867798791855, 3, 1); + _reserveERC20PoolHandler.stampLoan(14774797571502847341049892702368016998356631471170, 282682388861246782905685893006881793361935485288563369121844251682186336); + _reserveERC20PoolHandler.moveQuoteToken(40538826022387932214099116474462682932877214004655097, 0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 10604024299998376560142116795825658505880582276); + _reserveERC20PoolHandler.pledgeCollateral(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(9181435638297025849840556307332, 33683328643869661596339938248985, 1033673951343182449); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 498538017800301608609594969153500575642347535499775895296513826); + _reserveERC20PoolHandler.takeAuction(3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.bucketTake(19611249298880214933211815711155432206820, 3, true, 214612196116369784436370490620538135348338900885, 1); + _reserveERC20PoolHandler.kickReserveAuction(3, 383992116732781964090601934004351271848628473561667970388097); + _reserveERC20PoolHandler.pledgeCollateral(2617911165960546808004271721593145073796063765743, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(1334167250840853814639, 2, 0, 0); + _reserveERC20PoolHandler.lenderKickAuction(1302843812025554926752762356241761712972374059189620324081, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.lenderKickAuction(4888926642581163810585721251936811364447120552007560, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(108922, 920409267227225094332470547656627998890743206583921591565723224105630738, 1362118774691061698768648); + _reserveERC20PoolHandler.moveQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 74704356431761382119388342089835); + _reserveERC20PoolHandler.kickAuction(16371663756934434, 0, 17, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 232786354039); + _reserveERC20PoolHandler.transferLps(3294066274, 141390663691949285198641416976, 16191222585049975848795743, 1000000000000000011241632322345065975021667593, 1000145343274281661984286); + _reserveERC20PoolHandler.transferLps(3, 92661357410502692692410034604900401202797437945109917011850763, 348284505647976029129489661924475, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 154278547950988664231048602467596675469854544883198394); + _reserveERC20PoolHandler.takeReserves(2999999999999999300379724622421584563390789358, 1000000000000000001143194367098809186498081213, 7809942202952233906178885309); + _reserveERC20PoolHandler.takeAuction(1001138728008934391, 129883434534395075343412798417, 1096446602757681788784228378280553421008257348790971242232890328950771002, 3677610411130070968741751475); + _reserveERC20PoolHandler.settleAuction(97052, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1957483850950084199059694586727904294988119536939012, 272); + _reserveERC20PoolHandler.addQuoteToken(0, 381778195, 21306077568356364437640384675889724618591355180939293046704919177111, 191743825285376820367864237); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 645047911895149538471393959726369223068456377042823348518774399647, 0, 91668524430864574755290497372768435117818633818478); + _reserveERC20PoolHandler.bucketTake(1668978442461411351673514536210, 120908470227823288056937340697129, false, 1002307833709915521, 33008767251186140598495866355); + _reserveERC20PoolHandler.withdrawBonds(3805253257346912736060855, 368815280880396001696997104980866, 1323640660310923470); + _reserveERC20PoolHandler.settleAuction(21847702611045464265343088900662, 118133310966994154147375218165, 67628966820628032573644873, 7655051239289268905696505526036); + _reserveERC20PoolHandler.removeQuoteToken(92665058188181396508348337135200, 3046807786332578363165720604513, 16781531179843782394400782221331, 22979); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, false, 1, 0); + _reserveERC20PoolHandler.takeReserves(3592698150981964534429525401712963723, 67504, 1001734142070636425); + _reserveERC20PoolHandler.removeCollateral(424, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 204695360667749388947161135925314687168293098929510239232777161); + _reserveERC20PoolHandler.stampLoan(28815156743095854030210182649036464191874931404610812350753993496258917448, 613411796637732); + _reserveERC20PoolHandler.moveQuoteToken(33706276265939943257, 2, 11, 2, 10548); + _reserveERC20PoolHandler.kickAuction(15481572473659688425651141377147, 96631627078476854218826, 3025, 2817223900011533840728); + _reserveERC20PoolHandler.pullCollateral(2, 30773436576933256, 24020490776529617710657793071741913); + _reserveERC20PoolHandler.removeQuoteToken(2999999999999997233519205621486245425333061890, 786287590123230481233443502402, 79016324317247675128285910224721941708291947468313627947560571224688544979560, 26596810595989607911104827212690); + _reserveERC20PoolHandler.withdrawBonds(1686202883387, 25259, 336823433172524620154990923); + _reserveERC20PoolHandler.removeCollateral(79092638685346955599301120920432565191934310931349206529, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 54); + _reserveERC20PoolHandler.removeQuoteToken(3382923154, 735119420365682322033174484805, 42691633064643983812662858534459, 11463); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 26463, 317730427178934868724755149532395883138, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.lenderKickAuction(2295398684078376290325059884, 12257056036956733639681706781097, 126436527730166155990911); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(0, 547941427772599408760574204); + _reserveERC20PoolHandler.moveQuoteToken(537849406923711805300263727961228827528967028660815, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 100288371053683888652583690090, 0, 8400912998465558080851435381897753717719578087); + _reserveERC20PoolHandler.stampLoan(2, 457060790196234948414859046321334801767); + _reserveERC20PoolHandler.addCollateral(13376351033137862996591, 976925259721029664997215922334, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 571022); + _reserveERC20PoolHandler.addQuoteToken(6376870797828991668578642810296938563859658570204126406313287853994, 177929340256178, 1, 30328680398429199672962818); + _reserveERC20PoolHandler.repayDebt(322726448985023072989404315115, 3045490233665215312140342361678, 2084735794696790107472328056); + _reserveERC20PoolHandler.repayDebt(156978, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 221824548849295763310507441580114928688873423712563785677023798114); + _reserveERC20PoolHandler.lenderKickAuction(2018404211835180, 1, 18364241548601878244435175898376908350575); + _reserveERC20PoolHandler.addCollateral(8726379675447419, 34872798233623958294588012798276, 3066541646420121280314551058104, 90819657163930208112901249975367); + _reserveERC20PoolHandler.addCollateral(101, 4060871354471907141889711265925344870099959840383453223, 1313018427808283161044493997393339271816986210923698967470389, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 469500662626811132366711265465299485682915415963, 1); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 7692701467); + _reserveERC20PoolHandler.pledgeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2899207024634941259614175107651252394905417459816674439391, 8447688873121494188289356562128402306773361296971773987231484); + _reserveERC20PoolHandler.kickReserveAuction(1, 1); + _reserveERC20PoolHandler.lenderKickAuction(1954780218578569666855403512166, 724039269855146072641980730261897613913902059743477368526373973364938034, 188175168557667269434903833869); + _reserveERC20PoolHandler.removeQuoteToken(4720081540984829199731849117198, 93444, 1021824756617285563, 813433046909416599929671514856); + _reserveERC20PoolHandler.takeAuction(530807637324682125237550714638906431497666756419003959164850314, 62, 3, 19449964067296973798097872478002771866604136394548310444); + _reserveERC20PoolHandler.kickReserveAuction(226624120925524614059172960608447814471367411239851233643761759067, 2); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 43922249959558881840659492077553091158484441672866212586790918514, 0, 3630040723668741158974425875211); + _reserveERC20PoolHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 24414836720563745711075388945); + _reserveERC20PoolHandler.takeAuction(1954641861206170132871075956942, 72382413202382860734543793, 144373888714095827611372703278, 2640600983443882787873327); + _reserveERC20PoolHandler.removeCollateral(15453486193491933856514298805842, 833145363521940690511852170, 1297131413383638723837351218153824995725630388420402189921520542438678189, 23157575746151636584289872430052); + _reserveERC20PoolHandler.lenderKickAuction(539324693169143, 2594303710261225663177342909194055320637261278923767181660251813316952785, 5399416537039); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1420502851256829988059949059110658700532038789083606510032, 22014948730936060357011001980247838258845131792680884057625660, 1); + _reserveERC20PoolHandler.pullCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.transferLps(0, 58203729528846551963206109843155244301383, 3, 1, 14303678208663938321276780915883028); + _reserveERC20PoolHandler.lenderKickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 141394564737513031072577410488445250909496920757314122038545380143); + _reserveERC20PoolHandler.pullCollateral(16195935948835, 1717743748895398404092974903491489915897203368031554930095237146406475, 2); + _reserveERC20PoolHandler.bucketTake(190785847853056115981028239758, 26588757556604359276914626391549, false, 1580227338521002665811569117987, 5389378146597052); + _reserveERC20PoolHandler.takeAuction(2, 5919873835307989, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(1486677702533607493054251649, 1020987447138716094); + _reserveERC20PoolHandler.kickReserveAuction(3659385446804143255999802973661583088262652292872, 720308225448635602040936053); + _reserveERC20PoolHandler.lenderKickAuction(1, 636916300789296700900098624975992312790, 3); + _reserveERC20PoolHandler.drawDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 11109020578229468249426222659); + _reserveERC20PoolHandler.drawDebt(965330133660672608733760731199092541588544367540810247585499698292666520, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 13905862284220091313); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 2); + _reserveERC20PoolHandler.lenderKickAuction(233376097189937699851095364311543, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 362146502649276086209683240334485566846159200342448920); + _reserveERC20PoolHandler.addQuoteToken(28072926633, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1707686133790362, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 5122060114543251470946942261756530021372035567724698573289206994835658364); + _reserveERC20PoolHandler.removeCollateral(1004744400461823505, 1002563757546232529, 40021280748466473513420181169737, 65242); + _reserveERC20PoolHandler.settleAuction(19227280379897554566214045240805812999525653472826, 1, 513133451502212375106, 1509116089456592); + _reserveERC20PoolHandler.bucketTake(82641365274315560297701788, 1182546122646348418, true, 13266159652027206489850065989889, 17142); + _reserveERC20PoolHandler.moveQuoteToken(236428131779146511795177565331, 816712397995818008001540772977069515, 44367899812660584706998548681, 217639400272228881714561929496, 40738181213060196087837223018478); + _reserveERC20PoolHandler.transferLps(1, 5488488514, 196666486219848735345440202051149751468352598604977355486921, 0, 9731570860563138127969151949695); + _reserveERC20PoolHandler.repayDebt(5338251926933800424434595135724733642022976160857, 5990810833846904, 3); + _reserveERC20PoolHandler.kickAuction(1033815390759353389, 129496296499707487823680222868, 1484692398701317873691603374821081475373177696526565533961489605, 817009492438120371808454381156087837589235986237850253654739897932858861); + _reserveERC20PoolHandler.removeQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 9183554804975217057960393851289892635388346594534943457014659759527); + _reserveERC20PoolHandler.bucketTake(37655554605471184972963434086979, 992699617416039816327088085905, false, 745807401747040180389591183413817, 14445622935719862453432472017); + _reserveERC20PoolHandler.drawDebt(67456809123871989317892240443522, 1645, 20387489043694004508935229689747); + _reserveERC20PoolHandler.settleAuction(2684440540, 139891630968930130797005425999924, 7352756440108735266469539350, 1042442907990037533474182500913469470193140551665093043145759638473494929); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 2, 123154936687549301354406595469431175393, 972018640920332207416924751415514648513064301071928428006570); + _reserveERC20PoolHandler.drawDebt(1111530057087268950, 214657901632233099074493148081503, 28346); + _reserveERC20PoolHandler.pullCollateral(48241, 3315791291226543822120896907677817863512620983644913021921017760325, 8071122991208071047219524056537); + _reserveERC20PoolHandler.takeAuction(3115169092564542247333038154614867923551180270712212517489553550453, 3, 216687185253019081990, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 365415962206292016811970670628908681208250294285976264188, 1298314378253595679814215587095, 1); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 2); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 8645902114123079388483941693163923627847341936286, 898505291414155137, 2); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(33096, 45096, 1399803311019927826188425493231513800537); + _reserveERC20PoolHandler.withdrawBonds(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addQuoteToken(54086, 578775856125399601932177564, 300746401983860957676840392308, 74956278337148069601667); + _reserveERC20PoolHandler.pullCollateral(120346755884556655023573218635831046414315009353576775903017160485357, 238004312833092498855550, 2450896433870866319459523296725935819848); + _reserveERC20PoolHandler.kickAuction(2, 1858424504439015653784198455734225836106, 4371543301993457476428, 1009979949617); + _reserveERC20PoolHandler.pledgeCollateral(39748418273217834997120369355536, 1910730440, 8467); + _reserveERC20PoolHandler.removeCollateral(3308323934730605847865856, 1183081264577093675, 4397585601433237118777875498044, 1595); + _reserveERC20PoolHandler.settleAuction(969148218848962039956374330921037350657203871873285138135933452977, 62903094767770073279314909574685658776243688025591073379829182422099516281, 22974, 2); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 89123956639412588727782056071855810243421658720348612, 2747620452809067619714); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1533495422584498695322618310612296391781000530876965137459330602844636, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(3, 3930898617778575216113558985134259411307840640965561, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1302); + _reserveERC20PoolHandler.takeReserves(31859506742165569226991483980084401004, 15976522899956817306697591230412744097097989693296536828235, 4619721229506198190956397147629657); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 717554493291547518833732902599029428014699358434153982828505371901401148559, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 153936078735085144237169960344); + _reserveERC20PoolHandler.transferLps(9359911684994314650447002888239118540, 0, 1096266262519190549907984787583, 0, 13498974135959985214636450534636836499053974631780690175942685); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 222314102015386398274646748102952488312499499821081317330882408366119790); + _reserveERC20PoolHandler.takeReserves(2799072837997610692122, 999999999999999992182130257519573935533018257, 1035074613505696303); + _reserveERC20PoolHandler.takeAuction(0, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(57125575856700439719921807721933, 1000011555402182669, 732602071188700667198970330304249452472945617680895539057628655434265647, 141539040912438226646635719951); + _reserveERC20PoolHandler.kickReserveAuction(116516049079886840929106112103230514952, 3); + _reserveERC20PoolHandler.kickAuction(2, 12806902169810755269001, 3, 3464768846855587529213209040276); + _reserveERC20PoolHandler.moveQuoteToken(14161043196256769526346926891586, 106673, 2999999999999999827858120369812047177847472807, 67834546501247670195921400154518, 64249619098104904770634658995471); + _reserveERC20PoolHandler.repayDebt(0, 15315383, 3761872169687223852885804903894879762679347496332660589); + _reserveERC20PoolHandler.kickReserveAuction(21466935759123450206648402079156, 17370115010016264951275144583758164500039663449099578565677877684665391281686); + _reserveERC20PoolHandler.lenderKickAuction(21902624594809572773065808552240782762221, 11390238261425412435954507900912101803756373873438237, 480315571500828495744626); + _reserveERC20PoolHandler.repayDebt(6908342884062896268896901126073, 1462302679315879522044211215640363144471697094131570883536380856718827394, 99049); + _reserveERC20PoolHandler.addCollateral(20454620118827922856418678643191193648856034825739, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addCollateral(2538165891, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 66352699398166129075045665658739082229992228); + _reserveERC20PoolHandler.kickAuction(4561659193801667684514051775791646926000244469399695, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 765007, 2, 4633711191596005864907456486004310001706467118240277155307602444, 1); + _reserveERC20PoolHandler.pullCollateral(4967369371400813639407593802959513763193413178529503, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.settleAuction(455982741480004258472870434052406420814985204775, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 7431977384242344954636742985, 3); + _reserveERC20PoolHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1056795281481550986158790735124, 212184080982682646); + _reserveERC20PoolHandler.stampLoan(7886485103730146585933495554, 609891790236072573403898281869479); + _reserveERC20PoolHandler.kickAuction(1, 863947858965371783949500699343866, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.bucketTake(69296, 24976298711376256067713652, false, 14861680589576317920585455774278, 27884956682150789647221830548477); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(4289851085311505700462748399081406, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1096755897377771853712605344085670538, 714676523990682298915232299649099, 761741723406684273406746756442947659403249885840281880966929); + _reserveERC20PoolHandler.bucketTake(2458047211176492006585979475280721514522478385801776287240, 1811805960934085585685102334405472482055261396685800579684451, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + + invariant_reserves(); + + } + + /** + * Test was failing due to reserve imprecision due to t0debt rounding. Fixed by allowing reserve + * fluctuation up to ~2e-18th of the current inflator value in test harness auctionTake function. + Previous Reserves --> 13918232397922092976654436630 + Increase in Reserves --> 0 + Decrease in Reserves --> 0 + Current Reserves --> 91067298329299193714790177109399542 + Reserves Error margin --> 10000000000000 + Required Reserves --> 13918232397922092976654436630 + */ + function test_regression_failure_reserves_regularTake_18precision() external { + _reserveERC20PoolHandler.drawDebt(257043083505730622963654726048020155776745097649378157038219239, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639933, 11063142591666851141271); + _reserveERC20PoolHandler.transferLps(4661350864431513203503208105, 34076, 1001835736475444277, 217658603030204395377389531022921, 1452988969487430887049077); + _reserveERC20PoolHandler.pullCollateral(179603059153658796472195711441845462646565256125402037534, 1079242012414, 2879935480664825183739712930245634110365998359848719); + _reserveERC20PoolHandler.transferLps(866982035891428611531447726350, 162981594648296006363410, 3304708111, 2754083059703150142462, 37828482756055748242543747089676); + _reserveERC20PoolHandler.drawDebt(3449018733827822849673829417836, 999999999999998854532087634942678546535355343, 134342450685529144424468264532731); + _reserveERC20PoolHandler.kickReserveAuction(56984349660363091, 119501276180302544359557451717174228967557846296153); + _reserveERC20PoolHandler.settleAuction(14260111539963386747581726540111, 5485064210538452742261350405279, 23228469165479107950994143835, 753486813384716856964795157014298162524835996304781068686541732654643125); + _reserveERC20PoolHandler.bucketTake(2838051358791965360831319574747039079905007418588, 342698627039403391407, true, 41275576663067584102794789805618626099717313595270379819835053442, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(18901483816969623567746325915578308945694997525810, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(5402664882496432118, 276725293608671540816285121110105470119373831); + _reserveERC20PoolHandler.addQuoteToken(2, 669179798545966331780646439949430549442591890103997677626561, 1, 58711447988117185859666674703710414037323874156054); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 161919624717703522761268878951271771986458953918839925968708418880428); + _reserveERC20PoolHandler.stampLoan(41294898319875125, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(58468, 19567126163189505315162507741670, 11848101074444910014830544251005); + _reserveERC20PoolHandler.stampLoan(5285970396241692, 192766159607490288116863533); + _reserveERC20PoolHandler.bucketTake(2320065360902509692036382677940, 30628470471421788944299257758994, true, 19848743149677599114294572281204, 178394188523918761563126268635962); + _reserveERC20PoolHandler.takeAuction(208534244037647805789625951923, 1019851644931723944, 65201273842295305509484735, 107693); + _reserveERC20PoolHandler.transferLps(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 22130265, 744097377225727756244171098, 262); + _reserveERC20PoolHandler.drawDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(1000527870772296584, 1000000438963348359, 58867575243872931748661290742834); + _reserveERC20PoolHandler.stampLoan(15, 4202520654702873951787); + _reserveERC20PoolHandler.stampLoan(46487, 194491874921673985293312655); + _reserveERC20PoolHandler.transferLps(1, 105910989894742547374190670437872695758709746275689647906, 617433443312702353608355772953764701000855991914112954175023238080275000, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(3, 2, 227176863593569983975); + _reserveERC20PoolHandler.lenderKickAuction(0, 276542907720077483077538485838049153438047028, 3); + _reserveERC20PoolHandler.removeCollateral(1000000393685434446, 221692115893764310033089983775155, 19990861977591935198004195643, 1276499310924136531359); + _reserveERC20PoolHandler.settleAuction(600978, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 55611334396222817532543223163109956, 139583325684699477646535171); + _reserveERC20PoolHandler.kickAuction(22733099010374772473732023, 14368960431515515437419659129613, 1936276978, 175208162350472247170075606122); + _reserveERC20PoolHandler.drawDebt(15959968376473614682671239398683, 62588922334281293127026, 23100733850659544491193471498311); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 5136764564124390529078502671983141088727233759768, 34671265889941972202888816641168980525320636, 679677967817818293, 156549802185712244747); + _reserveERC20PoolHandler.addQuoteToken(21956495966843334336, 69763106514522688241938301522553708464194698463450462, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 45726779560843420849320839185366756228140917110); + _reserveERC20PoolHandler.removeCollateral(23918810088167379583040337677412444421066698718462409679977, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 21282511916612272528767375183892224116058365542618057551585832, 1); + _reserveERC20PoolHandler.takeReserves(129421413499763552677318841005, 65117, 27330073476736786505236312752514); + _reserveERC20PoolHandler.lenderKickAuction(158876064749133953868257047085, 28538178275570662588585605775302, 9138); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 497005964247398538756, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 1349363516707574105100809400503706231053291); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 1001025924284725); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 31923405943228913489302987702, 1); + _reserveERC20PoolHandler.pullCollateral(22064333895091391270327560, 3, 559049407188045042384953031212867350); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 0, 12186422340865, 508); + _reserveERC20PoolHandler.drawDebt(188695074211305425531579358307889, 195926206680202333064274016254294, 1052139587735726438); + _reserveERC20PoolHandler.takeReserves(90649713715265765331377153560260199702043788636, 114400572141002660554289034148224350458711644310597818731064, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.settleAuction(3, 25127310871415862962889, 3462711735358072296150581704327206265042809, 1633); + _reserveERC20PoolHandler.addCollateral(2, 0, 22152367105141624315789585540176661871550593826, 32061700358594025); + _reserveERC20PoolHandler.lenderKickAuction(97508448383718207004895759278, 2999999999999995264068062655825611546985935213, 738597383945320336692656831694953439891649714179170272344420076783322705); + _reserveERC20PoolHandler.removeCollateral(42886956248651036998110037395334698, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 11682346142167746675307244503544469393907, 1595663954307775275104894682142800197028478700162357189520874085894); + _reserveERC20PoolHandler.removeQuoteToken(18179600902200142008854129818320, 1029253298370447673, 1022634176479155943, 10023415648603389532767614028208); + _reserveERC20PoolHandler.settleAuction(33401514487749948821428749775466, 999999999999999976214071783711871660093307540, 45704, 1392412796036111969561461308999); + _reserveERC20PoolHandler.removeCollateral(1489079958669788387729294129786258272875639980690858222899755, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 55815970534089409256513861891236722971419431315328102445); + _reserveERC20PoolHandler.transferLps(0, 59166035758234079788534945358591, 3, 1, 115145368843021590857363278303798005204225609443510520514646257787); + _reserveERC20PoolHandler.takeAuction(1766823912262669459632890181057, 149010039354560399191750399557566, 6406738450312424103126513540667, 48318995659552495099154293709824); + _reserveERC20PoolHandler.removeQuoteToken(31064662101628280779403146844870, 34721379999182386169822959185148, 1000032228707307433, 40596); + _reserveERC20PoolHandler.addQuoteToken(85130412984420583986499733492, 2814711448297370074518, 17857543466264800777260414192043, 2805943636566559458395355453); + _reserveERC20PoolHandler.moveQuoteToken(1, 3, 4521943823144509961078924327672, 877773344819423, 6343048301629192584795481934182483572378507955224222454554857588323474465611); + _reserveERC20PoolHandler.addCollateral(0, 8837583778, 103534806297023768354949489180973438227540439778902979295546819382, 1); + _reserveERC20PoolHandler.withdrawBonds(1098497175932854016, 111943, 109612748345669164566754246778668); + _reserveERC20PoolHandler.addQuoteToken(1000002113428159210, 3261585008, 32247183070701370627664387773662, 1191092455838777580); + _reserveERC20PoolHandler.lenderKickAuction(2274, 5180610305125995342839811471, 84763247918520134281719952512); + _reserveERC20PoolHandler.pledgeCollateral(2966624014587045477214691, 175172557087711956555896196212474, 1003339680071697595); + _reserveERC20PoolHandler.bucketTake(869598845055160097266600216224, 1051120040435237793, false, 362350790932713272190532349948562, 10765404581356362595082086306); + _reserveERC20PoolHandler.removeCollateral(16944394833199782744727349938, 847734989519933335673707258628387744634243579297288994064647890471639301, 186458499304908545651423838787429, 1418300066462018393963311715904); + _reserveERC20PoolHandler.pullCollateral(3, 3652907174498391238784469541732519955036123721471718148739638695072136848, 1); + _reserveERC20PoolHandler.kickReserveAuction(2240248104280736582852617948658265189627376495, 6907736292175128739148602548912729547988156921090868994356); + _reserveERC20PoolHandler.bucketTake(935472763538911724524698, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 3, 11619412668178958270243894705606311406877040182282526846594209948411846583); + _reserveERC20PoolHandler.takeAuction(48367154775987869686550052001107967037814925413326676343496023, 2509962992473798074988441879893815, 114151919922337101164895779051945267712675116544577087, 2516431466897220130880092396698437965169047307774896343876157626257704206378); + _reserveERC20PoolHandler.addQuoteToken(1041480401895836369781716453949, 36631196432593190738655395242308, 89402749384764401636216823945, 43325); + _reserveERC20PoolHandler.addCollateral(1003014570878960602, 1312188803998338552243528917103798599157574147098341836138580640671956368, 1118117328433025239222118736795496562315605256114755979832397841793324536, 19150029584673104439933773391); + _reserveERC20PoolHandler.pullCollateral(740653771483220541575545464326128014067883966865940, 3, 14809136); + _reserveERC20PoolHandler.stampLoan(106354396508826136959, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(3448795715668820914390926848610, 930397876126259877582468205, true, 165573595581107861305962720527, 118672); + _reserveERC20PoolHandler.removeQuoteToken(1002113893539093989, 3490135759, 748626764093984597214613553047, 168295359742799313159276714236856); + _reserveERC20PoolHandler.pledgeCollateral(1033661264306371741, 5087, 999999200714483673958808); + _reserveERC20PoolHandler.moveQuoteToken(23900163122063437084707187829083, 1931520872715022907235094874944631, 1000593896660036247, 730303679696466190943502, 945745642456729987417369291242); + _reserveERC20PoolHandler.drawDebt(778522996028061118305728252985, 148051633044821685617253862271821, 22738052123332547061691654055326); + _reserveERC20PoolHandler.pledgeCollateral(101712182056956894592407088758193980324542159, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1165657435912447847855); + _reserveERC20PoolHandler.drawDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.kickAuction(3, 287996313836644002256200228549127410345473895004616214856683021093638, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 983758810781559338205); + _reserveERC20PoolHandler.removeCollateral(730254800192683, 67815198627, 1, 1047364054951057); + _reserveERC20PoolHandler.addQuoteToken(909425, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 31576137485960319451, 37236318279064716296344873179162813665604003639760119038469805); + _reserveERC20PoolHandler.lenderKickAuction(34579190445615205938463013216785731856413218673275510956, 0, 3); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 6433975666381579205574271416799736844701784564449460283429070002637635701, 8876824760085261666235568313932611340989431272124133973); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 3); + _reserveERC20PoolHandler.repayDebt(189902592402309031208189187, 32309998665109634466664279177318, 14309919785034383369116662286146); + _reserveERC20PoolHandler.kickAuction(0, 8706836806, 40135538547, 2); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 3, 0, 291718013380394023153558124349288892868176835271020342599594483358940833105); + _reserveERC20PoolHandler.pullCollateral(7907562427842, 0, 187920640001736941874935053161676967641771554917634559669933); + _reserveERC20PoolHandler.repayDebt(2195, 403067576384438575258001372541221475062179224767472783, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 22589953763886542365556551616134664779155297572413765, 2); + _reserveERC20PoolHandler.takeReserves(6421528112726848755368002902, 7379166770895667869845978672918, 158517542996717457961590033535770); + _reserveERC20PoolHandler.stampLoan(3284033595611211203160621747778, 29632667105408750785111076056139); + _reserveERC20PoolHandler.lenderKickAuction(74098485277603812663609518587546024034578, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2042981531232); + _reserveERC20PoolHandler.kickReserveAuction(32084594933356847080856155440086804, 0); + _reserveERC20PoolHandler.addQuoteToken(681845574479087550248435128, 1392231091759684932583309034916, 1000309455559404822656469, 116650352092256390489644778); + _reserveERC20PoolHandler.bucketTake(120708179995409760471444730321, 1000309154275982679, true, 1003648518728177963, 2999999999999998581838605654401322534609018434); + _reserveERC20PoolHandler.bucketTake(1007742183942093096, 219871561113933510884429889112945, false, 1308178994233604115, 42555); + _reserveERC20PoolHandler.repayDebt(2, 132472255787509083622885118532405719552220961401280594587, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addQuoteToken(12398530918, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 185204322844694763100281523483451155); + _reserveERC20PoolHandler.drawDebt(53757, 891017836979593975772685921607, 748627385478138392880399737966); + _reserveERC20PoolHandler.kickReserveAuction(2, 0); + _reserveERC20PoolHandler.takeAuction(1, 964544, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(0, 3181331672748620766394314731549937062651408287877882794247991183312); + _reserveERC20PoolHandler.withdrawBonds(1, 2, 14021120983015014760608113097568716455674658); + _reserveERC20PoolHandler.removeQuoteToken(4163223053898, 1, 99743635678, 1); + _reserveERC20PoolHandler.pullCollateral(3, 15000, 2); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.addQuoteToken(10262767771637201690865, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 37084131425, 18989421889058845272868038518423835486508888818737396879430304093122194); + _reserveERC20PoolHandler.addQuoteToken(38255099190226216930400207076436395145671, 725263009252206333086405557168490381347702256743451243, 220404931504024585798417749164345260053119858991107618782363970673990, 82515038297709896219858780116001038); + _reserveERC20PoolHandler.stampLoan(10004999999999999999999999430, 46069308615444920257332166723211); + _reserveERC20PoolHandler.bucketTake(6577519139333703, 13947757100389560718377266262099, false, 106189, 1000380902296927757812399); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2191160890207458048390353, 80967010824063395534889000114431638, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(0, 958803804959151610206731870092602044024466574345224232859351796219926, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(67440796233594657746097421430637548668851382036579817, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 557617709788244852139283465798464584039506120477940244357577); + _reserveERC20PoolHandler.transferLps(2166170279, 1030397231513764498, 767405549078662669198966207668, 8696824885555629, 1977964408510255838107678569361); + _reserveERC20PoolHandler.stampLoan(2679214588399487764041, 776171216352873914648723667423576038988405034684084295520856677302234866); + _reserveERC20PoolHandler.removeQuoteToken(1000051230376287179, 1001268109258256823835718, 942890904017111433086508151377, 212946193679706798005788554046); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 2287482606, 1); + _reserveERC20PoolHandler.takeAuction(3675, 96361854333217700491742683631, 189120033654275540522718914986944, 1025965738326051670); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 864382996617656116091090, 0, 133291131552568890238734287532042068560682258691157134119077142013); + _reserveERC20PoolHandler.removeQuoteToken(195177808430235955557959, 62292281322687535217031713542, 3020877393, 18841502565685978296849491467); + _reserveERC20PoolHandler.removeCollateral(84847258058253375466145307986400, 19885492976640959727983266558777, 267786201598625583901017838924872, 110577324935996847228496507738950); + _reserveERC20PoolHandler.settleAuction(1004419950842680885, 899721172548836418515777447168, 479399253065278079479383577980307, 209724067848908357051737025833); + _reserveERC20PoolHandler.pullCollateral(4060380600, 10012216705961224919840242634076, 10954293800689940294868818382428); + _reserveERC20PoolHandler.removeQuoteToken(28507, 2932589722656034518358355929556, 2673268143, 1032461888253414947); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3341793921990724321622080986555387); + _reserveERC20PoolHandler.moveQuoteToken(4162139809661339041320531321510158743365888924332885900887277100062654440, 264416790484683634996869366642027313268038610240394172702954113166812712424, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 404790694099142128214430628533546438074, false, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.kickAuction(3, 2, 0, 0); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 132284887404966059350, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(12480661458391838295822785, 18867771467352511835316479033255, 166673162492316461169598668383493); + _reserveERC20PoolHandler.addQuoteToken(4527342984922973724130798823900, 999999999999999999999976498650124508454277208, 10882882542416772635416190467267, 7965614537560513281015431688907); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 78250004465682877818379757218677279250058480701896523122793); + _reserveERC20PoolHandler.transferLps(1026689702290860649, 18108329821404020226734370742493, 11345462056256763674861865207117, 20769431899321873, 1497120882396387423599526126); + _reserveERC20PoolHandler.removeCollateral(77237717354306610840718672, 125767985076138655882814008045901051431988596909683788421885384559410775073, 195424898318034365934994797311689064008954338207857124844649303007, 761881843122798937987457068044586069138754401574533516160662369137); + _reserveERC20PoolHandler.drawDebt(21056320314401914984478766802842, 77012339189988277687286626059702090785708812323113561318499450230240897703671, 150519478267189168115543257270247); + _reserveERC20PoolHandler.repayDebt(1, 1381091153, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(24935527672620455252228968655768772368078598564813927591084555415370181, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(4183336639, 1002289490420639376, 719453318077343790000425723190); + _reserveERC20PoolHandler.addQuoteToken(28005646765151130145931437215887, 1033034342258241938, 65635, 11164); + _reserveERC20PoolHandler.stampLoan(320213238337363, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(788297989073104387556071459438, 188363830160460128554370784774440, 214454910017143975610551480); + _reserveERC20PoolHandler.stampLoan(40157743576832497630216815491283532176161240355127143, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(111704340860880701458428, 175367095876773890663362648243, 2566736016888236934265999997435830); + _reserveERC20PoolHandler.repayDebt(7091137788884715250888635334475, 11514016706055669250890536516365, 4672); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 244098746655269384605788480416985515756178070040881103311, 9309930041888650988017467352489059980, 86823835883624825); + _reserveERC20PoolHandler.kickAuction(536189680515079530169847963576485, 116503218873718900050648920571020458493530, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1113043380047859167); + _reserveERC20PoolHandler.moveQuoteToken(458015908894226, 5760393824652502997420380354177034394585610472315110, 6189204707535677007056068030823101954740037637863637524266288996424, 326735451666640029836035078747343101485757268544951364534740044831983443770, 2); + _reserveERC20PoolHandler.bucketTake(24491338676714452170983451149525560931171537319503511045707974303119033554, 2, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(83283661744280, 23985136372710619010143609528087155445353597856491475955430852447974567, 335287366073181176620373872700397088341424639015135957231198407061, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(1, 46, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 43732894128007423765004629145186764268536361510959832344342125518460813570); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 70995); + _reserveERC20PoolHandler.stampLoan(89244005762255758375332998453, 1000000002311643837); + _reserveERC20PoolHandler.lenderKickAuction(800, 1031555231164747003, 214918611633219385906150223279); + _reserveERC20PoolHandler.withdrawBonds(486851726000746654708238636457180272881946464123536636504, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 42002668225144165925337204227019454116); + _reserveERC20PoolHandler.pullCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(112117, 6713052107798989529173756914134, 1020573275076435830); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(374465417980004584907388805931480, 979459518231886007239811225285409, 1062215596771736577, 17046609907731109562900695696712); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.takeReserves(192155759, 168180458317399009739792191888789820, 0); + _reserveERC20PoolHandler.takeReserves(1407073824952834041436081877045890709616770653508303135358739120344674287, 2699409587072729675724, 21935763816534451612364168804609); + _reserveERC20PoolHandler.bucketTake(657166092227073783065732894129988902347491028246127965539817799225305, 1, true, 54036676762181543040601420271634425659974420572108136065900, 1); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 8, 21746079984729209425652876324527599); + _reserveERC20PoolHandler.repayDebt(2998486152060051856938587153610866581864304003660185495632182330932346145, 1, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1424488665737, 726849174174801157285306093714616482); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 232813345286066932053422613938104796530712, 1); + _reserveERC20PoolHandler.removeQuoteToken(631932965982527443684459169660, 637872363137958735545191816620, 8131656410101706274552169205587, 1002404985274014424); + _reserveERC20PoolHandler.kickReserveAuction(106625, 782524647259697766828490033916099008466248170165424294150336580306355241); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1177829028718177564037392959827611044077244728246642285368648154183357573, 23306884127055082179582943977932849591341850825103602893388317304040585480); + _reserveERC20PoolHandler.moveQuoteToken(1610634872545163541620284894353166982181661337240332241880672196504110382, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1656309858653681981406867303101889545106432847, 2, 0); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2336431079868007285942408729356474875121748171075982255, 261590397489989045643971253133769172120846156812377692839170, 257864097817790593914570689838101); + _reserveERC20PoolHandler.lenderKickAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.pledgeCollateral(27530896971949040385292916691, 214320049593003948830312023350644, 996496973589109194776765); + _reserveERC20PoolHandler.repayDebt(109770622612363058986903570005696, 100711661817520169465574765, 1030770577322378980); + _reserveERC20PoolHandler.pullCollateral(1000004646725401261, 677503853732216802501113518790, 386668863803604696797846367422); + _reserveERC20PoolHandler.bucketTake(2237118088879680696890424971347192431, 2, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(805372694421952000462406324394355326519524862889512881406279031811776441, 36572, 9364153039850407723227797, 30226); + _reserveERC20PoolHandler.drawDebt(25440211850997261856059272629627189540173051716065707937249047762, 6724819062305187426426877651, 2056228347528904528882904426059693540665); + _reserveERC20PoolHandler.removeQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(92345421446442303197742761937505424661280414857806977, 3, 230676004141733584946184644664690535385442521555426084102112320631621811); + _reserveERC20PoolHandler.settleAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1001290244969366, 7155030549048727089523159300949030067561); + _reserveERC20PoolHandler.takeAuction(1072001983804076361722902532634925279588, 6175070626372638503401789576180580051606672372886037679525, 51591015573475518242, 0); + _reserveERC20PoolHandler.removeCollateral(7732228095131536376058457087, 3077830854, 1049846137338806262, 3595585943202573); + _reserveERC20PoolHandler.drawDebt(28187032929783911048975588224300662535775350967811029036712773686181865620912, 7779018782084722684700097909, 129649328258444600850828665477110); + _reserveERC20PoolHandler.addQuoteToken(4229829354923351620001538858658, 1429214680741855365037150652647363285668157532119630614102292129552666425, 336352104247496353125376578629565, 9019511476133167101992474299295); + _reserveERC20PoolHandler.kickReserveAuction(168896893977538159125908402465767, 15948272743860702674787421498348); + _reserveERC20PoolHandler.pullCollateral(11261041102051323947189015104858697425097565, 0, 42512886356703403); + _reserveERC20PoolHandler.removeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 11581848188681); + _reserveERC20PoolHandler.addQuoteToken(9911893817181128151145767831, 1001788139345206388, 275016366511376248095678368, 2398713940); + _reserveERC20PoolHandler.addQuoteToken(3, 121250869204, 4746827199707004948532144689170326211720306651, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(144033629132108688616820798238881, 98, 422369472233929214081958271812384416498654567232372431208, 0); + _reserveERC20PoolHandler.takeReserves(188416170666803103814566091843, 45108, 23560); + _reserveERC20PoolHandler.pledgeCollateral(2068178414292783438008226733969, 104716943105362446354776127279176, 1369415884184229389162664593894); + _reserveERC20PoolHandler.lenderKickAuction(541659707019159322376191161639757, 24177352204630894077605432861753, 18973648150840463993725089190111); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 108180453342039544851295002797919644775350551187234134238); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 2, 82531116951545568830178528); + _reserveERC20PoolHandler.kickReserveAuction(1519186503795404694871825544276320815344157218104392037763503613224260, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(367926590218880254484625186538750, 111473, 240618615521665916870306407600932, 8085425195427926248151566283, 22320461508904467520977883046); + _reserveERC20PoolHandler.moveQuoteToken(32281712146150948736504199831, 9600062513822363794725142653059570674607068754144350, 1, 162653586076454755809231216799192261466, 1); + _reserveERC20PoolHandler.pullCollateral(23131, 12215064237878104178462054086317, 1169723762070189448233922447072868219900123055826790536595497113288193166); + _reserveERC20PoolHandler.stampLoan(652056253676040761017949763013, 3709799927); + _reserveERC20PoolHandler.kickAuction(116931152732441298253590709163414, 189182335191531215005503774913, 2999999999999999212022176317639663183950434515, 21055702841966204589165002032); + _reserveERC20PoolHandler.transferLps(23112114090441408650474065244876, 240255983335255087155985304923120, 83871, 5572250753411239597766296475, 1707744595); + _reserveERC20PoolHandler.bucketTake(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 152563207760842930513436418188695147, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(1413984774743221589591433, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(4887292964206507584945863114566, 2676935970267446555435554632925, true, 59825, 31964); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 304004118119879144, 2, 956117147481106799162728524941760294964434276811663078163814331486489); + _reserveERC20PoolHandler.takeReserves(215323032070700220094295428022, 135676930467369410026833899988704, 747577778354847985990363598638); + _reserveERC20PoolHandler.kickAuction(46931066107350412960069480433247, 30479398242252489103050265361136, 1002460796304068823, 4517002282366159880631486587694); + _reserveERC20PoolHandler.takeAuction(238592005441074827772781705195525, 9798538389465115502666599445327, 1005778542470315892, 870430226355825561906563771614); + _reserveERC20PoolHandler.takeAuction(1000001750735161518, 37919, 19420806643132020525602397686011, 296903043925425460193734861); + _reserveERC20PoolHandler.transferLps(2, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1871032345102, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(11099303624177713750927592, 998704885941365987648759562, 12965798847581874443707560248098, 5822); + _reserveERC20PoolHandler.bucketTake(80692355757456290994804095042, 162981594648296006363411, false, 2999999999999998176499167715229218895038449476, 1208776037474985056598642240); + _reserveERC20PoolHandler.addQuoteToken(93538723679553079959805038163972687257690889, 9841958286088499007844993332562165497318475683421339, 145431494057328721472250975441201567402666798762529853541322373302485424322, 6368277598576731789686189175546502034776873408025433903317451017); + _reserveERC20PoolHandler.removeQuoteToken(373179916455298163696849577662305, 18330689428824486410639830453708, 1002471531082450675, 9984837838694997883410659044329); + _reserveERC20PoolHandler.takeAuction(28522666015923666013121529899604, 1000000054042613273, 11023, 40427254828874895726135043350); + _reserveERC20PoolHandler.removeQuoteToken(94624187879024319063787913538, 1004656385171452929, 1001389329583021204, 8107926010654609014544187606670); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(219320879313592183203796762078315, 19981, 164314564476285829669373599430, 1032995513193646250, 8428715983060386995096151751993); + _reserveERC20PoolHandler.takeReserves(2, 67757061926355616046261543231274467107030, 621696917406401007838516274419975); + _reserveERC20PoolHandler.lenderKickAuction(818041438028, 532965504, 2316892056277537659860321113962); + _reserveERC20PoolHandler.repayDebt(999984982210001251813727488527, 22224855090636619468778187971340, 83240890105178293374883970652822); + _reserveERC20PoolHandler.takeAuction(3, 594359788143733202850783362594598506288999465758450080505, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 36607098827561213921889005705093164252); + _reserveERC20PoolHandler.withdrawBonds(10475237476345813699986346072065419197567510457888504216937, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(106319560658216376912120927744541320331026067926433612827705905133511451, 0, 12992460353370676943022692366158365018402006936807777, 154262453625121554910309098); + _reserveERC20PoolHandler.pullCollateral(265918011285820730340462065491185, 582827697576712977861580162730027, 94155965689058550272970499529); + _reserveERC20PoolHandler.drawDebt(87060612736, 1113524988132697, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 17470269911788813, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(114654571071726434703419094, 2024565365); + _reserveERC20PoolHandler.addCollateral(1176182015208771408137214, 26647087, 1656776724890488085414059024243525488585143478223131949747585904417, 71383208651302442397641267804809737370093131589826974991402650); + _reserveERC20PoolHandler.kickReserveAuction(117443009044992, 361533949603625686463970124); + _reserveERC20PoolHandler.drawDebt(3, 0, 0); + _reserveERC20PoolHandler.bucketTake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 584593001786674676132265862889035836148004347481776052435246, 97670); + _reserveERC20PoolHandler.settleAuction(27269, 1006046287986813313, 754457092553422942269978072338, 1041326861305022030880597331847); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 266069586614327730734, 22178998496761313090296499665467142627313414479569224288498035059); + _reserveERC20PoolHandler.addQuoteToken(351310668353577030523239603875907237190155896186565745534169, 483103202169, 5040873050979641829449285257674313697511826334596881659863916, 1341914); + _reserveERC20PoolHandler.addCollateral(3, 98918400854918398335981414825187487244, 153213623954607793679995490436413766932464984555745993080161, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(0, 145727059376246144320128321644534259108792599163582785, 0, 5745958895796427182098089924, 695286449275806192884675198483533216675815377609522775399142300190544); + _reserveERC20PoolHandler.addQuoteToken(652319477853805990777659783028271685061233233, 208543805920853451313242, 335, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.lenderKickAuction(8934869858042562092381334613398, 227633975155581683037816530857, 7240389052796426063410888732); + _reserveERC20PoolHandler.lenderKickAuction(924660434907579703226478665, 3243, 871336); + _reserveERC20PoolHandler.withdrawBonds(429862221700607028495027056343183074434082271113294425521904572663621, 1069775179842066891998483, 1); + _reserveERC20PoolHandler.drawDebt(2313940314866456627886770464729310159927382157767935042, 2, 587322790734106092052378605); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 34423261106701321575720021971917696323796688632864184658078581598663119218, 2); + _reserveERC20PoolHandler.withdrawBonds(1, 45415050420478346616289457457660894101908746102492675361363944402849069879, 1232134818719963594031808924771874980630154); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 38961114548555691293662242838677739445708101, 289172325242661776948851576691875771580911023163); + _reserveERC20PoolHandler.pullCollateral(73940819172704940119344625549603019212128810275281218045139288344767, 4, 20360684); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 943549056383282988532250084882, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(2238832727034240363453627542465813921479034038134113972672345, 10663277040716088144, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(54256, 99092042691591837132227220371, 2681767391822259328757845683499); + _reserveERC20PoolHandler.drawDebt(329073140586005987, 1, 15959717545945020); + _reserveERC20PoolHandler.removeCollateral(1, 2372321738927661537, 231166031675900338327297371916275976703554997, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(32650242081713205686908474, 1767167571718023392015219916675, 1041519175211828217, 1040094678567869403336925924301); + _reserveERC20PoolHandler.settleAuction(39963829831627123186096580381821315875, 2702486611457512176800, 38783794804300188988862647140941665869573553270054620848079217638367533995447, 2036842130151169449156111675524); + _reserveERC20PoolHandler.takeReserves(95368727269993207505273396461, 1003668070202726910, 13509155748276049650865358550367); + _reserveERC20PoolHandler.pullCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.moveQuoteToken(3592628091, 75956173636781184619559858519, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 45092440683845125263877426968790799867867514526414692919, 57473916563535296429065483001549028118687036145268829601959375); + _reserveERC20PoolHandler.pledgeCollateral(76433951803418265315361551464, 3883730331105860378365299736121872971504614500243542922184364149, 33702668970790467896703877779195); + _reserveERC20PoolHandler.kickReserveAuction(33181698889955930863200241, 162531409926878359196491713221); + _reserveERC20PoolHandler.addQuoteToken(1068183129876513967, 952558434883985415662623146435, 11055321735579659832, 3585011243143710552897471186); + _reserveERC20PoolHandler.pullCollateral(32491750421520256429698641592425272915503630246075886409126438014540381891492, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(11475346410145918857784968889618912404454028424764, 904782401905112349678068848510246103174410033135888111616873971942, 184023774, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(278264373176234892678618081, 680681041191217119610861158659, 34510, 624035018146771969764371); + _reserveERC20PoolHandler.addCollateral(1236763388338706568953439001650129000798301733878758046315865287034, 586105420310224808823620072586215134272, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 49542853003009198311549755520281463228884189629130207762360); + _reserveERC20PoolHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 22058733685, 42378918320730066954239775391052755280156); + _reserveERC20PoolHandler.removeCollateral(3, 19271174743840819661575637120002403406253841458235754006267294520057, 20857399901271688219511766710688372347992554756099240485646832218885449, 45576103030207746922933136568094041173307442400762673302555255818001297769994); + _reserveERC20PoolHandler.addCollateral(66424772662647727367934393878, 1472503958490919421763254272608120518009729485406792411760906639773628799, 69515, 2549980558); + _reserveERC20PoolHandler.kickAuction(1019156864612371919, 1032973005728357349, 18880, 7695636565939678999134); + _reserveERC20PoolHandler.pullCollateral(768596951208688114238489276460440398672597873622789817635440431276206152375, 84715490475667564296942239833805987213317822, 7916738435145367909096); + _reserveERC20PoolHandler.settleAuction(3, 2484281750835433321857823031782477672980107855301, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(2956638655616101007673874196429332868195715510143557698279987474, 865337562429396556871757709371643206705647587, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 131023481872285637708534387211130895); + _reserveERC20PoolHandler.lenderKickAuction(1001474268345796388, 17046609907731109562900695696712, 34760615614014291797765562737675); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 997356299422067207690680237600948242035306129654871257318548043681944845496); + _reserveERC20PoolHandler.addCollateral(1671203, 12848082190102, 0, 9584433110337648072665638579315305313905469201037906532192671247); + _reserveERC20PoolHandler.addCollateral(1690964220, 10009393562110109511169395631326, 1499812902687889152129210998341522510987994175753179008702097007588349157, 229383995336153394101753245902197); + _reserveERC20PoolHandler.transferLps(377219334615937006757441686702198546100911244804548943, 553572152366391215832975673989511526639807795048654831186937915618368161978, 22486033482944764035848, 2, 4425505482371098155); + _reserveERC20PoolHandler.pledgeCollateral(7124230825304028191340369559, 46666, 1912023600); + _reserveERC20PoolHandler.pullCollateral(7959299673069707777909178107956283953454979420074534840241148, 7073157595868027876, 781606608317345791826110618046825702714571183794091218471648341); + _reserveERC20PoolHandler.takeAuction(2, 1062688536891170, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(263041054839695, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(538568871470973523815262436815931, 2787833074, 3436689808911796293216501012494); + _reserveERC20PoolHandler.kickReserveAuction(1012042235228468326, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(24506, 4119439522052392964320749082253, 233627660917272642473655289459599, 124799, 40839); + _reserveERC20PoolHandler.kickReserveAuction(2407562983196890870072922536512, 2811671645134456941819); + _reserveERC20PoolHandler.settleAuction(2, 2459486890652860955208302203326366781, 12060605440592408444856332145910638058037736598111862135, 3); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 496990464496347953258479968467690591671146403565); + _reserveERC20PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.addCollateral(5537487453163646340182267884559978423704750219476, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 12909132554654137, 133225186414808158118868736593651255872005243809382426905035600113808); + _reserveERC20PoolHandler.takeReserves(3, 8034667940936012318628440223939, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 134, 484841); + _reserveERC20PoolHandler.removeQuoteToken(30303607399165660581975684393090184256721857355546588901133998961295930622523, 2999999999999998999999999999999999999999999999, 1092617357938938318, 31219258596435242400902302895995); + _reserveERC20PoolHandler.withdrawBonds(311210470500203475529852328486075349586614091389526362832130922975, 10150483403085339420231884221560814461661865782, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(3, 2241032857095970327256772116776922073202777260291536095523502190821593807037, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(1129607614900625985684908873590922277261895645367, 2, false, 286241392232069386451480935329, 0); + _reserveERC20PoolHandler.kickAuction(3, 5892, 3, 686532230461581521165211661854085576800934436980792); + _reserveERC20PoolHandler.pullCollateral(130102891459220189337171422, 230508483012823290019010248860568, 10798042454921968375623147246); + _reserveERC20PoolHandler.stampLoan(102872, 140645516989669946169922609339); + _reserveERC20PoolHandler.moveQuoteToken(312763979952653579621466565822496437322486078198536498, 1159013025171189462881362592668544463145602332337196454558738, 415174581655104214414718449772427121337, 3931224635514193239279417, 3); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1428465073323298685033010203529109070002, 0); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 105656179, 0, 1); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 6774901, 42351437562342821036873539413285527177069698396511298930936439); + _reserveERC20PoolHandler.kickAuction(0, 0, 85396, 1362626624261600); + _reserveERC20PoolHandler.takeAuction(0, 4227064605873520505243913419124336367738, 94958175857570898207594010148902492313951596361420384287104, 0); + _reserveERC20PoolHandler.withdrawBonds(7511759924575115884957293578919, 4517481057484386636998468685694, 1000728295084694931); + _reserveERC20PoolHandler.addCollateral(5342557875427570, 1001335115730342767, 7587643609516245914129668646, 2386858156095198363982314390385); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 6063179273247645193965, 1); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 67614710051006775846308660059009988, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(1019485976296082001, 7081962045284298366167488406682); + _reserveERC20PoolHandler.transferLps(6773861812355228824369233521364, 8123, 1018445142747781131, 1421749967793895840953749670108473009231539709622166204669340073665863782, 30982944015866677908254290619625); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 2985205249788225630339476341, 2); + _reserveERC20PoolHandler.addCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(1052273199108594388952568004409156605960773535982701659501386687532955265, 483324824590205144706002006236938727308589793709572932805909074894986254, 3, 1); + _reserveERC20PoolHandler.addQuoteToken(347782837036465426251013971388063973625484729492910716928009623432060353, 54998667039491099153605549692, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 43563141380123, 12742587725, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3759200545075270770094236); + _reserveERC20PoolHandler.kickReserveAuction(2652436797346215531479328411658844890401519212630, 2); + _reserveERC20PoolHandler.lenderKickAuction(1, 3, 1101157661146998015595097385878969008); + _reserveERC20PoolHandler.addQuoteToken(49224, 568489367872363348677117372971160, 14635264721230744691030852051088, 1015055590192632086); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 222348421145791852919064, 5224044342721428481342809762537, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 701839476513413618883900539962017385948545927553, 3); + _reserveERC20PoolHandler.drawDebt(749096154332987169380891984960, 29308424578707179944529869, 154871736469160588473308909174260); + _reserveERC20PoolHandler.removeCollateral(0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 424515773257807205087843907900333524115723); + _reserveERC20PoolHandler.withdrawBonds(505683881618778778, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1595644325119666876035883945975600615380683321668349487698585611347617718135); + _reserveERC20PoolHandler.takeAuction(46585, 3159670116845821490335809305, 102780524233926975800131237180067, 325785346325194322512080903); + _reserveERC20PoolHandler.takeReserves(20454251006396014044474792587537156816375857792, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(3168185568127347223635279619123309701559840859568117272240603305700273, 1045097332538596, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(1, 2, 807335548406490421179950647603387823621924579358921954811434544374, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(2999999999999998391795716476044523035980518811, 1987659508356619253382535320, 178981975088499040425194032252090, 281661187655134759862995567159876); + _reserveERC20PoolHandler.settleAuction(55481815086608935630138845869, 19042924225933337876102923215739, 1745275623503960265585063225454, 337256158077184093800848017); + _reserveERC20PoolHandler.transferLps(853799896629321, 13366134, 76001838214088103269331105958294686, 378759298556056014310365655794144252657525051, 3); + _reserveERC20PoolHandler.lenderKickAuction(1009400367848956972, 81186908796975797763089397370019, 126230482434571347795144596358276); + _reserveERC20PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 159122684775205382986386648513957201629882901974428499868999161642583); + _reserveERC20PoolHandler.takeReserves(295205976140110526521, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeQuoteToken(3836987158449802470252292898368363, 0, 2617817094595270880064249797077122914272730, 404465245562100292414287682581689259281306476982365953); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 123240631393682102800061006476569418712643217335); + _reserveERC20PoolHandler.takeAuction(968297511946823416122364440560, 131713888820925807650420484185086, 58727872410276574629193644009, 10982419506436771893743035683525); + _reserveERC20PoolHandler.repayDebt(208370936513544265799498986288604928281716639106669500757740615780, 935645173841, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(1004317941758273576, 514820057783608579701032436819364, 283152811120361510388835656759969896309876); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 467, 9450566338386004124433849238208359836160813); + _reserveERC20PoolHandler.settleAuction(26109924149491322277839355092364066821248331373447148, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 61096597235246740); + _reserveERC20PoolHandler.bucketTake(16061, 1411720950731695947671038669322045425767147193525142326206633844752715391, true, 45920049586805016154486581133901, 87607682083145788434146398809244); + _reserveERC20PoolHandler.bucketTake(87876083792641204674686333191983687236966728804132539074654233, 115792089237316195423570985008687907853269984665640564039457584007913129639933, false, 11246839115686780472832223053419097898007194545022795885, 13); + _reserveERC20PoolHandler.pullCollateral(1616974176125255826929858412224, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.transferLps(81851378639320019689201315214725576289, 3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2626875935835029935686548566637098711924800171762164878881834079200627584); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 225245421339577847495513882793368086987754480028071079659011272238857752619); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, true, 0, 138520343332789284517840689866281918236809391249692548110960627); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 657558267188180499848119983209725918048810656637198669496636725721353494, 1146400415900518619957872549222946646845208452724089658192562225141686, 504295665315079953982142740073247524595035691668024551474404166631050492); + _reserveERC20PoolHandler.moveQuoteToken(1019850872854663507068, 8730, 165250553299648180964029215570644, 64276, 36011501022018716588147233351707); + _reserveERC20PoolHandler.repayDebt(27559900543334851256946230085827, 115600445131546174706674573573, 2585998566); + _reserveERC20PoolHandler.lenderKickAuction(3448681816746056245252541350863, 22075211623770076936707628518931, 1003343988830589468); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639933, 22526930084092683, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(1248258, 89232648785589000403270936806893, 17775062281381938018018215476704052456, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(37822080177494029469278053330535, 122314, 9773510335025600357967195486); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 25654085494302629086265980353, 890969874635209646985747075348); + _reserveERC20PoolHandler.drawDebt(122835375886295489745940156086716034990297000549627794599274476331, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(1001315827868613533002243511825, 5405561973944890080450692219547, 2112579635, 6773355315758305133662006253446); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 291715154863910843399712967298732146320843683082359299623360111467044645, 164339381729019262834138716366230496); + _reserveERC20PoolHandler.kickAuction(179359551738339339040, 3188755953, 31070399832692643989697430769480, 10909131587262948647201378560734); + _reserveERC20PoolHandler.removeQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 48018878187505343740941718118521967302680358673191198664282991); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 102211537035792); + _reserveERC20PoolHandler.stampLoan(1000000336853176978, 193134040586759970543185226); + _reserveERC20PoolHandler.kickAuction(0, 2393332610626896445424692519121264509007711692215108445044, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.takeAuction(40001, 2963407743725235765268400851972, 549327080468939058784442074295746, 3331474586); + _reserveERC20PoolHandler.lenderKickAuction(12136023667705538872429176883680122147719056090, 155427330049506844505604235410, 999999999999999999998999999999999999999892407); + _reserveERC20PoolHandler.addCollateral(1133382493418813552492686416130460988501629221, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 854158754190538444950613619690026409853048238, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 61, 2); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1598223575346, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 7556105964107234121658077902679270010614358270427006203372630); + _reserveERC20PoolHandler.takeReserves(37845247, 5, 3); + _reserveERC20PoolHandler.settleAuction(1, 9493462784360186711797, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1728748360179757465418309796731807703097476114827087317341, 7887914028407322917136939697762455022486882460189); + _reserveERC20PoolHandler.lenderKickAuction(1000000438938895307, 2536171085, 688049282480894039155860253788108167562682014517207836387064191111753794); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 648903761896466234207430176653993655247229117891398203, 11043177266947015582800044230163597218383732145044497084846607602192370); + _reserveERC20PoolHandler.kickAuction(21868896127640113929083416404274, 27945293286302226155680477783964, 1019991841301757311, 473138185257238636703801080470561); + _reserveERC20PoolHandler.bucketTake(32822068185289155051217703034648107466131395267399697699851875933569165, 4280534002722093403946013921401170, false, 2622868295231673831212155561033058802748712, 1232431050028911663718728180584131702); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 23294314146679521296578292939962479763142871012764401576855807871, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 10063644232141479065323187700403723668875908252142357237988869533186137, 4931); + _reserveERC20PoolHandler.moveQuoteToken(18926, 1341635240785048976, 1377937958086970024070918065161327531322336001930044957203161735251396575, 174507895268123339974295262544, 1000378146521475770512062); + _reserveERC20PoolHandler.pullCollateral(266069074841341685155891682092, 2320317171907403386648904038951, 506934798284141584483637343); + _reserveERC20PoolHandler.drawDebt(39376, 76532, 3597212231324859311482656481414420570035839524763253755337097857618941); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1206519346693843025311006556655240132098507287, 10601901253804858804852028414981076680925097098422981396798698884, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(1000677206766822393, 999999999999999580836266988175019106176089709, 206134129008390541081793074, 1002471531074905013); + _reserveERC20PoolHandler.kickReserveAuction(1002498090093695096, 94586967479723026228186472403); + _reserveERC20PoolHandler.kickAuction(1, 3, 9495610341340860121909948079361239098268216783179607382106876979563442267590, 0); + _reserveERC20PoolHandler.addCollateral(16950212047975722041547635584463044458604630260667, 206427134778272067631350137663, 1754843364522540646959295035167496663472753182818606732693156577334660000592, 3); + _reserveERC20PoolHandler.pledgeCollateral(10297257703484586642687878008353668653124663816347, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(0, 2166270908865980722885525837764402850819987, 1044902985050417512217029454, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(688542347758668158290521775944823718531557711168245459504, 3126451848720840697019447957173143730302, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 62402707960383462516931234190536495804522056863350022115916978230516302407020, 0, 5231748759266491614437885945261658878208840368945385378706, 15087685648441509381083241556447225); + _reserveERC20PoolHandler.takeAuction(21908962173281690220772306906920, 999999999999999207287868940888531899332454901, 172401652786167388962865253497508, 18162216449408156139547860121623); + _reserveERC20PoolHandler.transferLps(1026053143865755443, 212378015046437138023145647, 11403, 811093552239327648009417266858873686529490010135706691111704366318574444, 886382266107455858164515089689); + _reserveERC20PoolHandler.drawDebt(41738794596902562734377999696382888262171212637295297802334182, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 6426880534676994202167059208629855061800629258773320223543415319955468); + _reserveERC20PoolHandler.kickAuction(3, 2, 4851, 3); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 857677027690804029816412401); + _reserveERC20PoolHandler.pullCollateral(20646303063571140834032571249831976653458640437274405337368567879793596, 73570285946330661, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addCollateral(16022144042944784856894804967, 64606503192816919170354447803294879995373390935344609346972601314582219409102, 1029988970144355319, 999999999999998656052570983435610163130969112); + _reserveERC20PoolHandler.withdrawBonds(7292738478704268712611496564615, 130733543622131703596968184689, 487690327108412671271771599974614); + _reserveERC20PoolHandler.bucketTake(2, 1, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(2, 7814894617122897610883313722087847, false, 2, 1883433053262508201582); + _reserveERC20PoolHandler.transferLps(113368075614, 513514050469714016189, 164448765639913549171056840540777967010494086197564034153614864369, 193716941705385247457756578461749177641108206900523544933, 1); + _reserveERC20PoolHandler.kickAuction(1546965177539582657203263, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 10515271034907991696692116826824775196); + _reserveERC20PoolHandler.pullCollateral(2020070166321023640438545203489, 14108332755203834384505998, 10272396450978210772687362372415); + _reserveERC20PoolHandler.lenderKickAuction(1001931447961623768, 1472415203452179764355970676977, 232335364872843022738295874803); + _reserveERC20PoolHandler.kickAuction(106582794568990967036003554729763, 911592539446531338534784293006127527149185611515714209118260189172014929, 6456720876995835414, 3388570002119250701799824135); + _reserveERC20PoolHandler.kickAuction(4676401515477820750877725193134439203384753075744950354515707560, 457, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1943558211237678838); + _reserveERC20PoolHandler.addQuoteToken(3305607270, 28534966167437627548675000465115, 19303272175469074986271368996, 24064404101402324080082029699175); + _reserveERC20PoolHandler.pledgeCollateral(145375877221079174058619913983, 3110733877980732073402238088, 2811252013388906867196); + _reserveERC20PoolHandler.kickAuction(3, 183358849569233473459595665123050514405451934592825153639991375628, 4885998903593464386, 2); + _reserveERC20PoolHandler.bucketTake(8153758034497395763450762673074, 1000000048826836246, true, 32396991291641305173742249752358, 1035243092192785305); + _reserveERC20PoolHandler.takeReserves(410467515152861389755901544152563153076732035424020409694, 387554690178952560669426239350319, 2); + _reserveERC20PoolHandler.lenderKickAuction(3, 131835180359098580597109845487114048825156740341574893950982899458375761, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(330455998982776040029900517139660294797401596597238602081388203, 66416077074520307459895701533699481745134142138299335330152646598, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 21988432651, 32161149760895774174505646698804024534068825151904848110586316796, 3, 7); + _reserveERC20PoolHandler.drawDebt(0, 3143305150574425904963468955572085997363491737264716097782061451, 140392340183800675641732711); + _reserveERC20PoolHandler.kickReserveAuction(2999999999999999996512045430291897534721043493, 1000060762526686548); + _reserveERC20PoolHandler.moveQuoteToken(533301750906485783267589106066, 846873369600876527105311052587532473484149266651958006189557007497263184, 127998, 135948732195783428163293, 47550); + _reserveERC20PoolHandler.repayDebt(377639825984753987410840447390809179974360917515875022, 2579548198, 2259141130693767799817649995043373765910435943367658889518074134); + _reserveERC20PoolHandler.lenderKickAuction(8329401678733152563522218397365788542172338666541, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.removeQuoteToken(52757812181305, 243163051047362933785972015753896855329455070508755527476306, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 48201694808533454247963668205753983683212870232280310006565867851950180617154); + _reserveERC20PoolHandler.takeAuction(3812703996240899885359980753070, 999999999999999937015704377980667025300382922, 1001858072561263679, 2844279433); + _reserveERC20PoolHandler.pullCollateral(3453181347510577547255302389543480019223111691325352688399, 4992175322743, 3664414604625050475260569); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5681130258607940832900827234869588893199435138044121482881526932364142522988, 3); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3667386046445045741289872193563451484536865852740782189308464428, 1, 1370329134464898665494181215894257144901729367068374767503089982233, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(111612, 157161035256335164376209817422641, 2482512382019663178634672421110, 999999999999998323180930191646076609723886533, 286194662770654232658466192557125); + _reserveERC20PoolHandler.takeReserves(9864653401132439198052263689818, 184775476501360840440583357497048, 1019005531649168979); + _reserveERC20PoolHandler.kickAuction(1177685942582936208585952582995994, 10002, 1497345224792118715689033636370, 344991873649724250728404435316936); + _reserveERC20PoolHandler.moveQuoteToken(4730826271106076574903174681, 1031747435579378034, 28366, 2079370621374101155278493971913, 1053077861921298904109959); + _reserveERC20PoolHandler.takeReserves(3693216315855783146, 3, 629043559780939343553142019828654); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 29174473895954920291878965083174581732454473706996599012473211513131, 15236930772858334464561); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 505907059406472953457189974727, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 187613875616995978720101292219792359236825742119913278177555207109215); + _reserveERC20PoolHandler.withdrawBonds(197822000070627361273838880788720, 36206672935158343446516624395, 21476); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2108086702); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 30250923912630763088320613476146853640341445403282559604927135); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3605012400308503375705293932611203740926981583459844, 0, 1032372261856219555584352); + _reserveERC20PoolHandler.takeReserves(146637425700541914153643871145709051618523866092344308, 547063879846298063558618040724136, 139178875887578925815637703042506434689206226); + _reserveERC20PoolHandler.lenderKickAuction(1080210574705641394, 999993250044949111999999, 16873741090968313756030417700688); + _reserveERC20PoolHandler.bucketTake(9560037085551186749384148563986, 1003727878172235844, true, 999999999999999104429762889747484962771602675, 1002802333700297662); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 681634005753087766404114989971510002855431507022693773, 66296066187770799949253945491074132, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(453325854, 300079687913611386730053181, 2932854147, 3310916102); + _reserveERC20PoolHandler.settleAuction(52376, 964654011515714677773236239, 3197523446457159778422482146392145457160725115799977526078989650086622, 2976896317); + _reserveERC20PoolHandler.takeAuction(19567089233749468805885346799534, 1000749474127275437, 1008705179521483680, 2348434411972902637745); + _reserveERC20PoolHandler.takeAuction(836356110766266450549411, 999999999999999999430505035718387996726918882, 72735644822013947188405440852717, 2214020746342950388915601527); + _reserveERC20PoolHandler.kickAuction(3, 410490095397892594851825967049971, 815946, 16595115353814267994496224887714384060074292597435655963572364526037); + _reserveERC20PoolHandler.kickAuction(847550092186670018581753555029, 26407906453544255713930981622918, 1000495449898101791, 1000821180944747150638428); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(34721970252085105893792696805765, 164287967878367176482180429048142, 1004991707312263606, 17574538141924491443772995214184); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 260388014410575884196655830290, 2, 14594655914854823119993865564731566277135851522084265233418728563666530, 3); + _reserveERC20PoolHandler.takeReserves(173425897638020568966285477481191, 110198, 103990); + _reserveERC20PoolHandler.addCollateral(32591228074129784963186486763587788781995552728936962267589, 456369169881735268001244641033877454320, 1465157619694151589552, 3); + _reserveERC20PoolHandler.repayDebt(3316668654, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 155238770752544901532692850486836670391697357307174563473820); + _reserveERC20PoolHandler.stampLoan(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.settleAuction(7535899993592804079615353798636864381239658839934403345802359544395468667, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 28909268765107265548982087601153, 444741323810117081); + _reserveERC20PoolHandler.removeQuoteToken(750719912257591195252266535998, 1000742974739501859, 101051993584849178915136821395265346177868384823507754984078593667947067386060, 1816815809); + _reserveERC20PoolHandler.settleAuction(4374614309, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3894572351304843466518237700679301914525977893869589681304258022, 2337865935026451558322333684397248898819519773); + _reserveERC20PoolHandler.repayDebt(140996511829761269737768885836149019260843408700554, 7637503065827967971911851556100141380946819260, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(16592533365389444334052203377, 165876128963464779641577291329340, 3478320842527590828268579116877053658131732438362246960689301297760295); + _reserveERC20PoolHandler.takeReserves(9950054233530649, 9962660409387641577275846908, 973782157709293244692012850617); + _reserveERC20PoolHandler.bucketTake(1047742386910921371, 488711943058066559408293665757381, true, 110248834269558644919325599528, 3366939599); + _reserveERC20PoolHandler.addCollateral(11326127703357669767276482364518, 1316087135112244796393274390417326975813243394491529104759792692807543088, 55862337647395782248172, 1000171778776209003); + _reserveERC20PoolHandler.addCollateral(453108262604054994945778330052221, 495817595081526831140230, 64326, 1000065395138154660); + _reserveERC20PoolHandler.pledgeCollateral(1, 10974833181087458929173090011463869787607, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(1156778284002363152290092, 808284838565, 35181591226285887492083247423549104145); + _reserveERC20PoolHandler.removeCollateral(3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 13612127521644806881892509026390271185737515546127824262680094210977864984); + _reserveERC20PoolHandler.addQuoteToken(579801243548931877433605600381889, 601483867423473412292398252366, 9166467539514950216024138187918233977, 338306434819080802465619251956314104346444287495); + _reserveERC20PoolHandler.pullCollateral(1000002253966264175, 60825291428991935610852444689, 157998826540352184836899362110633); + _reserveERC20PoolHandler.moveQuoteToken(4086641742125645136864181, 1122094540260019466653760947273493985249019650774963821031610903, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 108825039803620502600349868610992414872274948111687021896312910402858220183); + _reserveERC20PoolHandler.settleAuction(173881959772535041002904608, 999965931713566195, 423370653606047295946165, 97576); + _reserveERC20PoolHandler.addQuoteToken(2, 392898204283464398436236691829452986311483637317572, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.bucketTake(76080652428442402592749113554, 33223904850298077663656137793892, false, 39214582780115909221557, 213917100031090710289398368967); + _reserveERC20PoolHandler.repayDebt(7090750178089638721895607650654, 3833529317193259877332452345726, 13734471598365790650845016940797); + _reserveERC20PoolHandler.addQuoteToken(2, 4227547014783891208944019323723940607789305667790973703322670175, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 5726168374512371715717634762848250811817549323068993149776640212, 0, 2); + _reserveERC20PoolHandler.addCollateral(2, 1134665261750910360118158715083786265856946, 0, 302425246291659718641892483258); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1954, 1); + _reserveERC20PoolHandler.takeReserves(1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(1087494165039341344, 71916, 23042651405066388661706983927865917697143739504542815280987132615634384506379, 32553512202588831908631614, 2805248205507760216955); + _reserveERC20PoolHandler.takeReserves(131027223460719245694240315022, 0, 6480282106746323087066818493571825184402788532993634149968668460718); + _reserveERC20PoolHandler.moveQuoteToken(99654708234439808473491186405115717843600469408740480560227024166854583446, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2608842475358447017654674478269608645510304931326235211212129, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.repayDebt(2856351226880, 29791204695586139815055880126038802350531, 277272690977941675182610); + _reserveERC20PoolHandler.lenderKickAuction(1459345994533773953358623903912, 829185630409947563171875151231638627896726, 88157185367278686158169901322733); + _reserveERC20PoolHandler.stampLoan(28514739745928281725259166541989, 27052290677018347879824359747922); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 0); + _reserveERC20PoolHandler.withdrawBonds(146690055294571530233558210174, 149956404920105540369468809836, 22577889971971421308657770363588); + _reserveERC20PoolHandler.addQuoteToken(0, 776536651980, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2457881073468685160848902002); + _reserveERC20PoolHandler.kickAuction(37643748993100617237416231018170580, 85640081059478850519544962973, 56157906680524746419854855643918, 153656270799568290882645059415803794379238356976692922465409433341791409); + _reserveERC20PoolHandler.lenderKickAuction(24227535776837179880753431511, 144447867448158953932377749167, 1833215661003661368807078815605); + _reserveERC20PoolHandler.addQuoteToken(638291956708008993189764471053, 118355559206257394634005343050934, 1000000000000000000340072357193064902836573305, 2999999999999998359418858015127163202849057168); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 18246723113553312355973376, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(22690696937478757018320145409664479575693122401068122, 16834888267011782941793481165115909929605); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 4755010093470181367416095441182054907727122491172759416, 4913936543906479124139354689050639396554001112686824616165784324); + _reserveERC20PoolHandler.settleAuction(999962551695792945, 10384457863004087, 994481159121486194, 22330891216883155359588238568902); + _reserveERC20PoolHandler.transferLps(0, 74737364537886459056338600804616451449820613964732, 1060022325127699446817052944, 23874326356703041698022154261374271, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(1000728538893637861, 164647390121274048214919056859585, 3597217499049988971038893429053318318563750105465930480462260469735954, 1004668171035216958); + _reserveERC20PoolHandler.removeQuoteToken(1001365106964311333, 1000749474088259462, 1023447617743550317, 819244527116788169651721); + _reserveERC20PoolHandler.removeQuoteToken(118882948797209736637384, 24301077138699051606832059960, 27069750129628488953269353717768, 1009556629833245661); + _reserveERC20PoolHandler.moveQuoteToken(120, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 187323251002731577835692746457856859874, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6144); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 22615092404198466606976054580207281575023899943468700380451001436502); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.drawDebt(4393283269889252707212255838281586747107796101053554137766, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 9067514562439946245); + _reserveERC20PoolHandler.pullCollateral(1, 910966029102032131668353081904484623118648281795331767253469899, 16632381087444800910462142601062083710558838903858517); + _reserveERC20PoolHandler.takeReserves(2633734197569487703937764965260, 257845010695336589264757144090, 1970942592); + _reserveERC20PoolHandler.addQuoteToken(13003814195813277224879460231, 81651607673398677844644458236, 46642476533181923699884909001009, 39987227837911254856093568126918); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 4953115032141138481554638788621998, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(26840707036148533209828603990771, 647878186991556747261994866, 952200938507938908670595374636); + _reserveERC20PoolHandler.withdrawBonds(1240381458310190774336567420895677206817936542974098458156371280068110513, 1080805178010535078, 86703277221900297407040408028); + _reserveERC20PoolHandler.kickAuction(2453520021283123612805001913446, 1005666185145525602, 2999999999999999999999893134658661185913521601, 1000928055576505852); + _reserveERC20PoolHandler.kickReserveAuction(1102180007961205737732903585463269252, 3704376238); + _reserveERC20PoolHandler.transferLps(1, 454822267592418978536111518246088253038643387062802525838380431198, 116038090604347562276640938940155565042787268837961, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(0, 3, 2, 0, 1073445170690678349328542198273312767409938015550800512); + _reserveERC20PoolHandler.pullCollateral(0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(160634047503359202717439364616391998317201481, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 9504244754196622776652842787911178); + _reserveERC20PoolHandler.stampLoan(1000000101723682340, 28455500937485121913686669116317); + _reserveERC20PoolHandler.takeAuction(82751290341570360600185829549558, 2009048731, 107360, 183117490342); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 4279158061175000875704437731488975443, 256348893751277326646121155140466163402375437100851); + _reserveERC20PoolHandler.kickReserveAuction(43149325406898166644797611933505955231975815057520106109451620555850559703, 3); + _reserveERC20PoolHandler.addQuoteToken(172244538520839844544679, 41270428669792934044347128724283, 22038959804036185924116760786917, 1919717966509801318895449904093); + _reserveERC20PoolHandler.kickReserveAuction(46261077757002541184489288841951630061724819088128390671578437, 0); + _reserveERC20PoolHandler.removeQuoteToken(68537, 9564847135643556983169715906, 8746784735957585273726715133, 1810518713922719815263728792120); + _reserveERC20PoolHandler.takeAuction(78320541286112355684335, 1032128142815446803, 16192398133179295975094528159908110187224918906122199355540947774, 904323521910364185408102291798); + _reserveERC20PoolHandler.kickAuction(27945530928777371441871859053578, 9984831320403232358598446163021, 259567404498656758268695473664, 1032127479986761661); + _reserveERC20PoolHandler.takeAuction(33629971245795512, 16446833626210688363593681196962740600099270610425104620723505, 0, 185139374167807304548557444589064400352011408126694640); + _reserveERC20PoolHandler.kickReserveAuction(143866361, 865816153523046686216); + _reserveERC20PoolHandler.drawDebt(10935414854064539468564700317490380082993231895786, 38900228549209372782192613531, 3); + _reserveERC20PoolHandler.pullCollateral(94847209253180014377456, 788101666475241902777415902068, 246511806815632119738125539147); + _reserveERC20PoolHandler.drawDebt(25399562092085399576616303056182, 8977053924315166797135956515076038, 2130246445449937050782719); + _reserveERC20PoolHandler.kickAuction(7089343043112995173939019, 12285, 37472, 2841858284); + _reserveERC20PoolHandler.transferLps(27672184044836394851285844538546, 33249677152252453483994893532981, 35531420405227787347651435435306, 21868769617181618834317477792841, 1003454575076407191); + _reserveERC20PoolHandler.stampLoan(1000038893776107640, 58246554213685169707541175058112); + _reserveERC20PoolHandler.takeReserves(44568, 788163757338259225686956070870, 788303505420128468570238001023); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1024004736783571080748432354776, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.drawDebt(677125750154905495441351542017531082096019704807, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.bucketTake(1851791593115074996845704603546519329883492, 2, true, 120419842667711277778894344912132174958190085743930827618753892800, 4248816692747606632531584455); + _reserveERC20PoolHandler.settleAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 346699289229906519113725982398, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(122868119940530968777736285328706, 33560, 30783826180136890892039916921817, 21832712099949779960848935138560); + _reserveERC20PoolHandler.addQuoteToken(2, 2, 0, 123708734786974305563322); + _reserveERC20PoolHandler.removeCollateral(4983161497837050448801258563, 2, 2, 1316237); + _reserveERC20PoolHandler.pledgeCollateral(68642180794644881547395651055066, 8855866193888944041174382641702, 144135742120906570229753164151); + _reserveERC20PoolHandler.bucketTake(3, 246678334825586692936500, false, 1, 3573228293280); + _reserveERC20PoolHandler.settleAuction(13097, 44218318125421614541468538868846600891409429204431504277928, 0, 34905054962645766157688084466666891); + _reserveERC20PoolHandler.moveQuoteToken(0, 2582650853127671574902506706163942936602834, 16381249237031925721667069445454146448563, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6714517723195146); + _reserveERC20PoolHandler.pullCollateral(334261883573799786361587352857400518177407717897659082391853558, 250733804671, 46610743177287316252329114620110314437976518709382946909381203922155213671); + _reserveERC20PoolHandler.transferLps(79725439515242533055857907, 1006903176736796186954964804347164826545897922488265096299074325632518120, 974061115976992193559068656025, 4644, 6868037146193267314140571271382); + _reserveERC20PoolHandler.bucketTake(2465485601865423832241365263, 325200855, false, 0, 38665782511283859134568443326025852611029); + _reserveERC20PoolHandler.addCollateral(3, 890260916456627429833546507146543266458547575954, 11225349365658105897935183840003581956, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 260045052558532912532909574, 3300648, 9376065252558300094020412235308953108760692303217108341853, 3); + _reserveERC20PoolHandler.removeCollateral(4738087657009339247, 0, 49978181, 2); + _reserveERC20PoolHandler.addCollateral(4529928009175957372377217627579, 10553378262181166682294491726714, 2915553114668868269017356146224, 6644090913308462); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 424720630299640); + _reserveERC20PoolHandler.transferLps(89511685855305060595157579934042144950734224, 939218712584461, 162039490, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3087731429473185270943423647861242087147918710520933229701683050460781231); + _reserveERC20PoolHandler.stampLoan(97788902457792442333597649061, 2791651147032205242297); + _reserveERC20PoolHandler.kickReserveAuction(2, 8487081214380317923902235445806870488037808408652583746428); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 163184877524931952251185121714117); + _reserveERC20PoolHandler.pledgeCollateral(13149297878700891015369998966527302316881, 1920724744430624627972201, 508789031); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639933, 320604494398351477548174812161793420562); + _reserveERC20PoolHandler.settleAuction(32805159246697979431802610492362196204014, 2, 51700142694333800013507706, 441220706878676724093874591799915073925850993370574085116295); + _reserveERC20PoolHandler.transferLps(1349774743225553086414846420278621311632646527208730670282154325634369710, 811806624297684991251548311660592758097562555304202091187913191, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(2902541589580331146576721472515520818375953628499912335703749, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 12208836477836495481607541260898813308630905361402193567152528430177548531); + _reserveERC20PoolHandler.takeAuction(183004214067941577404819799505114, 53157334129343629740622877819779930880943887528029596074300707102573836329971, 2732567593530547611199084291, 2); + _reserveERC20PoolHandler.bucketTake(12242697145811737321552049120638445516559873510142757036110741979, 3373805, true, 2, 12002612004480078857643955013759012344); + _reserveERC20PoolHandler.removeQuoteToken(1, 137303943143184843767, 3, 21940669789116874793062264749282961164563822412174809226571653226183123937621); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.removeCollateral(2, 3158218, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 75897793261850); + _reserveERC20PoolHandler.pullCollateral(276744805042512323, 469103630538753727997931140171432607446705083816993705, 614229142292045973106712887723311628926331569086747795495838719212951629); + _reserveERC20PoolHandler.moveQuoteToken(1000000124556070669, 141867269515115271771521873281134, 16609287821944084631471487564399, 1079849644951245604990326971146485, 108940855995041322740688756305); + _reserveERC20PoolHandler.repayDebt(15922817691204536404718403471996293418608679, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2613772732547082517323863209090989622547); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19662557189475643223800475159522701836017325, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 741975410373877728828300196106222440189359073718782350, 3); + _reserveERC20PoolHandler.removeCollateral(207699432717957389188949383088012289718278802523302754, 1854, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(11831838549665730736208050871, 17837836697499377250355553952, true, 1245399045359860521210337582844, 17698121828612050193602750991); + _reserveERC20PoolHandler.repayDebt(197127369445826773479565862934692, 877218191241671112727236867551, 1751532659061715977772763208694); + _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3572846217568387170799393129, 98457209422061325132284690254555); + _reserveERC20PoolHandler.repayDebt(215684162009815260739321324655, 290123777200914960082663, 1000091095419989017281618401139); + _reserveERC20PoolHandler.stampLoan(5126512978056912936219747861885027950499191504622672248, 405919298618945855285638802724948558167); + _reserveERC20PoolHandler.stampLoan(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(56736, 14167418445236229667590162183945344036, 1057287925619596581994110060875116802449120878526492452728622326049556821); + _reserveERC20PoolHandler.pullCollateral(2, 3993702369241559739066752422560, 287426504484607549313); + _reserveERC20PoolHandler.addCollateral(48483, 136809794080717926970189569118939, 8677833030604393, 1028826461330474224); + _reserveERC20PoolHandler.withdrawBonds(107747, 2669815910783844018726286145164, 21868788078347645795181098511661); + _reserveERC20PoolHandler.takeAuction(183836155834802135750607399380040, 18004, 264417715279410305491110322048335994355397316893041110865797369, 481769895252); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 102760833096193132473687666582149082615168720366, 0); + _reserveERC20PoolHandler.lenderKickAuction(1120524000911294498046, 8169400827306579858941993448365058765310696658, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(1, 1); + _reserveERC20PoolHandler.bucketTake(148309860642045333313, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 412001645017136580278290581930635096884575135422378973125211634863, 1); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(625616136345606, 41095346268406518861724081704060196781878803467637544872493154015817500618094, false, 15017150, 5994703811016470305670); + _reserveERC20PoolHandler.kickAuction(11675078789760678909169933582800979136821052304541650893356982, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 538531091083394348845989838344091649828027, 7189918227323978390481250688338113135902610577615166753211484527200258664954); + _reserveERC20PoolHandler.repayDebt(3, 3, 49577554545487511341928099); + _reserveERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 501707759783740052116889453545191773343841276815438712644, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(90016045942964568634657551359, 184784706315546302413310581811397, 914499700983216258227466481271); + _reserveERC20PoolHandler.stampLoan(2, 3); + _reserveERC20PoolHandler.bucketTake(0, 1, false, 2, 5708072); + _reserveERC20PoolHandler.transferLps(1002478263218692513, 1691669539612925308851702658174919, 508456385096316418995993820, 1000481083600755504696865, 26669); + _reserveERC20PoolHandler.pledgeCollateral(107995, 6414242089482956599553941722839, 38312); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 28970966805522900646984619276043321548401972723785742560108639766903468274, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1574579226726042); + _reserveERC20PoolHandler.bucketTake(30160127831142282826309570802255, 866799399902426771494457622730, false, 52118239535055759321261479114893, 216427392050078438774261700519170); + _reserveERC20PoolHandler.takeAuction(15487816142047851, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 141450888120297707453772990911728519695083235004666996179002603783, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addCollateral(2, 172500863224277809186558044299876177629613864996514, 0, 1); + _reserveERC20PoolHandler.stampLoan(572692094404676505199832401072742305267787845035865178992404941, 1000051019179824641); + _reserveERC20PoolHandler.kickReserveAuction(6085298035414758811738993442009, 11627141); + _reserveERC20PoolHandler.removeQuoteToken(1006001204877523795, 128215647523491311226908, 999999999999999037687138586100260128176999356, 1000000000000000009759420844395852832652940092); + _reserveERC20PoolHandler.settleAuction(1000209115030952877, 581630864903419061953204559477, 762900904340714495471839914105, 2130006981); + _reserveERC20PoolHandler.kickReserveAuction(128490201315381424152555443048, 145790816216613156015723221931); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 198040130665308623348673008032664525104892162310616018628962939460412, 1822008489634547016011484403011341037533074522); + _reserveERC20PoolHandler.drawDebt(179720390949934322854215421951, 2999999999999998999999628621165686116198281445, 1000000000000000718609879320064397961454011982); + _reserveERC20PoolHandler.repayDebt(1000000002498956148, 1395969869854061865267448, 4061476931294558472021295112821900671913941431667642353844612437133810); + _reserveERC20PoolHandler.kickReserveAuction(9612632424878565748700187745180, 1026721795418847321); + _reserveERC20PoolHandler.withdrawBonds(35410486506278825958499363602454, 1000126960401338339388395, 1002601385551731030); + _reserveERC20PoolHandler.drawDebt(1765321003030050777614350494199117685087733812390277617794108325799610976639, 2, 19396692719370679662647255088045588877555929413514300232241722858781762); + _reserveERC20PoolHandler.withdrawBonds(586449722038909405287039, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 28); + _reserveERC20PoolHandler.settleAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5029915425173733462886386017195180022328987220270236814410163579372154, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(570444751100012681068640455341629136235, 114835260261758193350, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(5025121038984878733665, 1000000000000000007978179083269299411072196472, 3447132768, 2649955983092683161713); + _reserveERC20PoolHandler.kickReserveAuction(677051828227408425221860741, 15966433820034220489691463826885); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 137437921366846497532429615777818099496082206, 2, 24039599050357755214380856973136); + _reserveERC20PoolHandler.removeCollateral(3, 6183420672568345101950316251008714764509490719038858332244, 532716701802062825151720510469989, 38194276760362220806252889955161908426); + _reserveERC20PoolHandler.removeQuoteToken(41419, 973781689533328763879423413548, 1021132779502524484, 1010434576697960003); + _reserveERC20PoolHandler.addQuoteToken(0, 2, 774957943917987086110185557360567249160642609645490275899707839988488385680, 1); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 74707266534282069261798198396546072641255517518881); + _reserveERC20PoolHandler.takeAuction(709627541907271799732322287581033568033765800718811059807097206967279244, 640614429743575411731179529370, 788890668333265822885986438616580019872142554804556221757924475698215714, 1089306029570989203); + _reserveERC20PoolHandler.settleAuction(3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2918609043591931486903829715224104306568582529); + _reserveERC20PoolHandler.takeReserves(159142631214121927184691509830529578331667716467746406752155688841, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(25873014256453399526789202010508274659010251284861245072260812299381191251, 3515329283620490005391918627897303899118373390261528609777783); + _reserveERC20PoolHandler.settleAuction(999999999999996385078329095532214036740473540, 3314336532, 36294914392547659961431204855020, 724231536366889432980167264403579753697631010041593525653954819921238422); + _reserveERC20PoolHandler.kickAuction(210301332109390974260080, 112112051721153591648183403714, 3000, 27297135225045355328437826968351); + _reserveERC20PoolHandler.pullCollateral(25732847339556226324986240891389365844084261867790652461794, 43675098828582059329796678340068642905769721637958534991041000, 141030994881); + _reserveERC20PoolHandler.settleAuction(6654673534373300446467627489954216394626788037, 19998, 164763043068947683348971323279029697165360211418295028298731, 16172176802314171819031); + _reserveERC20PoolHandler.pledgeCollateral(1530739366853011976667223334, 51811284940715173426131633180, 2216917292150016479408704728644); + _reserveERC20PoolHandler.moveQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 1314468359577931810617290509146445918985160088432894951514); + _reserveERC20PoolHandler.kickAuction(3, 10987334782969926115759275971315, 0, 196889657865105714212341103621460384558318962962303792768634491462); + _reserveERC20PoolHandler.takeAuction(15817571773274713521353699804825, 1805756101123536269852079389, 2023638847957703512521894, 213597188940645862255346949155); + + invariant_reserves(); + } +} + +contract RegressionTestReservesWith10QuotePrecision16CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "10"); + vm.setEnv("COLLATERAL_PRECISION", "16"); + vm.setEnv("NO_OF_BUCKETS", "20"); + vm.setEnv("NO_OF_ACTORS", "20"); + super.setUp(); + } + + /** + FIXME + Previous Reserves --> 2775029494480168144683978144693760 + Increase in Reserves --> 0 + Decrease in Reserves --> 0 + Current Reserves --> 2775029494480169736295548669411460 + Reserves Error margin --> 10000000000000 + Required Reserves --> 2775029494480168144683978144693760 + */ + function test_regression_reservesTakeAction_failure() external { + _reserveERC20PoolHandler.kickReserveAuction(783212217385117443796734605499237250421694311837013698704809752, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeAuction(5124631688504091595669086529724, 7872291341180953226908461058832, 110762027021095348454322936028, 1003570667809068929); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 788097775288, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(1, 3, 376227332282377129915249935671383316780684); + _reserveERC20PoolHandler.addCollateral(1000000001678328876, 22157, 761609301969924517272693209089193096809666122619909710980828221613914290, 64224279485564790402623209010902); + _reserveERC20PoolHandler.pledgeCollateral(3, 2262051595919699091127878, 2871769226749034525974817123448); + _reserveERC20PoolHandler.transferLps(28966, 4819125906973043129448041259043, 23016, 12184006756313133490181586247560, 1002728973705263348); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 15390676656317351457714252219981192879522527337691288340497, 2334181839796020879155890678609838827218173895, 1672187154934360048557912712); + _reserveERC20PoolHandler.removeQuoteToken(23161356076196847958513292875396730273495389567271285521596733721162, 38449498076223611827356380142874894785064051939296230883324190722895, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.removeQuoteToken(70101214690180579331939567859861576890815865743, 50570315752607917981473203578030667489845917103611517330544178556218, 20838142513422961697282244751603119662518022, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(184349578482360114316345746866156402312291121062085630231544062188796994, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 62642556651904175880635790511965299576706007477311973758300539399130346386168, 1104374854493113522732541835539029958716916883822224207818); + _reserveERC20PoolHandler.takeAuction(1001332392221582247, 25159944816480304232691013748500, 76567, 5425); + _reserveERC20PoolHandler.settleAuction(3655813590206996829580077956370, 55062604912103946580633, 561890941827786419777203694539387, 3962664818288845262549583331308); + _reserveERC20PoolHandler.bucketTake(134838084543224110172483563253, 970528418738441254652582578836, false, 1000000833622512777, 3186873492); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 559765376299308638353636114818078192695284393663128, 1); + _reserveERC20PoolHandler.pullCollateral(5080057846070571871532725316681, 1000000259814015021, 10966191825061491194281576561773); + _reserveERC20PoolHandler.removeCollateral(1000012941058937669, 7016678521580002115409694863475, 1074025733363705232, 3217576206278144139872860900); + _reserveERC20PoolHandler.kickAuction(1000044183611616367, 299999999999999996634110056239448772211292405000, 1182422847499332729981392506911, 494953048170519867072934750); + _reserveERC20PoolHandler.stampLoan(14182, 1000000002279145976); + _reserveERC20PoolHandler.kickAuction(3, 720655973478, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 838684816325851332261218269263034688); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 67799394768202426835509, 308621579814936569712); + _reserveERC20PoolHandler.addCollateral(1000000025350413797, 60064, 60035472145417888681776767769807, 1006537724763566404); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 637845796989525910093745072537345948908366539130975511485259485085); + _reserveERC20PoolHandler.pledgeCollateral(9779943433358406946707733964578137904977466105173110086222062240671292, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2004176786687912018, 5115263684910718614440555700641992279168790086014503619, 203322479040619235118989457004031964551736325027735389405001); + _reserveERC20PoolHandler.kickAuction(2999999999999999977627482467572153196290170003, 1000000421483995728, 88080, 1000089271506855694); + _reserveERC20PoolHandler.moveQuoteToken(32038785176379362763264685863550, 1000982534843896262, 1703230288253644297901846864262, 1000005604422329840, 38233); + _reserveERC20PoolHandler.pullCollateral(1, 366669460464084592769921303850990283204717417457317969880152648479685398, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 5428380330164837799499980672254); + _reserveERC20PoolHandler.moveQuoteToken(2752495397664061427862039097058, 73426851128744297576763466933323, 5399169335608672534361931680716, 1008161081525274205, 1057147062609901731); + _reserveERC20PoolHandler.takeAuction(2740646098977863916199814161772993471740309025799331323286474006853198, 31247414254557726608724583181862097866435, 475189007012068449747101591906621292058126426375552462258, 4312390261994291509323842508319581282939631421215141122793185869049055646692); + _reserveERC20PoolHandler.kickAuction(5013858636, 20829, 80964511583998380934279824645720, 7094194806518717); + _reserveERC20PoolHandler.settleAuction(39452, 4707915371799938852538340199475, 1003137640077422009848686732304, 1009801257388824610); + _reserveERC20PoolHandler.pullCollateral(0, 5220972620680626937330400412739670699496, 2501743851606538217752); + _reserveERC20PoolHandler.addQuoteToken(9818267043696310, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 46808479129981522231322195387044892658556210270803021279); + _reserveERC20PoolHandler.takeAuction(220726750064763877215082011975552758515661578859069142669631663917048363, 22640158518770310521, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 123573793960); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 75532800331, 3); + _reserveERC20PoolHandler.kickReserveAuction(58678738233329749429427241546616974193671, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(3297272012584715323969307888432730669935, 1951487196492908224, 6375906684489117243820105398, 22578676635639757413646070106234462143381053519345605319157591362767390483799, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(50714323901550415391635431587346331632804229795582157790783374458425, 93657264653955479710518429916163327301109274844461627003529357853531714, 19211620324335745942483059408317310822951603111333827733); + _reserveERC20PoolHandler.takeAuction(2151892243731218264098686766074, 11444688337350608277125216, 739959360868921470781827, 130401932201022228698227691932); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 11148003616638434576348939449737766497659947391488, 420559017185165990634164985264330807610500544143933224724); + _reserveERC20PoolHandler.takeAuction(22657, 1000604423434435799, 7001038392276059866628247178401, 1000981397834899069); + _reserveERC20PoolHandler.removeCollateral(472797695755468048413825682568473311148448874843308748589, 4093418753475848174020520880737637788270248529, 3, 1); + _reserveERC20PoolHandler.kickAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 241534715189861196); + _reserveERC20PoolHandler.kickAuction(1075917365973198019554000169, 1558807364547380210403191071763, 64157713500503827845956787655038, 31863284317616057687008880800); + _reserveERC20PoolHandler.moveQuoteToken(66310822323562536238933522935884, 101857405662551365195393189017090561933760693738826083428418863338077783541652, 530334902264041817095468, 205549512007020186189905495520, 5982284978124563877090959786814); + _reserveERC20PoolHandler.stampLoan(996156212520173330, 9956441572725138707322501584332); + _reserveERC20PoolHandler.transferLps(1001428694680381157, 811651440532643516440561354231596, 1000000011677137522, 1000051272292085107, 145403103378715869245999255616); + _reserveERC20PoolHandler.lenderKickAuction(1, 8123845069857169400027647, 2); + _reserveERC20PoolHandler.takeAuction(22651912293456823508988530380, 18771916159963937997250482378786, 529060286154302161786027, 3717137168075422); + _reserveERC20PoolHandler.addCollateral(6230359526742248115485493684360, 1000072684071758630, 1000091864548622836, 16915376060623780016024889949420); + _reserveERC20PoolHandler.lenderKickAuction(1000009519392760182, 8442537843177884152441136575168, 299999999999999993736812665115996976662226887300); + _reserveERC20PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 65334957, 1); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 71471811255649098221607187192472573246938101382924); + _reserveERC20PoolHandler.lenderKickAuction(999999092091634144088350230643, 6970570543, 1211864629100698523); + _reserveERC20PoolHandler.pullCollateral(0, 3, 177406577490160911538260449399586796664280597707088889351073163729); + _reserveERC20PoolHandler.addQuoteToken(1807952041809162836645622811493, 418874053327363760273041323500368, 30110323845565115508962577, 12523); + _reserveERC20PoolHandler.addCollateral(388168527336022833044019773946, 45069, 54479, 46410); + _reserveERC20PoolHandler.moveQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 82927383759051843291, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 22629005064469176); + _reserveERC20PoolHandler.kickReserveAuction(3198613, 2); + _reserveERC20PoolHandler.addQuoteToken(561978629466237479506237449809753350913687, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 386207155068537406494296060439397198123861); + _reserveERC20PoolHandler.pullCollateral(1370299119, 175302760475826152580730579930394543847163817093774288063952, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(1001097364485353238346654041154, 1000007431743779276, 1003299181124166516, 2813, 1415271529393978466059392179103); + _reserveERC20PoolHandler.addCollateral(78385319150748486556715266665247893968742990154959296362895233601820804128, 3676, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(5795815723348394623424129826021, 33766141120945863229188936087665, 1000044186352853777, 1004799031319568935); + _reserveERC20PoolHandler.drawDebt(1000000000000000000000000020781900312861334381, 1000268313847685159, 38586535642540442230442100188051); + _reserveERC20PoolHandler.pledgeCollateral(7124044350385713178791787477893560696071397964, 55755739838792694832668414596541719058161972569807527, 531053069017018599550134031976012621072999120685550166383); + _reserveERC20PoolHandler.transferLps(1000000110261187584, 1000072476440394617, 1000000415530124447, 1002057035783655494, 12460838331541178332331008); + _reserveERC20PoolHandler.takeAuction(776892407681948567418226080215998, 22294, 155828403951197347014027718113, 2441603577321007763764062678921); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 64184824821127337293213035463226953837333791252249104, 641026552160195855436062307920944361499615381819767, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(108986540418029140491352287184584237262952372436047592326259272036426090, 3, 115240485461771363326553798041889); + _reserveERC20PoolHandler.addCollateral(1047521852240614854, 365459748686777240300000000, 242355620741713873136790742243661, 4316476364391126760856570514442); + _reserveERC20PoolHandler.kickReserveAuction(13113333584014829668682409561399624148305339679394589212937696029330142, 0); + _reserveERC20PoolHandler.pledgeCollateral(1, 4278851056967566578671854765112112809066, 877634043424144632568711724177210543374015303471911); + _reserveERC20PoolHandler.addQuoteToken(78931718811889341432231010742, 17326566077576432366799811, 19136, 938938368846484788); + _reserveERC20PoolHandler.removeCollateral(7268183313113665831311160239428659, 2330753870923609131068755915, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2221711869); + _reserveERC20PoolHandler.removeQuoteToken(3077972601083941888033904075144406575984480587808365520586417, 273582755009838441116638754420235879624370580767097, 0, 35332367725315030473019039); + _reserveERC20PoolHandler.pullCollateral(578522922193678471115207111393150158518571704957359360087833280262174, 20804552704142723746689927857020678, 10488); + _reserveERC20PoolHandler.drawDebt(136983675599642072344060498230383309839971798, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 514723333044); + _reserveERC20PoolHandler.addQuoteToken(3392226569009389715876804986729025212037025475, 137938343052400363120362905, 3, 0); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3); + _reserveERC20PoolHandler.takeReserves(26143946518085369847138163, 1005000000000000001, 4135761635497060998359915366816); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 908341143461830126812670032295260847584960818787); + _reserveERC20PoolHandler.addCollateral(3834322701034566044282962766117, 5363614377753186356034402373, 1000000120855121412, 20756); + _reserveERC20PoolHandler.addCollateral(8844801994160083258765145076437567, 59578540988169345580684820785419903366523440737448358691190966326257372241, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 15770062034818975597608632782039191931); + _reserveERC20PoolHandler.drawDebt(3597998827325053253426132116, 1005855474787021647, 1000684628423397841); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6097, 4040343374138933652255836616805712898063142832620789894003712320877713493); + _reserveERC20PoolHandler.settleAuction(3834234607350390540258353874710, 13371436696536443055768758, 288466894714427624132145072670, 299999999999999998040109565231381507280543098200); + _reserveERC20PoolHandler.drawDebt(66160853441522956395574012535980, 36983104809759159726688188202223, 4123616992112540491974203987395); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(211829310417012275495798128597934150063562837383584057079659497899003411, 232, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.addCollateral(0, 596702946219425937525939015857932162753959803605, 1, 13521158052232342424824514378353239658720756320004905935828559325945602366420); + _reserveERC20PoolHandler.kickAuction(2684629087707484549337, 29049751083885923101555411196449637897772934428886035471156913, 308294659116175, 3); + _reserveERC20PoolHandler.addQuoteToken(10585802442783544970423285180848, 7599680214632664779273014149231, 11638515062060819960815478581300, 7935773057151055939923459054709); + _reserveERC20PoolHandler.takeAuction(1, 227325488312329, 3, 407945585610011921420959456221093604139102882141982105707390795095778159704); + _reserveERC20PoolHandler.removeQuoteToken(412154315307614945230417295173834, 1000758178169407954, 1001864516404850689, 11883609299007697694816498107820); + _reserveERC20PoolHandler.kickReserveAuction(53026390740483954537233339756764214543216494005015993188910019051400537612, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(1822512254157782085293848400565, 1000008915374178957, 466425174264826352631172860840, 2576203009016747692066495424204); + _reserveERC20PoolHandler.addQuoteToken(16916614915866935161692539447830, 75393174113825835385480561467533, 2589840336811488318957052666610, 34318796610260848812924800005498); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 6850, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(31777, 4201658680, 698486113322674191, 1000000005061604789, 72876769772452745274019513944419); + _reserveERC20PoolHandler.pullCollateral(21220, 32806680445483270047783303760981, 1000000000498859772); + _reserveERC20PoolHandler.repayDebt(0, 12436546691908698020251018006908728383, 24113007429971166772684); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 136500310899306964559475499475499351863931519065); + _reserveERC20PoolHandler.kickReserveAuction(1000000011677137523, 1005651236692238665); + _reserveERC20PoolHandler.settleAuction(39439339176186339709848061087357790560862555012226555157, 1334120860786565187113763593559464843689287538547182427808463, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(61583478319547854054953232395, 34698250432089260598168416610006, 2579569696972678098020999997672811); + _reserveERC20PoolHandler.withdrawBonds(8152742916465998236552874969, 2999999999999999980272126545908640812837112642, 2207607961845999675148152984655); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 570098490925171476766118835649110168605, 2508527509660844061805106525229303667960646171827457); + _reserveERC20PoolHandler.pledgeCollateral(12, 151, 3297386900862); + _reserveERC20PoolHandler.kickAuction(2999999999999999947440958218091046352124229314, 22362904184428184406137532321, 8665476505344813342813822737, 1065247141844034699); + _reserveERC20PoolHandler.drawDebt(1098902371438191167349715329485175558322612070, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 14214); + _reserveERC20PoolHandler.lenderKickAuction(5361379110172103303287016766970, 1010605128322915385, 9021793408151005967759291194803); + _reserveERC20PoolHandler.lenderKickAuction(30473, 455104745109372345972847755300, 3541160354442737907319528170374); + _reserveERC20PoolHandler.addCollateral(1018156164796518302, 57181649142455182755079, 395048806081364594553216098, 1000009743057524639); + _reserveERC20PoolHandler.lenderKickAuction(300391236756362168568175401428, 30923, 5039992946237095718914946570395); + _reserveERC20PoolHandler.withdrawBonds(1072872540924280971, 10554564067484564238224485266766, 300092861772644990817754); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 20269494029480051042656471453186151112193761206, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2410207533328192852174792); + _reserveERC20PoolHandler.removeCollateral(17357858364524183843748273, 607236259984319893, 1246029236801918951141437197946344421055949649446395682298354380440602476, 787978178696424787939855642001); + _reserveERC20PoolHandler.transferLps(17298, 11706383477522518910695760194944, 8498685064505882745693040248308, 963029977297401823704249624715996771000815926780244398558849131786402005, 13778809665522186158614436042); + _reserveERC20PoolHandler.removeQuoteToken(5276463508894326118211028632549, 1013991311874823856, 3961761374566550358327942047563, 8510372759062574817520244022018); + _reserveERC20PoolHandler.settleAuction(42547, 1000547491856655854, 1030524053419619116, 7171285574); + _reserveERC20PoolHandler.withdrawBonds(582651286136058773047034309046374578, 0, 3); + _reserveERC20PoolHandler.pledgeCollateral(0, 1, 3); + _reserveERC20PoolHandler.moveQuoteToken(1000012649994732495, 21769148255051032047219175, 56224033986774878658692261499829, 18875, 36711369859167613105587021558982); + _reserveERC20PoolHandler.kickAuction(251949047738158, 18, 3751099983551446045723778466522139409, 40128953049634127350640439303490880738479144341); + _reserveERC20PoolHandler.lenderKickAuction(126365, 0, 585319419756455193604947014059520485); + _reserveERC20PoolHandler.pledgeCollateral(4426859322210795511597081195089, 4179301358675475823251840096427, 1127928687039441887); + _reserveERC20PoolHandler.moveQuoteToken(4362671168975478740769057202185, 60461448069113770676932049678858, 1000981379945389584, 3887444895143026724189, 1000096775605575889); + _reserveERC20PoolHandler.kickAuction(1000000556317867017, 4568789387, 14683865947739026019282681207133, 1001522520438897650); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 184531906314982338420802424148666639509884450063700); + _reserveERC20PoolHandler.kickAuction(6320, 84154057830463779002939880307751, 5814383987, 8478654111495580522003396954364); + _reserveERC20PoolHandler.removeQuoteToken(19999999999999999998499991966085426318693578011, 27558660193281232818914116879, 73221416170738724916182538364700, 2018); + _reserveERC20PoolHandler.lenderKickAuction(15083888993464127749681183958, 873328645282563575200000000, 35414); + _reserveERC20PoolHandler.kickReserveAuction(3837751378664589184315206270895, 115748230629755862961296708774); + _reserveERC20PoolHandler.lenderKickAuction(2783920387675129592115461529740017960133342355558357279, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.kickReserveAuction(133688831133534683465638858239998553134659349245601828144030203, 2); + _reserveERC20PoolHandler.settleAuction(24810734230509840389280034842129755757555855535308624249925, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 32014122924658499032508813263392148742950737807780951025034656318704901); + _reserveERC20PoolHandler.moveQuoteToken(522622184, 287356439861157713169534108073349, 4987101409072082031254553, 21963109364673374821139160001072685660651620609588002314863488186057596285, 898070112450859803722879223398638780832584398221727503291355203420926); + _reserveERC20PoolHandler.settleAuction(32335, 217892704391644071398485378083, 2746329465680119300623, 32365641331672724388683450214233); + _reserveERC20PoolHandler.settleAuction(1, 5467241596196649475104378962862690990846712954, 300540464518723070679554, 2); + _reserveERC20PoolHandler.bucketTake(2, 639063624636687586730477, false, 3, 1329091237537801029366405365927804079603218848054364050341249899892256); + _reserveERC20PoolHandler.addCollateral(3690581450526022629808477894053238, 3975363258, 0, 2); + _reserveERC20PoolHandler.pullCollateral(1295569025584031557, 2240196747999998240845618406078444, 15615896218288108917988622511122); + _reserveERC20PoolHandler.removeQuoteToken(117693554545, 7270312102, 2861734753480477547534870776836, 2576151726845191990372947315261); + _reserveERC20PoolHandler.addCollateral(945751726170025458521960006316648804348253116183458833172345069856447, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1050473739073412489960315055018947049450374728293687897924154842275224648, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(2, 7004055086656257008152867, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(192051208262034036163946, 923079608732495162152647404709, 26854655145954739574110103569); + _reserveERC20PoolHandler.takeAuction(56688, 20882383243876347165650210895637, 49507751791352476891663411484532, 7112455495); + _reserveERC20PoolHandler.transferLps(63472340947897881883891767986, 999999999999999999999999851590820118130278060, 381570225166184670340760093618710, 59993370950183815229512608, 1000025646846659811); + _reserveERC20PoolHandler.lenderKickAuction(1000656157720769949, 6467882189531989849381108448833, 2127902144630498503985900996390922); + _reserveERC20PoolHandler.pullCollateral(194219475, 0, 0); + _reserveERC20PoolHandler.repayDebt(4025815515522552508653218259589423973295, 613432384032952364180982739219, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(624527198396337520195247132979687297733891639136972240307727, 2, 1); + _reserveERC20PoolHandler.moveQuoteToken(144920449001628867930968379916907406, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 4041975, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(971256399432361440196313994347, 1000000014808296766, 54285526656070084416218125695450787296568748); + _reserveERC20PoolHandler.repayDebt(1001397666881567463, 998156455899723021, 787987366007242502390673235155); + _reserveERC20PoolHandler.takeAuction(1, 17874493732135, 14507613556298076750687694022578059546853881396915, 1); + _reserveERC20PoolHandler.takeAuction(203982836525073497053153524710, 151988233262566499327641705889, 1000093304759044923, 17655); + _reserveERC20PoolHandler.kickAuction(669830404041210779699919122940, 999999999999999999999997321540345941834017874, 1000004135884566515, 79386); + _reserveERC20PoolHandler.addCollateral(29128062632578948035125610840898248356690, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 82253913162897902712194769495638492110318794028620064535652910419282, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(306932459, 1009486055054410580, 81499043670715865391257667943583751862869212202460141952268097806427452652242, 1008407321227091657); + _reserveERC20PoolHandler.drawDebt(4634862635323533981993050770862, 743461658494156473058938693, 20368330569455389075116458783235); + _reserveERC20PoolHandler.repayDebt(25050130998160468821107039128175405648128109894846973211403174829221423, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1722051742396914846919537); + _reserveERC20PoolHandler.addQuoteToken(305910724481524200063, 13573994, 312036124832383881141730358272850, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pledgeCollateral(1000006782703291320, 34210, 1010621461235132128); + _reserveERC20PoolHandler.addQuoteToken(2847079834257749398616815572195, 120341117204546625914778749933345880361329547485641100512560571, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.moveQuoteToken(1130906084032655300740506309693, 74067722981420506161634939376242, 34300040146522196256476372073449, 38794146101215285139195876043475, 5877146665168121606506858973191); + _reserveERC20PoolHandler.withdrawBonds(311519262254609937975952976040583, 0, 2); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 78858326); + _reserveERC20PoolHandler.kickAuction(1, 6491154831988541123642665977420001062234984471407458, 0, 982997401521904402619619991749906757059972751245207906189); + _reserveERC20PoolHandler.pledgeCollateral(13548717033675583, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 60146279913155925582156453856849859499191651022035393949245500546191); + _reserveERC20PoolHandler.removeCollateral(372705327, 1659993103615807998978091588740753422578867, 861686413835770499629652727737525670996446645518745233407420241281438, 13734023582716379550736384772371836290597301731033158636893702730); + _reserveERC20PoolHandler.addQuoteToken(976800998921091520963236134712178962511941452267159017322806021243027373111, 744410671705342450197372135, 802748258243658273223792595967777538121168659255983132072711726064831517, 32437); + _reserveERC20PoolHandler.stampLoan(545010214623298467, 24780309196757652431461555093180331135003401300452213438513257147829495); + _reserveERC20PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 84159); + _reserveERC20PoolHandler.pullCollateral(2236580567, 1000106372786948300, 1000011590956742425); + _reserveERC20PoolHandler.withdrawBonds(1007739129859284866, 3423275927107721758295318911563, 1000001410928189675); + _reserveERC20PoolHandler.pledgeCollateral(30151814885560226044766954, 3961925412533450400667118115052, 1000000030901306689); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 71115580872753089261977657826229128067595513985145, 3, 3); + _reserveERC20PoolHandler.settleAuction(2543, 1778932095356334022143117997338783579699388706902883623659276617701331946, 66170876617830912589964997912503, 599371494170668251016011); + _reserveERC20PoolHandler.addCollateral(1938497086, 36982275572172621135665758960187, 18811359209217561102973855741, 4361758773475952014298371928131); + _reserveERC20PoolHandler.addCollateral(40525909069711104583726479368561, 504034309024392916115813207, 45766, 991703606513569998); + _reserveERC20PoolHandler.moveQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 0, 2); + _reserveERC20PoolHandler.lenderKickAuction(134779587441732461513826650, 247843580407472290268254951928018240311793376102096698, 62); + _reserveERC20PoolHandler.takeAuction(382503487389575519180120111615011, 995923247930461275, 128995130125628017533494207075, 5953875968); + _reserveERC20PoolHandler.takeReserves(969682, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14021670); + _reserveERC20PoolHandler.moveQuoteToken(1000000000007031407, 1000760415835655526, 62033863724446703361350209840572, 1000009955675934068, 210985866187155165269961883); + _reserveERC20PoolHandler.lenderKickAuction(1001388353155111684753318155558, 7303561585961089703403390417434, 60879495381604185076156494); + _reserveERC20PoolHandler.kickReserveAuction(1000000084908646857, 1267538509777492372569389133132); + _reserveERC20PoolHandler.repayDebt(4940208, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(1000001214219335949, 999999999999999999999999880970107901383401534); + _reserveERC20PoolHandler.addCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 11151368833326644692190283433021568726336414432914543251985508055227); + _reserveERC20PoolHandler.drawDebt(2, 1677164094866189436748631031265107934092, 2); + _reserveERC20PoolHandler.bucketTake(12457, 257165756076015917329360, true, 1043091368039438944886953678892, 817869384970646542964450520); + _reserveERC20PoolHandler.pullCollateral(1524990327992077498659799421907, 20532325488594451, 27932350943735420346876538084830546004639382841600536784606443719); + _reserveERC20PoolHandler.kickAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 42261031658731939965377888624793357193680288, 0); + _reserveERC20PoolHandler.lenderKickAuction(77436834849168088760286247016, 23254055052725484766433954, 1000007565603646038916085306599); + _reserveERC20PoolHandler.pullCollateral(1000046134117688724, 39725629022485320403477907246715, 58410); + _reserveERC20PoolHandler.takeReserves(19999999999999999996294133276917405564585501336, 1000000362459996639, 54860979631320106762776106866903); + _reserveERC20PoolHandler.kickAuction(0, 93611938753542955121893865765837805409819862049225642667646, 5424648469676990174052283137, 1); + _reserveERC20PoolHandler.addCollateral(934646883196604, 5608386054079800606068917370848796027734614022033798, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 409992749882227); + _reserveERC20PoolHandler.removeQuoteToken(5370899330682378989491201649421055710190, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 70134); + _reserveERC20PoolHandler.addQuoteToken(226417767719543789099791814777758037210234643, 3, 3, 144721428979503253794792977911570024733801049); + _reserveERC20PoolHandler.kickAuction(1001807, 5955803702960930521461819814426, 3, 49507108440727019225583566280450518397664648205889177540811); + _reserveERC20PoolHandler.removeQuoteToken(36161061678538960373085961846510380504995615, 49711, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1250408311854007706509802781542864107147239546134905083684); + _reserveERC20PoolHandler.transferLps(0, 3539456213768, 875759620601696051690701551396504598257564491894605, 2, 1826719853501714576291033689205864810); + _reserveERC20PoolHandler.bucketTake(2187697828713467265269297524688954, 9139050038628790363167359304, false, 135910856582518128239190080156, 6463495136542422929670511849204); + _reserveERC20PoolHandler.addCollateral(1738266703796026378165904784904694873490026367098240021443460499507327135, 1215667776750202854340397817000013154859847291419847360513528961708287276, 1000000008060827772, 508594585544539417139684732301807); + _reserveERC20PoolHandler.transferLps(95936490411035558621090496218044199662939799093676494761988328325946904219925, 22878, 2861745480949287938552177795137, 1983382159891701529128577422129, 15920522674763137933080959496); + _reserveERC20PoolHandler.lenderKickAuction(8745381071676678, 434268500265573340443251903513197572, 354736068804484540887294227899271361087142695276397776389764650365); + _reserveERC20PoolHandler.withdrawBonds(3416405760442613155601198640, 586688082854370436536769412964, 1001214101152251558); + _reserveERC20PoolHandler.addCollateral(17439419466214605427593291400481, 31153, 1058634839587449407, 657459949691390775031071103632446); + _reserveERC20PoolHandler.settleAuction(575533642987867322302924974479481, 999999999999999999999999889052114291307712116, 2349909502830997118352818930102, 21718711280594315622764930232018); + _reserveERC20PoolHandler.withdrawBonds(3007161541539503820016608246228, 4114, 3593821426265119704559837297163719020610637057001655526639360789846007); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 33847502136216262337162, 318546876297608704896900738630025363850722, 1); + _reserveERC20PoolHandler.removeCollateral(1063777772750577235, 1130, 999999999999999999999913675337616817430595841, 1007471877863148789); + _reserveERC20PoolHandler.lenderKickAuction(3909423979302309040230588982991, 1057578753483632229, 187668559395052278652889142244); + _reserveERC20PoolHandler.takeReserves(19142528793908611415516826293524986635, 1, 0); + _reserveERC20PoolHandler.removeQuoteToken(1122026502599211951459078990278453400632427087245929840873598979753450419, 7571760846348679156151691010, 3388029685765629550642327208831, 1003757292226936119); + _reserveERC20PoolHandler.stampLoan(999999999999999999999940310433050580050427961, 977738434145584157735871746524643836225464207615352813702403315799776051); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3); + _reserveERC20PoolHandler.kickReserveAuction(270982836401385760753525475454, 1000000057547379218); + _reserveERC20PoolHandler.removeQuoteToken(26878226221245826209336158951460, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 32808071326870127); + _reserveERC20PoolHandler.drawDebt(544182535223089415612031901733302134097240039, 24065734447637608926144772745149697799173624098874503819527130901793402700838, 2); + _reserveERC20PoolHandler.pledgeCollateral(1004640560486227415, 13306765780445385729694494448322, 10957664227315967255743547658967); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 97083); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 5724839085460304923042, 0); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.withdrawBonds(35679046195444495556013676352806908279, 10, 6133534436169425); + _reserveERC20PoolHandler.kickAuction(4291800291766589929025829223619, 1360303414435693983828050180886954621791199391959539042141241604983728857, 1006457482856211722, 2903492284426395530945567198400); + _reserveERC20PoolHandler.moveQuoteToken(1000001975559070244, 409694504896716960850597852598236, 26508791225595500657486914266536, 602218181923058868346751477629, 67058292847484204147358700000000); + _reserveERC20PoolHandler.stampLoan(1642056536024604858041615936069563825017884537937807274179073625707, 1); + _reserveERC20PoolHandler.addCollateral(826894156765885475874588069, 408715720753107624663639345709, 60188, 1266300339906675752731830656781287617793547623685372936029479081228120614); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 32914509903740); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 4993866104822182305772759236131934832657325926817111151789, 1032074, 2); + _reserveERC20PoolHandler.lenderKickAuction(74519120018169794861017192247885373433026440571892446848, 2888228172983338189492187370913700412988519292320646728020, 239661870698216453200436401159388889188654128804223920932174030772810497235); + _reserveERC20PoolHandler.takeReserves(0, 1030687152296484257795, 4045642751589854777146333984154045746); + _reserveERC20PoolHandler.removeQuoteToken(20724468576304781974493, 1000000032262964078, 2728128751619895815021, 1000765146220714859); + _reserveERC20PoolHandler.removeCollateral(2027399580249400608120867348216723047925840046194, 223615814037085441242545885242698676428447516940624396267209908911, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 9105962328529136841962576321479434889915802891349582732174320634982031); + _reserveERC20PoolHandler.removeQuoteToken(8222799205303259282930685095148536265321435244681735101, 3, 56806488923527612039423995746589453949890, 3); + _reserveERC20PoolHandler.lenderKickAuction(1000005872340192333, 2468633383518381718444, 8502562989401366174165750164800); + _reserveERC20PoolHandler.kickAuction(2942843206371546077341872418607511364709639032300267878136954290700943359, 121185100409374275075787456591, 30846975541876345299765011180, 9182389063603550224315450002); + _reserveERC20PoolHandler.removeQuoteToken(18268979368704909518901867284, 1068097195337769595, 6954572695789700157278053994991086390692153375814394774970151397, 1000001700058522722); + _reserveERC20PoolHandler.removeQuoteToken(18276260770846128137337885, 79975070072065882510266936056776, 1127928591384577068, 18322855405151711072098086938721); + _reserveERC20PoolHandler.drawDebt(100000285983506770200, 15274768773721224232346407633504, 1000253856383614726751407390273); + _reserveERC20PoolHandler.settleAuction(909620019779415917102617884929507321976490407598532727013424482022337500, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.repayDebt(625844031150019293893538436162192913487651510941554186214724034, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.removeQuoteToken(63220, 929207792742768884062502264092651675205388, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(8870788952990432992103772664560, 1008874290800590630, true, 9588353358343774914934970447538, 1000000101690055198); + _reserveERC20PoolHandler.kickReserveAuction(49389355058899980986515953152612064858830771254300953174065225556, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(0, 657524957990938962115190757535612970423631096204592581293331851808); + _reserveERC20PoolHandler.drawDebt(66652866814609142268322700000000, 7118632497, 82372); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 2454481398751515797297397777, 72625366906984063); + _reserveERC20PoolHandler.kickAuction(1004686593941425377, 1000013724117225264, 55958008711366741289275547086375, 1057002832807696406828325016923); + _reserveERC20PoolHandler.withdrawBonds(1528822, 20306307288540235157581723158959582604365065123, 2511); + _reserveERC20PoolHandler.stampLoan(980705901498104226718796100169226248070979184447700044, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(1, 15059534556428, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.settleAuction(0, 462707301149079718628043, 2, 170380); + _reserveERC20PoolHandler.takeAuction(748375108299613492760874299427317849098150867765, 0, 2, 43775907619477426518451155601441634834365923317886907140829081679); + _reserveERC20PoolHandler.stampLoan(1007737653497643017, 7510299424725548541578051096796); + _reserveERC20PoolHandler.takeReserves(25063651899116991397984680196260966, 2153791612071930295708902, 360333110483761440083009710611213546572970449766651573962312531113226517); + _reserveERC20PoolHandler.removeCollateral(20758218151440129706220109387463296235951158988276785, 3, 1875522564267522083179868257937764672, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(33242606053856521772294620394761836965915051968233871231247429613, 972970862668945060266781148260337514482050, 1, 1); + _reserveERC20PoolHandler.withdrawBonds(14610993285769198121304714220094, 15237024852369075685502293682, 1007471897946670716); + _reserveERC20PoolHandler.addQuoteToken(10269211583543639324396494478712801455399, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.settleAuction(419921963558957140097003617721, 2352537283610255842408796499045, 1126580301474288923, 16486466861985526413878790076760); + _reserveERC20PoolHandler.takeAuction(8152813597999797711183585712548, 1, 22508551960227847323587284, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 207982230685518018001153072985276325268241533838243167453, 2); + _reserveERC20PoolHandler.lenderKickAuction(2, 1, 26995537166584263200498); + _reserveERC20PoolHandler.removeQuoteToken(55762, 971391154129797100021190401468, 5401593214352012337585586491366805, 39314453412752835754839402583804); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 404228035251430038053543892804536909137133713223579389450751833631, 236959198596670544630242751688219); + _reserveERC20PoolHandler.lenderKickAuction(58258821425547423708194377349612970640988148003889115589, 2111212309719199649663803011773080759907565773222552344931420050518391, 1); + _reserveERC20PoolHandler.transferLps(345689182556998618143857, 4966664748956917963376123139128, 1000041789678634483, 5264643249197024174836709938212, 38059); + _reserveERC20PoolHandler.pledgeCollateral(5866883942, 213619719326083851367199862148001, 1000044182094437628); + _reserveERC20PoolHandler.stampLoan(45714296328073462287903499310794977016959200391793009, 8058305080968482757272370613323029855); + _reserveERC20PoolHandler.takeReserves(95221496989465846936462444021495113, 15139611517332412195245624431110, 3672413933793964329413827595675940278492543330282343413); + _reserveERC20PoolHandler.lenderKickAuction(778704683060205214191995842591, 32106337115282728412895740254, 1000002538847953409); + _reserveERC20PoolHandler.pledgeCollateral(24989072032845969948768419936897, 148072772129156030244230032883, 1987771536619392911952061812838735277068343326872790600735811891164242345); + _reserveERC20PoolHandler.removeCollateral(59850, 1610020839911967940610949103, 1010053169967316482, 19856370653725212261927522701711); + _reserveERC20PoolHandler.settleAuction(98061476950798, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 575); + _reserveERC20PoolHandler.bucketTake(24074954724081423931370486400, 994080613561475377, false, 6279050542017290712070411005, 1070815391638788638); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 162161649909034015, 1232872916033817257, 0); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 291335000528915693777085626); + _reserveERC20PoolHandler.addCollateral(95471047142644153073841427060729336411420179268899531408868, 825285979100144436124108273824529761708629335239156920, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 119075882533459869475450975871847); + _reserveERC20PoolHandler.removeQuoteToken(21737715955960971514361, 3157367069762317492367679420717438, 10577103024488862867104675603981, 1000905914079924815); + _reserveERC20PoolHandler.lenderKickAuction(12149, 580832846365005813842515363494877, 38010145118302625453182); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(27323, 0); + _reserveERC20PoolHandler.lenderKickAuction(998109200142294915, 1000000004585427210, 22964697999077158163008217263416210243731829040650775800840008034); + _reserveERC20PoolHandler.pullCollateral(57665575042216030069965136176426, 1000053598768919111, 1000984028002503347); + _reserveERC20PoolHandler.kickAuction(3531575975070670549536290383850774480751872715067929, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2122827889103582310037254180466445641783010205, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(2999999999999999973763807993228522004996360328, 18447134285009651016, 72876769772452745274019513944417, 290614222851362509232478); + _reserveERC20PoolHandler.lenderKickAuction(8093148917759892054525381331505383077964274, 2, 33467212724288208063310642018853997057047486145986879435878); + _reserveERC20PoolHandler.removeCollateral(57780036067398711633429, 1000001206187424687, 1000001839977541271, 161677220209212677806247135304); + _reserveERC20PoolHandler.removeQuoteToken(461602926159, 94966933414376149060333220023563165742840435079128724679158719075085, 314867460963919037416176, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(21745166009055281, 212862496186000677701, 2413785121747342588596006672073167604342128568904761958985657449230, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(14680288237657630200063388066709, 46482497083309950046084184); + _reserveERC20PoolHandler.pledgeCollateral(41941903127112706228681749572493175282350802791996621065911547901180129625446, 12533925095164806434066359101292836864, 5675504877141517634572920359761382923325676426685575341524422719882261293); + _reserveERC20PoolHandler.drawDebt(0, 2, 874483361595687011882469079462751569786294851546261); + _reserveERC20PoolHandler.takeAuction(1596952326348132419864925490, 5909501981, 14610993549124572617461163168348, 1000132409125789570); + _reserveERC20PoolHandler.addCollateral(30, 1003161938290153399, 993219481232283299433986828989, 21823392613374323107394960051117); + _reserveERC20PoolHandler.repayDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 10782765392245796250731926204246930145358935540658327116957); + _reserveERC20PoolHandler.takeReserves(1006084593578524479, 9117, 8510372759062574817520244022017); + _reserveERC20PoolHandler.stampLoan(7593, 5414693467493940193766574810876); + _reserveERC20PoolHandler.kickReserveAuction(2988352896104408872106019812283, 36982781214622834180934498503121); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.moveQuoteToken(1001206, 1, 3694273775171413589816178782514209463114665040, 1, 0); + _reserveERC20PoolHandler.kickReserveAuction(1000019327337151664, 2250500688960786556458812941529237473222272216100847305368734462996614403); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(154731405937068448492362716, 362422796544721787032440417029717678330000546957615517247, true, 3, 1); + _reserveERC20PoolHandler.addQuoteToken(3, 1515129955670912193, 1, 302372485691018290239450); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 1843459370035055836706813555775024479189658, 12289235315530440395071959495431023996028640226803); + _reserveERC20PoolHandler.kickReserveAuction(168939805628018546183963, 6665798937); + _reserveERC20PoolHandler.pullCollateral(164343957784408627719675870683125565118630115486064802015, 428358444302259, 0); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2320636066129751288144720782913685490868550934468871797132420861328193464, 173313354562669329103036833150794922081784885309887624547713583411, 52110947751870055604138830381863715532014797990386360798721179); + _reserveERC20PoolHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 17621283589344614381552602785806038178518469676333769462826248785845668446048, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3924352866635271104495962, 138782167945694243031627018215744617202283376); + _reserveERC20PoolHandler.removeQuoteToken(3652115727023368052112141, 263039830585611292976847403256378971113461987, 2974020217558135469732659249748768962694734894617, 45); + _reserveERC20PoolHandler.repayDebt(3000194208622556505773738002985, 584723077728569677316935595368, 1003819889046482170); + _reserveERC20PoolHandler.addQuoteToken(3597461109431611153151983944, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 15, 518896111650294092578333205548775226768642853009722454901039727); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 47445420758269742755, false, 213068420326632029015220618557377092736052, 2); + _reserveERC20PoolHandler.lenderKickAuction(7086843047534681691600954596828, 999999999999999999999970757041754717534669891, 4632413217294387306420544253476); + _reserveERC20PoolHandler.takeReserves(1, 5867323522967690833452503909365465, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(22656913524226599854813278555, 2999999999999999978694524906062142376936010325, 1150583026575632555, 1000981725530583350); + _reserveERC20PoolHandler.pledgeCollateral(87261073642441634572004739780559325558329592531320740532355848115318558056, 88288571577163746211089, 20339538840322365983); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 244689249583838737535406855175792898398729, 1101312327426853476955525685123997000102373391935528067, 0); + _reserveERC20PoolHandler.settleAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 70933014930519011215066028444369203009893015614374750255426209649, 56148630452899937699031076375717151127135790531948); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 126806184757904, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 276274405017121702680718856622483364963625279111236773791630798120737241959); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 91231972320773561854798197419855881182505277913139411391029390985651); + _reserveERC20PoolHandler.bucketTake(1611923459552669005295852646307, 1672916885689879288584443931233296506817865237554616454440019106985187920, false, 1000687840154357838, 14681008931835222909371471182295); + _reserveERC20PoolHandler.takeAuction(120320512466470, 66826876, 121258589448076143124739658899960431, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeQuoteToken(1690745386, 285705033673255645496840615533, 36982281103026371417886691835249, 1000003097456391626); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 37585168485959334223034350, 223873159553432063804057904, 108014735267104528); + _reserveERC20PoolHandler.addQuoteToken(2211033106826983233551879070035, 4652683914580282657012717272970, 1251748784797666971008438585055393465414912830434840447584645898100288070, 2959609911790094890367489662326); + _reserveERC20PoolHandler.drawDebt(3210906560177985808875001453918, 38512, 348163512637700415090879788513); + _reserveERC20PoolHandler.takeAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3); + _reserveERC20PoolHandler.takeAuction(0, 3, 3104728721451915445670343931042543013126468494486797720822897654, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 0); + _reserveERC20PoolHandler.takeReserves(1, 10401520835936128809005590911169375, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(61972874521058240397737011940341061644, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.settleAuction(3, 0, 3, 118212978977740019363736285707536624); + _reserveERC20PoolHandler.kickAuction(22097414882364222320, 2, 1, 1176736177461790639876290653129442688038586945679144721869793556202321712); + _reserveERC20PoolHandler.pullCollateral(1, 102058720512238924007075467908830009577444162635935271499321496027053, 8273106577077999314867652747763131283827270); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3627934548319556250166610966392555399854268392509219131411251704462552, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(1001021813187717737, 4135884838760214062172039810913, 1004495549543218931); + _reserveERC20PoolHandler.bucketTake(68304791236713993362385680239990665987770242596721199306400957706111918743367, 1, true, 68680612453858472224848505166624618580532, 2); + _reserveERC20PoolHandler.stampLoan(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(76981, 5293956536619132147804167747649546578324220979892479109317964468, 67010522317133398114257022024210, 1000001252623209617); + _reserveERC20PoolHandler.removeQuoteToken(3, 2586726566816148784959453626186305, 158255351733009024031045348687745, 23608572749246306117530053267929547625769109088329119072951443831); + _reserveERC20PoolHandler.pledgeCollateral(13074730946622429780760120584, 1000984720898717429, 242073776613573879480191438591); + _reserveERC20PoolHandler.pullCollateral(2999999999999999954573228466055786989304977156, 62630, 1005300450172909783); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 236590599, 562073554095524176617484607680282); + _reserveERC20PoolHandler.addCollateral(1000012790115848976, 1000035752225531026457243, 1000000136939061127, 1816493820); + _reserveERC20PoolHandler.addQuoteToken(6057660435262294582723304345656074383326979531319800993867852685517729, 141138865545253742402893320840924351649554829609933580991774, 3, 3); + _reserveERC20PoolHandler.addCollateral(1423041414088931170907654519749, 1000000605451631252, 938926394338530282, 3377381582498666110033); + _reserveERC20PoolHandler.lenderKickAuction(5445913208, 1526536642103005107268111896, 417807726120163); + _reserveERC20PoolHandler.repayDebt(3514218944120082832168511084324, 1000006282883400873, 1000000006947788724); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 55698506095942986721986756614659828039052089921587093626, 136); + _reserveERC20PoolHandler.removeQuoteToken(841439328961373996976672079194523, 63335861883546127161640198794217854802342487125151, 76537910288900648281069504617154, 4247); + _reserveERC20PoolHandler.settleAuction(501616426745965602228363, 0, 3, 1060735586438192589609183704486846547158710246029157821115325160964723891507); + _reserveERC20PoolHandler.stampLoan(785288349470292787709232902547490757905036, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(155129986606514450691479743196, 1000004786780701341); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.transferLps(360837530935023920006220466, 154008756280238169740397947675, 1803365607275239706100000000, 54064584477834382816879547876407, 2304552856484895136443725552012); + _reserveERC20PoolHandler.withdrawBonds(294256021685752198059926844333705787582603611403192883266336162866778979, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 234989773004586250916773046682917682194964463194253688678415); + _reserveERC20PoolHandler.moveQuoteToken(1, 2, 345887115037159932440480536423469300832319513349147023059673346, 14112182299650770729790314761060206656687681509413800, 915645897814609343899466859184643607787031623377130948693261065); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 318824444411850172704, 0, 2830857407098737438151991779870109683292191495704127831230851511); + _reserveERC20PoolHandler.removeCollateral(5129342909925044867108598569842, 1000981417019759643, 1371765048490799493772200134, 8756842724597963731875919327098); + _reserveERC20PoolHandler.pledgeCollateral(22564367, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5200102947326); + _reserveERC20PoolHandler.transferLps(172894122084405871131725555608260634039661132103921746, 172926370006699, 1295752884326738040993643238389608215, 7359834866, 8667230386067031); + _reserveERC20PoolHandler.takeAuction(18139583338711126766232483444462846487870904520202294798, 17247941047178512251921516963874474933108650681225549358, 203564, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(3844177081578083788849328156648182744791712449217, 3, 175613031095102495838541824175987988859722810993, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(48397367707321633850703795752663486327018515, 2956290772558076097543251663027701942276246074177813058853741985114, 1); + _reserveERC20PoolHandler.repayDebt(1000718810252620500, 1000000490487182692, 1107718487512576519523845490995227579439918880097402685557709791284374309); + _reserveERC20PoolHandler.bucketTake(276858117556978584997641735199556396228871809639990471353476, 29320836863892121870468, true, 0, 1); + _reserveERC20PoolHandler.kickAuction(1297015370355639347368509212608024323087769940, 184182595723628, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.repayDebt(12209837165160990552311093371284262586257765382686468488018111360224815089625, 3, 4276625825444896605270280229728609222975337762399); + _reserveERC20PoolHandler.stampLoan(1000036180947522891, 2113336777441644460624963279); + _reserveERC20PoolHandler.removeQuoteToken(13120099361145920187120300616962162495441316587844832, 68249319, 0, 3); + _reserveERC20PoolHandler.bucketTake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, false, 1998990816464499495011695318103144369579545, 240533143528969886027578469055492633582079667071); + _reserveERC20PoolHandler.kickAuction(2611, 36377, 106374436675558207917941728365939742727801970027318923095315995959333690610708, 40397623285775054410522616628827); + _reserveERC20PoolHandler.kickAuction(848276818276842105498122194893, 1000092232860727645, 875012193403184310755987705, 938959489947311489); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 23062111048437159893584539580470482985700458221852839); + _reserveERC20PoolHandler.removeCollateral(1573037183431471002147245, 3, 395062075411116109854225772379425003581842667430971660584491780172764894, 11984705374893840875803700606891); + _reserveERC20PoolHandler.moveQuoteToken(998268159864304823, 27398496396381650957793047222, 7935879031724674861988677271178, 2593800284379468293594734219007353, 1062737740907244676); + _reserveERC20PoolHandler.pledgeCollateral(61587, 3146, 3835067741139277017585016100337716695949617487588505258112330421056949); + _reserveERC20PoolHandler.addCollateral(1000036284147340736, 3586107270499285571642875798215882, 339502975284756950411353101294878, 5417548458); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1680698790674523, 371214237719697187749012731613797098750819608159370518544810480, 2230, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(1063880363623043498, 3195, 61385); + _reserveERC20PoolHandler.addCollateral(8786056135087286707904570667, 66904, 203921748453560768533449096348, 2740970989783998816081494300042291310523767420573780547092132375668570155); + _reserveERC20PoolHandler.transferLps(0, 1, 1, 387507708960480, 1175882204137091659613207133379918999795546158714589558); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1594156086068936593552199303857101689642, 0, 489061170239886227321607938324652268); + _reserveERC20PoolHandler.repayDebt(1000000382921940829, 22684, 7153515126); + _reserveERC20PoolHandler.removeCollateral(20468450480966236425888491, 1104143164813645379388, 600731166299186424751380, 1000626214678555467); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 9703429823055716020771087226769577174); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5535612218240466192719648026786); + _reserveERC20PoolHandler.pullCollateral(5139086339456454540542512696464478, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickReserveAuction(2, 2); + _reserveERC20PoolHandler.drawDebt(23216825456883126211108183322054009118912740876415094543032172076941662672, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 196496); + _reserveERC20PoolHandler.stampLoan(7647727491147174743139119, 0); + _reserveERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 271824197581988688); + _reserveERC20PoolHandler.repayDebt(27468892097016733219996715000555937545351302745614634749239876597566, 5861063893617052409054478, 2999999999999999968881289660592911481220800151); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 274488341491452557742914195396774); + _reserveERC20PoolHandler.bucketTake(82952206869646906885267911986214695943817706683636399, 1, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 628474376010219345075482649164467374611201); + _reserveERC20PoolHandler.bucketTake(29144067877196846309196466087991, 1005699415038427464, true, 1003973240499536263, 2131976465955262051739989176774596131341041953773756491285373064037160319); + _reserveERC20PoolHandler.withdrawBonds(633935527546172474565980619688845, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.removeQuoteToken(20414693796529470071908122342430702943790637895, 0, 839296670190228894089117318388199984592549728307, 554908716731344906403944067098938121265079919990674573531681500628024797); + _reserveERC20PoolHandler.kickReserveAuction(1751215852, 2); + _reserveERC20PoolHandler.addCollateral(3, 171557266881135194943188092726132328236869312, 1348225122146599011826651884857037969517856218980315093792777, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(1001350470641977131, 2175684730234509376444285876321158, 998107749222107433, 1002059618332693787); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 494327689, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(14062666429539502939012934978899511260, 14368668721328659579837946870156159847); + _reserveERC20PoolHandler.kickAuction(1, 2084638058004, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2875963326429922366725540704010312807619869236650); + _reserveERC20PoolHandler.kickAuction(1, 2, 2960081438686974232119844602154458457070835238768664713300705064, 34163895476069785343224828084); + _reserveERC20PoolHandler.lenderKickAuction(995395339051521852, 66963525736300745706883057669233, 4188); + _reserveERC20PoolHandler.addQuoteToken(440308971525471022766928007097194001183584281818355352360267907052943, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 250667792078948400687223534985709183614, 285617410928967995477477203100435604886950657744492902481127304561832); + _reserveERC20PoolHandler.drawDebt(1441516826848750227660841494784, 96167499170511593420844583, 4121352884561814886442811313550); + _reserveERC20PoolHandler.transferLps(1990602759749829, 2239942424114093662972681003464049870334648065602, 34503, 2491864877267325137200068041970445566480207857531468926971941501615822543393, 2673311205598672254609947682312092382675327325237209261462); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 28320777539293305772643120722116130388330236, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 52890830091351708341800036103504821223828662919851069530012); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 5590868549200765466863696724857645824425621016784649616398042); + _reserveERC20PoolHandler.withdrawBonds(1, 1, 1254072514190254197703095155768885619053653); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 1549964017091800929298012327142604703858671808); + _reserveERC20PoolHandler.takeReserves(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 50107904823601603); + _reserveERC20PoolHandler.addQuoteToken(23361171458076068981128836603405330226002533734131997108650126961008326075, 1434319851610606653519517137528520687910314322, 26416914115894678034488328290548526922545186054788610597, 126412250360024290); + _reserveERC20PoolHandler.removeQuoteToken(67010239793390680378937248287, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(3, 55730391016194262831493275466239284, 3); + _reserveERC20PoolHandler.lenderKickAuction(120966527894645179315177403333074217752560773653920477889053968672021474, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.removeCollateral(4338598300779068788817131872224169742953, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.bucketTake(4968021435830527334899979905604, 19887, false, 12286, 24638701983198572116974194425078); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1588983647949331216059657627566560424682224317959, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(114410960641135753373237848756918661415, 38061200218077384781198155825010020057134552665760612875, 170838117592897665536); + _reserveERC20PoolHandler.addQuoteToken(4975046536747732172325839272355, 1004112559092026841610883297706, 1008052795581461235, 1000675665056967915); + _reserveERC20PoolHandler.repayDebt(6302903540192003043584401933407, 6837340689, 5834754022116424927021714058980); + _reserveERC20PoolHandler.takeAuction(1000272077402378037, 1089546631751227119, 18054665015703146646601047194577, 2216418284553043233617038079218); + _reserveERC20PoolHandler.kickReserveAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 101, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(1, 9847430843512552275264682869812837262808602306585910677021791603065972553396, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639933, 618085947596268622936189870151316252540981212, 1); + _reserveERC20PoolHandler.drawDebt(304616612111806206094463778180758, 0, 7521459505602165952201183958791748497113491336); + _reserveERC20PoolHandler.removeQuoteToken(7096367169155313, 40573, 1002046819249917545, 1005728632554074663); + _reserveERC20PoolHandler.pledgeCollateral(1, 2, 3); + _reserveERC20PoolHandler.kickReserveAuction(55, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 412245434837930745883078264, 2989266502707, 57979528324762314425731098160137460998458801866794545); + _reserveERC20PoolHandler.transferLps(21767633648737912221070817290661, 275283570271069247845362160534, 507673230848976296156660696097738230635761932912, 3360646851448146352115258827216, 2328); + _reserveERC20PoolHandler.bucketTake(5431890928763090809832007718826513076891076059094, 18607796278481668664870254617435981530724761198360951425, false, 0, 2); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 193692453741250711028940223841599845920056376966563675); + _reserveERC20PoolHandler.stampLoan(4377017296415531472645477681068, 994589673894755975); + _reserveERC20PoolHandler.stampLoan(21189136372496729791477604347148469769560769477952986380, 1061920292653747059635515731544687715730); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3149268515511447998943263853049); + _reserveERC20PoolHandler.drawDebt(15257961468142288007372422933588138976800843560438708346234, 2, 21265941160038492775956352855556893957044928); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 15403783389396538637393925666940957657, 54570737862820968304278992606916271348268122349301324307620081566621773); + _reserveERC20PoolHandler.takeAuction(14600570752500796303600711151730, 9198, 33608964650724409842501, 5421845874593154049215065979807); + _reserveERC20PoolHandler.takeAuction(286335385708453031923, 253725978385526, 31571670348572625652678616539986838159263884713253061010310570873810647273, 3); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 38816329898, 124); + _reserveERC20PoolHandler.stampLoan(33932384114, 3838536711789822755499897885651815416930); + _reserveERC20PoolHandler.takeAuction(2, 47341898184536155546279450492489594205, 2, 16); + _reserveERC20PoolHandler.kickReserveAuction(0, 3037386); + _reserveERC20PoolHandler.removeQuoteToken(785200, 999999999999999999999999999199, 194943188092897518037851123099, 157334672102945896662645595304); + _reserveERC20PoolHandler.kickAuction(4190771094060666014636609, 38339649276483098865482771, 884978051240273130727511823765520873558577421397856649888061992805348379, 1161626825501275818); + _reserveERC20PoolHandler.kickReserveAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(1171893046107727185076594017361654517749368789503025075089039971087, 109286543868536855350542442, 1, 51629350150934560839355585432); + _reserveERC20PoolHandler.pledgeCollateral(1, 217, 4628738015841151780571109365300407776270797260568); + _reserveERC20PoolHandler.removeCollateral(2, 2, 9364, 1); + _reserveERC20PoolHandler.takeReserves(1000000008688677033, 1000005658836953134, 49552179679240054654235352853179369804196217633816587929628619443); + _reserveERC20PoolHandler.removeCollateral(1001205588212102123846893534920, 1001364138611229544, 25374631016398902197886112, 1041010669189022022); + _reserveERC20PoolHandler.withdrawBonds(345737321633651333347110847379, 367281079227353143378931676539, 36956692176811849413236607465337); + _reserveERC20PoolHandler.repayDebt(52584279264308288370631400854610, 3410203840410626239635100, 18722772517478930518234674137117); + _reserveERC20PoolHandler.removeQuoteToken(2, 8734051938977129301197476736934872109499570312554, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(55958008300763102172523527238971, 9816899790328321835858530495197, 1011097328099553932, 641777604633521954610472136774, 18781781328336804886998324); + _reserveERC20PoolHandler.takeAuction(1368915778019308483693717047114457767306323967, 666450326532748295669098695300336539379221197942162783619, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 245327077); + _reserveERC20PoolHandler.takeReserves(1025480882978887288, 4043520816, 45016); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3083186805819480290193436059, 3); + _reserveERC20PoolHandler.withdrawBonds(286665592567808327275064617925, 4822325553309219460461847165261, 1999903178615046732235952435296); + _reserveERC20PoolHandler.settleAuction(1313528550950522049, 1002787838228810723, 1000000003705150129, 1000000194565747944); + _reserveERC20PoolHandler.transferLps(262094040021552458601130194348691329576084876, 85681119348349007174623191953411835, 7587453935941760655646216649760903044299061930456016569877896546771, 2, 0); + _reserveERC20PoolHandler.pledgeCollateral(602061081339553762469508162025956, 52537018413684031957831408, 5984230089509606); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 1, 157960533364515556); + _reserveERC20PoolHandler.takeAuction(2134751816442568498706951217515514, 106574624640517416826255981255, 33511, 2576410882008569357895048117058); + _reserveERC20PoolHandler.drawDebt(74519120018169794861017192247885373433026440571892446848, 1000000057423573639, 1761774750); + _reserveERC20PoolHandler.drawDebt(6944565714589143384834118147395, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(45045846009152543318624087455475612416429293542253065823403250528, 0, 3, 52126362860743649010259378); + _reserveERC20PoolHandler.drawDebt(10996180775290569003842969971056, 4371417984170754115739864068235, 1182187169312933723825503486148); + _reserveERC20PoolHandler.pullCollateral(8159161691358637003723373, 50535639354, 0); + _reserveERC20PoolHandler.stampLoan(26320780367678113, 1); + _reserveERC20PoolHandler.addQuoteToken(83028511869131108830353852537802673293290298627782628194556, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.repayDebt(122500799449, 2001252358126299170, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(1006490549339355755, 405530711126031566031601, 31707, 132716015268103697639731740346); + _reserveERC20PoolHandler.bucketTake(622056614277513472567814, 1, true, 2330700257141138368240659525, 345929089421929370397670857217965905727558212670); + _reserveERC20PoolHandler.addCollateral(3, 107230638312688375106509301535266, 2213500350951076020216186, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(10528885045230994758485892192022395037, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6848749485527237817367048370191886676902074873184386327167631); + _reserveERC20PoolHandler.lenderKickAuction(1000016742173393966, 46351, 6262663874660258495718064113107); + _reserveERC20PoolHandler.moveQuoteToken(438885264868613174319299908, 21511697954760273320264279543, 15894, 1000111880285595785, 1003755583542107656); + _reserveERC20PoolHandler.removeCollateral(8588388313120583767664767231635, 1000008407939144734, 242145369702761497620063213670, 32097825599899006967190860630513); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(78103, 6879952666578736554672549491563, 1000001164662548260); + _reserveERC20PoolHandler.repayDebt(60457484181100460037869899740023, 994407124636035834, 60457483823867586445771913005338); + _reserveERC20PoolHandler.withdrawBonds(2323148520, 21166506728493791119711605404, 3000673206430171882532522896940); + _reserveERC20PoolHandler.repayDebt(788028542660420903176356334463, 1005100434819911543, 407634717915617433235398273100); + _reserveERC20PoolHandler.transferLps(250800064928304323293887689550912119951907030237417419, 2, 15256, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 75975708719530691126784266258765087661448127081566876); + _reserveERC20PoolHandler.transferLps(1687400304472983515021569, 3834461491507540469265577391601, 11364428923078719364430616002030, 1000000082342031902, 1006127541485826593); + _reserveERC20PoolHandler.pullCollateral(337579894498062091193460641, 0, 98197103689131805190774729997035663986); + _reserveERC20PoolHandler.pullCollateral(25867442233010635861912426318435665903428496282105810499032318887806641853, 44605173202271590490313974779934951461284277113, 665); + _reserveERC20PoolHandler.moveQuoteToken(87026, 81295, 22558, 46238, 2576316784824928033396929874504); + _reserveERC20PoolHandler.addCollateral(48503, 1000000009094720779, 1004309922898256712, 47107); + _reserveERC20PoolHandler.lenderKickAuction(2253527010598305859781678907751, 383877919025901611997933325901724, 4975059730086397531681086983810); + _reserveERC20PoolHandler.addQuoteToken(1000013747328007945, 71576, 1000000000000000000000000034584578024386238367, 971534801001629407776509336096); + _reserveERC20PoolHandler.repayDebt(8442440544956794907282322855166, 6811700860, 820102700004552667354174726128); + _reserveERC20PoolHandler.addCollateral(1000024145665489069, 1000000775748074049, 869222594397863017036593380320365399911969230368898765932591237069018770, 5051458034449526283961592168); + _reserveERC20PoolHandler.bucketTake(907972555405699093016175900046547996708003697, 20140937336309778594508341408594358987445189203087371653230176291810194234, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 387107, 26664227825536176); + _reserveERC20PoolHandler.drawDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 226332312885315619132079019349560747734); + _reserveERC20PoolHandler.removeQuoteToken(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 832035604800607412934697262077936, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 85549); + _reserveERC20PoolHandler.kickAuction(118258505927, 75247987435166083758272909028145260297942472076531013686649767367729573299, 2888360713536802387178566861462945294257966866581459954067537139, 730965874642711301647559058556251924922308905979920095013); + _reserveERC20PoolHandler.addCollateral(2916314569853082520456419045105, 13202000551855019465089475099000, 213954712181454789130905, 25541548270760513651074662); + _reserveERC20PoolHandler.lenderKickAuction(2, 1493815493434713606454232196825684, 0); + _reserveERC20PoolHandler.drawDebt(91564557866815564742285, 6068697873693419802793900300, 29167832539314141801622711483571); + _reserveERC20PoolHandler.kickAuction(3, 35603619198358679489456034804383655900250726, 691973842662359236194425989673374800, 47946439185562010422435904048053995478327308934666623369657); + _reserveERC20PoolHandler.pledgeCollateral(2151166405, 897896697522191074873780754, 4706028289050285510562294944226); + _reserveERC20PoolHandler.stampLoan(3079355532962209000169509481289, 948057951604779815096463705239); + _reserveERC20PoolHandler.transferLps(2, 3783541153610861778154628863067, 3, 304447424894779157164928050188577130376640074417840, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(33466699013305550, 14813768892300376943365078855362807191014279776296428040073932644); + _reserveERC20PoolHandler.kickReserveAuction(0, 56260009774484686480874747684654905003281747407509664364011180); + _reserveERC20PoolHandler.removeCollateral(2606, 1008272964158266121, 800834696468627618771598844428228, 374898523848651639013893204451); + _reserveERC20PoolHandler.addCollateral(1239389488110506227160, 2, 2, 879450526103095856911657); + _reserveERC20PoolHandler.transferLps(2, 1, 35119222713811962054247802014119, 2, 166471707889158884686171602800737167172335474082); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 621437259080642426771282905544542224171071149549967762168096447061365189, 0); + _reserveERC20PoolHandler.withdrawBonds(2, 3404406, 2); + _reserveERC20PoolHandler.addQuoteToken(592179134212950879536695010077561983461192239119, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 748043035231052190029189567269001570459181); + _reserveERC20PoolHandler.withdrawBonds(1201549379626866004, 7999999999999999999206113023429093253524034374, 2304078802424401755487723291); + _reserveERC20PoolHandler.transferLps(993936660890989690, 62032923996491108680767327917383, 1001474911475454730, 2005012622667193104197950300378, 59442447504760549240664215); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 81079578217545136780944771415801717972546, 0); + _reserveERC20PoolHandler.takeAuction(600341362208295034470457985010060291, 32913389698612398105634443, 26491527967829030, 9241); + _reserveERC20PoolHandler.lenderKickAuction(978449952658149666315813453148120771159062, 0, 0); + _reserveERC20PoolHandler.kickReserveAuction(1003339994644968744866529499335, 63228898697822506946554612); + _reserveERC20PoolHandler.kickAuction(1042126268342118962206830853451110738903, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(1221115164397221256168541357, 998613057433187383588, 3, 84222285199947005666803994); + _reserveERC20PoolHandler.removeQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(1509982016831934032073873530801133066124783058, 0, 15859819949406471198134904342876, 3); + _reserveERC20PoolHandler.lenderKickAuction(133453648, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 143310283311263012341328004215); + _reserveERC20PoolHandler.withdrawBonds(1109139166560309353230464647200, 552580429427427868367593774701, 8254327868849076220050230239); + _reserveERC20PoolHandler.repayDebt(999999999999999999999963832724247867482103026, 6066710416, 83188903336392743593022707345); + _reserveERC20PoolHandler.moveQuoteToken(174510704294704467997534318281, 1000095440262800048, 1264998079880641193, 16924813017516943966899873764, 762732192277941689357311018094612); + _reserveERC20PoolHandler.removeCollateral(355, 142301112611217304386751644607211307266509327712026705679, 2, 572250322592935807966062434282731623979); + _reserveERC20PoolHandler.kickAuction(20474794295219190230704692709231902694801617585241732939526790134299022143, 3817292897, 2525042395893725647986038757652546700309513339, 1199038752191063287751788956988589822754295548319691692173158359); + _reserveERC20PoolHandler.bucketTake(1000980328730603622, 7006283416, true, 2042557253, 1137172746); + _reserveERC20PoolHandler.takeAuction(61827, 105016699907187218921813253008, 19364, 1000000051963131912); + _reserveERC20PoolHandler.kickReserveAuction(7804601, 4365485519229875758787312643215952471023933176); + _reserveERC20PoolHandler.removeCollateral(1, 3, 5453128186631806878874438972956854344651788855385931800079171, 1184961674168331659158042652167308144807706600); + _reserveERC20PoolHandler.takeAuction(169315151215339420432429495, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.repayDebt(42623460471550128269603375358522, 4968825545301293080842495807302, 5814563856811420577978); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 7457964756730795265953891123472155483170055, true, 2, 30548147167945111984); + _reserveERC20PoolHandler.kickReserveAuction(79042906163181225429784564518710762377072573768883720864461598149978023752, 0); + _reserveERC20PoolHandler.removeQuoteToken(1528836510615339185191218597047065208025250981316317768933611407738127, 1287408802, 3, 22529733265207608843755401321778263971085873875114263568); + _reserveERC20PoolHandler.kickReserveAuction(397161360787400031883360975852287015, 1); + _reserveERC20PoolHandler.moveQuoteToken(1000049198437184909, 87281072709140746557192171573636, 169780301346388695275201051984, 1000002550061111067, 22758918328472785533506371906); + _reserveERC20PoolHandler.addQuoteToken(80965704122472632215112189716201, 999983388448094111702553, 1187240320525807874533394670613, 10761685205274995304275289106815); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.moveQuoteToken(1001349178192793079, 1068550650333496769, 7723106977289158334180784, 61761, 18456231147748292847333311272); + _reserveERC20PoolHandler.kickAuction(0, 52032236508705869687643471898457464187733935475950676827748523320844041904, 84429917397123494328667838827010, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(5585436182931816314726869090728, 3423256480763031628571944436512, 26934011133879890092890811351609); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 6, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 4714560712676365848972967211411033707148930138733945968212); + _reserveERC20PoolHandler.withdrawBonds(26122580599549787932905427415057, 20274, 23276931429098410943811335122570); + _reserveERC20PoolHandler.takeReserves(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1320340952193666854997192826437118421705921277109282324674406059); + _reserveERC20PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 45724826810556462379443300, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 695); + _reserveERC20PoolHandler.drawDebt(0, 3891181659315627198273962279992792, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(2063814980, 1000030848019771740); + _reserveERC20PoolHandler.drawDebt(6149, 2708532459928841298520528497762120264423753383283170825276796539932691055, 5050684524650168778601866487); + _reserveERC20PoolHandler.removeCollateral(1000000037722298799, 38237453942614834436542204140326209788668044353742912528592450563, 6960601125, 820027943752221227800775977); + _reserveERC20PoolHandler.lenderKickAuction(60473067605923035967564058843524785071061531243957002135, 10363030980160580015981784570509381754107607066254444325478472, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(1132922717784932128867418627681, 5859556092287014019329204730, 58067); + _reserveERC20PoolHandler.takeAuction(1571546641633373548731018361, 80517, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 73421747847789385458610069633558381331169647734286959047483545671928870336893); + _reserveERC20PoolHandler.removeQuoteToken(5327327550440163392089660123240164400108509072592928646, 44751192983, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.moveQuoteToken(586314509646088305950934105913, 1231223593456843128, 678163291299756267420605063830171841405155908586390015969240153802039923, 479233979244437710629276210, 84174725625479860); + _reserveERC20PoolHandler.withdrawBonds(1000012961900429275, 999999999999999999999939984122174692707862128, 83743933267735856675348401143); + _reserveERC20PoolHandler.repayDebt(3, 714805216846112658462128530535128841169345225070794744, 365251833491883730768252072565577026206978972578537655122); + _reserveERC20PoolHandler.addCollateral(1000000347788561783, 2766740661609912083727623263164, 1000010882976013594, 65637725855278617069529836937064); + _reserveERC20PoolHandler.withdrawBonds(830332429124859455115709326648, 2, 8753406283); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2203715517569755565958082713353516240265, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.lenderKickAuction(4518454591429082558022439130779, 65464796759824479898320615616108, 1850005800738143068215751716); + _reserveERC20PoolHandler.addCollateral(396278906851817509038491, 4361302365111922526686118122907, 1720895327334107275726564787006657543582502151057460750300517340952122615, 6338865402650051371067098466743); + _reserveERC20PoolHandler.removeCollateral(328027, 3097258018568440844161512188604, 1, 3); + _reserveERC20PoolHandler.pledgeCollateral(8789141396228423, 45944, 31142725759212449682382006348917); + _reserveERC20PoolHandler.takeReserves(494844915985816, 2, 3); + _reserveERC20PoolHandler.removeQuoteToken(2876572417099019295338560651550811921506335023764366114075, 2252094551596299854233639, 1, 1); + _reserveERC20PoolHandler.lenderKickAuction(4980490737839597568828586716077, 7108692850833846486500094293470, 11312837563916894846787052629250); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1193854001405444807256820804, 98174994253577931512071902411038548548699560604804446622600574605650743); + _reserveERC20PoolHandler.kickAuction(38, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.settleAuction(118048446217743211948910, 2885187062888106274407040647968198738813423416807712473000230019687645183, 8011713811834196494590730871, 1000093735135764170); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 77288880224646844044681281049230954, 5043124246073692529731624494766907752956752740373); + _reserveERC20PoolHandler.removeQuoteToken(1, 1689754446, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.transferLps(158744342582539554039, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.addCollateral(526, 0, 187304828011577, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(1000000552864931760, 1904371846); + _reserveERC20PoolHandler.pullCollateral(1274206542572886504065602899951633, 1000000008428027442, 8511729778762480540008253749002); + _reserveERC20PoolHandler.stampLoan(36142, 3018331315901950829180); + _reserveERC20PoolHandler.addQuoteToken(1000000270524426967, 61781, 4215019373765379494208952688549, 16901457509203721508664082009147); + _reserveERC20PoolHandler.pledgeCollateral(23619073793120186561095334222218, 12569209533849215166215436332176, 4116603123854602); + _reserveERC20PoolHandler.bucketTake(9004425041342441644584486813020, 7872591834224952900574348875, true, 1000009091311761214, 2671219820087620490500300852664946); + _reserveERC20PoolHandler.kickAuction(10513, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.removeQuoteToken(1001331563591481018, 2783899063028968888610816474, 54957689962320719747831258409040, 43186601286164427919); + _reserveERC20PoolHandler.transferLps(9486141179653077526865324414734, 79350, 1005939457710475767, 60299283790723095091294725701, 8740); + _reserveERC20PoolHandler.settleAuction(74854305495536886546292464002953797059234262074, 96207318507596855796661761999724184114890556637779596624002088202, 25298084647712155, 553293433900616610076350447394073370879); + _reserveERC20PoolHandler.withdrawBonds(3569553265886, 69529695790666470594781970886352756326246819995551574354570691588589220, 12514); + _reserveERC20PoolHandler.bucketTake(36711310706606894576456700222171, 1212089167768731305817799260626, true, 21737653016376164542478545792475, 2207399266248274085854603930998); + _reserveERC20PoolHandler.removeCollateral(2867584873970188562377976635775377863186591029881164578176363772687024127, 2720456827354476685097, 2766109637043422312593, 1183794805505521197); + _reserveERC20PoolHandler.removeCollateral(4745271937431625418274656349360, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(20414078356304809614523224017988158324803253137144, 40809037530853570593947971620425231, 1); + _reserveERC20PoolHandler.kickAuction(3837805429641374761697425326910, 1623974360306660142, 470076312335522230, 467872343823368425450000); + _reserveERC20PoolHandler.bucketTake(3, 318516373833645154894090179888510816982413766214714628318968784820, false, 398, 4968735352349761185556428078374968527049128931675495432612213310); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2211451680394148733039740742199642, 3, 62239804235); + _reserveERC20PoolHandler.kickReserveAuction(1058378937253741057336757587518, 28878303812141415810690352519063); + _reserveERC20PoolHandler.removeQuoteToken(1000000550523902843, 1000000088293068803, 27202182203351292419551995763421, 59547748983539231886386206553099); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 1, 2); + _reserveERC20PoolHandler.withdrawBonds(2393179093521853443364985964000557, 2, 2); + _reserveERC20PoolHandler.kickAuction(519876, 82581576631011301211841269781160332625267854583083, 2258077943881881346304731779617, 45817554657127659374575595775951107784914715548859956); + _reserveERC20PoolHandler.kickAuction(154309907380016466597178737767937750654651, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(284518828502635376026, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(44363727992126897303546643942, 1098525506176460445065212412908797598641771497804294856469970, false, 708251556740591, 10559255087055561624); + _reserveERC20PoolHandler.kickAuction(1000012671570959139, 1000000000087257170, 38797105620678870558350693216445, 37125334347383282); + _reserveERC20PoolHandler.stampLoan(11640859643629887767581824614715750853900236564293510212121921316471134985, 2); + _reserveERC20PoolHandler.removeQuoteToken(1000000021913239521, 4819297637972443007695188789306, 24573312352225350130722940667422, 54820); + _reserveERC20PoolHandler.kickAuction(1, 36245867680674429697153478768850832667191710697921347375, 250029689904130, 88991207847703480008687624030220683); + _reserveERC20PoolHandler.drawDebt(3448374069976216402691109255984, 1000004730321927647, 21948009263242186924151524900207); + _reserveERC20PoolHandler.pullCollateral(2, 366214714237101416172956830445893681707776372278867509106, 2); + _reserveERC20PoolHandler.lenderKickAuction(446261840228918588137292204, 1000000006246061258, 13301915942573982484254490215481); + _reserveERC20PoolHandler.kickReserveAuction(1001171938096391993, 4357); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 253, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 113996189897021835369792308915634753821804); + _reserveERC20PoolHandler.kickReserveAuction(2, 3); + _reserveERC20PoolHandler.kickReserveAuction(12579159519494983096, 1022756499455045217221871945170); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2942040316172138021956336772356835251501626042933931418250834, 3, 2); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3, 258122506503561914829704058558575); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1549441198556118762374680780386782160170325598634, 248166678288184450393854407605547481033267172870673846382385828847057364034, 0); + _reserveERC20PoolHandler.takeReserves(201676470540632529368247020329, 5270851581694449, 99999999999999999999997031415353249648138717400000000); + _reserveERC20PoolHandler.repayDebt(45644941749970, 5899263011503671581392141279195942041803993496833069580627967092105518980, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 67610109845756317134127248375747868268363189979952328934971794642011849466, 769270904112667556056342643266140272, 926291202701922784180368896957580344716625, 1); + _reserveERC20PoolHandler.settleAuction(160812774902753874431713747494, 24815272185660738140977058830638, 369982832585586917836619, 38700); + _reserveERC20PoolHandler.pledgeCollateral(45586880029727146345948445307348, 947801927546478368134887406841, 399761983733281237801326049325); + _reserveERC20PoolHandler.bucketTake(831696621988124069734686371948, 946822283118507940702357607756, true, 1441496727959246765909094259109, 163945287032873498839323968930); + _reserveERC20PoolHandler.addQuoteToken(6592265110, 24330273141066717150052919834195, 1000000008911980836, 724793600408808702594619369079596371975045740536265248575721177027058399); + _reserveERC20PoolHandler.addCollateral(108691931, 110597401432455733200041689470, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1442235302630072612235736); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 4651958931712529105364092179268203, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 292387851620731189071061461212384687); + _reserveERC20PoolHandler.removeQuoteToken(6529249900932267887827560118529828778080295070073553226345363208159068573548, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(16664951689007674293303499, 526801263971326003849728850456837, 1000001137609666088); + _reserveERC20PoolHandler.removeCollateral(172, 2, 1, 3); + _reserveERC20PoolHandler.takeAuction(1004187905825896319, 62290898789733868034816719, 22431, 434668910150178681959726124622); + _reserveERC20PoolHandler.takeReserves(29913859216906427332175074634332341, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(1000000057042506432, 63840, 1067353289199278595); + _reserveERC20PoolHandler.addQuoteToken(0, 0, 399, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(999999999999999999999940194815292356192200690, 611187691006233053900049, 1003836580682836567, 1000981409788602305); + _reserveERC20PoolHandler.takeAuction(8337279796860801835351968325370524543796202, 1259343308510755366245367554639692043824454714, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2032043722975422726256); + _reserveERC20PoolHandler.takeReserves(89392114961388530607988083, 1661406921635527251389655270, 1006210670247664309); + _reserveERC20PoolHandler.pledgeCollateral(1002144183729326474, 1000160882835942313, 12237666693436489261246343716); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 2, 2); + _reserveERC20PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 1, 18013407); + _reserveERC20PoolHandler.addQuoteToken(1904241945194175165132288, 89988078007568269730710066497379776786641684150, 1117603075733495271147545476078495236409762140056034008528, 1); + _reserveERC20PoolHandler.takeAuction(1009500223878166146, 2694584810027996860467, 30303266350003405936929389480316, 1000000032357436310); + _reserveERC20PoolHandler.kickReserveAuction(7580453821724212167643735177142, 24345577823518136077898773639949); + _reserveERC20PoolHandler.takeAuction(3721298244526421267032141245, 644621344621898462747153876852, 70041626171666891827588623, 1001429502062176502); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6836515093671405024549559342059363748446160606448820248173534142023306, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(2603736939789263115240752259227716559309623368572591871371306430265614894, 1000021541504493648, 1542, 2999999999999999987712294825097573100781667636); + _reserveERC20PoolHandler.pledgeCollateral(2072139360057, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 195280875296067883165114710657411184157915670039985691743, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(1, 23774406953, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(74580, 1000674253001204737, 2210704054233713401266139607771); + _reserveERC20PoolHandler.bucketTake(192253315806, 1, true, 461473245371157216379184236753, 1474933280568130468); + _reserveERC20PoolHandler.lenderKickAuction(12968846814927018652959363, 21738391984009007131003161740331, 1000000013085031613); + _reserveERC20PoolHandler.pledgeCollateral(105467896147870442289774827, 2007183994386945913639260024353, 1000089682294975471); + _reserveERC20PoolHandler.kickReserveAuction(1002088931288385191374956964508, 7429493719389936431368409283); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 315293812298672669946678601809858111391485061008744131845755064586, 122202779609579118015707958177122154770724954012277192797053); + _reserveERC20PoolHandler.kickReserveAuction(1999998173518997766912531354431, 123577141036714556415602169109); + _reserveERC20PoolHandler.pullCollateral(525745846634917489858063402725574819, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1079836579758016971666172948543109041054449413784); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 622938324267442899937560207, 2, 25038098504932755349780404723906179936348467985813130078924, 70719587748119189912461581557264057859206698807738857300942138407609399508); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 2244796239171482472820271900612520860444567676243979432968); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1369036162070632261198050303346216195004795927458705598803, 3); + _reserveERC20PoolHandler.pledgeCollateral(2948032423628386, 51593793238662461058055912389519, 1091355889181041612); + _reserveERC20PoolHandler.pullCollateral(63465173554277131480157290923974, 6537728582982146884210796427163, 1918726594); + _reserveERC20PoolHandler.addQuoteToken(225905196377872536279908181, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(3010846034, 990160924094182440991400893921, 160990646432034011748314675065); + _reserveERC20PoolHandler.drawDebt(456, 1, 11160579625097020813926654); + _reserveERC20PoolHandler.moveQuoteToken(1056624005474059941, 1000980801575306265, 13255888010788847394015178377, 50860826508412798451692418147456, 1000061085580859384); + _reserveERC20PoolHandler.kickReserveAuction(613011912938087315064906241, 1000000000000000000000000160431862598083329208); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(1000004807202331064, 2999999999999999990360975866771812745113757373, 628474376010219345075482649164467374611201); + _reserveERC20PoolHandler.addQuoteToken(1000000395142115685, 2583366705606041310071679628486, 1058758015277015405, 587688321707305496414098312062325); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 14799, 0, 15); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 16057131449364753956741513683761543887051246); + _reserveERC20PoolHandler.transferLps(62824, 152286660812081633767588247655, 1008593916265302167, 561890941827786419758794459507362, 1000706308775721775); + _reserveERC20PoolHandler.takeAuction(8442440864982568545426920413015, 2999999999999999994259080964263716084159579839, 3042, 11719899670829776265773120342650); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 362937639159221571138644785047034381958349852034, 2828521209808026516698161316785035036810); + _reserveERC20PoolHandler.kickAuction(904002374080711292177709012904, 1001583659906591113, 48739583890664125302767930494, 18897642321472850314760); + _reserveERC20PoolHandler.addCollateral(25802882568132079882967698793930, 18744036532590672050789972462101, 1000982793631270140, 67816299344940101952077082806597); + _reserveERC20PoolHandler.drawDebt(15986726937524602300682259654953143293457933950998087000522192, 40076604386995497980256987827837488, 16811280091235510917900186503577158422215956944238305454620644462685667); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 1, 2495943252647410326889355083378186039873296183891308388666858988); + _reserveERC20PoolHandler.takeReserves(837339184218939024, 3, 10398263879194206013); + _reserveERC20PoolHandler.takeAuction(67773895534044619619042299216214, 4267922681723251118244429339, 29168078540886689406844, 694526359354754352435612941708); + _reserveERC20PoolHandler.drawDebt(1074855233387447144262731048416560191471841647236869078285324571867, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.kickAuction(2727921949201563498409, 11971, 7182022876129305414505958464309, 48381371528453286555465884814049); + _reserveERC20PoolHandler.kickReserveAuction(0, 2148840721330); + _reserveERC20PoolHandler.repayDebt(3190319427080262917214234211201, 30586, 1279); + _reserveERC20PoolHandler.removeQuoteToken(6014576498997119981549108775314065811830094418450331759992697480159591486, 1578807824271424099872285390392903087079146853194013998618, 253, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 0, 1); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4111877490517262368658504228984822841958499255600895295713541643316, 3106838380123851309741235331516549043955773336840505848835477803057326535270, 62593963834525386983); + _reserveERC20PoolHandler.addCollateral(2729484423846993454565, 44039382522490930907377161288932, 5420915650039017965270424377043, 1001349578348292259); + _reserveERC20PoolHandler.addCollateral(1000000110889148715, 8053016244084609874984009827001, 46940737838975075949100710162, 695365185869716777292044993843943052563732228279399537684518681921729536); + _reserveERC20PoolHandler.transferLps(1631905568508385245010212724497, 1000040785464193728, 11895633501923418603861095113442, 2521156145017917379813387706632586499186412291206136454894074997753686144, 52927); + _reserveERC20PoolHandler.bucketTake(420251080771839228515098344, 32722059183, false, 30404344428701407561766, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 791824350741280867562752986394192679429751157443256659850786749, 1); + _reserveERC20PoolHandler.withdrawBonds(7993497962324570382676071417724299798383768377831036, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 8105758475667608393789945667167320461107, 5468914394313474431784906801228847568025041); + _reserveERC20PoolHandler.transferLps(15636989336669455237402293, 718667592837694482561465018308078020202984628933740732418954168120714793, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 458402222301664020308932157646966351294871834320005578492783320237199, 2); + _reserveERC20PoolHandler.takeReserves(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.kickAuction(169833092536974500284467895680592524853477880294, 821840217448426999617870021451632, 11671109262425393723857034721745, 53303104746773803231144346507680); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 30357250530129469278622585161888915584315); + _reserveERC20PoolHandler.pledgeCollateral(777386531459425692636024486, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addCollateral(20258, 6926656947372008494717634024961, 2916217957479835966585379694258, 1005622610772534773); + _reserveERC20PoolHandler.bucketTake(37669941396295291914195128782232979, 4986440865183950355791322442599157100985631544074973207, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 338655318574829243411565071534457479461224098); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1355706557434773616249978500705227163950778641103923939, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(2, 82922767681961815913969573027098525482999016024923978041645719); + _reserveERC20PoolHandler.takeReserves(145930200228049421805377049400559954448, 596339575374068, 8132298724677144466917162750); + _reserveERC20PoolHandler.kickAuction(319479741140498938911343005415475173781979327627, 0, 938262953834057, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(1564283878486217495619, 3, 258461451943350855223489049684108236046243149033844, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 9962317071068438291, 2); + _reserveERC20PoolHandler.takeAuction(2576301065632633833685833707133, 57848, 342855497705162486493123510885, 99999999999999999999996829658373828414563460200000000); + _reserveERC20PoolHandler.pledgeCollateral(947710397737739724356279351690, 255481183637172143483314454752400, 6790832264348235); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 192966698419279619191226457494115355334621573079489761621486, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 2299550745449931382600, 202467825645558956607660232098256577058748545220053497); + _reserveERC20PoolHandler.removeQuoteToken(2, 3, 71820935331702844703993, 2); + _reserveERC20PoolHandler.addCollateral(4820469120457975462, 41244527350352736163804325080951508890337777247946054353694248495624151603, 0, 242444131635679); + _reserveERC20PoolHandler.stampLoan(1000000007457979728, 402231442413151252929454823219); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 26058236277291184092477793724328, 2149907997378644376428795394238224187805); + _reserveERC20PoolHandler.stampLoan(16602533592405197879170490635412140569589556123879878570605460, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.stampLoan(3, 551972456671297605304999675198717150167280558303087868517911); + _reserveERC20PoolHandler.removeCollateral(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 661900055534860801487085601630393131937857429649987281390295); + _reserveERC20PoolHandler.kickReserveAuction(363057585187966493936124970159, 1011041269939567411); + _reserveERC20PoolHandler.takeAuction(51920582932841, 10648357891726204123634649777995390678283335479723, 54733529322909119969793140, 106949151702925662211369141); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(1, 25526040644763059637307877749337117201322176077, 1); + _reserveERC20PoolHandler.takeReserves(24357078989347692858846681514012, 975526201077040510108068196, 2999999999999999992120190598082336150126780622); + _reserveERC20PoolHandler.moveQuoteToken(43291, 1000000097949506156, 858710097192418662377397903, 809729181733052088380265468966662, 74395); + _reserveERC20PoolHandler.repayDebt(3, 218122165099039432247734129213640498890012190405661764409496333870, 0); + _reserveERC20PoolHandler.bucketTake(0, 195216618520009783739935135375492707673216275696068917315506370741636131100, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 12580363265367633657974871995416838708698018018106045811629469410020716522076); + _reserveERC20PoolHandler.removeCollateral(842391628807320766415178452219502673456807, 3608281288124515339734613580159168446342810558182471523602165391250, 6619006373758901175737251924611204000130472322, 140019179142); + _reserveERC20PoolHandler.addCollateral(9816898328541130514086282946087, 46847, 1173939165808994431, 5114); + _reserveERC20PoolHandler.pledgeCollateral(2, 6800747623687062363469269894803433, 1468528); + _reserveERC20PoolHandler.stampLoan(1, 10538151865118779821751333713762575286932198306555087); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 40785508735932358744561229211840268606060072464377095962646897, 1898896034455141764931179809441210001640778891422609758384, 319893764510655820728898465504604244); + _reserveERC20PoolHandler.pullCollateral(460322821671690554962677156826999589973311385834949537359488106854138734975, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(3, 194185785662616290914213963804533463932434701043701980022770550481734); + _reserveERC20PoolHandler.transferLps(11902598514904135193900561358982681286573577265421934521807390222, 3, 35, 2241208110996955801392533364738338866470448583, 3); + _reserveERC20PoolHandler.bucketTake(946983959584866146037298682444, 1108823921, false, 12553684529588013525429183303057, 1004450509362478453030585426449); + _reserveERC20PoolHandler.pullCollateral(3, 15413225105851201448885849654904339819689926906310077158401, 1); + _reserveERC20PoolHandler.kickAuction(5, 0, 2, 0); + _reserveERC20PoolHandler.drawDebt(2633630325770906048313, 18709277434573487870923813624, 5061); + _reserveERC20PoolHandler.repayDebt(3552841309, 1874885933286628704028695, 1058255879450925572); + _reserveERC20PoolHandler.pledgeCollateral(2352571572317512670161271046483, 17439055418607451997135470509042, 288463768656268028180998343155); + _reserveERC20PoolHandler.takeReserves(1, 154961547127568460176410386, 10624021819); + _reserveERC20PoolHandler.lenderKickAuction(993735817356579422, 1013260151009894091, 20147658771077402519536072989589); + _reserveERC20PoolHandler.addCollateral(37, 1, 7864005369864, 1); + _reserveERC20PoolHandler.bucketTake(1, 39322496761111417088463009278342959653927643, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 244850764498548517429766372038765922328145666468); + _reserveERC20PoolHandler.repayDebt(33074430557352, 13787587653564403726340823310392371547143, 2); + _reserveERC20PoolHandler.transferLps(1071290415, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3198253558750269469284991829408498634148549791006857389, 3, 810491790173); + _reserveERC20PoolHandler.moveQuoteToken(55384519, 66350664516002455123654608578007, 214882001257389269899, 4810970831355448713222904632201729, 4904994656802206880969557241635817); + _reserveERC20PoolHandler.settleAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 140716190861988164791711336517062866541842601627692701018518159678035, 68819647360449052); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 21107539132260403907539609498611459375023394, 4357881740737029758617734699285021644800126178408286); + _reserveERC20PoolHandler.addCollateral(6514757265343773625179787211, 5831013404001677363723998804542, 1000000178938372173, 34673); + _reserveERC20PoolHandler.kickReserveAuction(2, 3803505803708604747915540554931381551224043714226794843550163); + _reserveERC20PoolHandler.kickReserveAuction(306923291281800465079719418759111, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(16406, 1000981384296628190, 29227502153158268512770358323); + _reserveERC20PoolHandler.takeAuction(2606774304, 390996151347802694761854480393, 23481471721501466260074779, 23070549650593090483421746068589); + _reserveERC20PoolHandler.moveQuoteToken(1150351915044486490276935423977045936371132502117947, 2, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 213671296001881892259897327275498330870214756413989267997504104466); + _reserveERC20PoolHandler.bucketTake(5375138024515902353978120, 301, true, 105127285814, 1161716858633425863044314907244781433339667438869861376705); + _reserveERC20PoolHandler.takeReserves(53651823959272455877526987485225, 5874605780, 1000048589155058332); + _reserveERC20PoolHandler.kickAuction(3, 1, 833, 27298175283912808437975469528177690780225); + _reserveERC20PoolHandler.takeReserves(8255376897, 7177703417140577332737337586823630787612266, 0); + _reserveERC20PoolHandler.repayDebt(4822552480119158985615609841875, 23305985496842136154936223468881, 82425); + _reserveERC20PoolHandler.repayDebt(24551818451517156356918410596947, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1105342174187898862104952664687040125595915530279315464479188); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 3, 0); + _reserveERC20PoolHandler.addQuoteToken(11814882276523291678516561826229826839037783280004625911890764471217120823473, 50856, 6438446186649495033235608119809, 1002059445518142439); + _reserveERC20PoolHandler.kickReserveAuction(234102981318079597593683459809, 67779209334009041799412171091832); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 8152909833898354947467426337298861474334121718893140401471, 195); + _reserveERC20PoolHandler.moveQuoteToken(639349489078140007507993406028, 11364218512960926300418925109, 1939751274, 1009298798852352919, 530244555296966652491944); + _reserveERC20PoolHandler.pullCollateral(369022051306377788655358263775397298536050999168518421850222, 250631917719188905577786271214467397276718, 1); + _reserveERC20PoolHandler.removeQuoteToken(471254370320225031941033493, 3730713604314761651962416144300, 1000002599800369490, 10149912124389723923175760315); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 44678096); + _reserveERC20PoolHandler.pullCollateral(6, 15546575513360580857, 159147454782447650810261435254957409); + _reserveERC20PoolHandler.pledgeCollateral(53303439345456184243338558300654, 1000000818028681369, 5599249047526440237875518421436); + _reserveERC20PoolHandler.bucketTake(246785504970845393181, 125445943340495521500310, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(2656625060321240845792891238, 145502932454920242752544, false, 10538324865148999998694438, 25196222222654240986837302651172); + _reserveERC20PoolHandler.moveQuoteToken(3, 2, 54488031684013702, 1492376255583703445981465736635424038350642949138675061620961, 2); + _reserveERC20PoolHandler.removeQuoteToken(37844870270509841975802, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 46076834850158396461184252674071829819354937329); + _reserveERC20PoolHandler.bucketTake(267111144273558194321780773070227555329027, 883071578906259767063394376502075454613, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.addCollateral(11850368329196612147093426, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 779297152795049366982728354048664841250510108647161326693917); + _reserveERC20PoolHandler.kickAuction(64448, 75111, 1000009750427266504, 2999999999999999965967537892475072901478593506); + _reserveERC20PoolHandler.kickReserveAuction(6463640613897200741929788531666, 323999718779852703526310165347212); + _reserveERC20PoolHandler.lenderKickAuction(1010942191978472952, 18369015820869510459422170381857119461353837798153550572407407877, 174677146587700726422409092895); + _reserveERC20PoolHandler.kickReserveAuction(1, 2); + _reserveERC20PoolHandler.takeReserves(22448, 36982279779277924035373265021808, 310747086456839532453931469889); + _reserveERC20PoolHandler.addQuoteToken(54877, 1003806654562382340, 87078296544357038479205555445367, 309047052832255640403759800407); + _reserveERC20PoolHandler.repayDebt(79307257836241528109762429909485, 1, 3); + _reserveERC20PoolHandler.lenderKickAuction(4930889100161601297561064942482, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 8); + _reserveERC20PoolHandler.pullCollateral(50281525410820122775333449477616578857933987482435835641658967, 1, 276474022454942119196611128625802759389514); + _reserveERC20PoolHandler.withdrawBonds(160090364990088688834970546876453796, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 377685080488598845312722996670781514560650527); + _reserveERC20PoolHandler.repayDebt(156363260693933388916190331100, 3000086292777084829684457116337, 1000005270900781430); + _reserveERC20PoolHandler.removeCollateral(2044653850284826225854573504810001699146, 8166418984381113, 0, 2); + _reserveERC20PoolHandler.removeCollateral(8471469149962328888676615150081490505748940, 2, 0, 337637027774906254466091678135169006807902716898834749682); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 208522815061540899557127965522298312637832497831604291484570373852896849039, 3); + _reserveERC20PoolHandler.kickAuction(1000418185077845990, 2359166406333569027961605526077, 807998978092197635346517410000, 66058923511237812685866718459293); + _reserveERC20PoolHandler.drawDebt(2942404361307883005637663519179, 1123779210637498099, 1001428698329267048); + _reserveERC20PoolHandler.bucketTake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, false, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(214703004983105330894277731670, 3324487108, 55658117282835725961270482226583); + _reserveERC20PoolHandler.addCollateral(1004300935096254929365382753944, 135260572349320788539090592508, 48381251604941923019750281562386, 59942192562582982085589800000000); + _reserveERC20PoolHandler.settleAuction(175969410864992962490896360726, 1556278057818126165496286473346686834087781172092318473046508350, 39774201859916652809991, 209981119455543870517172475); + _reserveERC20PoolHandler.bucketTake(36203409944755362874696856721430167632079153736128288736335132110346041979, 8215925761154388561909586961085935, true, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(150421546299211828719879855910650953203436860265860058362280007, 847, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(1004777165630995093, 1372171883150840583901904310, 1000982584246730208); + _reserveERC20PoolHandler.kickAuction(3, 1708089162074158355239883167068100, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 112699794137265382798927357248812); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 18011383603717089793686282817466059, 118651654643597, 4533115487366411690852066217237, 1372245301280067246490306004434493503281514170); + _reserveERC20PoolHandler.transferLps(1000981386525857325, 5825055564848733545833632573215, 787992469630992988995302450318, 19430, 49210); + _reserveERC20PoolHandler.bucketTake(2999999999999999943667150158142132278687234737, 1000000033996508560, true, 40568, 112); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 22790656686020125250138027430400080795396125612, 734130596384570); + _reserveERC20PoolHandler.removeCollateral(3, 10002236410400136742104258752882369853962540846049504094164513242854938996, 180105813558659579620567137773266982828078999675905815253417, 1460553468223040880984476934262364283559314241702728658651893155122591); + _reserveERC20PoolHandler.pledgeCollateral(3555373250955214312230370639369079575383, 3, 574972032839885009710297660984161937933688295063752901894769975); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 859985629056782596188, 165006957464002869871859274791838246379681838513013, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(59459758455009559804804, 165404782168119987170196379534, 4847, 62692); + _reserveERC20PoolHandler.bucketTake(1009376060441724642474, 85941142082142777, false, 39224701835493089425541922308582059026, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(15986726937524602300682259654953143293457933950998087000522192, 1295585341409984890, 10535354094364589354214519446, 1000038072788259904); + _reserveERC20PoolHandler.bucketTake(37744999609627751214622511415411, 1000980558026693939, false, 2746330018847500154649, 4824926731605952218666836208); + _reserveERC20PoolHandler.takeAuction(148094024619970286876043239739018061689502969477929509598, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 313132242966842809182744491485745970288148796213262446516175981415); + _reserveERC20PoolHandler.withdrawBonds(67161529664110695039866218144228, 1000043319396783033, 998002627336766107); + _reserveERC20PoolHandler.takeAuction(12376114774652211845102351774360, 576125778040707083064846124317600, 17193836818815907042279347717692, 3695599066038943027146432261); + _reserveERC20PoolHandler.moveQuoteToken(1, 94718585765, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1247); + _reserveERC20PoolHandler.addQuoteToken(4178218511116033846, 26679393341, 5330612373601536368918361773092, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(999999999999999999999913873138343614756913254, 1000027877036733853, 5109900710556277962204559781); + _reserveERC20PoolHandler.repayDebt(18523961, 5670295335, 303965196030916357211707901977361065867115472045458381441820); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 6967599040162851889787300712029184988519255406749527873966842337980030205, 318023750982786412922536089780533227952803442913429911, 103736229250745824296045); + _reserveERC20PoolHandler.withdrawBonds(3, 9791132954510246341666818110772848925369070358, 1); + _reserveERC20PoolHandler.takeAuction(79194, 1002059547314463040, 1000005000873558980, 270734368677032001606414130828); + _reserveERC20PoolHandler.bucketTake(3, 2, false, 7290086616589, 0); + _reserveERC20PoolHandler.withdrawBonds(2014, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.settleAuction(1, 59297217860708477421018702767041868632271609303761458529019, 0, 263518376376840476007380651540580911248172040965435037152363624); + _reserveERC20PoolHandler.bucketTake(1000012683938674495, 1000037912640198145, false, 9956288147758110497569383887197, 255618868785376436529594); + _reserveERC20PoolHandler.takeReserves(56773209116211288631430629450133245183961549, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(7449627713001500056625821276109, 53834622623124651191432532625698651030730364977215346959940894, 1612854831028829233008556515035708478023566898084800126288); + _reserveERC20PoolHandler.addQuoteToken(16823005115416381606, 18325556315281752222271575735, 3, 2); + _reserveERC20PoolHandler.addQuoteToken(6004529783688702, 87176459934776856749463141642739939754949399501602036650348514273851392772, 51930524973686058370233784434979390188, 435807481044808024918389934906); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 329350105179447963); + _reserveERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 2); + _reserveERC20PoolHandler.pledgeCollateral(1, 2, 145889137309575871342170073243); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 26439481643005342248928995268, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 32454270635342); + _reserveERC20PoolHandler.transferLps(146492543, 1654385123579136106172387646443450509, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 543241253932979991, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 7704); + _reserveERC20PoolHandler.takeReserves(220274149875236691350083846377, 4326517798617073303167722522461, 80402); + _reserveERC20PoolHandler.repayDebt(134246764910044812606942868618999150134039205331810563851220759, 0, 2702462085920011267078086817223515741514339764); + _reserveERC20PoolHandler.lenderKickAuction(526357600536789701822994472329274846094628886974135728863, 30260748386735153305607583049354029143487752800, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 17499213563878345347, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 980990977278293); + _reserveERC20PoolHandler.kickAuction(1840377142408345370428318730216213, 919160445797027216356365568201, 6782946832441869267548713936179, 1006518908214293476); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1589932485844510546806273816931377795, 2283853212757232729203945013779185336141); + _reserveERC20PoolHandler.kickReserveAuction(24726520705236243274737185723, 23421007516508431); + _reserveERC20PoolHandler.withdrawBonds(3388592032920532292431054449739, 24820007862037949449533727498956, 2305307807501481199533816364); + _reserveERC20PoolHandler.transferLps(5980395069550022899626002490748, 4602731165541759854726, 2848331422423437579029022404970, 90779, 35527); + _reserveERC20PoolHandler.kickAuction(120368538467371083623876, 488284340631805949796, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 196036508183509177597802894165398965196304691550912323233, 182556716679, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.moveQuoteToken(11244541847268548763258516747637493587681505656309638, 44029642776816434129370329658456233312, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 26138058768930501699275980356600366208761350473561234375899504149625); + _reserveERC20PoolHandler.transferLps(1000000018504804559, 718175455357631985516372386464890, 3521476415071293089653878961959, 5093247928414144313894182, 719930902369107427999927960037); + _reserveERC20PoolHandler.bucketTake(0, 48043460778, true, 26349074744566427840672704097336870784667997605045288583471, 0); + _reserveERC20PoolHandler.takeAuction(51454518497, 491163269866249445132, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.withdrawBonds(3961363880540290606638756058076, 1006949867309891563, 1001431187351635865); + _reserveERC20PoolHandler.bucketTake(426677569353116951217, 1000435924371409183, true, 4833352130841182196258114999343, 46031); + _reserveERC20PoolHandler.lenderKickAuction(2, 297684587805471080591367458984499282594588784435810469721019818607155081683, 4934233145782853059571925992299402710774255819680466075156221); + _reserveERC20PoolHandler.withdrawBonds(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 6652856541025358649768062878042285); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(0, 5860285253419, 3); + _reserveERC20PoolHandler.repayDebt(490576049738, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(1000095305377978531, 22090584719300405741683879, 31305750750805014929799786, 14610993285769198121304714220096); + _reserveERC20PoolHandler.lenderKickAuction(31998743535569485142708844249875, 50779, 1005676333555296833); + _reserveERC20PoolHandler.settleAuction(3707130915174381883540753920501, 48144, 1000000048675198408, 1023169063559074456278548505810); + _reserveERC20PoolHandler.pullCollateral(21211071050543513208853388909911188339741949924477198967, 2445742580146552200036078952899585342, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.withdrawBonds(76788236867576694793633924772356893173638949471657355448284624897060072301049, 2700945171647338867404, 1205806862726224078); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 3); + _reserveERC20PoolHandler.kickReserveAuction(553790905933630289244012902554, 60509772636535688731525873228909); + _reserveERC20PoolHandler.removeQuoteToken(27075422895874564228551, 3, 95956012405218914465719498293412189846833859054088014877270717974482162, 118631132696966698017193520105135958019080067900594); + _reserveERC20PoolHandler.stampLoan(437972468174545996117738910300758863675877342114037831134, 14229161141541793499808461201863259905874524932979576411); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 689654593965280704825314880178380152813301345640, 17546705683615); + _reserveERC20PoolHandler.removeCollateral(4062120057659, 28513339019835396219450539344139549415945, 225287535467742435, 10098502630907670104868193820531195060239517210); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 1, 0); + _reserveERC20PoolHandler.pullCollateral(115916029241644946129117100333, 8179, 5785898033475123); + _reserveERC20PoolHandler.kickReserveAuction(38203420415445897172617785858961182275980118248248518603088594148749313588971, 20882259522190993193249460490502); + _reserveERC20PoolHandler.takeReserves(32146833474235735785387577618922, 1001590141180968887, 997728559505939396829823640651); + _reserveERC20PoolHandler.addQuoteToken(1000095305577532869, 40481, 1527553579079044791378646119060, 15283609339755507314550101561416); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 98179336860828213559972016871884594928344985905951126311350916183965277, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(11042071939684331517380253361203376829539545524051, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 414371923908495457681489888251091520353752711552481); + _reserveERC20PoolHandler.takeAuction(22006496719045011901769108393123362208196895204070447247, 1259771, 716331602213779155926933513221178154205186296401893937636094527061387760, 0); + _reserveERC20PoolHandler.lenderKickAuction(62742241543057026279850602, 2, 55380136297932672665740129914682425449648432562276); + _reserveERC20PoolHandler.kickReserveAuction(85675043396018010, 2); + _reserveERC20PoolHandler.kickReserveAuction(2907270412029156347427577222961506912191875119825435528158594544899497631, 2); + _reserveERC20PoolHandler.stampLoan(273889572008043765003541361598639840575, 0); + _reserveERC20PoolHandler.lenderKickAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickReserveAuction(229067010709890259860162, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(2999999999999999995317970230856835761229909190, 1019256274775479571, 1058814689813730543); + _reserveERC20PoolHandler.kickReserveAuction(9177170967757641914511229179722, 1125994264796636925); + _reserveERC20PoolHandler.pledgeCollateral(999234650261968995, 268101666899076575877916059353, 34726); + _reserveERC20PoolHandler.transferLps(889124722888702938224952615447575525218438, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 863896978301647999018852298398280569717922648734447232394087823150638040, 355566568925648306949565199807); + _reserveERC20PoolHandler.repayDebt(1035859528734798830082, 3, 353363511017297586047635058070836223); + _reserveERC20PoolHandler.repayDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1435728892624103562068093178934392434638507770500); + _reserveERC20PoolHandler.repayDebt(1091660918561522699346162025332, 9180678971116378628701172875320, 55658201077537772904293966487889); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 267791148); + _reserveERC20PoolHandler.removeCollateral(15467767533470832337889845, 3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 185044800333434171337920361328439003816244364422924); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 89698878746238094652323, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.repayDebt(15400, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.pledgeCollateral(1939680221, 1000072335253384112, 1000010467045662884726098); + _reserveERC20PoolHandler.removeCollateral(13119, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(1000012352704441963, 14163, 31304014619669761090961386055478, 961937895882152960268098006225); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(8539234479124, 207973669942009404659256, 0); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 119, 126498930714510600218816570334640922146436817043314038944953); + _reserveERC20PoolHandler.lenderKickAuction(5537289775914505722421262446443, 14417, 12177091339777865976016979704); + _reserveERC20PoolHandler.addCollateral(1485272314918483115099931961019803088189471088753689101, 0, 2, 2); + _reserveERC20PoolHandler.settleAuction(39790113998843670960309542125, 6502320599563037463844132528, 2207500556787768650373935099038, 1000000006610407255); + _reserveERC20PoolHandler.kickAuction(40886710261323990939954771094645, 1423584235802189897887079120, 2999999999999999982846439377430249994532785482, 1004548971782447693543668565497); + _reserveERC20PoolHandler.settleAuction(4705107565614476231, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 360920712057605047218665072038960776513059848718470443361019, 22004580320100505849615520489392951879516240923); + _reserveERC20PoolHandler.takeAuction(0, 0, 10970404918758437382003820971928449277238958044334687180153703260, 0); + _reserveERC20PoolHandler.pledgeCollateral(1206893995960185039, 1000355359772012147, 154026898386531114272034034079); + _reserveERC20PoolHandler.pledgeCollateral(1005466596625054454, 204381184644559235008386581695356, 1000000003047567383); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 10561831606363742460694987583222988522652204707077016816441060, 2256764521602300189235812574979553684363867791149317020595325117052144716269, 3840451525472561776103660417741); + _reserveERC20PoolHandler.repayDebt(92434623825250177217445899333272620176132038304178414, 3108116991796495307965418819578762935236164701444411340618098947, 16725359920329034769643099082155226210209768384800930962437745187614617993975); + _reserveERC20PoolHandler.stampLoan(1418097742608714255480462314344060914483944644046479863979709511947013539212, 2); + _reserveERC20PoolHandler.kickAuction(1035167360811511487, 390566845631138405930083899719199, 2988462391092527136634815115967, 663412418800110986943033077508854); + _reserveERC20PoolHandler.removeQuoteToken(1002052643568898905, 129739827463383760406236435537, 1000000810122093750, 29322419197768702807627); + _reserveERC20PoolHandler.stampLoan(39433286198077727379433513748333307488726054772299082457582123110722251, 1764326786899860707462482979); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.transferLps(4435396605966342107087111756190597426768574, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 38018747780249394188793792584756745705081807379325079495196292653765635, 6); + _reserveERC20PoolHandler.removeCollateral(1886486362541737770546009858804215087104603158999872146837265954889449188, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 167585832540160229328512602984505110967959784, 2203482081339426968); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 91046488852146216670272923726, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(4218175551206446485103741604727964, 1999998173515981736117685742678, 5238503912140515899619262654451, 1365569299150920806361636564099, 11035462948610838583514004859); + _reserveERC20PoolHandler.pledgeCollateral(10588417125558066528608529286712, 18630430666658658448022336205, 53789149765731550363904221638332); + _reserveERC20PoolHandler.moveQuoteToken(153773093668690810136739073547, 1775031597454965429596179223891, 1000000022452865858, 1000981534864651705, 999182536668392028269394316912); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 14550912461); + _reserveERC20PoolHandler.bucketTake(2, 3785815353433, true, 0, 1); + _reserveERC20PoolHandler.drawDebt(1000000001797632528, 67809761341097563691414245252901, 11071); + _reserveERC20PoolHandler.pullCollateral(394012169183686188308252745413649340113793, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 380291214592338019775); + _reserveERC20PoolHandler.transferLps(0, 110160138170532958, 3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(5117220546326629858805968282, 86020252734584038885562675688227, 1027594633239275032, 6978166954); + _reserveERC20PoolHandler.pullCollateral(2, 21685979640551031347152514883252393632409581149297343029571721241708018, 388092152567103692856866375931097781037566687550655459024184612075); + _reserveERC20PoolHandler.transferLps(4970838045219992995742607279283, 2505739253, 26637132373254796834267823524888, 474146859677952114582075217928390, 2944058680390846960000857418921); + _reserveERC20PoolHandler.moveQuoteToken(17760, 48503346241704549006793, 999986432189475262414238041368, 21013, 818146182126854472136747164); + _reserveERC20PoolHandler.bucketTake(1000477763876985433, 692326146789671490943308014084077, true, 250433285405029225010057489732, 1057001979693573562176981675592); + _reserveERC20PoolHandler.transferLps(31634748126788445967432813642699, 2999999999999999999999999991857473485395435191, 36183411359542968180819498843191329944675962195184522815400173109497640044646, 212865062585461562346, 38462); + _reserveERC20PoolHandler.kickReserveAuction(45268758549247928116421995644579813334404551427803578427, 24330366036865721407910508251624000805739838008770); + _reserveERC20PoolHandler.moveQuoteToken(7305448912, 10134327087811032929632630659771, 753087577366634331982133923542545437391278448717905351768529636894896716, 80964157021346160647829100161484, 285770366795279236206238908604214); + _reserveERC20PoolHandler.repayDebt(240318, 1040442282556027669102, 0); + _reserveERC20PoolHandler.removeQuoteToken(2042308201399744, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 149430966425223907470639313513275293, 1088962164163035756); + _reserveERC20PoolHandler.bucketTake(1, 572714980562293495758894610577221178784756867378944432994746678663278871, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 62318225948790490019823); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2678745345349197338242660240885568261362607434241879518100699, 32801831446366076231052580212038); + _reserveERC20PoolHandler.moveQuoteToken(499117977627763503669171791642173754, 44318156863555412542106278814601848343324912551074066530048706051356850785151, 1, 72776866965779269037447428839974955362822926590, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(2100892806314072438659944631538703840731853739608559, 1307573309415889357600111839266779406201781, 2, 54577063045050, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(77161, 1000036207470012920, 971740614740240872722159328230); + _reserveERC20PoolHandler.transferLps(81327500952941288357205546120082682627564857201, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 12164564411937838972990144180755052408495093694924673301531007952692, 39052630718579770709660567597835568995338); + _reserveERC20PoolHandler.addQuoteToken(3, 1, 6848200252655886808052890940607228458486826025806169002438399156010412422, 1); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 5002093638133161563026605207237632); + _reserveERC20PoolHandler.settleAuction(7936248699986775530408813986855903, 1000006845050670052, 3304764594454842981937728834113, 87398194830843876155259); + _reserveERC20PoolHandler.settleAuction(1, 15116185734706342384954107127486338092777827758727145714, 150986389410667216744216095703476257003172450767794, 54611418826732578716878891842029175147); + _reserveERC20PoolHandler.pullCollateral(1000000566273625578, 125209044274473361611621806149, 1000000229524121356); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(5795794031257472635471364190786, 6444925816600163788569234070463, 600000000); + _reserveERC20PoolHandler.stampLoan(4426847278338984518675223522072, 1091269448295297949259570852695); + _reserveERC20PoolHandler.bucketTake(1000000191118667579, 97543577357575241479675412951, false, 4582245332660824, 1000000036166503696); + _reserveERC20PoolHandler.takeReserves(3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(62773, 1911254306274896922493560290556298140745897839, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(1545337642978, 1049857761862083562154077361007504197669030397561583297570672514678677, 0); + _reserveERC20PoolHandler.kickAuction(891288909266796364241967704396484461185, 2, 18142072967048895205282829427819397995892703, 53798772752974010809233026131); + _reserveERC20PoolHandler.repayDebt(5621349586257939934246348667, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 668817323191787102734081691948034438515507974000536683759258729334232642); + _reserveERC20PoolHandler.addCollateral(1002051021182969468, 393558353391302875097579660433, 299564633705951748688314863721, 857044575100694171091078459100); + _reserveERC20PoolHandler.settleAuction(253457404541, 1861672288403016173598780640662999113472086361323680358312565551608184, 2470615383000617311305050426926591031986315036590682263125654801258734011490, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 349956766139822823028719884394587565501759857588359731462370538910338, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 91182630043983336711576891, 3); + _reserveERC20PoolHandler.lenderKickAuction(106266645235350086219200872434, 999999999999999999999982100659387036106096067, 3567633030481374863207599); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 33627548651239920350282080754203641191199013856282468469330135026654); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 482266944890372671, 223433435962321439678767571676429494391472872929642); + _reserveERC20PoolHandler.repayDebt(2261958652204824211632471051941413384029118579, 389285269754810370146172389890526902945003944506095944583, 1); + _reserveERC20PoolHandler.addQuoteToken(2176, 1022680203756913975717985403834, 188667396020924477269311284595, 1169274003023332178); + _reserveERC20PoolHandler.stampLoan(1, 0); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 97020189506158018944122529328176952617835661661717102, 2303965292824359784); + _reserveERC20PoolHandler.bucketTake(8992884321100906960007317675981188917216331429001451, 4059253211462038025751600258044850765471, true, 3, 0); + _reserveERC20PoolHandler.addCollateral(2, 1336144057758956148525980741441829105589880681420029223063005899, 1183156706892352992069009797038142965265033006415093373002608188, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(149463009987303408469710567788, 71384, 94392111344258433547438082, 1000015502155347643); + _reserveERC20PoolHandler.takeAuction(2726637867553418590753, 6024726301246198467119363092, 1001831131447194086, 3564342444218565501793843999); + _reserveERC20PoolHandler.moveQuoteToken(1008567295905992647, 1131391626650936491725382849735, 9816899790328321835858530495199, 8442639624339291184643064535805, 9909704721838767600241774285052); + _reserveERC20PoolHandler.withdrawBonds(1156338824648924697772552, 1, 4408119035858953089804360411774537469056907372286078181350753817); + _reserveERC20PoolHandler.bucketTake(530416317220640140519692443231863755393204172832445973, 1, true, 7656876, 371788384346896325797208437774848589217255085097952555851268932842652); + _reserveERC20PoolHandler.lenderKickAuction(1211144470570029544675095436, 5276503378686925159777197246685, 972139970734998824943059472041); + _reserveERC20PoolHandler.removeQuoteToken(0, 5175582504, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 245186960641260715898363761); + _reserveERC20PoolHandler.drawDebt(1000036329494047385, 1000188620591984696, 75555); + _reserveERC20PoolHandler.kickReserveAuction(42910305714613320472346823029663983, 11906855); + _reserveERC20PoolHandler.pullCollateral(999999999999999999999997043903871392808829377, 40288, 13991493753426895232299765047528); + _reserveERC20PoolHandler.kickAuction(48242, 1800, 1000760786175702794, 2007515664383518160529608089353); + _reserveERC20PoolHandler.moveQuoteToken(2, 196359657953683258138923, 231748715555971966502001061845969636018365322915, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.drawDebt(283285658285336780538101176630175647420764761740, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 61962516781381437599972092617509604648); + _reserveERC20PoolHandler.takeReserves(1, 223363977957698, 82430909341208433491834470424667339178407333164045376541797918347); + _reserveERC20PoolHandler.repayDebt(1076876877232612446800000000, 1000000930173535644, 73285597292980); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115521930425845136195273348282783716900540951875240763327642996, 1287913541314992956268426); + _reserveERC20PoolHandler.moveQuoteToken(3, 22900486941787, 6887308776393699979112581244082, 277141783642694406378, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(6907714822, 3679264774681785625177977131); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 12628271915452177, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(26864204274283642854650548116, 3909497424692194613216116905728, 643720202235848251883777119334); + _reserveERC20PoolHandler.removeCollateral(1931770304654233006, 48248168650285020503858956601889136118191755, 0, 10832344662623722602193315828); + _reserveERC20PoolHandler.repayDebt(59410818744426515289272345672971, 52668, 160722718913630022923990456981); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 7901813139192442065403100286907239333, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.kickReserveAuction(1000000038360674246, 624747283137604309); + _reserveERC20PoolHandler.removeQuoteToken(86213767155653037256383726400628, 7287855743, 20358, 4361063434531739611944581565006); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeAuction(6445420686969130853870360101168, 28544261539701121654782120, 1000355457992050329, 202902297750595803536314588266); + _reserveERC20PoolHandler.settleAuction(739893334380905938265578331312802428068196593710551277344062344767416506, 268903175277919408283436591513, 801214576449429, 50444271109048707102240795); + _reserveERC20PoolHandler.withdrawBonds(1134710716032341674, 999845351271602695850746209568, 1131068085221222002734700798016); + _reserveERC20PoolHandler.kickAuction(208379241002290271575730999823, 9151, 16733991498251797897200942181, 3416565995800769342777513239446); + _reserveERC20PoolHandler.addCollateral(1000000004614630291, 10638684092948099027398480880366, 81666, 1000016014655808125); + _reserveERC20PoolHandler.kickReserveAuction(22687, 999999545748309345); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 4396158942837, 111018996347883141787320825546549660, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, false, 27352185607059324327564677537345770324874007756962, 75799648374521464685476350844952); + _reserveERC20PoolHandler.pullCollateral(5175371671119230462385, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3059831317915290074811816187410828163401077486557, 1, 0); + _reserveERC20PoolHandler.stampLoan(3360861819481270636480456509641501018601238230781382801818872091849614182353, 11349808223346176339111590862120074389187574472651233119962); + _reserveERC20PoolHandler.removeCollateral(11705888820185382007641450095537, 1000981384300588519, 63729195352751423299373, 36982280882376362864992235970323); + _reserveERC20PoolHandler.withdrawBonds(970183683503080590135588369968, 1000000028692654019, 4830315684596077300368017956772); + _reserveERC20PoolHandler.takeReserves(3909459573216060264708257822996, 238735149097432661436051971260, 9004829992889535361653661441380); + _reserveERC20PoolHandler.moveQuoteToken(0, 2340227190047974513540520090961, 3, 1, 3); + _reserveERC20PoolHandler.drawDebt(75787, 463660915003816297713953, 1000111850506708338); + _reserveERC20PoolHandler.stampLoan(2, 795925916519934557701726183044588158318121773264442013257171533); + _reserveERC20PoolHandler.removeCollateral(1000002667684876498, 1125794095879624637, 71051489989602853200813945030, 61045); + _reserveERC20PoolHandler.addCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(2819439781229774059635441580327262600162850, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 24957441382512957436806988302243955, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.lenderKickAuction(38883308108672663138632063101505772109172519356061810, 6857458802255467, 856701655); + _reserveERC20PoolHandler.lenderKickAuction(1007529894284167111, 15278007233326485643608176457904150658719523119499588922624946662, 1022696268495386011232357467342); + _reserveERC20PoolHandler.repayDebt(1001428696473216829, 10216775755689494345260053006203, 2006182968031387982347119164203); + _reserveERC20PoolHandler.repayDebt(4936971942992633693011875105576, 68007287397163019155995815926623, 46825); + _reserveERC20PoolHandler.drawDebt(1000000047263904672, 140773512543155168161393008349, 1000043048065773614); + _reserveERC20PoolHandler.removeCollateral(14593584983218143369854032515051641204881548010780015050818166551409, 7869840800253960088891, 1, 6193993948441137365634083337250322); + _reserveERC20PoolHandler.pullCollateral(1, 96638697764, 12326739507813260598941361208459785839700809939566781819487); + _reserveERC20PoolHandler.removeCollateral(43495765239766747761360457808780145880498037866913951488344918623977, 2280695587429, 2, 798821797455929644888218720650404350719906); + _reserveERC20PoolHandler.takeReserves(1006325918084870386, 19940506739176776873277036005061, 2349119507361695110618515206953); + _reserveERC20PoolHandler.drawDebt(6877714916923779600746199366095, 443461067613254110331536303135, 588549829444792638519653235692153); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 51416021796301538819140576630136039858617601865280829336835757998023336838, 183035911990636313397); + _reserveERC20PoolHandler.removeCollateral(2278338044634752225156379038555349788660040162815, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 15182706191030721805878013346552332663691527665029917395925208692411059455, 158341925571825019295520140046390); + _reserveERC20PoolHandler.kickReserveAuction(3448458227792303923331236099439, 6155169883151768425473699045431); + _reserveERC20PoolHandler.kickReserveAuction(631777096986884844954429739577, 197691534908063864232422336436986); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 2); + _reserveERC20PoolHandler.pullCollateral(5578214662638254276910033563425, 938956987911695265, 62033666469167696042899840484004); + _reserveERC20PoolHandler.lenderKickAuction(208681455567130831577314286310, 2258895956438172404713461804201, 15282990401061678430735803372846); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 1); + _reserveERC20PoolHandler.stampLoan(1, 17103718585183525111796067); + _reserveERC20PoolHandler.pullCollateral(1000012667448423107, 54592, 593232880138513710270963273066); + _reserveERC20PoolHandler.kickReserveAuction(26836460401767939754409205688784979191826720073856509665345028275696785, 396867485517); + _reserveERC20PoolHandler.addCollateral(0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2065672338); + _reserveERC20PoolHandler.addCollateral(1016798867648372426, 1638786252127424301591423357245, 1000036284187339806, 59600); + _reserveERC20PoolHandler.kickAuction(768488071313828926399558334039289482698340905159820322949535561066735615, 227367560331364132894097706, 123991547084492644861320055067, 2725568211175710442346684309); + _reserveERC20PoolHandler.pullCollateral(3, 3220146756752632190980677959, 0); + _reserveERC20PoolHandler.settleAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 196932331539042525268994341564374140210195094, 1030217671930604945010207795510531017593033249747434445); + _reserveERC20PoolHandler.stampLoan(9033953275217645063884377493, 23176); + _reserveERC20PoolHandler.repayDebt(1, 0, 121250036549594486145954358695527421909909461682186232); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.drawDebt(44816480304232691013, 4736979598470382, 257858473923760428499022076669515); + _reserveERC20PoolHandler.transferLps(64157710043163089524067896562254, 2234593096518359559814180263983, 1000000366382515282, 1000001048167723350, 21737653721354832717237409397795); + _reserveERC20PoolHandler.lenderKickAuction(2331639754956177272146746, 12122, 6438505278598121527830666034000); + _reserveERC20PoolHandler.pullCollateral(19475595001, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 13898647868576225, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(3387951862352485177325787639152, 1008049049806419726, 3000086274051054214466650000811, 1801292916516637155646349026100, 132715175748785003941295552672); + _reserveERC20PoolHandler.repayDebt(1363975281627540213983675617806474613875768077, 162365313931, 217899982295391633519496778168); + _reserveERC20PoolHandler.stampLoan(189668396925984130327567502, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeQuoteToken(33228798058135141577089604421423359080906120943814, 89984726878655661127307277259403270786333339921105, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.addCollateral(83744288279204167546797085685458301855529854594398039539663, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(9823794838627529177874360358786059817008145914479134302739, 30864477070834693719972289827279526243371811053021564168589019407689903217, 2, 3); + _reserveERC20PoolHandler.removeCollateral(86091, 191171408997280206131308322969753440406759930088275, 19339632431030723416924430, 369859158855693); + _reserveERC20PoolHandler.pledgeCollateral(756118169550626242285339666134904855113072994279632957167697947678, 56695589935252491017413037573369451315191377090803759733155179596637441399467, 1000000014681767657); + _reserveERC20PoolHandler.kickReserveAuction(0, 12); + _reserveERC20PoolHandler.pullCollateral(159361741361227246527976966210389138152, 3, 275423993205914136271021829206180); + _reserveERC20PoolHandler.removeQuoteToken(3, 54505764668, 992, 1); + _reserveERC20PoolHandler.bucketTake(10812697155503230741519727173403, 18842708570841285623360012154409, true, 1000000025606847209, 2576333209724912241436955375929); + _reserveERC20PoolHandler.takeAuction(34211, 1531857107174677763, 195979292677762744254895, 1000000007264360654); + _reserveERC20PoolHandler.settleAuction(518219575724299691351070113841056512289460640290480371, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 65895555524894265361429542624545737823561876908905404799574107778313710, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeQuoteToken(84957949381933833795941394334168, 8460622083060736501100198753, 258521723509531816676463115928713391588667995777539517919795005781052677, 341255869075379466219093381986); + _reserveERC20PoolHandler.stampLoan(999999999999999999999918311061545274655875050, 125369027731779112223813114953); + _reserveERC20PoolHandler.settleAuction(1699117480134834493435933161075414510035955120120191199484634786397644883, 1000317539481870001, 29478792660610849980181395716873, 1000017467364549968); + _reserveERC20PoolHandler.repayDebt(154222759952581550893970899923509337345241962272514032888497944775, 148562412350281078210106536388, 14260180925508426615213008032448); + _reserveERC20PoolHandler.repayDebt(5300395207395712459830383425779434005752457613335093782425960734325217350145, 31358642229357069519185279112879798, 0); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 0, 0); + _reserveERC20PoolHandler.settleAuction(12667519620207179334692587467982798629772255602702206193978970630, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1080767311086858948025071706212102865737550971857842162893515496, 1); + _reserveERC20PoolHandler.stampLoan(35405244811369861915657648022854, 2396000370); + _reserveERC20PoolHandler.addCollateral(2414492242701169698938209938574109785894141, 1294596085107266368203244588964494350858, 24399184124591277095055135726206024441860804931914671531671890878473305082, 76150447431339974); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4058471487573146799820729280102244613840135, 214419618628088227046228605559, 5677237614469165441840465256034224607225790621086687178048528, 4277859398185974838583232746730046330209032990986884953702331726); + _reserveERC20PoolHandler.bucketTake(2, 22647536216064790782649875747588796583366, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC20PoolHandler.bucketTake(77710, 5287143794512678150671728978, true, 1000255584059928381, 27488174423469693307162586496); + _reserveERC20PoolHandler.bucketTake(999998885442776842058761752861, 1000000368031768759, true, 126588111079539155816463952171, 25748563155535124538973397147); + _reserveERC20PoolHandler.addQuoteToken(7826068423181782441523787485, 7876879294247552785672020293697, 16256463239824937131676875, 1000000196188502248); + _reserveERC20PoolHandler.pullCollateral(844991740537396813384822433056600633142239595397794565749580827499773210057, 338491715508623, 0); + _reserveERC20PoolHandler.moveQuoteToken(3, 21854490899153791031758985353564565407791097158, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeAuction(3, 3480455223807037142776457197, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 26550608); + _reserveERC20PoolHandler.takeAuction(631659629895491046810608635432887899409928061, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1410451217230); + _reserveERC20PoolHandler.addCollateral(1, 9385529896847553221546609241290212407144120597551753, 7972080988, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(0, 24536934960191180, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addCollateral(8107, 994765581813983448, 365459748686777240364414971, 77273623247092892385555028454212); + _reserveERC20PoolHandler.settleAuction(364242569690494727613624218626607831242308876793787494234943812, 3, 1520103819626956000939957216252685830992058122359346410795483, 141707602057020964626639095673464224392451526623621437428314869); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 153658643709344593480987654154840271027072958144571577); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1450152676113581072957919337676216721134311151903079038898938041121995, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.stampLoan(39248587459463533519740951, 1000408449274108184); + _reserveERC20PoolHandler.settleAuction(17499792701487773267079261858506085069522820085758, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 64151542537417664026559728669420084088536278); + _reserveERC20PoolHandler.removeQuoteToken(932064469794255949244137018390723928255438856171930652720310739432224, 90960291104830262, 2, 81824783338534698754); + _reserveERC20PoolHandler.takeReserves(1750439375674480157535568393656204123451759830536367596553172002147631927, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(4948099825, 2); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.removeQuoteToken(1000091534099250772, 731460461675821286807375777098363022265688846351399567091859793162248153, 275571579435972634081304563677, 1000000003396935960); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1005104008737478091504659189126708725524676, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(321750415014021716418730, 10478785645, 818784308647562329544186222292943782162616, 3); + _reserveERC20PoolHandler.removeQuoteToken(215077, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 286439816526433791738244040992545632651856); + _reserveERC20PoolHandler.pledgeCollateral(1, 7150706200748382700, 66184049748495787150123170); + _reserveERC20PoolHandler.lenderKickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 53652616950433589402298165427928283277940235139805); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 555247920068282387868541793835); + _reserveERC20PoolHandler.lenderKickAuction(19744155902120005510919851814492, 999999504846534484, 15691162258757800670915856736); + _reserveERC20PoolHandler.pullCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.pledgeCollateral(14682932742736907120272048130329, 1000002578992417426, 2925199640981325498281); + _reserveERC20PoolHandler.removeQuoteToken(1008149999918670041, 181788632340566217966631436751, 2115168277399028264286898472336, 116023305140644950394621905110); + _reserveERC20PoolHandler.repayDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 595595); + _reserveERC20PoolHandler.pullCollateral(2655498375242763773, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 21923573353097184778515502700442695298978313070736049880387234576694); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(1, 637667456395362561907414255577752400699848695179, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(1793859338901833923060406554388685765886517118544370646319385833026475737, 5966654098994931410454824218671, 1538); + _reserveERC20PoolHandler.addQuoteToken(0, 8115620192272547240281586616, 22821157197887401724786180757580754591643253021, 19580323445151965943184089711983156858803337511995034); + _reserveERC20PoolHandler.stampLoan(17817210337035612246375760741871668916198, 31947); + _reserveERC20PoolHandler.kickAuction(2409387514694614867731473687038093895952838103962252119915188227283736, 497108245783675545063204366881934709229503358035297015584, 16865894098935073239627685548165632093312053679096590631123137336942034, 0); + _reserveERC20PoolHandler.bucketTake(1012948845969068580, 2363817973860142118317603515906, true, 4887260958561732336997189110, 1445588412531312978771932); + _reserveERC20PoolHandler.pledgeCollateral(1002245212299544621, 4830343340210256597949528603158, 4364561670969669940322688239956); + _reserveERC20PoolHandler.pledgeCollateral(1000069555031725733, 417048100385197199787055, 1004661266606339791); + _reserveERC20PoolHandler.takeAuction(6960420902, 108250892770094302889911690858, 14992835975278471972162384783141, 74170020918603089009989122271674574949355441499812410308755434542246012498177); + _reserveERC20PoolHandler.stampLoan(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(55653758671807447958604067274852, 3655800148484168536207940331414, 126625615819509945354195157474101); + _reserveERC20PoolHandler.removeCollateral(1000043296908390615, 4634699559314301503528119029, 2366218898985050270036623680135, 10388270454879436037502158809); + _reserveERC20PoolHandler.pullCollateral(164164893209671633951, 311547468237477841938621200373069094854615, 1040921647154460293101681468); + _reserveERC20PoolHandler.transferLps(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 14336070274645454521927890520971226678040, 9270932022652768539689269981421, 1977274973129006477503510259136350867387634130233251582127154825278); + _reserveERC20PoolHandler.pledgeCollateral(243019118974689470760979189321, 1001948728633217191, 1006727941346035234); + _reserveERC20PoolHandler.takeAuction(2753900819246881357258, 4937288840, 31748892049865463309178853176777, 16632568671085054330617318738); + _reserveERC20PoolHandler.lenderKickAuction(3, 11116383055790779806011, 328714); + _reserveERC20PoolHandler.kickAuction(493016537150844663158477374000, 229102909116665241612260763474, 25686492984072426389346012920590, 22994); + _reserveERC20PoolHandler.removeQuoteToken(148803365627223155, 143507072463741731, 2, 2); + _reserveERC20PoolHandler.bucketTake(9378537965511994439006270665439, 1514836917641539984257706977114, false, 399279692754502191455246497723878, 282802779224147566981900116343); + _reserveERC20PoolHandler.takeReserves(841167724585391650932622356871400753602189840661162863197, 2, 778836551593761); + _reserveERC20PoolHandler.removeQuoteToken(785200, 1169276167643092350, 6471346266114497262727010059, 1004278470785517492); + _reserveERC20PoolHandler.takeReserves(148189682818032080729312250072, 119643234093199337368736230157, 1000000107607684463); + _reserveERC20PoolHandler.withdrawBonds(209666341414212018800000000, 1001416979798170626, 3661501071928359385); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 833822157382112310379512809230856882375950, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(104592303741226878478756278323156512268414953011524248344689, 1140100780225586612955745863498048953, 2); + _reserveERC20PoolHandler.addQuoteToken(1000000032532748340, 1000000024475549346, 414806036443332436310609631914929, 25989071491641390460177368274497); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1371329216627087175457576257621111737606283731237); + _reserveERC20PoolHandler.removeCollateral(1000984032251240931, 1000100154774492748, 2641492657, 1006457489957003501); + _reserveERC20PoolHandler.stampLoan(32174, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(72166604577499754683, 2, 0); + _reserveERC20PoolHandler.bucketTake(3556480266209637985100000000, 1000043291054109200, false, 19999999999999999998499991966087009840897294508, 4191141387957489084695909); + _reserveERC20PoolHandler.lenderKickAuction(3843006794340455004553939261038612463572474483275974946686986538867264276, 3, 20385764437958572); + _reserveERC20PoolHandler.pledgeCollateral(255927969666200010955472236241702423447556339422, 5984823412919400226992, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeAuction(5673051031, 44403525581114807478321, 1000001213914993516, 160592971122554930485688914); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 6416188362258492500175338, false, 240182846857, 2); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1130549871425184452849537682, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 206786259); + _reserveERC20PoolHandler.pledgeCollateral(121586754025020744556174887206, 133583740621358298933681451378, 29716901866062548712667251323193); + _reserveERC20PoolHandler.takeReserves(42383, 8314559871958020107137672885680471093820117496586713656688195951, 4355694454577037620618932045698); + _reserveERC20PoolHandler.kickReserveAuction(0, 49809230294950785113030403490822289507645893765655809156494858079085); + _reserveERC20PoolHandler.addCollateral(2806295104188667299301337021, 5200279087296371400057844042, 36168, 3927937962567963659933663404471); + _reserveERC20PoolHandler.removeCollateral(0, 2, 92470, 12450377094004170711503424576992603); + _reserveERC20PoolHandler.kickReserveAuction(25986491145409645, 5928069680352991306386009523840710726099537036808117154296105984); + _reserveERC20PoolHandler.removeQuoteToken(32527010874572894522342548, 1035822975498601000, 1000094706922646149, 971820699054383356576530567470); + _reserveERC20PoolHandler.lenderKickAuction(7217545721, 909354948247490466312162453, 209570628562757589075107); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 705099297374331041437544782651552543166685, 1); + _reserveERC20PoolHandler.removeQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 2); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 381102985544038894603212240634712740398638904633436704223819638, 836177823124905255285966791123170272261910, 2); + _reserveERC20PoolHandler.addQuoteToken(467340530870302340910138351750379, 299999999999999996982446555562922515357021431700, 1000010305512196425, 2882219328364666768470867943232462367965653974627555787148301371857043456); + _reserveERC20PoolHandler.moveQuoteToken(2096133460228138252931264669101, 1064245821460670758, 161944898230175559256443656428, 54603344394945738564451088, 2582326825820920305607907636900); + _reserveERC20PoolHandler.withdrawBonds(5029842396096285875743864698223, 2134699424465126881, 1000326550618844009); + _reserveERC20PoolHandler.addQuoteToken(31418, 32154147068305596119322187725542, 30457190921610308061268617566, 15142190203131685563040046882721); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 171237844558539347497814066983244889388281926529302285); + _reserveERC20PoolHandler.pledgeCollateral(3834303767162269453128358937719, 1007060457218531889, 1000000008348641949); + _reserveERC20PoolHandler.takeAuction(2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 95642977036386659929225573295612829101989163103742538224778230516181300); + _reserveERC20PoolHandler.transferLps(80964975039041851854516053586638, 1335581064425781965, 4447783031342533558349685467, 94746529051349664448790148, 19940683623546759891682533681708); + _reserveERC20PoolHandler.removeQuoteToken(998114084034926790, 4865586163912396974539135642125, 3655746575260299014819152220991, 29413); + _reserveERC20PoolHandler.drawDebt(31844890057527831513292378557555192826, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 164520068819643321058459087598717); + _reserveERC20PoolHandler.lenderKickAuction(1215276822269088645, 2091293358945760886103808345900, 35275743468015554755332395); + _reserveERC20PoolHandler.takeReserves(181588589870853232226456520754424, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.addQuoteToken(0, 188508261312721718772, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(4361758189470856070510381147801, 999999999999999999999970583783747837836810445, 34309); + _reserveERC20PoolHandler.pullCollateral(229363209252, 186198431200098365152532494, 7901454045765467512429748714550292); + _reserveERC20PoolHandler.moveQuoteToken(75602100927653868638293735650, 14697538436618842504078807365368, 1000000002511462134, 6027266601217728263189792987, 984816764903554069981217814833147370679158886358858372691475852318); + _reserveERC20PoolHandler.stampLoan(327968565334262, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(67720, 85035664073748116599784293974254, 41497054165257999999995851, 43464); + _reserveERC20PoolHandler.transferLps(52662922810824362646595782508736293597258787314482681827041487, 2, 178388025167055341277770214451784252014254629263568589305144837664259, 3, 20393111775436768050018); + _reserveERC20PoolHandler.withdrawBonds(53018222209963482444795665681505768014690289383703397186837703260252081, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1709816625813203203152215089655249739904048791173772755); + _reserveERC20PoolHandler.stampLoan(3122731976778821654872607277831748529899919607128, 50400963614742220543951945); + _reserveERC20PoolHandler.transferLps(2, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 11636107445920355041001994222773302616181201754); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8049354417611797833746182, 8983799283413485789897); + _reserveERC20PoolHandler.kickAuction(999999999999999999999993718717570807631306211, 1000046315745137734, 29194023489140055271274131259599, 1000000009355146991); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 24779993484679477935735060439933239959857030605048568252699204470397, false, 475222233102730148633594599359437808739160685225891682890477316, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(2, 6674435041867194276668075, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5812610211156492065933979276824245926931466870171388522, 200324011855850940201597494301286429124); + _reserveERC20PoolHandler.bucketTake(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 466254706086886115468572467273525468059, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.bucketTake(2207525871739124293282418960996, 55657057635966437795556788493859, true, 1000982151393173262, 1031447522182647435039683); + _reserveERC20PoolHandler.settleAuction(3, 4345635169550910322754638659468833804282138520627745602625272809, 9387701206056167762320213547476397365173288336373012336794478, 14467386210906834095671489382752727290015128814854950815214001422844588434); + _reserveERC20PoolHandler.pledgeCollateral(1273472659447459617740887527997448617864896427635717216980941661080281117, 1000164835791311468, 938929468941334478); + _reserveERC20PoolHandler.settleAuction(320549967781776367, 1, 537831519428080723749058789499884497483415041, 32294620845303607256377721007316848632190377395520693); + _reserveERC20PoolHandler.addQuoteToken(3, 2, 1, 44597681791322564192334345145460355026558224308775404214977645); + _reserveERC20PoolHandler.bucketTake(256887819375200148707006882552243706120, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(2349234377626561442546931334564, 4814510570, 2256052875085339779051307309, 60638); + _reserveERC20PoolHandler.pullCollateral(3, 2, 1); + _reserveERC20PoolHandler.drawDebt(1007849759040418731, 30303442602365203610046761900835, 1000127744924715483007652041356); + _reserveERC20PoolHandler.kickReserveAuction(1000000128282169058, 367680884037763951634182598251); + _reserveERC20PoolHandler.takeReserves(5187245061207290870205076666684, 1000000039384712743, 5876468564534107014347608343220); + _reserveERC20PoolHandler.takeAuction(6569, 14896041534957859889047133317335, 4970471112212735923548080584274, 134971207432203939674009812881); + _reserveERC20PoolHandler.pullCollateral(9627595139751088476220856237170841532742, 0, 2); + _reserveERC20PoolHandler.stampLoan(2, 3); + _reserveERC20PoolHandler.withdrawBonds(237397312871338922227241792762954011534053242452491073277194793, 13484226243526539790188847856828576380116099, 0); + _reserveERC20PoolHandler.takeAuction(1005308035753894110, 20581519574078042082346441743217, 30199, 17530); + _reserveERC20PoolHandler.kickReserveAuction(0, 4357213380889175954263617922388723457511); + _reserveERC20PoolHandler.addQuoteToken(2, 143601788198642856684368068772228657340, 0, 3); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 416449065704236324910, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 6, 0, 461446736833139864128); + _reserveERC20PoolHandler.stampLoan(54061635670561508888218294680662, 23545565025957646914060594623793); + _reserveERC20PoolHandler.withdrawBonds(3, 945956735202634721782199556269495799987922723662, 152225339729898663891480119209130325762328817289443100); + _reserveERC20PoolHandler.removeCollateral(0, 0, 7573728153900413090021568223629867262876007663725010329428516907100671, 19181193457975281426391879030493236881745693838990777415); + _reserveERC20PoolHandler.settleAuction(1000000094803397319, 3487908320429777229917058525644, 2999999999999999968312840861883162143967474654, 1006153413455506069); + _reserveERC20PoolHandler.repayDebt(16514, 1000940391779255527, 218431070613992401840369783445); + _reserveERC20PoolHandler.kickAuction(18855210211379060297045237516424268005397889582815165528029, 304419814583571609, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14089586695972936613796689080514396); + _reserveERC20PoolHandler.transferLps(1, 1, 1, 1, 1); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 158947650168500); + _reserveERC20PoolHandler.repayDebt(1361784217610076, 12408296162190387996137025, 1); + _reserveERC20PoolHandler.takeAuction(50287937833471819113862690196907233326818392080424157156446457673439225, 2111447748534264544799623147685125193234730625279912246951074280, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.addQuoteToken(3, 3351132035866243494291690311142477496, 19027663132128772421854325033503853321096601924471479132, 41903901257828471252522783790199992031296113466011079401217714812853117005); + _reserveERC20PoolHandler.removeQuoteToken(5747919537212350623379705648737637309801895677694313353890305, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.removeCollateral(8043780961056505961455372351242, 62918, 1000000011171743844, 5629240548); + _reserveERC20PoolHandler.drawDebt(726787666947702803859150525023, 17968, 1002142061565769701); + _reserveERC20PoolHandler.moveQuoteToken(18770742606748800818056197487548445640334, 1, 1365786231, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.lenderKickAuction(3, 3, 100433610095477097999828227); + _reserveERC20PoolHandler.settleAuction(33755262010802187822377172814782131282133241664882792592178272175577, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 211593156928289, 0); + _reserveERC20PoolHandler.stampLoan(41586365874692634724791, 0); + _reserveERC20PoolHandler.moveQuoteToken(24432592122191432336390374313021, 9279411963727900805552323175707142108201215676379406039058732950, 3961862566527752656869860630692, 3320031809210744460072002725035, 32976385048970415738649800000000); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 151218224623664494200629654659260358602875971384017675132155651721943789130, 78586722566936694093, 136872237431090528053030479189346442678775868022141153410761458926163); + _reserveERC20PoolHandler.kickAuction(3, 710476448073904269213294256170976862196898568670255286708997986, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.kickAuction(0, 394173680979180714133, 1, 622821561244294658119873370151585920548001); + _reserveERC20PoolHandler.kickReserveAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(2999999999999999969824465555629225153570214316, 2459994468106674438914174822966, 1030524026052512936); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 4237613807740853438208842004099435734); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 8408823464118353505836689167440498275691334098601529063586655839); + _reserveERC20PoolHandler.removeQuoteToken(2074211306149395161583658597271969898416520727047366995843927260231627227, 291667048866694706524681235825, 2633544282270457113592166722099, 20760150869937576705732299058623); + _reserveERC20PoolHandler.drawDebt(98531892424029788715546037001870426908893509090111268, 12004417369136265034929684336995234353, 173843128783855241267666); + _reserveERC20PoolHandler.takeReserves(14600569143651978482643101695921, 3389591222577974830053059014580877, 72181); + _reserveERC20PoolHandler.addCollateral(1925121822293296216279758294898742869633711454718162176282180530195, 217627093584439028912003937367759241676141336395095809814982351379788700186, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(101680123898637051161340513312, 38398, 1000000022661633917, 23278); + _reserveERC20PoolHandler.withdrawBonds(22804242426342, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3245269291613708975017483859937130946204004229); + _reserveERC20PoolHandler.lenderKickAuction(143389431773004540456148506841977195936295680314, 2, 3262450132446687908741231168305526605860279519421); + _reserveERC20PoolHandler.addCollateral(237724760849036285908916423403174707432118857243177028912719802294024915349, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1659381797795082335635921781, 1039182943); + _reserveERC20PoolHandler.pullCollateral(257278828201454660, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1541197422605959); + _reserveERC20PoolHandler.drawDebt(28684, 3875787990745657498795142304738440356199554616827337070788717, 5786042964398425950776628186); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(23612906838294937171329902, 9004023507141795218080889491415950757055416913167032817224598509171310253, 171258319723110004357710925605652364, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(2, 0, false, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 19334450208878065611194948790883826226743574351015043451399587918); + _reserveERC20PoolHandler.moveQuoteToken(2216418284553043233617038079218, 157209073197251032691309054939, 1030526028597965668, 1231672815441619461191235571, 62543); + _reserveERC20PoolHandler.removeQuoteToken(5596721942722557329667848807200, 1000003140213046688, 3416575153929464752848393592086, 1441513441670871600822246414689); + _reserveERC20PoolHandler.moveQuoteToken(24248933939642662263865771103635811624437068925413678442300404279, 21948929022726362433699549269572, 18907, 1032315817216247413, 2147800467); + _reserveERC20PoolHandler.lenderKickAuction(123673793356353219209777229943, 2345363127057177100232310230, 1000002366020491262); + _reserveERC20PoolHandler.addQuoteToken(648051072946852140905405429051529759, 3, 0, 620525787655179579453768563810611); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 3571698810485756917535409909098341670302547118287000989315400253044782028); + _reserveERC20PoolHandler.lenderKickAuction(1000053302091035189, 2999999999999999983862057125610523130462443289, 68618656953303940721611); + _reserveERC20PoolHandler.withdrawBonds(0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(39643930631789735643266877235361156, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 536008814691516073636221458568, 3); + _reserveERC20PoolHandler.lenderKickAuction(31642405455986471146936193485463672852804672763394926899429981124099323914, 928245158480, 651439633473352062289409897); + _reserveERC20PoolHandler.settleAuction(1005017975083897958, 21308, 52583647829029596555229319645776, 315956408269702456247507545881); + _reserveERC20PoolHandler.kickAuction(6691369386464570, 3847058374181600926015843903167, 97250228345334528162060572832680, 27551686973765941621395944); + _reserveERC20PoolHandler.addCollateral(1123638139390430544, 36377, 1009800879566217504, 2906839799907629089420478168360038163165050852863014104286832354921152512); + _reserveERC20PoolHandler.transferLps(366376647543105509879708177945166562028689985161915, 0, 98379394040124801572185874588135, 2, 24773644039711018133420); + _reserveERC20PoolHandler.bucketTake(190697836689925692940152927485570, 5976541473472559497526803314915072172280322639777939, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(220061742147736876055646381, 41316361745904475052811685, 5734662111163497695972040682425, 30412802970844556509162385); + _reserveERC20PoolHandler.bucketTake(1854297230295490150718976273959959948503946380792909650268548, 0, false, 294248954529961, 2); + _reserveERC20PoolHandler.transferLps(8048304785080843263923195042327, 10169993547478103632201285329, 1000000050087755995, 1023468524281531949, 1024532492603303625); + _reserveERC20PoolHandler.takeReserves(3, 3, 994799); + _reserveERC20PoolHandler.pledgeCollateral(1, 638526449742210117812136905122650683, 2); + _reserveERC20PoolHandler.removeQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3705, 11442208); + _reserveERC20PoolHandler.repayDebt(3000563907565888230926075018404, 4123284580333318751290106970091, 1000003071124996050); + _reserveERC20PoolHandler.addQuoteToken(161767987470053665076671429980, 64384154406298648500203, 221188860408058935854428098563, 1001391237363775038); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2675278851049); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(1072396632422191461, 2456637399279900174157036495316, 10131195993691, 999999999999999999999986081653485701980931430); + _reserveERC20PoolHandler.takeAuction(44714285186272241079819550098358782079663135275, 4886270639517350563226155922946031133566639607974042603585876, 136774485078, 612303788269808558870341203407589512329); + _reserveERC20PoolHandler.addCollateral(4226156114842195127988924341827, 3624818508892028318565794686055, 1000002856157569513, 32957); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 0, 1); + _reserveERC20PoolHandler.kickAuction(219363596475977954, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 125074450000975830110823717848156386177071685296114583044103580924168479171, 0); + _reserveERC20PoolHandler.moveQuoteToken(4004024166853, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2954182500537049414923117336576427645954243453454082590015513, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 9654438500270389526722, 3, 51996169046979365701878097796388196238116367560864592530605352650); + _reserveERC20PoolHandler.pledgeCollateral(57989046799583975933033142446476935231709315, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 43956888043993628211847531557282635616866709152686532111862701413); + _reserveERC20PoolHandler.transferLps(169286948634060643065658940647704718603123924926043854578, 294102767071490001553040071259859286836439, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 99197654835197313019124244559199076522378974308274033, 103555678415690201078464894696561188092794475805135558794959783923); + _reserveERC20PoolHandler.removeCollateral(8448676084785464631070891117, 603022832404071082558693438, 64459119569852637472931237065166, 18470704807434830198793053215406); + _reserveERC20PoolHandler.drawDebt(34290526534338941, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 551639407739533778990731255574383571306148788932306314749327, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 4383278399021953195305087056365900938713502919655192959); + _reserveERC20PoolHandler.removeQuoteToken(2277984266453, 22373391747897784130297590282, 29250743260294224808539451570320839364701149243918003436827404, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(37081520, 163868185584804124878717563010938759505721900, 76197772038442076470491596702846194521200809424963, 652602054186688473794735); + _reserveERC20PoolHandler.removeQuoteToken(26846571047064857759072116982532, 597088266373694146723436234383877, 1004863576897894584, 17375579409723286068326174797); + _reserveERC20PoolHandler.bucketTake(1028078553758156084880460843787, 208674355934458992823064476408, true, 4647881042317416157777515631, 228658926052830732251896288993); + _reserveERC20PoolHandler.transferLps(14311431588199952746249268386, 1030524053287924092, 946983513465831074499513694735, 1030525428893724392, 4360604238615975705163767628429); + _reserveERC20PoolHandler.transferLps(3, 2, 2730259878851164144730099227041196032168078052, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.transferLps(1068098988363929078, 3640956309738407240887019779046469228849106097013227280674202351652789318170, 999999999999999999999982541674420174735264220, 8875959449941209170458300955734, 2774661449352321); + _reserveERC20PoolHandler.removeQuoteToken(881546607252692530076, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5310302543849750313784287828067696433894619670, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(54671, 25054538719082605367354906979942); + _reserveERC20PoolHandler.repayDebt(26421636213883506155341365807692070721129117577589298715441, 4736416905657510585637901202340, 10744278009971119923748345400004777); + _reserveERC20PoolHandler.addQuoteToken(34444112174731769182207563874451048200665741662334669522778855415, 2950130435197952936141566566170371005320789416907265055412672416687285108, 1004659117450551159908695699348, 377347915223023198568807270857); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2651386314011818000613379621229523948, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 237399388978333871803488024196417624729167798877506831159428763); + _reserveERC20PoolHandler.moveQuoteToken(324626566325089005960993932783, 1001525391964445866, 1000863460931357307, 283587831217333526983006174551530, 213208709728391096935095); + _reserveERC20PoolHandler.pullCollateral(3655813922104623975822634528455, 7855581025412889261, 1000000002212442062); + _reserveERC20PoolHandler.takeAuction(191775822974891714811682940408352105432132034561425782738205282670328374572, 4537233757010977069, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 43140513633075412927783747157273846576454909296083265740); + _reserveERC20PoolHandler.takeAuction(2930541562355377308, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3524887105686755104973769062680329753547828956202662819, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(660358095128704142772464508941021, 1598636607053173934076979687367664556369955994942276542332931924970488680, 2158793770765394638242588566799); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 12055415430014624616379504600645004, 2200313653758533610678278428664, 2); + _reserveERC20PoolHandler.addQuoteToken(4, 1841886326538668923078328780566845522390593, 3, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4008109047552297564540045649789127388037814402296006823295, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 8987090475264); + _reserveERC20PoolHandler.kickReserveAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(94560873146727742886828132211660269134651597599935631101926269772, 61, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(787997585755624917724904569295, 1003512754026876698, 84134871564860491001654262115); + _reserveERC20PoolHandler.takeAuction(865908379592791524216476768454, 356093296, 883037, 111312387236282199835287909798772625416055149117022032157324363984730917); + _reserveERC20PoolHandler.pullCollateral(56180278291697116214, 3, 6076885022578); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 65755529377240830); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 47417); + _reserveERC20PoolHandler.repayDebt(118453919321782330763986865032145255304983926, 15323672449175759985148406866489842791321712131644915975234091012, 3); + _reserveERC20PoolHandler.pullCollateral(52584278520625880734642644156588, 432092806908164750672045414754231, 2999999999999999987897886313908659594478560502); + _reserveERC20PoolHandler.addQuoteToken(1036059998691821550548773949225525577059675902962088151965438749530040967, 11193639299517188159014449840, 2999999999999999983552886052415038974959428652, 17100300242567036427527614064271); + _reserveERC20PoolHandler.withdrawBonds(3393796622754434966956043431240, 3, 1); + _reserveERC20PoolHandler.removeCollateral(10982660804240211539338600000000, 55413, 1060573897813019481, 1000829771086674207); + _reserveERC20PoolHandler.transferLps(4037490362255245034007147793131, 6083960563725941670716447971977, 1089533131731590994, 1000395826122412382, 15066148277338555155003712477); + _reserveERC20PoolHandler.removeQuoteToken(187805123042349591231875141092733745486209999411825833941058644902780894, 3, 11764108508639429221329784799668809226640314843372246605042296, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.settleAuction(285704124466068894500518075899, 212727702028907423628474872837, 2279543410376566581550220196839, 73956953578265940179754094275828); + _reserveERC20PoolHandler.moveQuoteToken(103355054977238, 115292754447241907892024, 3, 855287360098831929359658341185788387, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(2141008421948550379326176125543652881531392001317908235981500770, 13088174446903093378715989149522, 1000002561364632437037623809128); + _reserveERC20PoolHandler.settleAuction(44639, 96678469923162217305937995350555147721, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(163173585473544033921066862447, 1440078024973148198034541166617041948427831090959234115538852307563505017, 1003357254021930644, 4313423464); + _reserveERC20PoolHandler.bucketTake(23247, 671300092435333643666142, true, 31985180602029124633205534915474, 11998); + _reserveERC20PoolHandler.drawDebt(348432577464826022031102783918, 971304816909508306947562589529, 1000234214397643933); + _reserveERC20PoolHandler.drawDebt(1000014580034176653, 787259183422495290057434887512, 122654158316450364644886913059); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 45242831238578419785940, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.lenderKickAuction(393810579373444228761694053, 74334, 55654831836235775856722298931262); + _reserveERC20PoolHandler.takeReserves(18350896104892976394025832164011619048700834580143145947421852982900, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 171736902283499841633); + _reserveERC20PoolHandler.takeAuction(2338428268094390850916536900350541856248, 15337, 3, 282201401299749225886066000485044899858361643292417818282548368574); + _reserveERC20PoolHandler.stampLoan(78901, 117116312038120003175508); + _reserveERC20PoolHandler.withdrawBonds(3, 12086083, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addCollateral(19639309139869978958429589224335, 35516, 125894550239730052475937244570, 466948701717420062893538518799); + _reserveERC20PoolHandler.stampLoan(0, 248445558); + _reserveERC20PoolHandler.bucketTake(417344237379199886792563256505626368330355911005140565647111242181233906, 4400173630433739355831204952952954, true, 28993641794, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(3, 3, 369792303428581026916658518721872057288497, 2358417043564691421526723014484, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(1, 777678552887404778419, 506437012083560603371303739458874830891453279, 2914459984106712213590408226753370358643224726643781434102562372021833572462, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pledgeCollateral(1065494611939028380, 1057372074842011885, 1002706451893623645); + _reserveERC20PoolHandler.pullCollateral(1003891145603955734, 9636469294474436, 15285535487095297849025418582136); + _reserveERC20PoolHandler.addQuoteToken(361069579796306906972829482151, 3118123372163047221960220272644, 4656128296395696151129445, 73981598591762902979859897352974); + _reserveERC20PoolHandler.withdrawBonds(31247, 3061282411175214414595965412, 52978); + _reserveERC20PoolHandler.repayDebt(1, 572443683678962837886080670695446580545642911147342967, 1); + _reserveERC20PoolHandler.removeCollateral(204318691286662889703839344204359710094582951854819286178734952276177385195, 345634184540070111996124142390183603856836785135407939693920825457482201032, 3511321835190796027165619892550241234545156022142732101, 19655298990154519606444187739177655553608964739215995835991730); + _reserveERC20PoolHandler.kickAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 11677727698892142073367740887591536162042799401017862286552424745092, 2); + _reserveERC20PoolHandler.takeReserves(1000537722791930127, 1001399948856084874, 1040442282556027669102); + _reserveERC20PoolHandler.settleAuction(475759225244954620462142, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1062226826228925217114137293349733026757295624642529544553853959); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7557122); + _reserveERC20PoolHandler.kickAuction(1401012919082882114, 57092711042853709801001131, 938946753463058538, 299999999999999999021361522289774512547007060800); + _reserveERC20PoolHandler.moveQuoteToken(32872813440691392132947401, 11928976209041059089429841322038, 66953606152693905081536867754415, 1001612660187994350, 999999999999999999999980035898198102476030466); + _reserveERC20PoolHandler.addCollateral(983425410735987234280447, 2999999999999999994306518664694468188410794536, 439564910041114833013872254184, 58096760945567555552978442108997); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 29036619133066327140840005993952, 1007104682373200810303837817); + _reserveERC20PoolHandler.withdrawBonds(24503870586299861607097609900649686154663261, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 24217071165972565689310311000577138111066070124881); + _reserveERC20PoolHandler.withdrawBonds(20178, 367288306286359551459402393361, 7183994386945913639260024500); + _reserveERC20PoolHandler.pledgeCollateral(1182169884308393196060607892553, 30303896126728052422731944611106, 1412169204550628170467507451); + _reserveERC20PoolHandler.kickAuction(81773668214496507577269667673065642523210785, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2173889465922414281854786); + _reserveERC20PoolHandler.addQuoteToken(389, 341372831542331435344103131200240652587323786, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.withdrawBonds(66772, 252141662471900094450218409886471, 2813571462404852604369887588851705367756867596840716023862981207053297); + _reserveERC20PoolHandler.takeReserves(5944302506, 4037531719347441733297291350731, 482546885167955249118933); + _reserveERC20PoolHandler.kickReserveAuction(1004859778805671600, 1000000896577375731); + _reserveERC20PoolHandler.withdrawBonds(237188807695502458169177283280230947809638887202044354972475439, 440021469694830237472142388148755822823, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.pullCollateral(333612188252069351334726438809450265653021176251918724177790073625837344389, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(68629049426333195236269069869, 1000000050658716572, 1074432440678482779); + _reserveERC20PoolHandler.drawDebt(45914384299803216218845211988, 63041, 20459435345366310915921745512); + _reserveERC20PoolHandler.removeCollateral(25160, 995440923369356974, 3834276736112111435089173986726, 796885586145716948226341853218); + _reserveERC20PoolHandler.kickAuction(24560, 35845, 78922, 3516510244716905325647919614075); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 126936457547209799204697252402185213454867270713353982765478620); + _reserveERC20PoolHandler.addCollateral(2, 2421460490158430454369983, 19987, 158860766920923437369473); + _reserveERC20PoolHandler.withdrawBonds(16818308163712329711808426472194667897010901392001, 1556978, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeQuoteToken(51133963045798958964686208532930121384427437049920990146, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 20, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(11392598872365598278729417336684221870019472685587839238, 1869504184266798607050279524676830500517602453184684905183305803910420127, 0); + _reserveERC20PoolHandler.kickReserveAuction(684941869536135586330441858529626, 6187866); + _reserveERC20PoolHandler.bucketTake(64210950564407948142586988532545, 45486, true, 6543255634891636076612227297504, 1064384900747576984); + _reserveERC20PoolHandler.bucketTake(1, 1, false, 19584398124015609078901034087333935155808981905, 228364994267); + _reserveERC20PoolHandler.bucketTake(2357618424788980109691212796232, 301465171645591179797885, true, 999999999999999999999967788807707724849043216, 1001432351188039952); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 18806389606948300808380972548414092777963838908540290495900304724407109015665); + _reserveERC20PoolHandler.moveQuoteToken(5303657604602269196137479656292598131806137517267, 120236361168, 737382015326383, 184614641633350709045452126086434020467699407, 430154721); + _reserveERC20PoolHandler.stampLoan(18227668055845204916232725533882, 1008279349013253020); + _reserveERC20PoolHandler.addQuoteToken(4768648597, 49225, 18216611593527841432002230448, 1000067898108287267); + _reserveERC20PoolHandler.drawDebt(52026428490606390, 32723207234189124401163021738584064338, 1); + _reserveERC20PoolHandler.lenderKickAuction(12029537800858888148298145877, 8372201916811682002028555006435593089409594693362141814, 4617684944586825412042922487281089750910249134384); + _reserveERC20PoolHandler.repayDebt(1, 2647646633336744414456344185167966552159485252558301277344385793871450, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(1, 58041863068023855683815221066837823045199259989, 0); + _reserveERC20PoolHandler.kickAuction(47581941456446119413585192832274285164558451363010726501113, 305970184875363988261607492082835777230887171896, 749731870920141077411985827979304650657288719392705, 368115294535932818276); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 173109186723788146164435782234976, 2516392652563887324996500720457405357815078130137591293100571022812, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(603634373282531204263993507457118, 2812845815145785500666435508304135605971588609221769760013626508605210888, 8328, 52819); + _reserveERC20PoolHandler.moveQuoteToken(15930094904274496947955948234430, 6810540642707584, 1270642507130544717, 7875449627696196747450168639846, 2999999999999999946239484853633183007977406545); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.kickReserveAuction(902214372, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pullCollateral(2362325869030242816081556189341287696231, 210289965168038218312776121926440716, 42482027232337467093328187828747576908388453096702601826); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.lenderKickAuction(1, 3297793170898470983233703784830307285455428429840130828914011274979, 98296068432447); + _reserveERC20PoolHandler.repayDebt(0, 1635320245638182424144093617244436451461168845470981957811241527881334851833, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(1001504366550434752, 36485); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.settleAuction(1062967525586496243078764, 1, 88341146273604936245190991992719362490470765167542527196064, 244849965845584140990386880441); + _reserveERC20PoolHandler.withdrawBonds(1000036180947522891, 1000075818796340655, 1000057449489438481); + _reserveERC20PoolHandler.bucketTake(271839318149630457045799209071, 26628, false, 17375062889742142550796268194, 21712); + _reserveERC20PoolHandler.repayDebt(1185630553454626098, 9816339422198997905423342432876, 37634); + _reserveERC20PoolHandler.removeQuoteToken(71246283319766018881096965287, 1000042159307008366831666, 395212329723112458471675934, 654604027793905586586153); + _reserveERC20PoolHandler.removeQuoteToken(1, 0, 52871919405545348172424969490371406061014140383, 1383588); + _reserveERC20PoolHandler.addQuoteToken(38770458906805883674143416663411, 19173179833309231615272742271310, 1001667059636996025, 83953719753360188477010779252); + _reserveERC20PoolHandler.lenderKickAuction(21435, 6661710984742503125868625965769, 2999999999999999985733377318209586755176861900); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(6515108231565709525115672471, 1021535857277361600787742668747470534501116495845393152408321880629433880, 288212593012650303079708772843); + _reserveERC20PoolHandler.settleAuction(62787686, 4428042499748429214084052711842775721250, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1168817669424894957378147615885); + _reserveERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 0); + _reserveERC20PoolHandler.pullCollateral(808391216223514149261318672264, 47882, 1001679473155434561); + _reserveERC20PoolHandler.bucketTake(89324311065178651145384506900251, 3181907244474443199843541, true, 39953827385235427320669416, 188709160100328140452909880139385318194592958451412); + _reserveERC20PoolHandler.transferLps(535111403952649008741808806432833353197410623429861201809376, 37133290369304815156465258046575757549641278, 140380728846803763413451818, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(269420665309822283361784036, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1824278644366186369231474292, 68705760335); + _reserveERC20PoolHandler.removeQuoteToken(2, 0, 9640215524831006841269340551151155473389207355461347801318774691121963097252, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(494587674085086605719629, 1126551850138216499, 16976575010303665108919077498241, 24729870813589003134801497018497); + _reserveERC20PoolHandler.addQuoteToken(1691217197104743270497087626644891769317021148023358008512966729189602249, 130, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(6912563504755788048322, 1380401572334124478156074042, 2412029785787265233914724319267); + _reserveERC20PoolHandler.removeQuoteToken(608767512544964982759802225701, 3297790649713080912739218368, 4258280593526425389940727329509, 16924813005132850893929277278); + _reserveERC20PoolHandler.kickReserveAuction(1404282098533359283661796194278828220651065679704542214397242852344082876, 1000000093314991679); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 32758089620896055744901322023454257362861465868379328902119938, 318039485097497679053375529512718428068665660054276363232366571271278237); + _reserveERC20PoolHandler.bucketTake(1002141416014638466, 60603745337062195334585400000000, true, 1093345216237186187261558026223, 1006537012239813250); + _reserveERC20PoolHandler.takeReserves(3, 402456370641974709898707156732572797601976626226767530080369110491220836, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(13569798698252873500826408917, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 3); + _reserveERC20PoolHandler.repayDebt(9162515023128128431427473381039234542, 0, 8095645119939646563950959012406101543602858827633855217611532); + _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeAuction(612685692243904505, 1061790069486751793, 1000000015759766739, 3322034136410414721367175833245); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 26199170625336724063111166618295344316588148997720125060154930712191858356699, 379875629486840200511193732504130946879114); + _reserveERC20PoolHandler.removeQuoteToken(169993413156558013442518945013666, 6006647418164541672809255249880965738443370144403845827, 3, 1); + _reserveERC20PoolHandler.withdrawBonds(3, 2014007219748430642113648937116357276837867517411157265945873264282938, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(18371328, 1636009562930891777834110004425779066535849700919571361797, 404192993452004456, 1); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 51129901656220409071675616417332715, 188752646614865209919921578629802913369483452175148530157482771636, 269689287027390190789155117695222296972466010209300859464577507534224543481); + _reserveERC20PoolHandler.settleAuction(272982579007, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 38329414290104406518790279, 27062072318); + _reserveERC20PoolHandler.pullCollateral(1061557214862442518753075089198418697883047303695654888100, 1116025707778431587608, 65058703246972711996119851226671501620101255); + _reserveERC20PoolHandler.pullCollateral(476157213815710026764478239657230222491369613667408341250105938782223431217, 852652123281737767291824, 29824375455928752149841596855510583525413222573405068650824); + _reserveERC20PoolHandler.withdrawBonds(4706133279202222624727979212681, 32146822935996581063664326608800, 55619904411654654400726540123130); + _reserveERC20PoolHandler.takeAuction(1019191095071931035, 4361091195716796291584645866823, 640632599034669235, 24832359543942068571923595783521); + _reserveERC20PoolHandler.stampLoan(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(49508, 1183559408628638256641408484605); + _reserveERC20PoolHandler.takeReserves(2916238662387805255255346474603, 1000003546036310199, 25940368475958843057822131161811); + _reserveERC20PoolHandler.drawDebt(1000012684876263443, 3116609417767080201443, 136086659285667148101696014198); + _reserveERC20PoolHandler.addQuoteToken(231993617168, 2604573, 546178414262635019152910138075298294388349726161731534134932615988, 3539116680330163155373927636370761); + _reserveERC20PoolHandler.moveQuoteToken(317651921330919178067830439167838639851089232028071265811351057458932883984, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 98795877); + _reserveERC20PoolHandler.settleAuction(3510838931605670292620090608, 3542729781070556481759952201288, 1793956558602089574555789154277929619269052508544784009485153225750887587, 75189454873364953344384243324344498659181030022739929501447929046676795426457); + _reserveERC20PoolHandler.stampLoan(3, 23264280080086599769687033491852256490958958551792481762299937390); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 30707576976); + _reserveERC20PoolHandler.pledgeCollateral(11598103847078409431066837453319, 999842174626873863108673235631, 1000026752960220762); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 10999413539, 1); + _reserveERC20PoolHandler.addQuoteToken(630116607499214242850010852409051631239813569094, 8243811222233157804266470783, 1923074708397356399749633117116596746814572, 363828510437170898148404928483866122905783731976899); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.drawDebt(57590583091971784135743116857210, 30259963111796639067281351546133, 5801361343474060956478624492); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.drawDebt(1023549910723118715, 1328195674873330162, 1000003133027407257); + _reserveERC20PoolHandler.moveQuoteToken(869111625684278668204125554586116688587289457118960101390547591271528055, 2732699609858347268907, 1720687725131265821078366879090936264931404387906760854555804597035912518, 1182626988902725465003252031774, 1006239776452531970); + _reserveERC20PoolHandler.moveQuoteToken(12553685800350601451098069994447, 500000000000000066709632548, 12469201618423089609354024833272, 1638849054178496043716490939353, 2963938058929329058987143141122); + _reserveERC20PoolHandler.takeReserves(2633778689208086621600325414024789055605224349468892, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(946774033607353591711096606467, 1000000292116086906, 3529538957775340898977947513935, 6527438603816496735721107087); + _reserveERC20PoolHandler.bucketTake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 11, 2098919986983); + _reserveERC20PoolHandler.takeAuction(2254570023, 6469970308173145763400000000, 638768582896856895767727951914, 4518352570373276935379912026748); + _reserveERC20PoolHandler.transferLps(21364, 19215, 377893466289830799641706685166, 823739265, 2988470281985318683580344192961); + _reserveERC20PoolHandler.lenderKickAuction(3962160435017153498274314016175, 1000000017347941781, 999999671280035337); + _reserveERC20PoolHandler.drawDebt(4488214488, 7170401932687350288352391261081, 1001431290788513585114686645430); + _reserveERC20PoolHandler.settleAuction(1, 10208207037892087829277543932425206012088047767, 2, 940457184848051716401038788671192913652980495384717406326672); + _reserveERC20PoolHandler.bucketTake(36370136014276, 2, true, 3973503736227805, 0); + _reserveERC20PoolHandler.moveQuoteToken(11060, 205549512007020186189905495519, 583217162811328436557245791584, 25055682190784346993398028450748, 10588607443642541686302390209); + _reserveERC20PoolHandler.moveQuoteToken(1005506784793427698, 49408, 3343483457, 67779015508917952228408096593884, 2576308609402805831640203204237); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC20PoolHandler.takeReserves(1000256449419128299, 1000009762340804919, 60222887034774007364358843803087); + _reserveERC20PoolHandler.transferLps(236653975348113458259171443039, 20089644412939349756453982984040, 184450331801338353588057248084, 19999999999999999997884029835987860337868501148, 2382233734007972336238794); + _reserveERC20PoolHandler.addQuoteToken(105326755413799629772162, 82840133286038311202870171682706, 80990, 124462405323395744155838400039); + _reserveERC20PoolHandler.addCollateral(1, 1110245310284775, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(2, 304232902686867885858981201643435810800357541423280617421160482180682, 1, 20763945910853557673333577, 1030533796309751212761796408239741116361897783468661095645684258); + _reserveERC20PoolHandler.addCollateral(1999639959095920240104667570515853595548945227335451789233, 60481338532745061862233565679992579266362399049489735933359622914175851660, 105, 15580959409686066102399159462431655198397875632306611662050327217216); + _reserveERC20PoolHandler.bucketTake(20, 0, true, 1527324728550870304872625455797513984, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(3961733777129452838541012228139, 53903374324103989294514653440, 25112610681384299423251347510549); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 18241910070449345510695450, true, 78377542424259062827713321724809847462259115539, 42072471233266534277783696009271650631769765262963621237); + _reserveERC20PoolHandler.settleAuction(1, 2, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.addQuoteToken(16050979787500727673575061205013046301015884205, 3, 1819999739731635841474715044659085884930243083, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickReserveAuction(11337973223315249784283662280, 7244155905076693945032979376029); + _reserveERC20PoolHandler.withdrawBonds(126978111067398, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 153033121464986925388230992930206784376567445858962120265); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 49909453005765830807664161507383029242881163921462242496, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 10566857280219293002871800786, 37592669066859315048038509505231117); + _reserveERC20PoolHandler.takeReserves(44607084154612840015575, 1, 0); + _reserveERC20PoolHandler.kickReserveAuction(8289408046549762307283625993477, 176737626740298562497375781021893); + _reserveERC20PoolHandler.settleAuction(289480869459603498613225665398032152542262109371146584001393668, 997827645040285063722630029742, 21231, 2771890772609385134596); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3808360384361168889302105483860989519833534381494002233616697853); + _reserveERC20PoolHandler.lenderKickAuction(1000005970047438116, 11435281379914596292224152114, 72938999669641824982067591602304); + _reserveERC20PoolHandler.removeCollateral(6616581386831937138940728245192844799591145841218759708901523823933482182, 1, 163471592671915079616748380471742910138857500160674831970040336141, 172198315907731311250); + _reserveERC20PoolHandler.kickReserveAuction(0, 3); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 8505, 3, 1166673196049899640555791090067203294222744894); + _reserveERC20PoolHandler.stampLoan(9822174294330495473534655, 3998429780014773547306182956794764788616010881758026); + _reserveERC20PoolHandler.pledgeCollateral(0, 1, 2); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 832737097845005548789901012957889000198506802102412329949126364385369, 7932, 20265523192157858654642640310259418513444986000327488); + _reserveERC20PoolHandler.takeReserves(184496796061197336714380000461191394778570983, 10362951668780622788728654046594, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(934, 7755217422134656390454475392031); + _reserveERC20PoolHandler.takeAuction(368615967911997057162758356236960486391723455187264041, 258612533307483283815850869613368944066156909222460625608178, 151821660444704098011768607486634255838734478894762773, 5378255430549720706600260099937); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 6571612672661488482870928139050946016770267190355203087744758680130, 1, 87297493642452471047770481467516022914512946128057162553706451023); + _reserveERC20PoolHandler.drawDebt(238886784018884680587568005115, 1000043284544045858, 4970073921677034851444817294127); + _reserveERC20PoolHandler.stampLoan(3, 598578792299299581251632856532892934729798354881346787); + _reserveERC20PoolHandler.kickReserveAuction(113652099411538303217671714, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(3, 232998292761); + _reserveERC20PoolHandler.moveQuoteToken(1067240267552535568, 13416246877657478651819660, 2972555037205432845792841692580, 1000002235732643421, 4375634635884227270309218964532695); + _reserveERC20PoolHandler.takeReserves(71632186783875320927968718914, 102386786996979421632819068827443391, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(1000056502039659808, 3489956751067833650463706824100, 14931791841840284229152017575854); + _reserveERC20PoolHandler.addCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14948637254819748284301, 2); + _reserveERC20PoolHandler.kickAuction(1690075249129992691786633928852, 7211013679990825, 476280539996254370363909772886, 1009945224140246113); + _reserveERC20PoolHandler.pledgeCollateral(10577436386061688092483931250784414042591349077895009036359026594, 34405105673457324309721145631560, 1004375942484576097); + _reserveERC20PoolHandler.repayDebt(45036, 1000000012273721863, 30303180061606618480633184989837); + _reserveERC20PoolHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 20437729105059327025156200826273197832136460390578444037051617394028); + _reserveERC20PoolHandler.removeCollateral(1039103637091668178118346279, 8848003324780981, 22765, 1009298993668993242); + _reserveERC20PoolHandler.addCollateral(1, 3, 3, 2619786150515829150566455342542271259180813); + _reserveERC20PoolHandler.takeAuction(5759759806217462819011522377279163549659717389372452177791087753400, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 225047998619797935946224190906211132430524425103365602); + _reserveERC20PoolHandler.pullCollateral(30303974904978694544734711233613, 9277381251803792082352123743230, 307822884028080537032901941); + _reserveERC20PoolHandler.removeCollateral(1174670110583673052282586464545093, 41119813715931750261727320603946812980840680282681802293, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.addQuoteToken(3426716217109678367292648022105, 73409641992746506976436282341, 912708340865933693130813687675354727871122233615893582642051340482983839, 434683825830945480375002954097); + _reserveERC20PoolHandler.drawDebt(47378071265460061835123031, 12220890912476110565633783060, 5057988605266915); + _reserveERC20PoolHandler.takeAuction(45503, 722666296251915177931645460013415, 29317, 2395003884509596434705448867872840151044192144933237770661063155782455693); + _reserveERC20PoolHandler.lenderKickAuction(70074602017956677936577923622, 850006997988717341212949767934, 1000000342647510816); + _reserveERC20PoolHandler.repayDebt(881436844026950121494788739652, 1915579911726836380164759250751246014632563215739322182365563915704559910, 103392966151834720169371862019); + _reserveERC20PoolHandler.removeQuoteToken(923800147088217962177574438391, 1007710318364723356, 174707245355991918620533487153, 1000000000066909451); + _reserveERC20PoolHandler.removeCollateral(1, 102, 3, 47226782861878630494264346832468759698322372224646849023159860); + _reserveERC20PoolHandler.takeAuction(1, 45699778, 370148119561664889, 3); + _reserveERC20PoolHandler.addQuoteToken(1000000331640414039, 4987, 10302149831528467700043673024153, 133408829763179851121016804099); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4023834664364116034695637965289717289988460523080494828470, 72302422437159979542765984419341609687685404431379752802398552, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(0, 2, 36043771804395259106077243431813096678558736329438245216301201111384349145106); + _reserveERC20PoolHandler.takeReserves(3, 41679061318044774234918971590114682238735914331, 3); + _reserveERC20PoolHandler.bucketTake(1, 0, true, 538478399909566423422513616317971567443, 481229344522910246015489528574213270); + _reserveERC20PoolHandler.takeReserves(1000000201306962107, 1000000008007780791, 38527); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 1600760824885934400401511405567171829199563519244276); + _reserveERC20PoolHandler.addQuoteToken(54949072542679471126054523852230216312007883696110620103871457135966267, 2, 2, 7976707692738660); + _reserveERC20PoolHandler.lenderKickAuction(1124566382891082874, 1000001628474111024, 1000000001455624077); + _reserveERC20PoolHandler.removeCollateral(10588382767244802342019917924, 548592784658694787195408, 15753408336281111268017724, 1000002100633881844); + _reserveERC20PoolHandler.repayDebt(1000012867176409856582799, 61582094762591623313645189352, 1000002509693696402); + _reserveERC20PoolHandler.pullCollateral(596, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 139758413196642138279392); + _reserveERC20PoolHandler.moveQuoteToken(1000675703118033996, 6069657654482372951235347762, 1012948992634861897, 55746295109666377953361, 2663520191802667151752193677645); + _reserveERC20PoolHandler.takeAuction(0, 2, 11141905586145962553946446240020521175568413694430588, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 309517391845897, 28783125686442171524035710); + _reserveERC20PoolHandler.transferLps(517913178554799274877140803407371, 28988190134824672161153142938661755531821299355465141, 214130748321254204247, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.withdrawBonds(1, 1703377920385534741557759421940957027625, 3); + _reserveERC20PoolHandler.takeAuction(3613304376426316262438, 1217549301744811866502890040326131, 187809674657452973474515962946552646955078698266404963015, 274288196043232512372238371979346); + _reserveERC20PoolHandler.kickReserveAuction(3, 0); + _reserveERC20PoolHandler.withdrawBonds(3, 3, 2); + _reserveERC20PoolHandler.transferLps(37690, 1000343300584052368582208899249, 1000095319319620488, 1000438066261331401, 1001429138376881494); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 23426263212796888936661599993890513960910034508020, 89380006167170403281722886342763997663970510976663132969859426867119335104083, 2); + _reserveERC20PoolHandler.kickAuction(1002101389767165062, 299999999999999999684830407381148174934428400700, 29446107326529458453480300000000, 39168); + _reserveERC20PoolHandler.removeCollateral(0, 5006621827752839456, 7330966906116054721, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 246403, 103016780401340335058642331); + _reserveERC20PoolHandler.pledgeCollateral(4837982049327522473354706025, 27128180169460124930083772268176, 18829055428916575578521072088066); + _reserveERC20PoolHandler.pullCollateral(30976045172989934768964155, 158480334039533386185380132852500365950932209383196484067, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.kickAuction(32685719527851505807605037295, 996438865206679962, 2339290182654819366118196459452, 6138739082194562888816261767); + _reserveERC20PoolHandler.bucketTake(1547321435884480259204015223083163054524756829793415337173, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(1004199175829084600, 3963687148195783704248654556574, 145662581868648018078193529269, 13573994); + _reserveERC20PoolHandler.addQuoteToken(241318503486344697607232865506674930, 446502218538695545178129, 19906475109258654719760, 3); + _reserveERC20PoolHandler.bucketTake(24052338999347483591725098638040, 2743860706059738695525133786161, false, 263784801442113424464018635514, 125738281629227655078932249075); + _reserveERC20PoolHandler.withdrawBonds(37519, 4937288841, 3396923309841586841797520640167); + _reserveERC20PoolHandler.transferLps(1024375925055844584715544163274, 1054266464717456456, 7875509820474889506071223494859, 36983100848020789874278014514523, 247089489442689005262182); + _reserveERC20PoolHandler.bucketTake(1315, 23337073614258561787688793658978, true, 3655746483742997569051797437398, 1000001532948335882); + _reserveERC20PoolHandler.lenderKickAuction(3539409818531861675929839724547, 31476328900846215519265, 426418291638456561316575408976); + _reserveERC20PoolHandler.withdrawBonds(312389002838688, 10416295114392094789635166973002472014107796109359394794080, 27527); + _reserveERC20PoolHandler.pullCollateral(388139729106665537018, 4214506778377114593600068928449193, 3); + _reserveERC20PoolHandler.pullCollateral(2262722289819684715902700803785253596810004427783, 376781712110867269407133809391758331759541114428, 339461025); + _reserveERC20PoolHandler.takeAuction(803098259488491494409518745341644364, 0, 1019419, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(0, 40746324349086161032113257175045313400114863775525431861130432234800402040, 9263743269744509281793655299749334960797133547545558729920986461891944902, 741741003532460474943235); + _reserveERC20PoolHandler.addCollateral(226821794650984905098831823710925, 1000000098031038220, 1000644407352123779, 2999999999999999984980177534865407594454171014); + _reserveERC20PoolHandler.removeQuoteToken(9102539219628923726041848748, 59410937807593976713341242644101, 18712201346545470262322425191, 371345666270070000475200103106305); + _reserveERC20PoolHandler.transferLps(347140240436420124194448579095875695392753578704550245549634627753292566631, 76435050032717036460995256215239, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 38957828777739628786650583266806602016955492393736033913894761437, 0); + _reserveERC20PoolHandler.moveQuoteToken(0, 3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(788017616788741289223292574024, 288573868731839268879444894132, 606292492745230233581614); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 240368791417238, 0); + _reserveERC20PoolHandler.repayDebt(923077448879890138959579703987, 999999999999999999999952127494363765279889696, 31024077180029900686415556726639); + _reserveERC20PoolHandler.transferLps(121261817354808787196102077548, 81501234786151203711151630142530, 285706412297209815145665709473, 3521476379991125116310774142853, 1000000005154455098); + _reserveERC20PoolHandler.withdrawBonds(1000355055663309096268983415747, 128594063942993449809958677199, 1720921952831973150831231386024258208431685650460818600847893543877856639); + _reserveERC20PoolHandler.transferLps(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 394052755694489389432360025550535798380431, 124831318, 1034785825312254259600130723502400707053931473152724988393260854); + _reserveERC20PoolHandler.bucketTake(1002098740876075163, 1000000223439427392, true, 14943665865967874006821291821717, 1006385835212980779); + _reserveERC20PoolHandler.bucketTake(30028194897295845195447499701760325568456, 115792089237316195423570985008687907853269984665640564039457584007913129639935, false, 2, 2); + _reserveERC20PoolHandler.pledgeCollateral(3834370914637250664634396139265, 1000066465154745026, 49176); + _reserveERC20PoolHandler.stampLoan(22657512889353718646501758918323, 14993146573278895998680094441452); + _reserveERC20PoolHandler.addCollateral(1000000000000000000000000037226452113912994924, 1000000253672366977, 1023061112222557934002898504048, 1000000010705497898); + _reserveERC20PoolHandler.addQuoteToken(320239442736929919504024902865, 2363302943570375503010004733595, 36680967435214802615164801562848, 7145); + _reserveERC20PoolHandler.transferLps(704221791586679351794086397951571691687278201183763089800, 45108390739690422772297501488146078902714936088996749787, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 4702200886144770605754208181448652486831319331685571320); + _reserveERC20PoolHandler.settleAuction(22592253128485667261659651807390567837567219616477100144, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.moveQuoteToken(4652997912128709297160873200, 1000000139862362003, 277433975519704473159617031437570, 3542226206409518654309762750599, 4031580380570482007522399); + _reserveERC20PoolHandler.takeAuction(189955404962934464086018381415, 102864382345012917388286, 1003645642636798003, 591716744564703508667442055222951); + _reserveERC20PoolHandler.transferLps(107385993658156502071197084877559580383697124192333440897300780371667718, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 19216144749101112974853007604525906, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(15836, 86142443992187596334189088672017, 2714421680749298681014); + _reserveERC20PoolHandler.takeAuction(64224287196871251176405921192416, 2999999999999999974302240697500263113830799001, 10087552314460509419157414648, 591382822894202225810984682); + _reserveERC20PoolHandler.removeQuoteToken(1389520214757978040095491, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 544430067418071995553); + _reserveERC20PoolHandler.drawDebt(1000097312485280780, 107266368203244590257795839773, 111818073958478123568909275502); + _reserveERC20PoolHandler.withdrawBonds(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 77422192309757919); + _reserveERC20PoolHandler.takeReserves(3, 846038055344330550, 4148780983751778773753267919551822758); + _reserveERC20PoolHandler.drawDebt(765038846269783500099343659509, 1001518301205338854, 1137515106322056727844935120216304366190291723016822061408520098531379984); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 187868757974780429415735679278877431393190195488983136445081231821503384, 1183929916, 18871999214613407109628255690904, 2242446264495199221674611106129764842772880152688906770676806); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639933, 80695621489206335006237, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(15601547432054064887208807532947, 1004694282594656722, 6663969409867396978859125344002, 84879); + _reserveERC20PoolHandler.settleAuction(12568801609480883633035099914208172071123431053017265160930424157222865349269, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 5826592154003984707490553716444090111024470441966787560, 37196340301618914826857411273397, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(24541299943220786604118900000000, 32342, 1000000031559064034); + _reserveERC20PoolHandler.stampLoan(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(12411284593095759038440106551, 125901899311242193868225775048, 1000013775055288462); + _reserveERC20PoolHandler.addCollateral(815376687610364763988746977196, 743841609910578563130185, 125911898828500833946383750599, 240426891849953731092386223566); + _reserveERC20PoolHandler.pullCollateral(117176320934761186087757869544361642443557163310498569871984404941338, 18345859551623, 20370716063762137244462511383165687989750834344556887743944787894494); + _reserveERC20PoolHandler.removeQuoteToken(9086991667443138147587633607, 998003112794614567, 10874947560581250829736873808, 2304515590546611778157321568172); + _reserveERC20PoolHandler.transferLps(47266621164112469512400469251305576, 3, 1, 15109579810965206862064101260152872496529999379446, 170534185382487067223064056367110554927); + _reserveERC20PoolHandler.drawDebt(2999999999999999997517766924709639139191710568, 55940, 67856671249928450448471592427731); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 19994411340192929547472242674217224986183520140847900749695924340, 8135193611926131347170380091, 2168199286921218114001063015473094246316416498950441064098914921433); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 20221326443135608122839939645839762814108223013461177486045102506527670); + _reserveERC20PoolHandler.repayDebt(695042622421457570875422, 9020036760294328785185171532172, 1000985757772400570); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1309594840307647245798411503, 111422209196844240721); + _reserveERC20PoolHandler.addQuoteToken(1000002163697292973, 29167794476036418330047639545572, 1000000010676154642, 79522); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3818433064975227162016, 2360343553481278); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 66417923472868172682788791293195305103, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2208350558450789724653915232303721629616117364244792897571116); + _reserveERC20PoolHandler.stampLoan(1690042573333297967980552561824, 2443058595059278378152533384599); + _reserveERC20PoolHandler.addQuoteToken(9816898596511520497255757746135, 1085984237956549962587300760972476402895001366746893096440397998908693012, 13992214330883263659848784176897, 1922844711091998532935194294467920511638317806919418868955755727819975435); + _reserveERC20PoolHandler.withdrawBonds(1787272288128625, 84799887446507604955173839589522666249515399, 41714325412863598494191424675636245671095); + _reserveERC20PoolHandler.takeReserves(27762182674536828712666218, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 17191461950209269642480311446978066196829762849588338437056505486009762521080); + _reserveERC20PoolHandler.removeQuoteToken(1000004429772255917, 19939976053425536006090322576654, 1000017140698797115, 1000145816823952956); + _reserveERC20PoolHandler.pullCollateral(30960957131520647077697100382380527533068937388821674262941346, 491436143730454, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(2890554817638527177579823276775, 1030230952017636490, 23140, 1000000013839251437); + _reserveERC20PoolHandler.moveQuoteToken(667819214812340537250948565746385971453885028745, 1, 3, 31299039733970642686866, 3); + _reserveERC20PoolHandler.settleAuction(11098149320936033941536089760340, 771326846036810021354178186643, 23973322713652917448671315563251, 54031708165246203550291111550558); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 46246516615085563140258004545553336197672199938213592300191144, 3); + _reserveERC20PoolHandler.drawDebt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 103014287803325784998252711632555600361038699741083673086641151587); + _reserveERC20PoolHandler.withdrawBonds(0, 2, 146720955); + _reserveERC20PoolHandler.pullCollateral(433693023071513699564582494659294762573490761773944502780330150460, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 55946925556204728021599780); + _reserveERC20PoolHandler.moveQuoteToken(1597014381277321856147369237187870243668249306405711848, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8573724461219542940361188942061135662866837817228, 675206340785232989181744529331641775582610099778438829826975601179, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.settleAuction(0, 148698015841464332276030304718898489507827997632, 1, 324733843294490179739869331223670602628897601297299550819514840662); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.bucketTake(967141761, 968743143433752541250762097172143516, false, 38904292173237248372632527356841411481949441508769, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(141326, 55925285961450, 13827512188304209570925732); + _reserveERC20PoolHandler.pledgeCollateral(1000706622135274400, 172196184571848232960454967849, 1000216378692139095); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2307968507674571129511513642845521644983919996479044836353263398760008, 6180815803378973906972435045296534512941160796076421298480, 261930831500836565704353565077616767083454473339249, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(9741824990513571863311859198694489401732196511438677071920366420, 3524609894353703413335280621422347328795302, 35892709434419487468647565630337820006241); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 71136194073654084937566541402416190576015174108); + _reserveERC20PoolHandler.bucketTake(6452067799189866929610964425983, 1000004655698141810, true, 17021488344563955547836181631, 25055819039343175987375329131248); + _reserveERC20PoolHandler.removeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 19188640178241105650995912410430008414412840297395828849882424481783160513528); + _reserveERC20PoolHandler.takeReserves(1340588347014257592678956968302149406663320862192604840579, 680197033074293631399730441698903, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(48874233145077304245626, 89024167865547780578225904645210056570844, 6013868499778138372488337781571746074215878204696330963499, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(2, 912715245580322959228289692178461875051852599847327784704390962975, 38272254987600, 623988814333189179395619567320621981588000668430709141324536797108569); + _reserveERC20PoolHandler.takeAuction(3962163103765603985673780605984, 4385366429081614323247307412, 3413691637, 1000037939574238755); + _reserveERC20PoolHandler.addQuoteToken(9224766534704902056563710241721, 1001314741618949153, 332198191376579820335196974438, 996522958656701940); + _reserveERC20PoolHandler.drawDebt(28653380789685580573478238617453827246918814182478647928170318965687, 39197059999834991350081830803176681177019883, 119124669516323471168237); + _reserveERC20PoolHandler.settleAuction(1009298916377840114, 1719, 5035094874463451039920774294706, 1168141700616438799717206063171); + _reserveERC20PoolHandler.pullCollateral(999999999999999999999900053509, 1000044888058919597, 6452067799189866929610964425985); + _reserveERC20PoolHandler.removeQuoteToken(4943811731654855836017319560603, 1000001552411096195, 2352519343047818754347040698135, 1000000410076345943); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 63092109001565621091769211466, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.removeCollateral(216008451503468684004788409283, 874440031281868659297700000000, 217545546217886334608284, 70519273744378501076681512217315); + _reserveERC20PoolHandler.withdrawBonds(1000003588641559892132703538208, 1090236744706033312146787770136, 16947287175555604776378616923); + _reserveERC20PoolHandler.kickAuction(15554, 3340352688130053, 3, 4501098384815345010193984678968760458975495980569881530657); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 258848269840794489084672034941229132360399125185, 118844829431089563645841179, 2); + _reserveERC20PoolHandler.removeQuoteToken(21716718136902835020296254102028, 46843029267, 0, 1542815109789519634697614724067626228820531743241849461843929880290976); + _reserveERC20PoolHandler.pledgeCollateral(647086124643395187887244600286993691873, 28391417316323085303342036, 2800999204598252643445149550766758086755925970389); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 147803871, 609064974885220768610); + _reserveERC20PoolHandler.bucketTake(18741873424827133890530110679842590749271279560049451830, 33793958597217216533846558731514312157228992693547238642, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(194486496686599881019446325730, 6892, 14682552720754873457579891065690); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1069105208720748163279985342749021220706088581589738454739079, true, 0, 0); + _reserveERC20PoolHandler.stampLoan(36475, 1387834457110398512); + _reserveERC20PoolHandler.takeAuction(66222446, 1, 3263071408539432132048041956589446841714060406397632730487, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(1189166733024609935831483780, 1004978555946048114, 154491030144373365485); + _reserveERC20PoolHandler.lenderKickAuction(255956387292562622480482133864, 384173833782878751650863607683163, 877769466424550463658491899183545492039449302931769670469518681557684576); + _reserveERC20PoolHandler.takeAuction(54076724224437662187893905610392, 1000981593818555757, 10055525842010611507000000000, 477411979173555673400000000); + _reserveERC20PoolHandler.addCollateral(2014233025335984702651125316948, 7522788152844797531341090770, 1000001466600199908, 80570616164241285528260372638569); + _reserveERC20PoolHandler.withdrawBonds(79393224801056831229862253292799679149970413684759218628672935353, 877808272, 74116076955732645116965921); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 3); + _reserveERC20PoolHandler.kickReserveAuction(15446567934037059809, 4024772527099662559876903714934213991648073045203022886779376); + _reserveERC20PoolHandler.takeAuction(27492, 65679078409471218047988105651127124377757004404137197774796138373350509540675, 282801619238325741272970949857, 299999999999999999638697599107918089851576891600); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5573355251400986954594580466600887858460633575); + _reserveERC20PoolHandler.addCollateral(1012948922934162877, 14023692599523120252333121456000, 826495772777524253600000000, 1000005497119326390); + _reserveERC20PoolHandler.takeReserves(944908111768724333599799829221, 1025390734099246900, 20360); + _reserveERC20PoolHandler.lenderKickAuction(3514567108884285890618849089215, 217350681059589414657890668195, 19734180020152223576585865639462); + _reserveERC20PoolHandler.kickReserveAuction(1010082579674167480949354833991, 7289340998630622207487573372085); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3288847532839); + _reserveERC20PoolHandler.settleAuction(1, 441969839339019873547, 1, 723969299745316204979127287835029021428); + _reserveERC20PoolHandler.removeCollateral(3, 141443938043366932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 128401212456735193987480015184635455967388391104651117340, false, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(15818829042462260969103883009, 1096842623189866608, 29460967865594942227081951236722, 140740499870539172659280755664); + _reserveERC20PoolHandler.moveQuoteToken(162082727856096448737025818788186890928170171435500, 2, 43421849350937361765235399685107918198041, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(1000000615268107976, 20464079536742740553051513, 1000000011620261557, 913665569947660675064178734429366424396945184408909444989128783776174318); + _reserveERC20PoolHandler.moveQuoteToken(847295039860273503803004540182323, 60222746796067881597270960740165, 9102529564839610270491388509, 75557292692081467644429, 996690736827651365); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.removeCollateral(3751380187641282, 22021, 2006183349100215204428960409299, 531339619731344510800000000); + _reserveERC20PoolHandler.drawDebt(0, 0, 10810796442364135788425435126973706568478665304); + _reserveERC20PoolHandler.settleAuction(834770076821890549699687059229819979874383160029435571586980, 2, 40025472798600069005262572479827016499044525962, 2); + _reserveERC20PoolHandler.drawDebt(1, 965166148256093, 174858752867135543658225504257297290877650702608492582); + _reserveERC20PoolHandler.addCollateral(31167585579846889154289043850725, 220599285419903579943460, 3966034322773388382096484517426, 115231007485356357675273351560); + _reserveERC20PoolHandler.takeAuction(58363553, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.repayDebt(1022680173809898907979973603660, 1001391102101990972, 1008874242815740570); + _reserveERC20PoolHandler.transferLps(432613673231725889151461766034600170785207754642, 1, 8332563085161574763713937497924006565591691790964899948563011798913938, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickReserveAuction(7125139065230616780, 2274683383169829974249); + _reserveERC20PoolHandler.removeCollateral(3, 1303046641851118004026502459788464565, 300576895448948121749147338940433917360, 10468); + _reserveERC20PoolHandler.pledgeCollateral(8889937480657214826555982, 3, 13182472147340456366408990794867986606848952362); + _reserveERC20PoolHandler.stampLoan(0, 521696435901308964); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 732999410671906231495866407, 0); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2206422393311301454027570, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(1000004238856615479, 50887772728097235375495256, 34309, 125901899311242193868225775048); + _reserveERC20PoolHandler.addCollateral(24187988318258990492975575280916, 45912, 1003721627532237413, 2600192616355176865404393347902989136451531713288277516262336833429744121); + _reserveERC20PoolHandler.settleAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4080983028116672924804, 158314003981989476636972950016351187980311525876341948168718137537); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 95650909932184327291777064182440, 1177121981183341828575230139555877557823936022883809424930827435572007573105, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.settleAuction(1, 509347498796641919830, 32966169687952516927171502887723038987824308864662328836775, 10186776422941877255207139070663900173571591883697346687754846327512479850749); + _reserveERC20PoolHandler.addCollateral(849589547301717065598075320912026, 1001868370451195958, 1001404521416118377722802161592, 1005845652820914735); + _reserveERC20PoolHandler.takeReserves(1073987024277804403, 2766711794612820307653070192123, 1954268703878211242919964918882358936366471859675020309768780460376901874); + _reserveERC20PoolHandler.takeAuction(2, 3, 103325896526371265659700926990731444055019129478016828683821395594, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.settleAuction(1532180801470488617687301726375, 1000000007287183776, 1000056835713188997573617446042, 844730644942249933122179831179); + _reserveERC20PoolHandler.addCollateral(13607557307009445915653542, 138649508552079838697473348012337242, 61683010888632545033631783509559517792445, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.drawDebt(12239222346993437890219471012741, 1000007706693786568, 3552813424); + _reserveERC20PoolHandler.lenderKickAuction(86566133743422718504181722208267265429460348023775626242998327363561, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.moveQuoteToken(92942101407947541380641756506, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1012921, 31558707372105, 92740276650645948178050072748757); + _reserveERC20PoolHandler.removeQuoteToken(0, 25451924015853713052392322635849746589577792752651740, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 562); + _reserveERC20PoolHandler.kickAuction(29105, 9690057363791132578202459483505, 14895635749245478318274239968160, 5472542385); + _reserveERC20PoolHandler.bucketTake(1608188379519430784109219384, 2, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7500757330817107970730168032); + _reserveERC20PoolHandler.lenderKickAuction(3335856250784427316854388585612, 1831519572, 2588611080705090826430024138756); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 9799845433227239077, 1); + _reserveERC20PoolHandler.removeCollateral(1000003068621086463, 64479647880383811038650109664532, 1000043150009275523, 340464082070127722238149140479); + _reserveERC20PoolHandler.lenderKickAuction(1, 0, 9837467268849239612287880037008634521870646959326502103803196865); + _reserveERC20PoolHandler.lenderKickAuction(624818508892028318565794689000, 4975125107185204995339019924600, 1012949983865637432); + _reserveERC20PoolHandler.transferLps(0, 2, 1209118249639963089408417839847297808434100104239751352, 7820684663897512250624402097509569145318539126, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.removeCollateral(1054262044386166033465639231348, 1000007939143412275, 1002145768253677954, 3275342514); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 48867032515433698141299); + _reserveERC20PoolHandler.moveQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 9738792054362252343209362969067284813358969297, 65451807277202, 105844411); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 28005949, 2); + _reserveERC20PoolHandler.addCollateral(2, 127811418, 3, 1); + _reserveERC20PoolHandler.kickReserveAuction(0, 3); + _reserveERC20PoolHandler.repayDebt(37431, 20952757304256975404470316729007, 18816223392043264987990346378715); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeAuction(61034807308042061781990306922298, 1230143636424094626, 10760959323544656587353423883716, 1000040551081346596); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 114258699830975557922500656433236980911755830809034588371828057329533471); + _reserveERC20PoolHandler.repayDebt(52427965093446377324190060732, 1000098797393109027, 1009114683691152940); + _reserveERC20PoolHandler.pledgeCollateral(43321167198131815734, 2, 41518540797378126439584213649170064950708); + _reserveERC20PoolHandler.settleAuction(1, 81326649478092441635379671335863, 5111247966413051129094045254726790274298403521972347534, 36912356550981490654054878); + _reserveERC20PoolHandler.settleAuction(5586030468219170545687518074449, 15455844325997368278533084, 39270877460605565863082054062689, 1028664174942666237294691439012); + _reserveERC20PoolHandler.lenderKickAuction(836572526086282985836550956240117, 847972868224877223639188078250612615079591, 714148241246555180); + _reserveERC20PoolHandler.stampLoan(4734631045700311066275044608699, 2672643627168383970169); + _reserveERC20PoolHandler.lenderKickAuction(2077848752388765472442656653151418902493727991565473262173939713994405106, 72374680305797534515424381084197, 20109); + _reserveERC20PoolHandler.settleAuction(2889834209647151286487374477720210532570018895354433950680566403816947712, 994551129436228503, 57654729909195818694290225313743, 1000009520550163253); + _reserveERC20PoolHandler.lenderKickAuction(17934714343235852, 3, 17436289584397176465253940288322246033717820500299492408); + _reserveERC20PoolHandler.removeCollateral(20159486916214, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.takeReserves(91391064774360641448137334979775250444298393440958539726, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addCollateral(13992219334675237600475044454410, 1006241522670716624, 1006125565562585394, 71725075692369368369585687710666); + _reserveERC20PoolHandler.drawDebt(4283, 106672217691195642861693, 7016727264415269591872819067972); + _reserveERC20PoolHandler.takeReserves(15246882911015977468643958003825311107108964817832447256575341793, 290593433, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.stampLoan(4790639904151014592973324925381068790862802210108728664958022540791, 12520); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1534557, 1); + _reserveERC20PoolHandler.settleAuction(1000043585581052781, 177362148, 56974946090541675007137584488, 5524082923247780); + _reserveERC20PoolHandler.takeReserves(4842753902381828801200419653927, 18842685813748126072831783816430, 638809966979160283564002547224); + _reserveERC20PoolHandler.removeQuoteToken(5105394692157254, 2075045569315549360992002970516, 2928, 1000538228674718549246360521486); + _reserveERC20PoolHandler.addQuoteToken(8676816157873569386249409152518943839997254896369393662075515293, 3, 412614816123030104179656328815616565222853434071539951527999459490, 3); + _reserveERC20PoolHandler.transferLps(146266019434337558, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 4049, 9085381921233484354167682685130963490144583426360631); + _reserveERC20PoolHandler.withdrawBonds(4323382957944262943715489105499, 896712037331892539, 1000002334129696383); + _reserveERC20PoolHandler.drawDebt(1737613756154081028428970, 1015122592225593055863293105136, 1463400166269558891616991425502588481882513258381565755325346333767105974); + _reserveERC20PoolHandler.removeCollateral(1195967497154266665392326753, 9004626415096858067877346166893, 140692917452701742199526689005, 17622954249795678047857085897852); + _reserveERC20PoolHandler.addCollateral(309461054358147, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 51456708728295553452498405521446638566599818082450508720334590700341138729); + _reserveERC20PoolHandler.transferLps(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(938926415679436331, 30273, 2207724769227284423852621423895); + _reserveERC20PoolHandler.settleAuction(177276495033409827444873073105763176041077187075486479688969202253860, 2651154558128181912942223107511645508, 2, 627866031255335545661096910633748874022353); + _reserveERC20PoolHandler.transferLps(19832453371284769678141793094718426621644413505914189397177385580370, 121829065257071, 2327430265899884128831308622688553890452723132862212597434275199802, 2, 1); + _reserveERC20PoolHandler.settleAuction(1, 0, 18294988818366756653173759825218778935248507, 0); + _reserveERC20PoolHandler.pullCollateral(1506335163755303416292106333514013280015368919685323194587, 1816156661630092298969918201996105962574096, 120103596645374601041588949407964980510975905383116279144607080638); + _reserveERC20PoolHandler.addQuoteToken(10957198066059685861749614, 1, 2, 4500371874444309671949377); + _reserveERC20PoolHandler.kickReserveAuction(3, 0); + _reserveERC20PoolHandler.drawDebt(620383167246479648103560793759122, 697977707591234435270187758, 2971062223112618963310409); + _reserveERC20PoolHandler.takeAuction(17886522992952932380962696842081, 4903368828383879580949906577763, 4966679077509529, 1000810471165815426); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 3); + _reserveERC20PoolHandler.kickReserveAuction(5420915650039017965270424377042, 999999999999999999999972996243178248843477262); + _reserveERC20PoolHandler.takeReserves(5536934887326285853430, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC20PoolHandler.bucketTake(411303303243784301606111417416758861910445701024822397574117611415608, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 185208712582681440603490568, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(1057399210735276005, 1000981559610947842, 1008448138271207844); + _reserveERC20PoolHandler.settleAuction(472535495732263927359594109306176, 52090111867777734993951391056054974660760925663444604668932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2179587109914692, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 36136755); + _reserveERC20PoolHandler.lenderKickAuction(299999999999999999921047244281821579500534605600, 2545589195599154981, 1000000007055382150); + _reserveERC20PoolHandler.settleAuction(139802583704900057662432380653432138308064929281367728382512435, 1102995322542639082261, 3, 23436523256720704764); + _reserveERC20PoolHandler.pullCollateral(20064597878581567719843646310818919156394783937918, 0, 37747657504641653115233844484); + _reserveERC20PoolHandler.settleAuction(60096848, 107388537972984051591376368363195434239233207270306, 248485994902838517882004045065116171803199090402812201380147, 3712435095433979336870182245175727062565); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 376669895298167895903734701283589110717959022234377, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 7011565306586687531399975266823169942471530019852451796613258117718702938); + _reserveERC20PoolHandler.drawDebt(5531242699371453420741747259392, 29143952444462064698348424965665, 5847905067369116262871532845466); + _reserveERC20PoolHandler.addQuoteToken(255712231048134018568093655285, 719447200, 2, 1269703989504302707343610103700990029145711214); + _reserveERC20PoolHandler.repayDebt(3, 160566014222219874826990588140601204972275, 239648123296359877430269996443351459343952889005570393408709206574811853); + _reserveERC20PoolHandler.addCollateral(2741768819291386141287, 2808770964078985576222949423264, 1004903455064855425, 1010053610817872674); + _reserveERC20PoolHandler.bucketTake(410101574093433452017836806884116051604812531869102444205210035848942429535, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC20PoolHandler.takeAuction(1816428621, 129744208895858962678874823774, 28015374918524712992798879402, 5147048035); + _reserveERC20PoolHandler.takeReserves(2, 36165065439499901921717228537605353668347580655673046124470528950499593375, 771555); + _reserveERC20PoolHandler.lenderKickAuction(200140510840569305, 0, 1205113161574253735679027118072); + _reserveERC20PoolHandler.drawDebt(11286987850996347780, 232281403237554034093298, 234822181597180991679708234222); + _reserveERC20PoolHandler.pullCollateral(14469686436917147154289467, 2749357885017384613273, 1057212034098332834563010074362); + _reserveERC20PoolHandler.moveQuoteToken(1, 89105777789803, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 446932322169093610425185036107744613357286); + _reserveERC20PoolHandler.removeQuoteToken(7639946804100964, 9749820071020678989669021577701777253208, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1070136142227155303039824343385310213207249671704996700175129); + _reserveERC20PoolHandler.kickReserveAuction(1000000495190198978, 1525115229823853936870457941603); + _reserveERC20PoolHandler.drawDebt(2237484487496924187416928809, 33, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeQuoteToken(160570482691949605861496046338477852844855249539513783170680410652650313788, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 933321485954050778278691988870514791618030295130063); + _reserveERC20PoolHandler.takeAuction(3834415264739451135448395822679, 999617720655146910366477105390, 4822325516153381655518840673298, 2911416067380619769211149193891995890327319452553691348321344929391050752); + _reserveERC20PoolHandler.repayDebt(29815286584517834100680799175270880617435600624161818231251661355774662983, 0, 11930097831220); + _reserveERC20PoolHandler.bucketTake(93182, 1432741878175885155091324325591580947261530953334739422559382999212278121, false, 3573939458980687106100522030225432140326385674148983080458824750151486, 1000001181931675832); + _reserveERC20PoolHandler.kickAuction(1865160553444770725092937895109, 83063343945432155627493189196201900263335269365669636870162403425611185, 1000000045345927803, 106056446148660962870369457995); + _reserveERC20PoolHandler.stampLoan(1000000072727872829, 1008928657502851122622839896382); + _reserveERC20PoolHandler.stampLoan(4936953274269581128883466352154, 1001504366550434753); + _reserveERC20PoolHandler.kickAuction(8345086075182899630358513, 0, 3275010690049775929897764337595302826, 1); + _reserveERC20PoolHandler.repayDebt(138432014788, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 13659372656286609938858539600497364464457); + _reserveERC20PoolHandler.addQuoteToken(54079285809274504735508584956492392287, 42251939535519781392988573611015891830055490606, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 12825039282194629817347256884); + _reserveERC20PoolHandler.kickAuction(326860160021154798172071132777186, 1001524810602126853, 76358033609953764325060266798402, 1000057990805429437); + _reserveERC20PoolHandler.removeQuoteToken(61035105306253529114981109641218, 50888244192488855922435634, 1000000002863235655, 35405346163797164573203013641680); + _reserveERC20PoolHandler.pledgeCollateral(7216865946462408917500454710096102986611381171506094, 636495622218794602764435888193160600160793068246781, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1915520593); + _reserveERC20PoolHandler.removeQuoteToken(18852015796772440115593620312686, 25980307072213987371854726231073, 2999999999999999993993947889601511467513772177, 2077611101); + _reserveERC20PoolHandler.lenderKickAuction(999999999999999999999979761695953737579495857, 7614928371738252803841340192, 2859932310633341388743104752493349135255662004502963408177733419495042079); + _reserveERC20PoolHandler.stampLoan(1665997190146573905110400345, 25144843976847580134556087406856); + _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 98, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeCollateral(1000000021384504981, 157341432941538175869150058878, 42007, 2740338920897844167938); + _reserveERC20PoolHandler.pledgeCollateral(2605862188524225296048003030617, 1028319602280824181813, 139061805264648754294276112942); + _reserveERC20PoolHandler.settleAuction(147432356806150240817970197, 745998911379363684764778006132, 2011477654666822879155570080719, 1000002005588097579); + _reserveERC20PoolHandler.addQuoteToken(1000004918760104538, 113316548744346663829779, 85019243285840200334300375063099, 1001160918964580846); + _reserveERC20PoolHandler.removeQuoteToken(99608876738708189960494462855897061545093943220425693600629281, 1062616227352873938723619059980897998946521, 7565379107847194126179054101996980726915745961849560802162584, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.addCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 4001408220171816864357665774859600834309912939066569648688); + _reserveERC20PoolHandler.lenderKickAuction(406990318788496062271921310527, 2208175451059163648900000000, 1000177168787411855); + _reserveERC20PoolHandler.bucketTake(124917907604787277515200, 1000032711953814011, false, 286350775382693520740710547254, 4225719933); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0); + _reserveERC20PoolHandler.addQuoteToken(20599, 59915454665915144329599846399, 154525649909030218049748118116, 1023419231511175465); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 236997447043497501386043610066602232319567775768626687243619, 15727773361864271307993497659317181827867948); + _reserveERC20PoolHandler.transferLps(164616705933396243227, 3968440809061455338407662835263, 1000004550111860459, 1000000237662865888, 10577065684767405916946389867129); + _reserveERC20PoolHandler.transferLps(1000000747087751522, 285704097369426494303251944526, 4045693043246061110837350344787268633365917791710233024614408126330728, 15919367867038832112916085304004431679403, 1314992559917595836); + _reserveERC20PoolHandler.stampLoan(54072873209856571119923236540097, 1000765286959929512); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _reserveERC20PoolHandler.pullCollateral(14261700477923685943380876946, 21076971515037762466929605947021, 16987795039132493710082163); + _reserveERC20PoolHandler.takeReserves(28152949599418778459589846105360, 22132, 569701639173967089497962647115441); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3, 115912362809081898, 6455660709626623131642219054188861514); + _reserveERC20PoolHandler.transferLps(293442880542610857993, 63, 12213430311154162041502390863, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.stampLoan(2, 5738888577190205643); + _reserveERC20PoolHandler.kickReserveAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1576143068193286821169426114921580203); + _reserveERC20PoolHandler.takeAuction(7541682682561141662110758582, 1000456584681406069798389298242, 2745644410033317721661959, 1957267147); + _reserveERC20PoolHandler.takeAuction(197297, 23972046626150186554399589260293631744145563154501789, 11980001969056859784365206286667284718365461551491176700692486761079554978079, 18666433864275857713082021939992471578961880542721449378833005); + _reserveERC20PoolHandler.bucketTake(3516579893638599840, 87483419593160249663320316096131754167804363, false, 1360445988, 17310861115080322011907902391674834114697408629815349); + _reserveERC20PoolHandler.transferLps(872954644012163317533924151584790811054130423356938346, 42124650447198312022620223244, 3, 2290688966619449546525012964197286063172, 1); + _reserveERC20PoolHandler.moveQuoteToken(156300081179142503935454087771, 4980376406811634321150159458499, 287928895811517343585668032228, 415817230554637415748692412065, 64224288685164283188462962513865); + _reserveERC20PoolHandler.addCollateral(87923809197666111519428279469460419050, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5946106253775136005134909319288124174064591876353355331456, 585); + _reserveERC20PoolHandler.settleAuction(531524750433068781326933709034552753554289346941096646640059066366, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(67921313755638519624118834407, 53768, 1000000016255986268, 1000000282897180804); + _reserveERC20PoolHandler.pledgeCollateral(3, 10436372706916240499614180931285888874380376, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(3, 133776705759155053510739085523195761736790866423732850462662282110358, 2923716264118549302); + _reserveERC20PoolHandler.repayDebt(3, 4319907065215784885373987, 89722154528409124483692848974794525); + _reserveERC20PoolHandler.pullCollateral(2464294490171943169859381757189585946437501719459713, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1997581319501734014284293345545); + _reserveERC20PoolHandler.bucketTake(1, 10693056818757472532249787, true, 1, 3); + _reserveERC20PoolHandler.lenderKickAuction(30442573281825719034923394512444, 999999999999999999999993636701231776950641863, 1000000771602117053); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 75612, 15799825630222571); + _reserveERC20PoolHandler.repayDebt(606551387991801359463056914911291, 1423906092376099397956890946191, 1002119211751005069); + _reserveERC20PoolHandler.kickAuction(63826121, 140725429750402097, 40980717573817304852369908693200407697310300009891330638670973947085837501991, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 3, 36340488506676538105854562811803004657958940159296582689430413985500); + _reserveERC20PoolHandler.settleAuction(59816525929766374155800000000, 1296322769493142379, 3162457805591358904400000000, 1000003884155781518); + _reserveERC20PoolHandler.transferLps(1320313947070732218159011976891277081459491339243182915717, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 288229358692278005249779548612879542463027773047872362, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.withdrawBonds(5376409519998385240012664913810689647038752975553178538461135, 1, 2); + _reserveERC20PoolHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 244547542987445907997445536070773376491536850746, 5752914069420336009242634558121286888003693950, 80927300); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 11999469580287768671073428181, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 232778898266998125286073247909702046339828358303214298, 35989527759459190756886060873735884799682799837861487501120, 43319023891401415423288683114615743249157537247895891699420); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 5267936740558937398938304660686297286951090649629563809, 31932893039408461563389105531996191, 2408794); + _reserveERC20PoolHandler.bucketTake(8780064047119346613143486149345965695987527604290, 94904601260152064395719467299, false, 1, 84538995916254692683167227633042336484); + _reserveERC20PoolHandler.stampLoan(1000000060244284906, 1198395560378283574390233372764943003409042826313857830486015); + _reserveERC20PoolHandler.lenderKickAuction(21536997094922048227235018732674966822340175097756392212725460113311, 1, 228862411715320164879792); + _reserveERC20PoolHandler.lenderKickAuction(20201483770428636782425719761982973190961022934173193062833, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addCollateral(11880844297608292620873573241316390697844671241977197465622362240545087208, 2936158986283141895299152619772179235528202215769687793281259343597990, 3483039900355987266069656898242146077903182132522439153612671, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.takeReserves(4484671482368079955734585945, 1065838723559587806, 9177573940153613770866284746638); + _reserveERC20PoolHandler.pledgeCollateral(49708302109877815335850505431262469724532716584575, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 53423010568); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 10487549887120875247700500154511886799809, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 815469874981876229212426178670155363952339150308493382597092783664154574, 1); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 602890131688403258330835299843191320798699502356218495623362643955, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(230747604284211202646327161541162, 1311747082606470144699862267660, 1000122073011495466); + _reserveERC20PoolHandler.removeCollateral(755579566040575149969107, 735897324167573398273134944481340610903, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); + _reserveERC20PoolHandler.moveQuoteToken(3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 1985383001339104815550394727193147525878072272271154104910211219419781334); + _reserveERC20PoolHandler.repayDebt(4215059458086271241843344807073, 4338983905220692468843437410751, 999999999999999999999982582295400578078324942); + _reserveERC20PoolHandler.withdrawBonds(245663687566001052982470268900615, 1002140051226005241, 1939861938); + _reserveERC20PoolHandler.removeCollateral(4018702147293660432441149712832736627881, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6297710844089087832581272103376202809050790547032391931454163529586891907, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.removeCollateral(74613, 2239598874405409591689906990424, 33686, 993083453493944125); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 0); + _reserveERC20PoolHandler.stampLoan(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickAuction(1000053466025319548102767247749, 30502148941185267773414018655676, 6918705557718471927332213054002, 938929543681988692); + _reserveERC20PoolHandler.withdrawBonds(2443674003517431808767878950505, 18178084646732646051104133416381, 133354483560115873925030136081); + _reserveERC20PoolHandler.removeCollateral(323590642351027263266844755624, 22687577999212545443374583600967367427887252586114888241350355044098, 0, 3); + _reserveERC20PoolHandler.removeQuoteToken(16840142628753122976822523676312774109000345562878515435351486490715, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3314, 55801818588062955); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1307151277103691726035, 89183035429270860160583718100283032547000226502276460, 199904418647441836664); + _reserveERC20PoolHandler.settleAuction(4694345956111144, 45548067148662787980635639207672615, 130441103009722954396446120771495841559762550086, 146867720798629793537275932530376015072670); + _reserveERC20PoolHandler.transferLps(1132829106296816137, 36712615166860652658566792571175, 79309, 18247016129631708318474833, 291845993859991370779206400320); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 94988359332251014298512078173586417, 945846480260330880904593831115298467806294731692126509, 0, 188206894362710977247089966789359773636934016779446469409621979139); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 10287448821797781285401690039084444, 2); + _reserveERC20PoolHandler.kickAuction(3, 23181601278878066537501823341365392511687848334, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.takeReserves(90668873881776985054998931, 56495545257117309601751766935, 4930681920859154880892879037505); + _reserveERC20PoolHandler.moveQuoteToken(1000000003467465758, 48209911293278568189972834532, 1006887352673641389, 760566058251224962596489616708586171179571461766357517366996145171700093, 6779179653870343673566272031820); + _reserveERC20PoolHandler.takeAuction(1000005084229651515, 4146159838820013138903480150818, 1010765919667516226, 33606458890863150292147386); + _reserveERC20PoolHandler.lenderKickAuction(169779641316023136680201222829, 1152797156961794706824458846489, 65258458428172656217981162128123571); + _reserveERC20PoolHandler.settleAuction(1002100815827445535, 12505085163970382376772376000, 998214331156758114636539199658, 123370108992727187046827130112); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 190424718932452241350516984348438991370985746302594706442086664198220845, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pullCollateral(21195972264145669721129107885, 1211465245964974629, 95865059949284999548593820091785324903360134779325900387042543662754215500231); + _reserveERC20PoolHandler.addCollateral(312212877313993854931070439121828913893166885785805418, 1244018834078702157339842423136267470270119064338781123451732538830159760, 3, 2894400191975335200526335564717135821445883320830); + _reserveERC20PoolHandler.takeAuction(999999999999999999776192414025193997456975173, 29370881221058862951906474, 23168739164561700647316864288983, 65460371095600656241120038186551); + _reserveERC20PoolHandler.removeCollateral(3, 2, 0, 3); + _reserveERC20PoolHandler.pullCollateral(78089, 552942729127093104059209, 60222868298216994724591806286125); + _reserveERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 131019114100312520676401667259372464447802622136205463460916); + _reserveERC20PoolHandler.pullCollateral(1000000844156171133, 1125180032921010707, 6917682506848364959914308185); + _reserveERC20PoolHandler.withdrawBonds(1000055238561526049, 32464445566082942447646, 1002533342993334438); + _reserveERC20PoolHandler.takeReserves(0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pledgeCollateral(35112825715589544096993776215621, 92145036669947891160705570223, 2713926143889458881306669522159); + _reserveERC20PoolHandler.kickAuction(1085662888232, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2020701485735006686083798598642422596839239587730605481539); + _reserveERC20PoolHandler.addQuoteToken(9991, 28950624635698808828843848099642, 1999998173515981735999731750865, 1000001264225875396); + _reserveERC20PoolHandler.repayDebt(1019303272066308816, 21260578278908530694045151923881383434215204946063389669421528068, 32027707242911234917141228); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 41643873364654674791051371033691524584494634004, 107672895999065996871587984503340071329869903961723234754843444159); + _reserveERC20PoolHandler.transferLps(439418782267416931308829621923, 3186798217817062529, 891742974645706957771366326695, 6697568672, 5167219512132677014763184593); + _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 11736921156026182725929916785045, 25312040207); + _reserveERC20PoolHandler.settleAuction(2576216902536704583834917178072, 5613963504635648271331244745401, 134966526301680832041644054702, 145310982838873237656495863771); + _reserveERC20PoolHandler.kickReserveAuction(7394330324982687798146440233258961299255900825384068615156030611691217493351, 165474090); + _reserveERC20PoolHandler.settleAuction(1809167443674266254967745327317518025729923781356861, 431460080132217202123943331205950927836, 515727590009829056064485302, 0); + _reserveERC20PoolHandler.removeCollateral(54812, 22189896295455598446574964153339, 4922666057537550, 46451023159374697024324488); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 25438912356796440193153189834824187, 13978, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.addQuoteToken(77949, 45167, 458365587226, 1000065550921713090864396); + _reserveERC20PoolHandler.kickAuction(24715429546763299895872111732523, 1939359212, 7204692030907274033569232166, 3536284505118342936025797114722); + _reserveERC20PoolHandler.kickAuction(3, 3911929491, 858358727948132680064362613300060208064619448830837205942598550779636, 52330306336269066798090491628653225151389794456190); + _reserveERC20PoolHandler.transferLps(12187845694986315780494136619978167154730, 465301214580282217519927249475661397900643665141012045787590467816228785769, 1, 2914010532384288143560738040697194277317793651169518783056234785289, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.lenderKickAuction(767027985763182116699292492230962744428019069, 6529047072964542993226026874842529045651737949987480169057366592220, 6249233460216); + _reserveERC20PoolHandler.kickReserveAuction(11758236945925548077335948187975600008603191847, 61998); + _reserveERC20PoolHandler.transferLps(285437854125016611868485996382603, 65410, 1000000029286149003, 2904146168185458338692888001387082352453012293629463100419405364974847291, 3724496696419704423104); + _reserveERC20PoolHandler.pullCollateral(464004192404203960972527909669857, 8757957825194850107261729956172948, 1000758178169407955); + _reserveERC20PoolHandler.stampLoan(2013411910316, 50910891947825399057770753223152022778129798550395727104695481582512); + _reserveERC20PoolHandler.removeQuoteToken(1, 63719627278214417474298505448752470812881908708080775213771505702638628594449, 62026827906317524154218640693, 190879673793972821369296023600241706701830821188489); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 7785750890094029071664961829791221, 4116468159171997611605908929669744715060856, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.addQuoteToken(1907430912207, 3, 2, 232654324799289680542158851804906575869400609275270252748323979837); + _reserveERC20PoolHandler.addQuoteToken(2304600140487772986939990827584, 1000054837708670318891437251242161473740111785682717646307108465228808126, 1000000258743434017, 1000000815454882956); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 70291114302478456190455812288729, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(793672211293006137588732798043124, 14129532867579676119069762366, false, 139749551409465340836751525710, 30184249111605178497545494); + _reserveERC20PoolHandler.stampLoan(972853389022726375964443910291, 395294316376357847072415411350); + _reserveERC20PoolHandler.removeQuoteToken(76540293226156317838381233985, 33406039747445803651, 0, 2049371501829); + _reserveERC20PoolHandler.addQuoteToken(993798654756994855, 32092500537638565022682474532034, 33679905383852455503602008, 53303070776392236677187222016636); + _reserveERC20PoolHandler.withdrawBonds(176154853644025348, 2, 209540593155512076016427081204281523422460712060927142743303406497); + _reserveERC20PoolHandler.settleAuction(1036625054951159218576324536904736950269194834481196342, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 59642198424255298855224058002267666); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 56315037881292585052352762870369682376448641462609407438455835044146283977877, 2); + _reserveERC20PoolHandler.takeAuction(38371, 4085349053, 1000509079385184849, 1000980559012355438); + + invariant_reserves(); + } + +} \ No newline at end of file diff --git a/tests/forge/regression/ERC20Pool/RegressionTestSettleERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestSettleERC20Pool.t.sol new file mode 100644 index 000000000..04533c8ca --- /dev/null +++ b/tests/forge/regression/ERC20Pool/RegressionTestSettleERC20Pool.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { SettleERC20PoolInvariants } from "../../invariants/ERC20Pool/SettleERC20PoolInvariants.t.sol"; + +contract RegressionTestSettleERC20Pool is SettleERC20PoolInvariants { + + function setUp() public override { + // failures reproduced with default number of active buckets + vm.setEnv("NO_OF_BUCKETS", "3"); + super.setUp(); + } + + /** + Test was failing because SettleERC20PoolHandler was not catching expected pool errors when repaying from a third party. + */ + function test_regression_settle_then_repay() external { + _settleERC20PoolHandler.settleDebt(3113042312187095938847976769131078147978133970801631984161493412007580, 71508422573531484609164655, 55359934378837189558162829458006585270105); + /* Commented below call as repayDebt is not allowed if borrower is kicked and removed the handler from SettleERC20PoolInvariants. */ + // _settleERC20PoolHandler.repayDebtByThirdParty(1333, 3439, 3116, 2819); + invariant_quote(); + } +} \ No newline at end of file diff --git a/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol b/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol index aeb17e536..6cd0cba8b 100644 --- a/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol +++ b/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol @@ -148,6 +148,90 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants invariant_auction(); } + /* + Test was failing because invariant logic for interest accrual was using the pending inflator to calculate HTP. + Fixed by calculating HTP using current pool inflator. + */ + function test_regression_deposit_failure_on_kick() external { + _liquidationERC721PoolHandler.withdrawBonds(10151, 18965, 1020000000000000001); + _liquidationERC721PoolHandler.removeQuoteToken(365303, 507275043721539544302939, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 125911375); + _liquidationERC721PoolHandler.pledgeCollateral(3, 9996808070360292113771437527343998095987, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.pledgeCollateral(6307, 872, 341); + _liquidationERC721PoolHandler.removeCollateral(6605, 20566, 24086, 24750); + _liquidationERC721PoolHandler.settleAuction(3, 6680755863680591634516978573228506572678958484447741053105113661241, 9834485764842002831925334809916199166633064298755379483552181801112594843616, 50703884214635118721624182290913); + _liquidationERC721PoolHandler.kickAuction(39057024788508847549173945341071998484914610296608937202299085565969969640252, 3235, 10804, 8417); + _liquidationERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 123359, 65135767502483322888879658363255802111200969216152288244494, 3728304808243239040071486687027857); + _liquidationERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1148335230970937770228357354206417397254312, 1035898490921891589378470660981278329641, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.mergeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 250816888133993755286503823043955376630422416601097); + _liquidationERC721PoolHandler.drawDebt(11, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); + _liquidationERC721PoolHandler.transferLps(15164, 3320, 1806, 24015, 76658); + _liquidationERC721PoolHandler.addQuoteToken(5042, 26511057352925151874817900429276281706694346584662189088043467429524323658544, 3995, 110349606679412691172957834289542550319383271247755660854362242977991410020434); + _liquidationERC721PoolHandler.mergeCollateral(2501, 5506); + _liquidationERC721PoolHandler.pullCollateral(22041, 23031, 10131); + _liquidationERC721PoolHandler.settleAuction(11839, 4259, 19703, 9693024030714756568067279153903244326330763878692170628927831827550217958896); + _liquidationERC721PoolHandler.transferLps(511931736016295037753186721368463022982877302778388892623354192, 553696476731907182347014230710049406932822682801485701715456718968074388, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC721PoolHandler.addCollateral(55413914203880181617863896666300790188000185525332589491462336155216289396896, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 133233428933732810679239771747092881, 2); + _liquidationERC721PoolHandler.transferLps(1823912203085512184641541, 1882264261310549184763878438481473378, 9390339394047767, 4414974500083230285889258322251947670680166129266357160851208, 1454257427256505668793722804826066321244748623461395675065095); + _liquidationERC721PoolHandler.transferLps(3497, 373702251020986977207790889868085050901394374962, 49090186810688179261078073503577808280209137270570567486019912342355983157986, 869, 21668); + _liquidationERC721PoolHandler.pullCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.pullCollateral(11, 99036894565123307346187197492593689057928629848983777222631, 1); + _liquidationERC721PoolHandler.moveQuoteToken(3200015543879080977978631399859206700164459691074831432, 546920627716800193603380200657873, 955442091705193936, 262774850139282107595856507261543741866193, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.pledgeCollateral(2079081365371439630533360595904787989338722, 20975265286992043997481427078, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC721PoolHandler.drawDebt(1469926278681390766507302132782139948879666057661270, 848317814986, 0); + _liquidationERC721PoolHandler.stampLoan(2306, 16052); + _liquidationERC721PoolHandler.removeQuoteToken(78144, 28935746538934562635267948776175440970003463695910303326678356370008353344387, 19150, 3660); + _liquidationERC721PoolHandler.bucketTake(25320, 26511057352925151874817900429276281706694346584662189088043467429524323658502, true, 115040648028213763271245853549043880494636874452181292758191479633142775385701, 13693); + _liquidationERC721PoolHandler.withdrawBonds(12603, 22583, 10741); + _liquidationERC721PoolHandler.moveQuoteToken(13595, 20808, 7027, 12900, 67990265283967347010428190204940206325369423363321040257100631028051732765951); + _liquidationERC721PoolHandler.pullCollateral(2, 2704263492620157737497782640272014567052322021231, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC721PoolHandler.addCollateral(72954192179059125710500624555767362548334585960590749550312047, 0, 1516245675353177124, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC721PoolHandler.settleAuction(2564, 13907, 8260, 4116); + _liquidationERC721PoolHandler.settleAuction(2717845938335, 1, 3, 2); + _liquidationERC721PoolHandler.bucketTake(3935425623270109966153362048114416736349485, 182, true, 7459, 2740); + _liquidationERC721PoolHandler.addQuoteToken(274, 3718068959393935372383794679, 92001987806333700856071384682550468910212704266158266358190575554223580054799, 3137); + _liquidationERC721PoolHandler.addCollateral(1449507396, 3719398720937196887342302451, 21266833574923104133284801100447832832056180790662699274815137743018857468926, 15718); + _liquidationERC721PoolHandler.withdrawBonds(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.takeAuction(0, 1665125224821926496, 598404668070, 575748930687813014222703790210422220130552545612388557471); + _liquidationERC721PoolHandler.removeCollateral(109484454297595735571924153327555045951160158000225248947426577949447976440767, 189705619361989332678389445740195554268896305433, 14179, 8785); + _liquidationERC721PoolHandler.moveQuoteToken(4642, 110349606679412691172957834289542550319383271247755660854362242977991410020166, 23969, 14269, 57762265046662103); + _liquidationERC721PoolHandler.mergeCollateral(115040648028213763271245853549043880494636874452181292758191479633142775385567, 3010); + _liquidationERC721PoolHandler.removeQuoteToken(247752252501017934, 2172864402628579596102868786712321772713236941993807609250120966089411, 36936808497599283344991293148953976393371727094711283898131892270316603, 23329414938600567202790202035023442036276955684083276597); + _liquidationERC721PoolHandler.kickAuction(13371, 20763, 2195, 706553361502694834509667647); + _liquidationERC721PoolHandler.repayDebt(117008833284489603970636493757855586386746279468790394, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC721PoolHandler.takeAuction(69262802403772644744922008717209538173404218648276454739580932, 136864923250953306899532527369597003355144806891657, 311896552325518511587323776648924867793954322205178929, 24140077857493540332049223771915); + _liquidationERC721PoolHandler.repayDebt(1305, 7996, 3113774100); + _liquidationERC721PoolHandler.mergeCollateral(86240864503547464300898056724575762995699014, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC721PoolHandler.bucketTake(1, 2256377999112351740720, false, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC721PoolHandler.mergeCollateral(6882672892165481254938378795088299568615165783590916, 3); + _liquidationERC721PoolHandler.takeAuction(22498, 5674, 103942114792467962182600111834022925436783569985540614801358664111080265919968, 110349606679412691172957834289542550319383271247755660854362242977991410020593); + _liquidationERC721PoolHandler.repayDebt(5667530734404109228751125561212187329593970104182840261102550845737813833162, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.lenderKickAuction(379411238723978665356778891480391108537792610866, 11247, 369); + _liquidationERC721PoolHandler.mergeCollateral(13935, 6094); + _liquidationERC721PoolHandler.kickAuction(110349606679412691172957834289542550319383271247755660854362242977991410021035, 11393, 3262, 92627268634462374139813757911566025023182692124064317657466656153466661777012); + _liquidationERC721PoolHandler.mergeCollateral(1000158904577156016, 15736); + _liquidationERC721PoolHandler.transferLps(52341347409429374, 600049113027082824983025770417509503093832355143140652853, 114, 3, 3509926951427136102353881364614470); + _liquidationERC721PoolHandler.takeAuction(3, 680404348027311669085825735134827003130, 1681, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC721PoolHandler.mergeCollateral(18015, 56344); + _liquidationERC721PoolHandler.mergeCollateral(4740, 23678); + _liquidationERC721PoolHandler.pullCollateral(1172558782393486269570, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 51905830384025996195135138815400656860412787804619267321385601445544560951011); + _liquidationERC721PoolHandler.lenderKickAuction(194590724822592229762843737684685371738401106811386487583089, 2, 3); + _liquidationERC721PoolHandler.addCollateral(2, 1777179064050624845780215695583500702303797880787696711805104433662670736988, 1117521870440522256110836023810334082747147037107534, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.failed(); + _liquidationERC721PoolHandler.takeAuction(2997657514669928355520715518098550540193746441521768370, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 30386800514428768267400850843350326025203372485968485472638487922845873361095, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.addQuoteToken(604145652791249977744, 3205952, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.kickAuction(3, 12132, 6, 8211904554); + _liquidationERC721PoolHandler.mergeCollateral(59288, 15111); + _liquidationERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 20732501674893585329351539, 2); + _liquidationERC721PoolHandler.addQuoteToken(44570925613339300411199038756706214321532256605944080591127447210242818008657, 431415980916, 3310, 14373); + _liquidationERC721PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1008879104448547538881, 19764046445139426957555248214479792721787949); + _liquidationERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 21794204538944429217381875706473226113415731944796407, 87554192579501648160234657, 1068738981); + _liquidationERC721PoolHandler.settleAuction(3403886074587726701583543, 1, 74301928586827294, 7730699770853526855555571916078769718916); + _liquidationERC721PoolHandler.pullCollateral(45607232071536911626338559407340181, 24109584780821349367715661292271010615181300475617075667172349023790998778041, 23862); + _liquidationERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.kickAuction(16583, 8591, 92001987806333700856071384682550468910212704266158266358190575554223580054719, 100589673509517359208075717225481249637171673458804355786573416587132293745451); + + invariant_fenwick(); + } } contract RegressionTestLiquidationWith10BucketsERC721Pool is LiquidationERC721PoolInvariants { @@ -278,4 +362,39 @@ contract RegressionTestLiquidationERC721PoolWith12QuotePrecision is LiquidationE invariant_collateral(); } + + /* + Test was failing because invariant logic for interest accrual was using the pending inflator to calculate HTP. + Fixed by calculating HTP using current pool inflator. + */ + function test_regression_failure_deposits_on_kick_2() external { + _liquidationERC721PoolHandler.stampLoan(1101520973663, 340849898329139925023363944281044077674288910705); + _liquidationERC721PoolHandler.bucketTake(38564, 124, true, 6506, 18478); + _liquidationERC721PoolHandler.takeAuction(19698, 12620, 21009, 13986); + _liquidationERC721PoolHandler.pullCollateral(2, 541134438805065095329626877656013320603754476643916851085315771839632, 44); + _liquidationERC721PoolHandler.settleAuction(18445170105345, 27768820298551929539573416057308546294, 1831348234646695979701711193265195624765015, 19806589885779083564708666293665202909299982079894821404); + _liquidationERC721PoolHandler.addQuoteToken(24581781323667122669825371202617098709092025642599709988487142902, 6751483549889384391330009179862741721237430, 2074840997258950548059555849447762, 41004804690541978327690188027); + _liquidationERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 4405533926191186669079387132587588); + _liquidationERC721PoolHandler.mergeCollateral(1170, 6791); + _liquidationERC721PoolHandler.lenderKickAuction(261557594648386107050309690843, 2149531941380581, 21398813494550530131524859572390158043429852771132077812453); + _liquidationERC721PoolHandler.pullCollateral(2244700571660709034536706359572610085373763379015793501107352541276, 618, 23239); + _liquidationERC721PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 16274470882238481041, 6197097, 21823864712259522241570554056911363918960970405); + _liquidationERC721PoolHandler.pullCollateral(2, 7599229, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.stampLoan(856705470883081255239073139418291890062277533648218028719451656473135, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.removeCollateral(584, 703, 78068, 12645); + _liquidationERC721PoolHandler.stampLoan(436561101136594799844207135366044952491661248823909950, 2); + _liquidationERC721PoolHandler.withdrawBonds(4563146251932219736759239506220144592591590156131202302006611845039429, 14350, 3517662147741923340791168219309848016076091); + _liquidationERC721PoolHandler.removeCollateral(25192, 6323, 23521, 16383); + _liquidationERC721PoolHandler.transferLps(20695, 15851, 1517, 3856056065, 20098); + _liquidationERC721PoolHandler.drawDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 859480409215446731702270203541533710710020319377429967504251221729934999); + _liquidationERC721PoolHandler.settleAuction(126936323669234570513273085709441059235, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8248932491597069592573032352920451438269307575316205933141289543353452443); + _liquidationERC721PoolHandler.failed(); + _liquidationERC721PoolHandler.addQuoteToken(62, 16565086470505342429058968, 3, 0); + _liquidationERC721PoolHandler.pullCollateral(0, 1514221, 2); + _liquidationERC721PoolHandler.pledgeCollateral(0, 35924561148819755256489348713910568088, 90016113586623091009188116577000963562088529923191612303619720343); + _liquidationERC721PoolHandler.settleAuction(2400, 19226, 70782602156620013982052507478745924339327460599400232115223540562545500139749, 9354); + _liquidationERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1199072574072325921531799195390860, 295013, 347551799326168676289233799); + + invariant_fenwick(); + } } \ No newline at end of file diff --git a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol index 3daac912b..8244569b0 100644 --- a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol +++ b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol @@ -468,6 +468,23 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.lenderKickAuction(1, 2380963819538393125633366019791981, 0); } + /** + Test failed after bucket take with incorrect reserves due to incorrect borrower penalty and kicker reward calculation when borrower and kicker are same and borrower partial collateral is settled + Fixed by calculating borrower penalty and kicker reward from emitted event collateral values to separate kicker lp reward and borrower lp compensation for partial collateral. + */ + function test_regression_bucket_take_reserves_failure() external { + _reserveERC721PoolHandler.takeAuction(5614, 5711, 150000000000000001, 11889); + _reserveERC721PoolHandler.takeAuction(51, 17159, 13313, 1965); + _reserveERC721PoolHandler.failed(); + _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC721PoolHandler.drawDebt(4037, 1015403262, 413376868404700886282978542123985269303539411280089634060); + _reserveERC721PoolHandler.bucketTake(14110, 4985, false, 1366, 13954); + _reserveERC721PoolHandler.lenderKickAuction(190601454519858205896974049525891537012496008839583350325368160, 2813171022655068506479644642529791249126593717492917545887718879120, 336250622645138163229276253658670571624001551213796); + _reserveERC721PoolHandler.bucketTake(59580, 11550, false, 7965, 6543); + invariant_auction(); + invariant_reserves(); + } + } contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants { @@ -1791,4 +1808,71 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.withdrawBonds(6162407927856572007525601797448903049478809668711157, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 107488441665597113470438432006472595205433191723889867333936566853); _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 101660650320013120840863364686996498168471542781622903660015386008, 26551745986563838800685120771903690269972431445); } + + /* + Test failed because compensated collateral was unaccounted for. + Fixed by updating handler to consider compensated collateral in bucket for auction price. + */ + function test_regression_take_after_kick_reserve_auction() external { + _reserveERC721PoolHandler.mergeCollateral(3, 0); + _reserveERC721PoolHandler.addCollateral(3278554184137405245391966474532112471766735411313029736086976919798487989, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC721PoolHandler.removeCollateral(178856477755247763592418076481722332721576806718, 3512044071412509446309469827849256457235042086921767134251619447845217062408, 108499898875484850595696, 3); + _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 29989773090518); + _reserveERC721PoolHandler.takeAuction(40145434837837809581528812091273255013271814820308867555041683395488371, 1142284127781016, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 62624677501462717915428868533223849); + _reserveERC721PoolHandler.pledgeCollateral(24235304654388520161885516661416, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC721PoolHandler.takeAuction(6838, 1027282540138283065, 1013072918407583293363113000000, 62335089559264398832833); + _reserveERC721PoolHandler.repayDebt(4200763110793916971366403567, 359244169829533724231793641310683551411599722750043309991464595847, 4362034365326543007107733784357197205138908748013909941194441624041); + _reserveERC721PoolHandler.kickAuction(43028, 88144399655257062863950938037803699837192476742137713357313051484610381448500, 82286160713314137388879812406894344234589028242647342969353190308185323465417, 367900800563727); + _reserveERC721PoolHandler.settleAuction(194062310740808202576803381364246893256673861322417750679, 2, 3, 14736209260610492857637339562648610692681325114421721182376335306168); + _reserveERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 285620975326430939397128478097); + _reserveERC721PoolHandler.withdrawBonds(3264662593828391665657339329929498650683103932365707675805461111305, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC721PoolHandler.kickReserveAuction(20648, 35707195250398962055689370806773673072600080434055307998993172548148871531088); + _reserveERC721PoolHandler.removeQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 113177423557347505419); + _reserveERC721PoolHandler.mergeCollateral(3380, 39876); + _reserveERC721PoolHandler.pledgeCollateral(15488275672478470073827550, 56600, 2760); + _reserveERC721PoolHandler.bucketTake(2, 3, true, 0, 36031981110492415934608753324525592456844); + + invariant_reserves(); + } + + /* + Test failed because compensated collateral was unaccounted for. + Fixed by updating handler to consider compensated collateral in bucket for auction price. + */ + function test_regression_take_after_settle_auction() external { + _reserveERC721PoolHandler.mergeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 30366213271444225217120609420097055671182); + _reserveERC721PoolHandler.pullCollateral(4768217050022891163821, 23162835199090917303377378586, 20058679922310275793972462975); + _reserveERC721PoolHandler.pledgeCollateral(3293685337948339269392982012661790, 2564625770874168117286201267822265799058478533644362, 2); + _reserveERC721PoolHandler.stampLoan(82056665245256249465439968072924916070922652948648236215303266391377835171470, 6552338875626040099058182821311906768274833679008314103495576099267966882404); + _reserveERC721PoolHandler.stampLoan(1000000004022219204, 20151393292804422049467127106154756455207003708505129163023606176247596206870); + _reserveERC721PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 81602409102016635599064732297021914048765891750750662158, 37137476195449428728678245831749114, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1455053623668294917961026262200526540211402683); + _reserveERC721PoolHandler.drawDebt(0, 213539000613194655252658914727088812926094416026871209959398, 3110); + _reserveERC721PoolHandler.kickReserveAuction(1866, 14766648264728167024158); + _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 205924429502436266913032622573279722390985423634543694850605, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC721PoolHandler.removeCollateral(73815944580, 5522347884369114837788593197284099622584673, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _reserveERC721PoolHandler.moveQuoteToken(29421874121631, 1, 13385934, 0, 2); + _reserveERC721PoolHandler.removeQuoteToken(999999999999999999999791281274231988808448685, 78388996652328019455663701387783790127459464059398085443848446997649153195749, 197741244146086, 29927285348170654593727544572838); + _reserveERC721PoolHandler.settleAuction(2, 581, 42492846836, 30767210395157885076936414958483812525613494876); + _reserveERC721PoolHandler.withdrawBonds(18324658914141373517052960816, 4782582725402278850016210688, 490131426654511434422856214); + _reserveERC721PoolHandler.pledgeCollateral(51375309540246015480, 1147795175590457414347539, 14414804271525002719863362); + _reserveERC721PoolHandler.bucketTake(34889080203931, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 1, 219436693212925882750080696659941120759963892575123752135499606153174114); + + invariant_reserves(); + } + + /* + Test failed because kick was not reverting with BorrowerOk when debt was 0 but price was MIN_PRICE. + Fixed by updating PoolHelper._isCollateralized to handle that use case. + */ + function test_regression_kick_after_reserve_auction() external { + _reserveERC721PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 6935739002941423355049, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC721PoolHandler.bucketTake(1, 68298831663979631596289246956670551985825478107896188, true, 873193787008170413724397952426848542555828766842772550062607158488206182552, 1755961235259972539); + _reserveERC721PoolHandler.bucketTake(1059688629222756016, 1000000000000000000000027624872788925611714027, true, 1000000436829433309, 1726113828302394559154); + _reserveERC721PoolHandler.lenderKickAuction(798548716449031226788513776464931583931653468137708864548183282831, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 336458097); + _reserveERC721PoolHandler.withdrawBonds(91351469402150005, 20135321806946154, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.kickReserveAuction(2427901310042246836092666709297076039807059369179899651290575214128933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.kickAuction(1000000038825063504, 3815158141615494281861519, 33063346009737933132629913678857, 463918506144460971); + + invariant_reserves(); + } } \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol b/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol deleted file mode 100644 index c58332bf8..000000000 --- a/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol +++ /dev/null @@ -1,430 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { BucketBankruptcyERC20PoolRewardsInvariants } from "../../invariants/PositionsAndRewards/BucketBankruptcyERC20PoolRewardsInvariants.t.sol"; - -contract RegressionTestBankBankruptcyERC20PoolRewards is BucketBankruptcyERC20PoolRewardsInvariants { - - function setUp() public override { - super.setUp(); - } - - // Test was failing because token needs to be reapproved for stake after unstaking - // Fixed with approving token before stake - function test_regression_position_evm_revert_1() external { - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3, 1, 4456004777645809093369137635038884732841, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 40687908950166026711192); - } - - // Test was failing because of unbounded bucket used for `fromBucketIndex` - // Fixed with bounding `fromBucketIndex` - function test_regression_max_less_than_min() external { - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 47501406159061048326781, 110986208267306903569458210414739750843311008184499947884172946209775740554); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1881514382560036936235, 3, 14814387297039010985037823532); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(797766346153846154214, 41446531673892822322, 11701, 27835018298679073652989722292632508325056543016077421626954570959368347669749); - } - - // Test was failing because of incorrect borrower index from borrowers array - // Fixed with bounding index to use from 0 to `length - 1` instead of `length` - function test_regression_index_out_of_bounds() external { - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(8350, 38563772714580316601477528168172448197192851223481495804140163882250050756970, 2631419556349366366777984756718, 1211945352); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(211495175470613993028534000000, 278145600165504025408587, 27529661686764881266950946609980959649419024772429123428587103668572353435463); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 6893553321768, 0); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(999993651401512530, 102781931937447242982, 270951946802940031780297034197); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(142908941962660588271918613275457408417799350540, 2, 7499, 21259944100462201457856802765711375950508); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(10312411154, 11741, 808194882698130156430790172156918); - - invariant_positions_PM1_PM2_PM3(); - } - - // Test was failing because of `(((tu + mau102 - 1e18) / 1e9) ** 2)` becoming more than max limit of uint256 due to high debt - // Fixed with reducing time skipped in setup from 100000 days to 1000 days - function test_regression_arithmetic_overflow() external { - _bucketBankruptcyerc20poolrewardsHandler.stake(6896318739925897886189247783689616912, 1590163, 2, 5688123131144312514755107); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(17317, 82811632090972520860339125222186388174810191857321772017180113650309637681174, 36183411359542968180819498843191329944675962195184522815400173109497640045084, 36183411359542968180819498843191329944675962195184522815400173109497640045125, 19228192993203316367726728173133990710204659); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(886000000000000, 112677305303603608793464000990919617579761525091244043308691041092632466068329, 3966754565367876880350885451679960164951761383523769778082696271101602, 2039, 952915384615384615824); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2849871794357244235869, 3966754565367876879428138587689740691886557263849923988907562808019157, 90722805810612960, 2407, 15129); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(177039972880383490828179033660932658535136887032468656, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 38713024359055902250662472670480188719905855, 1); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1647740717046213962030928987916339867520444123409750393400408, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 92438060068404637120570616271893238026003952273845567189711565754357678, 2, 740729473877833425174185945952031582872090596768955274878); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(12280, 100059799535193028234836608013586712161184179292262900980302289180450773349084, 39906399523299059107967942071142446494738195742899699015085450065764556124872); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(563808366315521888139814758131568062747410028498, 717762288499217961103026455619904233444784602603, 639614423076923077217); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(179970444047069616, 3966754565367876879135983927223377519202887228228036839903452619493402, 4733); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(7077, 2849871794357244236815, 89565878125998494124776859909564617778044840185111596024548341691824014913081, 67510848143351065130353186739542299459422428500681234436222588824509516955128); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(345331730769230769391, 1153129030861181662264128353544855947712724763189, 13746, 10698843914281808001296099412637890910894001332208464018741338351061051465914, 100847138996028487776982507526530541183387119239170631100097115978417618128629); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(36183411359542968180819498843191329944675962195184522815400173109497640045129, 48819922315949799267070624682529131378372410957, 4181, 112677305303603608793464000990919617579761525091244043308691041092632466068152); - _bucketBankruptcyerc20poolrewardsHandler.stake(2244, 995, 58606104743229720510079823024387185916963550951287480571399502469054769761605, 76550499216257555889321112575510855021078684718864441654047861970454785529430); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(37559901722735453672500465593449923350885790554902835, 551970007141884604422321369676694640861689485316027729520843135985700546, 47661766323110); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(283600966131550275, 4225, 3054); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3305681070264227794977, 74106, 12559999863349, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(537, 13076, 13358); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(923000000000000, 5118315719793605164353342667742056876611746894854750490526105565680017101203, 66382540837033874); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 10266341061973857960018410655132814, 1, 1); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(16522, 24995945723326373875772837096154005408860764913638412228031745013630478857018, 512011103318869781848676); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(2, 350590244621993631975269433997674629739798644299962688761173, 1344692490437700114798712237992600701, 11956262); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(73624586998592616701514720900276129068340183692521862970378800053138201630477, 68710165003106503923300701473932010517182965684103004549833568373358389724401, 71800436766229664078026657500885479541081649751618083508801195706457245577220); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(9453, 19205, 66868048033817959774686748497699809781406078236372444649234275513206538861672); - _bucketBankruptcyerc20poolrewardsHandler.stake(8925811310805445351997878058708827307181477404039834765939848102762107933524, 15396, 333333333333333335, 112677305303603608793464000990919617579761525091244043308691041092632466067970); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(49354806076664609737639320143283225715325929918170457855370734498987169336, 0, 0, 224207154149060304368571539032, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1238008048, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2169063360537137360112800101939791654946494300546407780004241577631164); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2345851545937962757778643762496267029085540856037776148147808038944642, 5957091736115285211, 27985731991685908798232634683132989817806071982114803741897441260168560867); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3, 1, 770986253285442867064880897583817379708, 92781664698833630287489852236611504234525413121274842462364219872); - _bucketBankruptcyerc20poolrewardsHandler.stake(1594, 107191883964854757344296271860238969622927688664914404668659378108385854836026, 3966754565367876873370423057737583368405849023294119111275034969686468, 19958575429898560154085169419221224945725333143564312471139253950974388039284); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 2); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(77052356306827782713422247930543027861392973120644625016, 1798476982980588193703723436375810811222069733299353125141863312, 1098297152145905559672257161091692); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2, 342041592964680825954896142059203952628580209831935619634002805536, 39846960399867003370202173839379955192, 822343706632112, 3); - _bucketBankruptcyerc20poolrewardsHandler.stake(7984294068074609994912921437324, 7838, 15189, 175000000000000); - _bucketBankruptcyerc20poolrewardsHandler.stake(24962334191555090884200901697709326249765046066909050188293351411730598993973, 2147483648, 393502552471956099440181996575832631444286908472, 14802); - _bucketBankruptcyerc20poolrewardsHandler.stake(7256, 929000000000000, 675412562135798344425486121401750, 13510); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(109677534373829370582420891034109789248617180581764663703953628089987520264326, 2573764082904, 2908); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(1587, 11728, 20371, 1761736553); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2849871794357244224888, 21613,36183411359542968180819498843191329944675962195184522815400173109497640045063); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639933, 7816592721461, 547796365072063422163463132831470635072549324118139340225274709, 23239411057593528819373457684352214287995257450694130149326937362); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(601672641157204830463731144581, 1, 10); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3844156373059697976150225328289758, 21067959307417482890549604370787421964344610209838270154238906991002); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(68710165003106503923300701473932010517182965684103004549833568373358389724401, 36183411359542968180819498843191329944675962195184522815400173109497640044952, 27681604022032244008232927876918610662012006233608617573888982434118344074872); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639932, 546249949564771975556206661259711240, 2, 198775369677794427185735801472315926769782965724); - _bucketBankruptcyerc20poolrewardsHandler.stake(500000000000001, 112677305303603608793464000990919617579761525091244043308691041092632466068117, 7746, 917812924747606707090506589076440198415899010589); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(47390443050477, 2, 24907716377757111202952223651177368542, 99036046654470658779217472134, 223412317271864254); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(584150118814135535797598359987484192650707686887, 4759, 27314416541679884417682362568089041974037272849399973641581125802989563555875); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2849871794357244244015, 264054995773979190, 447, 451433653846153846362, 9648); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(21050, 7775694,154085490025371729225110012928624230180770264485398324359658277233, 57927770334825); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(27314416541679884417682362568089041974037272849399973641581125802989563556154, 741712500000000000341, 102395000692947319608275989700597991885819255417485385121140134029182011063769, 12630); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 440744070881956564449467649, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(10000000000000000000000000001, 740, 7258); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(88726916073212290156777326422200, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 34199279288); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(17214, 73384897344814417155958327430359004483378729061591027007351093540094357466111, 51206296630672440992795321509376579418034509656975184376065889683943438593770, 5884, 8262); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(2044562291296528291030625278429523218566755073094910438325803240354, 1, 15304323218114486738795227081682471, 19829306); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 124837474259495102675939548974323950, 329054301975170069286574921653462268546056642575848355092114042163); - _bucketBankruptcyerc20poolrewardsHandler.stake(199147622511101623, 789000000000001,231, 33101730025310197535578397667035503858659584593443933073973462411188265487645); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(32357, 162121775210335745176768462891133518974, 2); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3, 235172445463430520134164649932838126511768787911883505, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 8556272701020798093908796721428703862785571616320106889880411706632, 898342879931592588219); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(6871437890782, 22722437225746852199549, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 49335930053431267338133128938678, 12312700374952538413699663457513300906362172890995955163025450435265437519460); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 867997253226679023134472172637178866960140585025356872075477020, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(14195, 4120126606, 892000000000001); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(53143361220254641097319023834726093633429636617299696, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3008666890405061958087053360596855); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2849871794357244241734, 7376, 4733); - _bucketBankruptcyerc20poolrewardsHandler.stake(491801577241747986710629564741072784295090200116, 4666, 336338206907638295, 3966754565367876869122227334475572820434993478726803479380549997488878); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(588, 9789, 5083); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(975573743, 2, 7486511129908263831530464268126, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 408377816173582479794442004131690473732206230537105633285620578233, 0); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3193830813357417, 240); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(234667819334761949964119092206494130890231852099316545331, 11931498178817218152978210620161711035796631751178664213653196, 6840034619969503616899963423366754377629584809987338693684203); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(0, 1, 2823373119980992364828421558687377775878598015914019948); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(63937, 16773945002237412540693101797847272493598737453594325081026067588528, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - } - -} - - -contract RegressionTestBankBankruptcyERC20PoolRewardsWith12QuotePrecision is BucketBankruptcyERC20PoolRewardsInvariants { - - function setUp() public override { - // failures repoduces with Quote Precision 12 - vm.setEnv("QUOTE_PRECISION", "12"); - super.setUp(); - } - - // Test was failing because of `(((tu + mau102 - 1e18) / 1e9) ** 2)` becoming more than max limit of uint256 due to high debt - // Fixed with reducing time skipped in setup from 100000 days to 1000 days - function test_regression_arithmetic_overflow() external { - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3966754565367876882011475305970374373581843216523327606696944469982560, 23951, 27342775513801048612025508136217148135354231891871249189205419889059958895920, 5764); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 277955739357896056509186172170724926307041); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1410631634716305975327239311667501746230064938363700, 165627380598340247145446842744163, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(19, 2530080042266327931552762435318905970448414613174692360332206645244, 1); - _bucketBankruptcyerc20poolrewardsHandler.stake(8666801014510249463714719779804008890723512, 1,83443108184118454880135593969467466093223604269, 15883848302414522401895); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(12882, 7777, 6629, 97879245264338194306861131699634660522218295410970784557138028426270717400370, 8368); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(13483626428470537411264656142812, 3, 43261357659, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1388408991433152321764177891234838153250463504820877); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1, 2, 20563013357962289806221756347401611786110937543040356031901156, 447919006151828756764428252561915147896770196082188602773330761, 798396599462289786815989310634148690896897281016819117397861); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(92248702659654157400825310446726854110696903499169410212619700758795452822, 37604, 3); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3966754565367876873053743387718720534708426719378234395015112294331820, 1891, 6354, 6407738580936730947617400026186481015907031668070029619638042254901247); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(155528622244088217616721520914751415058731841773, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 517704163087, 288990527056564619478); - _bucketBankruptcyerc20poolrewardsHandler.stake(0, 103562875210896097905879456787026624674683989786414355636238913207580190275, 4449509262329152679, 2); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(12789, 516496153846153846391, 1373, 2432); - _bucketBankruptcyerc20poolrewardsHandler.stake(17298, 2520288506, 3966754565367876862909903626043389090569250934025238262077644133072068, 70048973491614882813651882306278555733916041147); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(14730549569217254337324272971273439639, 10712676910574077307719914120290505539758384452430355043102986598551, 25861299350166086615951335); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(19490, 3145, 100958019455552403241513419952879830954846771871560814580751995001715468196982, 4320); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(18380078816620787637106444195826167006943,9105121993717164823200252859, 39582079114752207760062142810162); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(102938198731890455483, 3, 52050632211266); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(500, 924977286184975233873859450789056758036024240832241462431898388643636693224, 232003688276085664164189481417956820170145390, 504095117088782794907830496954549563124074003355); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(10009, 522, 229781691635202364607605263483, 13964, 6303); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2585532, 30263717, 295729539); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(1984, 4652, 2725046678043704335544); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(349, 10557, 401731786528032649302150062457257044539448918705); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(94291391897249807881798731698058020996506531563934658123907732088334042997896, 1683, 922886538461538461965); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5009532820319301678432792599939739); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(1368179552630450116, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 34412996693170762789699607283878930530798448071823276400203849362089566); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(30743674041281512912789390937090188969141866220723941124963519834291052939594, 3966754565367876873053743387718720534708426719378234395015112294331821, 3693, 199999999999999999999); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(2849871794357244233297, 5729, 9436, 3966754565367876848917250723019599313865029386375836114489444464347617); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(13336, 751722115384615384961, 79902525729132112172182628727403585636031841353378040928728196869469094823677); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(11848, 88935689212870099548894352559477176008817225920440919577532104643626259385686, 1626); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(58606104743229720510079823024387185916963550951287480571399502469054769761570, 15156, 216879045993470961471641212581); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 883524181985928268306667951943684061963202522679192596148943284885177111); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(2924, 15953431440961698465116049405554517352474802910093790483384259164665308441857, 11379, 3966754565367876865848146090991267689838419410304387485907095558443874); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(30743674041281512912789390937090188969141866220723941124963519834291052939594, 24095571472578277997716226198122273937443180744573574132530939729041516935842, 3966754565367876862304666055471450811092813038866066209363567991707702, 938000000000000000001); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(194697860333279706454142791011527465766470841248150462925425546902865792, 10918718947124557284093286805184333760565060406738006519481479722466762779012, 168468217510963482200654846013032790275226); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(58347301615953207705596250146, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 940844563678598855758006578093833226886661828778784869140315469182111914414, 319314552411346300225910579); - _bucketBankruptcyerc20poolrewardsHandler.stake(112677305303603608793464000990919617579761525091244043308691041092632466067904, 9141, 76550499216257555889321112575510855021078684718864441654047861970454785529449, 90156338318561149845207557102717525639219958457419849688382040762167829323088); - _bucketBankruptcyerc20poolrewardsHandler.stake(485466346153846154070, 4047, 41236831521177614171812965194954188943377267884762881554238952423602296083644, 748928859761915073403783232409846872252823377512); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1842, 814000000000000000000, 7386, 8949, 41793232874593872983939891402504271449042722654854023829157932315219071622588); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(112677305303603608793464000990919617579761525091244043308691041092632466068159, 2849871794357244244502, 104081267022762746751665747606660, 71229933733954908637545747917262425351075939551041697044067017386326458518973); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(24517088812426303533366187430638951177066673723059003443596328868588485096503, 58606104743229720510079823024387185916963550951287480571399502469054769761351, 64416168674241980143640578666243527631773805575549605444878358964770079875198, 857, 1500); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3626, 88054211744890545047854682720362692474121698843596563640244510813389729172929, 1428317552094315315517906204753391481814958706674); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(5152, 1112, 114255409676579882224300171557671234047763533365509370065937802142537610636077); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 418054629776517004596675, 3, 1, 35279645324127465272326759608); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(6728, 82093671015361185348901971732692156706718930259320396354351606002076191819315, 956999999999999999999); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(35118430032806250297491677757753828041611787435033927125054378068651577059830, 6369317236171228082814892, 7387); - _bucketBankruptcyerc20poolrewardsHandler.stake(11817, 9275, 5385, 1207369317); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(51953396903491667884348938599208174393962381719940333807794356892097124201559, 684, 10657, 76550499216257555889321112575510855021078684718864441654047861970454785529116); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 1, 148281571130219420965533181191380429225208794627, 0); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 4239153815896722593765078521373119840402276014176812838, 322); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(5832, 114325486997113895, 25771513998157767631206, 58606104743229720510079823024387185916963550951287480571399502469054769761640); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 206482); - _bucketBankruptcyerc20poolrewardsHandler.stake(7927883901223247210108134121974524593936498558593831315905690, 1021983417944036249199635837038396943666727341096303405788220, 767087832347197496171017453170, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 2874117576384309917899907813356673917244578826423882407945693049513858301); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 513981014459270617692452615619057434252871630198349563427); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(6300000000000042791841612, 19286837295908603553266787544912289890662357020459285979135247069961616838694, 6000000000000000001214045); - _bucketBankruptcyerc20poolrewardsHandler.stake(3, 582489990557683665156778587139, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(3, 0, 35168320991909411639035941130092257126013094953); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(14813, 37985565034524940, 2145, 20082); - _bucketBankruptcyerc20poolrewardsHandler.stake(4709, 27314416541679884417682362568089041974037272849399973641581125802989563556408, 12840, 12086); - _bucketBankruptcyerc20poolrewardsHandler.stake(69038858858407874287609809184671540840387410961394619992844383524920134424318, 36183411359542968180819498843191329944675962195184522815400173109497640044724, 3966754565367876866196088114064796746224277022091850411132522280259220, 12791511181959941491752949292075057207018412420834161138452224935883231372655); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(18192533247055195113309035583539, 1, 328582664058452398603332112189467575863731833506487867823485836, 4602471638333068831301900889260476934074379204208975, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.stake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 56337316561494319009393836013630587683761391839374494258944738437916245958839, 2640259112854475455524369794554852490061268235127682838018933103811); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(5492450293033381591765430790693418, 137254969503698002491565595388909, 0, 20988469343989249870821526948977277703231799942855); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3349, 9610, 76550499216257555889321112575510855021078684718864441654047861970454785529360, 82356314548626890097785557483647633355000630013025733579942984190419831216102); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3, 114146396809673629522339599); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 126618531077782339112782240609126751547958141385, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 12162819707221123631400623212); - _bucketBankruptcyerc20poolrewardsHandler.stake(105121213529450126323853881532755536544144710500048612197500352815038325229734, 112677305303603608793464000990919617579761525091244043308691041092632466068251, 293033093642118704626758970120533267875914812703, 371788002); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 20429554514719932257185316611193961084030832868502); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(676552018761914467, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 59118278259681); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2156, 7545246309671992862734104294126293323679086381417630106133956125163420559268, 4364969487729155111838774393422, 132396289780528671, 8264); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(112677305303603608793464000990919617579761525091244043308691041092632466068059, 2082, 14781); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(337194160126177136918766792240, 3, 1313730499206179905094243898173812338722150955516328682874207); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 0); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(471865840740346309280830746508987758285335124696, 13021983620616879922120557237553195351332782342710477424375088385066717568307, 436588081726929394630979089567144071868327424332); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(17374180793863161866451563901603790046833465309545825925601, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 855794879660868210624); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 439349802057718495654968534586028); - } - - // Test was failing because of interest accumalation to overflow uint256 max limit. - // Fixed by Reducing max interest rate from 50000% to 400%. - function test_regression_interest_accumalation_overflow() external { - _bucketBankruptcyerc20poolrewardsHandler.stake(320307692307692307841, 2490, 10917, 403196809217289663458043223580906563641609617294); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(15059177663891191985498469564581, 21691241494814563657, 5959198137984416944871985040941211962546971878394061014854717427126670802); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 306748590411024027068452057, 3); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 3, 3, 44869774749435413944328478986895177316804030, 2); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 667409171832157313382210046675580725011953, 170966693897056629150807196294457349572402758607401923355019500107511084513); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19549319890719740959827156450505379259184673736260904583824030491, 16629388526339); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1, 57, 2126726397172127776919, 3); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(10662442004167, 0, 5497097760623451146595, 3162190482019759261701358441242229); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4633); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(195082403288206510116943243208164172979846145506483861331524728636984, 5999490491512003998567204139527071137962581199636349206, 1); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(193, 115638053, 82905768405815550325167864157103591796198207319836507298376269364238808467864); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 728230189013838280072632353261014942101509879986, 1074852977686923754516502207503688995019457654331626079784, 8647989100256796072321456855285912878676340053147534437521304860653); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3941357502157973923804, 2, 806977082765068646659096738618743289712629038, 95470398010431964952450128551272930452522452449699886025877059807238, 1); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36183411359542968180819498843191329944675962195184522815400173109497640044908, 5526, 3966754565367876855970249316229461606728002012105551523079085776320493, 12000000000000000000786344314428468140209160332, 1514); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19347515940517406236500101946818541192254229344198927883872669126, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1236588951273351231845418839930179263983011495754, 38238240862444672488745854665, 105710195453976313965439090442863258002796095759252242871256962165021905861650, 447301751254033913445893214690834296930546521452); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(46514948025651225960345695072605648432715982671974779016300427285754698287368, 3286, 3218715805466846511984533600393324923883748231); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3950340310148269005, 5673061940259815795875572950552217903, 0); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(201, 16652, 456263400021039761424850168808020383038614345114, 185177884615384615469); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(844186718371423468438148597031199325852724093549, 8971, 1238939858024599757491003772585973626666495470478); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(14560967560043099906703147047009467303604341499091340414611613631940255690293, 1721, 1330742788975674320956191865797062835971931496250, 8012); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(610999999999999999999, 18990, 2964); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 2202462407395028941916385359630457052998061369773792102517381208520162, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(259629493051510264, 23614305666380977416230669400318875317806232271123308657121989217833132243233, 2497, 27835018298679073652989722292632508325056543016077421626954570959368347669748, 1606); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4650754146616051773693243800451532316887707892427, 2674637045933147252314476540226577815868397623, 1637859); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(32610811746778589434426055746005034344393175264036753585460265204263347653842, 16005, 105710195453976313965439090442863258002796095759252242871256962165021905861709); - _bucketBankruptcyerc20poolrewardsHandler.stake(27241022853949367504447088193, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 128000899661578863761148718566665636525956915466064429, 1336719368342255666688); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(41124169807925345164795, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1313063028941469943130200174691186594877948408346228981); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2166715437819344420775617703353734409787244706488647403995037751254234644362, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7532212); - _bucketBankruptcyerc20poolrewardsHandler.stake(14552177917818508405730171864883921324, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 84190559757713757784279975706433133519542327009581632460886117089373); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(37747710333430245980940452738832839721522435977096927851794211126014890045043, 105710195453976313965439090442863258002796095759252242871256962165021905861568, 4881, 3966754565367876869122194268884518216957992861677661334548387666061342); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(159533269946056829911817908703969087399676830547153393250667762079770747, 120375821746749532031, 553664897755275959629); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2318, 371788003, 105710195453976313965439090442863258002796095759252242871256962165021905861824, 57957110594642022010328291066590663082489422500, 378363461538461538635); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 3108493389566117837926341948558162909763275523381432406469124236768340906924, 32229393624772079505360513009288184415901939, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2836923789, 82757687462225415771947516030365134680378685014411112583900985134363263813950, 17992734256423583958967370161492784553176489409); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2, 1599018514952142375998297880); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(55687575924400638, 727999999999999999999, 15644); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2673041966562049323144905243406346442490148198615, 1285995676085316511341291864375645429377044076357986037173062379358204); - _bucketBankruptcyerc20poolrewardsHandler.stake(27836410677470140405893559165022839553284246026566794216457, 26100442293941930306313869947915225019447736484493936778052910988, 1100121169003966414850619669523011925033070895519974812092, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(751722115384615384963, 87573722621992251438460370142942144054516549109457068516979097052450755011736, 3966754565367876854520184869943068556144348793969914759895680118784807, 27984893582647316189577999054762964794852908603917399358854612125647292485578); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(15048, 20980142891430666358441099170678931589412918730, 26229794335232538522551515320652626439652093573752750988891734989405951307592); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1623645501211, 581895706741971570416382, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(16294, 37775847772112785254257, 20408); - _bucketBankruptcyerc20poolrewardsHandler.stake(233076476716696715, 19720626000000000000021835, 14786, 880); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(91, 48915418688551403693013933582174377748045,1, 0); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(8520254760456735866522434792660074894149362458110124278618188561008801076487, 4508341423132101367979353817313302855733981519104609141429822885854284517273, 1045732366170946687500335725634396288218029048535); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(5250764587436405674967118092556206155749365731, 141015099610895938496827107324000508240276523703380995216176939659, 0); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(75715332515, 20249, 139492422255, 105710195453976313965439090442863258002796095759252242871256962165021905861575); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(5433, 21391, 754284941459726849420512743397530252182784738229, 23905); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(192677, 4773, 2683, 940037522744286018063446172177794105409762773472); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1423000347840435497235966844164533984931800601575, 288276923076923077057, 17572, 4256931000379123634785033661970275022184774617022768398310874942392452426, 139403335757771137); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2, 2587348281013517652545024121589073614070441106624530521348844741, 519685398); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(84919864282925853877573619845135091960602695946894030665170367426270992811938, 15050648105662257143935681434472465116789984907642743379717753234643085664126, 22213, 16413, 175589814974774645221481909980815519088940506341); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3966754565367876881842889880294569887040448346346191805828869027190062, 4571, 5227); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(907000000000000000000, 2868991328, 99389371209329274803747059355072193342651880195070161537527945916651123372097); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2784308567599248162087449504, 3589, 476777860815159664263285898208782485328810582592); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(0, 93446225603511499598845951183108384660272702, 2024254557338330727781790737102999642155730612363585, 191889378792020151); - _bucketBankruptcyerc20poolrewardsHandler.stake(36183411359542968180819498843191329944675962195184522815400173109497640044984, 50146794086275195190991942805708459010074680271220970599602693206755183387706, 2065, 32789382558206698454860319624949663673430750389618486004860947532855016388844); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3, 29811238, 69968346427577179605244273168972327088469976079256197056454, 1497742154395667232899123570108019263133908353144179120765); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(3, 0, 87185381081925833627461609395751279524164897425148697297070669197775260); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(17279999, 3966754565367876867473138000603430830185306546546874883932992520117722, 776481524764705302352605934280580955971144914555, 962787287); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(19060901126391672628476228072540859898, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(26920601521589162671147619654088067061266745140905760588388649977853848299620, 1875, 27835018298679073652989722292632508325056543016077421626954570959368347669985); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(553591494574561111154252750468593088203, 26003311767849788325482998126201562168467079599, 3503171015763161693096394522251351236934013944546); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36822330623891827054618617680243779734013976879104614005453233537599913890987, 2030, 351827466436279533, 36183411359542968180819498843191329944675962195184522815400173109497640045092, 431); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(4307769405459937793464500814388987723043870007160919438680139924065536869, 20774, 20905556733966496908705142171609168952816592958194260630754626678628699156025, 112677305303603608793464000990919617579761525091244043308691041092632466067909, 3966754565367876866027363177544639294642486780494516334079839883146086); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(5612107944, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3758652); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3, 13063704682547015731607989179567642095598985357156794100666758119236, 1663082272433979660889799306293339760568971320019141218266316592279716982939); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(698213858938870538487, 14890451379766624461267359941375, 48557935465010072094981800005966219309615168007618540929696328537074564550805); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(355000000000000000000, 49046620449355538574108822723048473721226797556007972061207479861126558122006, 13060); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 1); - _bucketBankruptcyerc20poolrewardsHandler.stake(320307692307692307841, 2490, 10917, 403196809217289663458043223580906563641609617294); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(15059177663891191985498469564581, 21691241494814563657, 5959198137984416944871985040941211962546971878394061014854717427126670802); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 306748590411024027068452057, 3); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 3, 3, 44869774749435413944328478986895177316804030, 2); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 667409171832157313382210046675580725011953, 170966693897056629150807196294457349572402758607401923355019500107511084513); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19549319890719740959827156450505379259184673736260904583824030491, 16629388526339); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1, 57, 2126726397172127776919, 3); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(10662442004167, 0, 5497097760623451146595, 3162190482019759261701358441242229); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4633); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(195082403288206510116943243208164172979846145506483861331524728636984, 5999490491512003998567204139527071137962581199636349206, 1); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(193, 115638053, 82905768405815550325167864157103591796198207319836507298376269364238808467864); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 728230189013838280072632353261014942101509879986, 1074852977686923754516502207503688995019457654331626079784, 8647989100256796072321456855285912878676340053147534437521304860653); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3941357502157973923804, 2, 806977082765068646659096738618743289712629038, 95470398010431964952450128551272930452522452449699886025877059807238, 1); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36183411359542968180819498843191329944675962195184522815400173109497640044908, 5526, 3966754565367876855970249316229461606728002012105551523079085776320493, 12000000000000000000786344314428468140209160332, 1514); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19347515940517406236500101946818541192254229344198927883872669126, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1236588951273351231845418839930179263983011495754, 38238240862444672488745854665, 105710195453976313965439090442863258002796095759252242871256962165021905861650, 447301751254033913445893214690834296930546521452); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(46514948025651225960345695072605648432715982671974779016300427285754698287368, 3286, 3218715805466846511984533600393324923883748231); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3950340310148269005, 5673061940259815795875572950552217903, 0); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(201, 16652, 456263400021039761424850168808020383038614345114, 185177884615384615469); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(844186718371423468438148597031199325852724093549, 8971, 1238939858024599757491003772585973626666495470478); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(14560967560043099906703147047009467303604341499091340414611613631940255690293, 1721, 1330742788975674320956191865797062835971931496250, 8012); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(610999999999999999999, 18990, 2964); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 2202462407395028941916385359630457052998061369773792102517381208520162, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(259629493051510264, 23614305666380977416230669400318875317806232271123308657121989217833132243233, 2497, 27835018298679073652989722292632508325056543016077421626954570959368347669748, 1606); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4650754146616051773693243800451532316887707892427, 2674637045933147252314476540226577815868397623, 1637859); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(32610811746778589434426055746005034344393175264036753585460265204263347653842, 16005, 105710195453976313965439090442863258002796095759252242871256962165021905861709); - _bucketBankruptcyerc20poolrewardsHandler.stake(27241022853949367504447088193, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 128000899661578863761148718566665636525956915466064429, 1336719368342255666688); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(41124169807925345164795, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1313063028941469943130200174691186594877948408346228981); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2166715437819344420775617703353734409787244706488647403995037751254234644362, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7532212); - _bucketBankruptcyerc20poolrewardsHandler.stake(14552177917818508405730171864883921324, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 84190559757713757784279975706433133519542327009581632460886117089373); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(37747710333430245980940452738832839721522435977096927851794211126014890045043, 105710195453976313965439090442863258002796095759252242871256962165021905861568, 4881, 3966754565367876869122194268884518216957992861677661334548387666061342); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(159533269946056829911817908703969087399676830547153393250667762079770747, 120375821746749532031, 553664897755275959629); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2318, 371788003, 105710195453976313965439090442863258002796095759252242871256962165021905861824, 57957110594642022010328291066590663082489422500, 378363461538461538635); - _bucketBankruptcyerc20poolrewardsHandler.stake(1, 3108493389566117837926341948558162909763275523381432406469124236768340906924, 32229393624772079505360513009288184415901939, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2836923789, 82757687462225415771947516030365134680378685014411112583900985134363263813950, 17992734256423583958967370161492784553176489409); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2, 1599018514952142375998297880); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(55687575924400638, 727999999999999999999, 15644); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2673041966562049323144905243406346442490148198615, 1285995676085316511341291864375645429377044076357986037173062379358204); - _bucketBankruptcyerc20poolrewardsHandler.stake(27836410677470140405893559165022839553284246026566794216457, 26100442293941930306313869947915225019447736484493936778052910988, 1100121169003966414850619669523011925033070895519974812092, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(751722115384615384963, 87573722621992251438460370142942144054516549109457068516979097052450755011736, 3966754565367876854520184869943068556144348793969914759895680118784807, 27984893582647316189577999054762964794852908603917399358854612125647292485578); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(15048, 20980142891430666358441099170678931589412918730, 26229794335232538522551515320652626439652093573752750988891734989405951307592); - _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1623645501211, 581895706741971570416382, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(16294, 37775847772112785254257, 20408); - _bucketBankruptcyerc20poolrewardsHandler.stake(233076476716696715, 19720626000000000000021835, 14786, 880); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(91, 48915418688551403693013933582174377748045,1, 0); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(8520254760456735866522434792660074894149362458110124278618188561008801076487, 4508341423132101367979353817313302855733981519104609141429822885854284517273, 1045732366170946687500335725634396288218029048535); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(5250764587436405674967118092556206155749365731, 141015099610895938496827107324000508240276523703380995216176939659, 0); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.stake(75715332515, 20249, 139492422255, 105710195453976313965439090442863258002796095759252242871256962165021905861575); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(5433, 21391, 754284941459726849420512743397530252182784738229, 23905); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(192677, 4773, 2683, 940037522744286018063446172177794105409762773472); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1423000347840435497235966844164533984931800601575, 288276923076923077057, 17572, 4256931000379123634785033661970275022184774617022768398310874942392452426, 139403335757771137); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2, 2587348281013517652545024121589073614070441106624530521348844741, 519685398); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(84919864282925853877573619845135091960602695946894030665170367426270992811938, 15050648105662257143935681434472465116789984907642743379717753234643085664126, 22213, 16413, 175589814974774645221481909980815519088940506341); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3966754565367876881842889880294569887040448346346191805828869027190062, 4571, 5227); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(907000000000000000000, 2868991328, 99389371209329274803747059355072193342651880195070161537527945916651123372097); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2784308567599248162087449504, 3589, 476777860815159664263285898208782485328810582592); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(0, 93446225603511499598845951183108384660272702, 2024254557338330727781790737102999642155730612363585, 191889378792020151); - _bucketBankruptcyerc20poolrewardsHandler.stake(36183411359542968180819498843191329944675962195184522815400173109497640044984, 50146794086275195190991942805708459010074680271220970599602693206755183387706, 2065, 32789382558206698454860319624949663673430750389618486004860947532855016388844); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3, 29811238, 69968346427577179605244273168972327088469976079256197056454, 1497742154395667232899123570108019263133908353144179120765); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(3, 0, 87185381081925833627461609395751279524164897425148697297070669197775260); - _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(17279999, 3966754565367876867473138000603430830185306546546874883932992520117722, 776481524764705302352605934280580955971144914555, 962787287); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(19060901126391672628476228072540859898, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(26920601521589162671147619654088067061266745140905760588388649977853848299620, 1875, 27835018298679073652989722292632508325056543016077421626954570959368347669985); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(553591494574561111154252750468593088203, 26003311767849788325482998126201562168467079599, 3503171015763161693096394522251351236934013944546); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36822330623891827054618617680243779734013976879104614005453233537599913890987, 2030, 351827466436279533, 36183411359542968180819498843191329944675962195184522815400173109497640045092, 431); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(4307769405459937793464500814388987723043870007160919438680139924065536869, 20774, 20905556733966496908705142171609168952816592958194260630754626678628699156025, 112677305303603608793464000990919617579761525091244043308691041092632466067909, 3966754565367876866027363177544639294642486780494516334079839883146086); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(5612107944, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3758652); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3, 13063704682547015731607989179567642095598985357156794100666758119236, 1663082272433979660889799306293339760568971320019141218266316592279716982939); - _bucketBankruptcyerc20poolrewardsHandler.failed(); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(698213858938870538487, 14890451379766624461267359941375, 48557935465010072094981800005966219309615168007618540929696328537074564550805); - _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(355000000000000000000, 49046620449355538574108822723048473721226797556007972061207479861126558122006, 13060); - _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 1); - } -} diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol deleted file mode 100644 index 8de3ba2e0..000000000 --- a/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol +++ /dev/null @@ -1,538 +0,0 @@ - -pragma solidity 0.8.18; - -import { ERC20PoolRewardsInvariants } from "../../invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol"; - -contract RegressionTestERC20PoolRewardsManager is ERC20PoolRewardsInvariants { - - function setUp() public override { - super.setUp(); - } - - // Test was failing due to incorrect removal of local tracked positions(tokenIdsByBucketIndex, bucketIndexesWithPosition) in handlers - // Fixed by not removing local tracked positions - function test_regression_rewards_PM1_1() public { - _erc20poolrewardsHandler.unstake(156983341, 3, 1057, 627477641256361, 0); - _erc20poolrewardsHandler.settleAuction(2108881198342615861856429474, 922394580216134598, 4169158839, 1000000019773478651); - invariant_positions_PM1_PM2_PM3(); - } - - // Test was failing due to incorrect removal of local tracked positions(tokenIdsByBucketIndex, bucketIndexesWithPosition) in handlers - // Fixed by not removing local tracked positions - function test_regression_rewards_PM1_2() public { - _erc20poolrewardsHandler.addCollateral(378299828523348996450409252968204856717337200844620995950755116109442848, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 52986329559447389847739820276326448003115507778858588690614563138365, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.memorializePositions(2386297678015684371711534521507, 1, 2015255596877246640, 0); - _erc20poolrewardsHandler.moveLiquidity(999999999999999999999999999999999999999542348, 2634, 6160, 74058); - invariant_positions_PM1_PM2_PM3(); - } - - // Test was failing due to incorrect removal of local tracked positions(tokenIdsByBucketIndex, bucketIndexesWithPosition) in handlers - // Fixed by not removing local tracked positions - function test_regression_rewards_PM1_3() public { - _erc20poolrewardsHandler.memorializePositions(1072697513541617411598352761547948569235246260453338, 49598781763341098132796575116941537, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 59786055813720421827623480119157950185156928336); - _erc20poolrewardsHandler.drawDebt(71602122977707056985766204553433920464603022469065, 0, 3); - _erc20poolrewardsHandler.settleAuction(1533, 6028992255037431023, 999999999999998827363045226813101730497689206, 3712); - _erc20poolrewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14721144691130718757631011689447950991492275176685060291564256, false, 136782600565674582447300799997512602488616407787063657498, 12104321153503350510632448265168933687786653851546540372949180052575211); - _erc20poolrewardsHandler.unstake(5219408520630054730985988951364206956803005171136246340104521696738150, 2, 0, 7051491938468651247212916289972038814809873, 3); - _erc20poolrewardsHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 120615857050623137463512130550262626813346106); - invariant_positions_PM1_PM2_PM3(); - } - - function test_regression_rewards_PM1_4() public { - _erc20poolrewardsHandler.moveLiquidity(832921267658491751933537549, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 62241022956197145532, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 108613063553696015935192567274231711586207468226993603118670370534031542, 2, 1); - _erc20poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); - _erc20poolrewardsHandler.settleAuction(1694548149298356876485941302354, 9052, 1444291546717740702970, 1303240033616582679504132393648); - _erc20poolrewardsHandler.burn(0, 707668523430171576399252973860135329463494151705, 13231138491987546580, 3); - invariant_positions_PM1_PM2_PM3(); - } - - // Invariant was failing when rewards cap is equal to zero - // Fixed by updating invariants to run only when rewards cap is non zero - function test_regression_rewards_RW1() public { - invariant_rewards_RW1_RW2(); - } - - // Test was failing due to unbounded debt drawn in `_preUnstake` - // Fixed by bounding amount to borrow - function test_regression_evm_revert_1() public { - _erc20poolrewardsHandler.kickAuction(4927, 15287, 1672621391, 7794); - _erc20poolrewardsHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); - _erc20poolrewardsHandler.takeAuction(2575, 5650, 2711, 12004413); - _erc20poolrewardsHandler.mint(1515215594322469882937526919173, 2864); - _erc20poolrewardsHandler.removeQuoteToken(11445, 2303142144561970723486793685729, 3879, 1008905021187010892); - _erc20poolrewardsHandler.redeemPositions(23630504830242022841459200705989645184404322170375013590678501625107, 1, 282473030835977356124316597209309127812, 0); - _erc20poolrewardsHandler.redeemPositions(4829, 7399, 20165, 19797); - _erc20poolrewardsHandler.addQuoteToken(8330901901683684346410, 1944730599598704240629, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.mint(52483, 375); - _erc20poolrewardsHandler.removeQuoteToken(242161003333451991910682, 833804465517702, 0, 153306087017); - _erc20poolrewardsHandler.claimRewards(5460042422485935527540305190804180316252530934172557782973004, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2317020199583405169185090105199, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); - } - - // Test was failing due to insufficient user token balance for `addQuoteToken` in `_preMemorializePositions` - // Fixed with adding minting required tokens before `addQuoteToken`. - function test_regression_evm_revert_2() public { - _erc20poolrewardsHandler.redeemPositions(535, 10526, 16402, 90638196); - _erc20poolrewardsHandler.moveQuoteToken(3, 3, 3665933105380066469, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 35609320936341689682324970775); - _erc20poolrewardsHandler.lenderKickAuction(65195123838887638071598468995195715179071041842210505440218069543269527898574, 1428, 1550); - _erc20poolrewardsHandler.updateExchangeRate(3324, 3433, 0, 385); - _erc20poolrewardsHandler.removeQuoteToken(487993211956248337274085963929265840000354071708865988088685578811819, 8714694397591072960002001972219030782403253520, 0, 0); - _erc20poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 3, 0); - _erc20poolrewardsHandler.addQuoteToken(8049702985159192133654841011926250176578891096284667148191654768576101, 420390974052856985135062265979816823871512, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6168047604119363323178237637165700555180739052007127817776433423995137133826); - _erc20poolrewardsHandler.pledgeCollateral(38623724134600076305519407, 1, 42313782903); - _erc20poolrewardsHandler.takeAuction(2520288506, 56779, 10626, 2578); - _erc20poolrewardsHandler.updateExchangeRate(2374, 3180, 0, 11271); - _erc20poolrewardsHandler.moveQuoteToken(3, 84452381279, 65209096465360247728023547148755401892588275436, 1, 97710781974409185143365462469280072552935020234615584635942788); - _erc20poolrewardsHandler.claimRewards(4219, 7299, 3792253, 3829, 5); - } - - // unstake is being called with a minAmount that exceeds the rewards available, causing revert - // change was made in regression to handle this case - function test_regression_evm_revert_burnedInEpochZero() external { - _erc20poolrewardsHandler.takeAuction(7657762660104020786102326341030666744203129169035726688092178, 1, 3, 63603943629412590405183648739466756021204); - _erc20poolrewardsHandler.moveLiquidity(853498184631967766239539459019, 860800972267934599, 2712933514310088838415608172991, 1940131010529342263123392466824); - _erc20poolrewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 427572220473655037333866875012561018809807470070214697627941860984, 44890261877119855592686274106685080718432502924958626579185298373762938186596); - // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) - // epoch: 1 - // burned 27895 - _erc20poolrewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 2); - _erc20poolrewardsHandler.pledgeCollateral(1, 0, 2); - _erc20poolrewardsHandler.pledgeCollateral(46380480507328, 10, 1); - // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) - // epoch: 2 - // burned 27895 - _erc20poolrewardsHandler.claimRewards(1852732090424016924140170274064383911484, 183940675308906, 0, 53861119148520095956903865568282398357460507464813555898544376318790433189, 3); - _erc20poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 395769107397432386894162390920154234120, 10606604808645482457593038172768629927057694502686); - _erc20poolrewardsHandler.removeQuoteToken(2, 1, 2192625645230692453890585257984624461888, 6660232197673667038115249964); - // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) - // test was failing in the stake action that occured in _preUnstake() - // * totalBurnedInEpoch was returning 0 since no burn happened between unstake in claimRewards ^^ and the stake in _preUnstake - // * caused underflow since rewardsCap = 0 in this edge case - // * fixed by adding a check in updateBucketExchangeRates() to not evaluate rewardsCap unless totalBurnedInEpoch > 0 - _erc20poolrewardsHandler.unstake(10754921060610721338628656060623251463708357833056948746687720475, 2630, 3678, 47729066275298389217682475444047844926190, 2); - } - - // During this last moveLiquidity call the user gets more quote tokens worth of LP tokens than they had before - function test_regression_PM_failure() external { - _erc20poolrewardsHandler.repayDebt(85714, 1049291847999068770, 999999999999999999999999628872336833145697942); - _erc20poolrewardsHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 36806208, 15184194898560474755071902858637273513435561597233554208311133688, 467793045980282819019245873531034252276885664851); - _erc20poolrewardsHandler.takeReserves(430754706367378, 137895823818768170443343531843552347803975, 136256767494531323); - _erc20poolrewardsHandler.removeQuoteToken(151907177410358060568159872791300321117419489937830, 7129107044982420534725125240530941606156790404561718416111313794090, 9379839670333585391370, 64411724624691339174378); - _erc20poolrewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4761347487120837320733494601307653768982862843053132338897249261174, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.moveLiquidity(1387083372699602, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1); - _erc20poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 28562572353266841739143693967402627296578365988173585532380692, 0); - _erc20poolrewardsHandler.removeCollateral(880053353375737921406212405707, 1753558590, 6280826978696699921318109415672827430264350217031853972826832132306719032380, 787979188955935138704416864067); - _erc20poolrewardsHandler.moveLiquidity(11088, 1034959661872260168, 999999999999999212021821301557602448736097220, 999999999999999999999999998999999856219412005); - } - - // moveLiquidity() call moves deposit from above -> below the LUP causing a fee to be applied to the user, therefore a loss in QT - function test_regression_moveliquidity_below_lup() external { - _erc20poolrewardsHandler.unstake(4735, 7947, 99648028073174186569406251043082614463523861559444314198794141049070931765266, 165, 1); - _erc20poolrewardsHandler.memorializePositions(1017586779835017595, 2000093450358386131913319801132, 999999999999999994705800289221, 5936); - _erc20poolrewardsHandler.lenderKickAuction(0, 552702177486359210209998874773373639789414577510403177176780671, 1); - _erc20poolrewardsHandler.lenderKickAuction(5408465446957, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1244705446892222810789723108370662428040158); - _erc20poolrewardsHandler.pledgeCollateral(17006067685850655253277243263894458277559455, 365821919836536381007791134, 3); - _erc20poolrewardsHandler.transferLps(1020398235799939978, 8615, 10094997325303278, 6365, 16905); - _erc20poolrewardsHandler.moveQuoteToken(31568984050285372419235475362633334556373463, 2459831956710974374263868230506844670431779539018807045, 5569725293573705060280053370462598629680698918, 3, 0); - _erc20poolrewardsHandler.drawDebt(2189769129255122063229251712703191878940949, 1, 30); - _erc20poolrewardsHandler.redeemPositions(4988, 1000000019294578543, 113393, 20000); - _erc20poolrewardsHandler.moveLiquidity(11546346822809939448153205354420218227887882771387, 17456495056515572411115147660, 182412808598764326152439106919570567805594493064808060386470, 34611500787879233737900); - } - - function test_regression_PM1_PM2_PM3_failure() external { - _erc20poolrewardsHandler.addQuoteToken(1000476160430240196, 31831819542854202372682438294297749483895311991281138887779537875208920731861, 1690250244645061953490579723838, 8303344632134790875350129671); - _erc20poolrewardsHandler.redeemPositions(24517164785660125111092467892090015256239780879372312856314705897654233071616, 789619793367986175384776327373, 17366, 27337330393966417869011597343142520438331591211099340735032445540394415961142); - _erc20poolrewardsHandler.mint(4918260799182, 7979); - _erc20poolrewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); - _erc20poolrewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 541386860615883, 3, 1427594577268427, 3); - _erc20poolrewardsHandler.repayDebt(3, 73, 14148592833); - _erc20poolrewardsHandler.withdrawBonds(408448193972491682247856759691, 6725156476034981825430803209361659548467896941475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.burn(207659258550486295439876272535780992392904995291122705229127151, 747338929, 1252191612369811194685436, 1); - _erc20poolrewardsHandler.settleAuction(40898023934445005959403090083409155881516500501072076223, 14829255767842040071, 22556694249976650341045163634875596221258685026085348004092232963852919995373, 0); - _erc20poolrewardsHandler.lenderKickAuction(3, 1763503097380079097391449321238134748267573906097584829633224009446989852620, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.pledgeCollateral(992967362603883335031186827777494890596884348, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.moveLiquidity(1439924512892792038061585821476, 12312838412972807476774254, 1386973529615993967509458441, 25874047955237976217666127598767369999822558723350386077928985570803529547776); - - invariant_positions_PM1_PM2_PM3(); - } - - // exchange rate is below one and a moveLiquidity() call occurs - function test_regression_exchangerate_lt_one_failure() external { - _erc20poolrewardsHandler.settleAuction(1, 38076326081732675084782953958723025268483402, 32122014834284740581605218790860586945, 675323572528116699998584163938054267674059083708770338684825); - _erc20poolrewardsHandler.takeAuction(3187233434979664450766064117497382244786499427506246277958134435335, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 68185348, 0); - _erc20poolrewardsHandler.removeQuoteToken(9799774902, 0, 171307717744339938462212153344256080, 22090621942183459004431027189984935997454202251794379); - _erc20poolrewardsHandler.settleAuction(10469641420936113, 158810559950203569266889779145, 2729976800298283367181, 629830085692443228137978633631); - _erc20poolrewardsHandler.kickAuction(1999638989041095890000000, 2621683063801908884388370586075, 5202919328337784754771241, 1704327030); - _erc20poolrewardsHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 16473, 1298950632239640199, 92988305527741837015515230); - _erc20poolrewardsHandler.addQuoteToken(4513829468825775442619016612, 119081395592772229137, 2956368200448621153724264764841, 43337887745458188956665754735863930); - _erc20poolrewardsHandler.redeemPositions(1280000, 107418549682317941, 373995538053150407541675996799144040378996115919481128822550428, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.moveLiquidity(67209037983603756736, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 107047380550, 136465421231555); - _erc20poolrewardsHandler.burn(0, 215634488088281622713592282980500574552450094015166108001671516324248273978, 2872470631302225600444008164197436445, 3825369962689014919985865); - _erc20poolrewardsHandler.redeemPositions(9321565985916881685418690197371166789551668163901391336422536021610052010235, 1000001049598692774037881, 1000916926448247166, 1294903748407840); - _erc20poolrewardsHandler.memorializePositions(11357398784982391024848846139138331345877617925164801651509999164448020739, 129054800695, 2, 0); - _erc20poolrewardsHandler.unstake(1008040767152967082, 2705590298374864519261, 2711436202524373179865882211354132, 1058992097359326876866506180, 0); - _erc20poolrewardsHandler.drawDebt(0, 2, 2); - _erc20poolrewardsHandler.settleAuction(3, 109119248607504264825921197422518323470603, 2736316384792465597, 12368015967168137); - _erc20poolrewardsHandler.lenderKickAuction(1, 34593728349238363, 2); - _erc20poolrewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); - _erc20poolrewardsHandler.takeReserves(37288205583577963230409441522973702491285105267336919446, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); - _erc20poolrewardsHandler.redeemPositions(46789, 6151865526048672236676594, 9043006728606892937350259542, 93268112651994959075836677); - _erc20poolrewardsHandler.moveLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3563135139286698066907701283845339, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); - } - - // exchange rate was less than one in fromBucket during `moveLiquidity()` call - function test_regression_exchangerate_lt_one_unstake_failure() external { - _erc20poolrewardsHandler.addQuoteToken(6142020986804765534920167884740010286243484147097745265674427, 112422117, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.removeCollateral(10151503789076003424768351930, 50838311790159949733482050440261, 787978286748398677564101888697, 743157368739340183819239223268107466431333883452773104647798952518671555); - _erc20poolrewardsHandler.updateExchangeRate(21755610456008175749216891385815221667397636280908693792396899755901148039675, 76822710358333592680973548681291198, 0, 183811652651622670286097901303322315169696013956957316331731965); - _erc20poolrewardsHandler.moveQuoteToken(3843466665413066001504591, 1000009389351870783, 1000172353696212579, 2796008107630611079450058960364, 10168864164675898312163); - _erc20poolrewardsHandler.moveLiquidity(673087759601966739507343763016554, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2339943610295551416526796192911912414311026002620, 9446221296393433187709657992720367407411357294298157052447175); - _erc20poolrewardsHandler.stake(999999999999999505134320049118757567405586786, 1025431341927257246, 1090, 13569953566136947230136843); - _erc20poolrewardsHandler.moveQuoteToken(1051099440087016359, 1357438875313834074678021636760282066916630639717893146590321, 63313628, 84622650405653151060672, 28876); - _erc20poolrewardsHandler.bucketTake(7462, 1121098501725271973, false, 999999999999999999999989741489665556227804536, 442072679406687075418827994186); - _erc20poolrewardsHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 11542363425921008807915173674517106); - } - - // auction was clearable when `moveLiquidity()` was called, which fired a revert - function test_regression_auction_clearable_remove_collateral() external { - _erc20poolrewardsHandler.takeReserves(1033259874529284986, 115792089237316195423570985008687907853269984665640564039457584007913129537237, 999999999999999999999999999611297087410149302); - _erc20poolrewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); - _erc20poolrewardsHandler.settleAuction(1019166912441147606, 1174, 24356906371720, 1427315247291615855384771361467057592874190974); - _erc20poolrewardsHandler.drawDebt(31570870468988913, 2490457201062127395317721901417, 14518); - _erc20poolrewardsHandler.removeQuoteToken(234409660495649, 601338041799139892223226281710979, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 51209466403350773952498018); - _erc20poolrewardsHandler.removeCollateral(1615097416247525221325833769791620, 999999999999998491682012949797990382689794890, 72294939771647531696639626124859859519954417706042013154, 1123754474529168009989296); - _erc20poolrewardsHandler.addQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1418766863689180288802735178388574160614681714182842545424322601317331241, 0); - _erc20poolrewardsHandler.burn(10779801302631984284074768919, 1022785462636254549, 4247197939956962367856295710228836, 714087046845131802724051059732250799440226582946566742486292756992468224); - _erc20poolrewardsHandler.settleAuction(44188076061165790147414944966563643572374763434799334, 1, 6140, 982305872882119302926935288339691246129501298); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0, 1373087264969562284412462993767160637254468276739905307938530638280854638702); - _erc20poolrewardsHandler.pledgeCollateral(10321692057145851776062997, 45715379632908488147290369180827577791327034825339732187105428425706, 73584310749102695099025849803685991935361634); - _erc20poolrewardsHandler.moveQuoteToken(267424702347976937182244333, 53012, 1000122761636267185545584328894, 81844228617571507568624913, 2091433423541324315018709); - _erc20poolrewardsHandler.memorializePositions(4341569243600918031477893648, 1037146955303444803059178, 541740178036862, 1079117209305474618); - _erc20poolrewardsHandler.moveLiquidity(7990221475142856060836580, 5177379241789726416494109766258664604084660827937056770440668685154449638506, 270858793106233, 4554); - } - - // underflow occurs on kick with Deposit due to round up occuring on the amount being removed from bucket - function test_regression_kick_deposit_underflow() external { - _erc20poolrewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639933, 486888075223510502299880936499251496488108390102993365331518154575959314103, 1489390063300625330233647743808860618285793249553177794776030333650229253556, 29413051449830420745080834496160737679746193111333313068326, 3); - _erc20poolrewardsHandler.takeAuction(2000097453768943289819883643139, 1616, 9008, 2957522668165515327594480); - _erc20poolrewardsHandler.kickAuction(1023868299540571449491438, 2726, 3501, 1009546288143049196); - _erc20poolrewardsHandler.claimRewards(1850558667714835415003, 1128770330214, 48160424827244602174656651208212101506580, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5); - _erc20poolrewardsHandler.memorializePositions(2706256741681, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1224263559891519537412449982749693535319617589850332219938434821323); - _erc20poolrewardsHandler.kickAuction(2470057927126901389325412029621991572541444590040210706345694, 33212171733138561367109746153438995283000410403806989, 1143982811769352536641977506, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.addQuoteToken(11577, 2847, 701077953563936355129549681402475369359939627904709959917807724349081600, 6164); - _erc20poolrewardsHandler.mint(7455, 2274); - _erc20poolrewardsHandler.transferLps(3, 461323124985628625982, 3, 2265109234892451242814665907719473205880324711447657612395270, 36536442103629333036112242276175423646850388752964235954199714605113762301); - _erc20poolrewardsHandler.addCollateral(4807, 1257702269788440403102767606588, 10232361733685599944417, 8154); - _erc20poolrewardsHandler.moveLiquidity(1147643, 1101373970, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.redeemPositions(715216745373273013565709474193709288265853036742499324291033262974521344, 925844451104042264560, 21216664920724276219251928893592593152072674630296951273414530379050570789349, 64994818096056336519112112386345118349558865048523329927782158963716200486113); - _erc20poolrewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.drawDebt(7803620494871325091384326, 1000000000005890305, 808187899175442127626759093647); - _erc20poolrewardsHandler.stake(1881897373701350, 1, 384457493842895898324057, 2); - _erc20poolrewardsHandler.kickAuction(1801888015, 36313972, 14589, 68230236911552087964619588008895983939113692817643498711581573912769382961420); - _erc20poolrewardsHandler.lenderKickAuction(3409291658389088656420401948375478879628336006312790484, 256489454668391, 264957533719095533849934255388); - } - - - // called takeReserves() when claimable reserves we're 0 - // fixed by switching from poolInfo.claimableReserves to _pool.reservesInfo() - function test_regression_takereserves_no_claimable() external { - _erc20poolrewardsHandler.settleAuction(2, 3, 132571599922733151315276632984852300695962190184833433609822587845, 7127747531336); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.pledgeCollateral(66498430692251244700, 1672526787, 999118417682487042682458556356); - _erc20poolrewardsHandler.settleAuction(102521875, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); - _erc20poolrewardsHandler.redeemPositions(0, 11874544000691612616189791308069964024776658688403726762, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.moveLiquidity(6932062779809046417357379434, 37304063095178465963, 289377204519251903, 688903335135867866827970099664435153097141537805976741866417852208381952); - _erc20poolrewardsHandler.settleAuction(86639131860678742534809729831583343741269560864832321, 261140637, 18623697431831025536282119954975103467560305081672865, 18753717689854910664818243334489713190658697158135381); - _erc20poolrewardsHandler.moveLiquidity(688023305723199887936675774367107725948935104557465010923465143476322304, 426, 1361140653919103091484439143, 1690059365); - _erc20poolrewardsHandler.removeCollateral(3, 75640118, 25456, 2); - _erc20poolrewardsHandler.stake(1201518266017002700145955555, 422051400149996, 191695523226259206952824982, 2575958376257460112331288247217); - _erc20poolrewardsHandler.removeCollateral(1724406295, 1153800818710038190908366, 198135760955974969122979112, 4072468695723038050466180656348448601624931627598867728374067772641581); - _erc20poolrewardsHandler.moveQuoteToken(1, 2, 7848862956757903893727, 108398233646184752124495509729309782170036195843104530456166511127401848014, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.kickAuction(1033780344472464085003, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 4939129467716821333159227066); - _erc20poolrewardsHandler.memorializePositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5339231111427732, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 49134859377105172171787763664088172754470175); - _erc20poolrewardsHandler.takeReserves(1000017062814174578, 695225158368402414621475732431414969707809712405441717937557041383099862, 1000099679120030632); - _erc20poolrewardsHandler.updateExchangeRate(1798084723794266922073360424201, 1000261123000933782, 0, 1010104555201180320207069905273); - _erc20poolrewardsHandler.kickReserveAuction(14193, 4151); - _erc20poolrewardsHandler.claimRewards(84674527179871518692009907151225958831784072125472174554, 1123074827467033894904599425374, 0, 2, 1); - } - - // the rewards manager took ownership over the position NFT on stake - // fixed in invariants tests by transfering positon NFT ownership to and from rewards on stake and unstake - function test_regression_rewardsmanager_transfer_position_ownership() external { - _erc20poolrewardsHandler.redeemPositions(1513, 5414, 496, 2041); - _erc20poolrewardsHandler.moveLiquidity(1634580778705039759, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3513140137853878345040965, 6059353902491193986166404361793496); - _erc20poolrewardsHandler.takeAuction(20887, 7435, 2230322682, 5173); - _erc20poolrewardsHandler.removeQuoteToken(1, 37847095259185386235427787, 7586404791082, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.kickReserveAuction(746270214, 3227); - _erc20poolrewardsHandler.claimRewards(3, 17838572802108205165768007139310483904447158906777650273909618150730155082, 179308467167974215120170861599730499666095743876089926251458944458077, 3, 2); - _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 410137998186978556584901507876419312185968499332529, 0); - _erc20poolrewardsHandler.repayDebt(17165, 29, 4926); - _erc20poolrewardsHandler.redeemPositions(10181896186129835628862076, 4191, 2070, 4316); - _erc20poolrewardsHandler.unstake(2, 721416428842444814, 1, 1, 2); - _erc20poolrewardsHandler.bucketTake(1701628611252955073601757907075824586952502043588380, 9931050451872161232934786702827793159570303822, true, 2925965874111818002623246439633594772, 3); - _erc20poolrewardsHandler.bucketTake(2, 15470539950385543111949808932971047871463497008525518386, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); - _erc20poolrewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2652132885321220255, 2, 1557926034); - } - - function test_regression_rewards_revert() external { - _erc20poolrewardsHandler.takeReserves(1, 176264227116073539466710292640534, 0); - _erc20poolrewardsHandler.drawDebt(1, 57859908193408492548049732123715354988106416421644089, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.addQuoteToken(1807664453705980418, 3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.drawDebt(14810, 12501, 11607381230457826577033271); - _erc20poolrewardsHandler.kickAuction(126, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 296936791599072888382604547047579799590572591); - _erc20poolrewardsHandler.bucketTake(2084, 265280, false, 621014983179582, 6560); - _erc20poolrewardsHandler.redeemPositions(7465, 451605496, 3970, 1512); - _erc20poolrewardsHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1751716589805844630991620468, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.kickReserveAuction(11967, 1005568066651507152); - _erc20poolrewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 2724518779079179784049138199493777186815675, 1874); - _erc20poolrewardsHandler.addQuoteToken(3981, 1690101581, 97503618599900271359071534105156178950663445728441824941278920981153136631167, 999999999999999999999989741489665556227804536); - _erc20poolrewardsHandler.bucketTake(247, 1291084637306870208638, false, 14752, 753); - _erc20poolrewardsHandler.updateExchangeRate(3, 2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.pullCollateral(1266635973860390773360, 1, 3); - _erc20poolrewardsHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.takeAuction(2214845414466110799205272778680836428372471699, 49004997820594553259859787080944156522906733, 3, 271825241); - _erc20poolrewardsHandler.repayDebt(221806598861099254438373725802873431978648517331723635037739192841369, 11212235606391953616223043585188034400902381408644500974587575, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.unstake(230323675018036494562757, 21630132699099546696940190603184460107953215649, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); - } - - // small rounding error occured in poolUtils where it looks like the lender has one extra QT then they actually have in the pool. - // fixed by adding a greater than with diff check - function test_regression_rounding_on_moveliquidity() external { - _erc20poolrewardsHandler.bucketTake(29456557203126366201854827466482433206831494327361303, 19307664601998129837361, false, 3492651658979151995106448, 0); - _erc20poolrewardsHandler.lenderKickAuction(4429580015302257459201655018526, 2770867242698718418626, 9388); - _erc20poolrewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); - _erc20poolrewardsHandler.moveLiquidity(41132919728951221583605488, 1102564553356549573347, 3410238307441803358653636, 4545656474572434187813557497); - } - - /** - Test was failing because positions manager was asserting popol errors and not position manager specific errors. - Fixed by adding _ensurePositionManagerError and _ensureRewardsManagerError and use them for manager function calls. - */ - function test_regression_failure_rewards_error_expect() external { - _erc20poolrewardsHandler.redeemPositions(696309158766729979589534440166220067073887038152281856742599135926157312, 1870474563221356095022900189266, 18339, 1788135699833095102184812046279); - _erc20poolrewardsHandler.kickReserveAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.memorializePositions(3671371551743995865, 99428, 1769100398, 7346319752739159); - _erc20poolrewardsHandler.removeQuoteToken(2192844669750518881733689799257684129590332632218546259991943830203, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 419); - _erc20poolrewardsHandler.bucketTake(1606233188525778759956925750889, 999999999999999529711266919982837439648513939, false, 9949287379244091378213227, 3763880249088816172848545904993); - _erc20poolrewardsHandler.settleAuction(55047125510583885662282424543762268712076435621770843340435135, 110421716658405583291991613217254392572785222796303390816855215908218229630, 1, 292423500273437202726891613067834132052054453755096719350366291073639790); - _erc20poolrewardsHandler.takeAuction(6950266099624730892351521874528127288800419, 193622918230501420262501464441837, 3, 20111879376924408726124755543747277966848148390627132304350); - _erc20poolrewardsHandler.bucketTake(2, 747496798808534888002766542, true, 221618799467305555283, 661410089069342); - _erc20poolrewardsHandler.settleAuction(39300471897997857700471, 363003327028528645286555715801688230394596448247050, 10248673406547114848805417911883714616830860910846335722973488061592062643, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.updateExchangeRate(3, 4485331781540521052468660062240, 0, 3); - _erc20poolrewardsHandler.burn(20137826853855347137082717445, 194771708143610511040376640, 3706358530371129512271612, 14017756049926664649805910646); - } - // Minting uint256.MAX amounts of ajna to reserve auction takers, which causes overflow in rewards staking actions. - // fixed by minting a smaller value to ajna reserve auction takers - function test_regression_rewards_minting_max_ajna() external { - _erc20poolrewardsHandler.transferLps(13692, 15203, 2000001367681895243673966806260, 13770006083256457112227, 1672449141); - _erc20poolrewardsHandler.takeReserves(4947313423932616986372909633726, 3107772, 18585868099953215630514); - _erc20poolrewardsHandler.bucketTake(3, 3, true, 5727003712726959800, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.moveLiquidity(3157314460140, 999999999964761098816798416093, 100749181527550271579655357, 2453039451665641392603351405279); - _erc20poolrewardsHandler.pullCollateral(2227999026154255580938434049821, 1929, 21209080205145509799924600234705734221480599); - _erc20poolrewardsHandler.unstake(77763028316274741760991770148, 889544954655483052642168760960, 1000073821603105106, 14781730360850539958536528862089, 1); - _erc20poolrewardsHandler.memorializePositions(3, 2, 357097079890085816811291167102020270214, 1); - _erc20poolrewardsHandler.takeAuction(9839460449437189937506383151267733565283, 75862151750582034326928310158878873987779724, 442512581894915658301040013323770372275116408434438200991, 4465076566725287152347371577222429); - _erc20poolrewardsHandler.takeReserves(18196, 115792089237316195423570985008687907853269984665640564039457459248091501068020, 7726328457662922431145272); - _erc20poolrewardsHandler.updateExchangeRate(934079800963406838548241273326154438, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - } - - // Staker earned rewards for staked position, RW6 broke because invariant was incorrectly accruing `updateRewardsClaimed` vs `rewardsClaimed` - // fixed unbound claimRewards invariants - function test_regression_rewards_incorrect_accum_update() external { - _erc20poolrewardsHandler.bucketTake(4645898402004950106563597036, 1, true, 3, 2); - _erc20poolrewardsHandler.kickReserveAuction(3, 144); - _erc20poolrewardsHandler.claimRewards(44705418907931161819765043998797583827, 151688058596538037321153972615358552, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5828173, 5); - _erc20poolrewardsHandler.lenderKickAuction(1, 0, 58846077910505664190879804); - _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); - _erc20poolrewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.moveLiquidity(7886, 1223, 249959471556478, 957); - _erc20poolrewardsHandler.drawDebt(3724423259505818275008000000000, 5967, 5194); - _erc20poolrewardsHandler.claimRewards(1, 0, 0, 330972817125, 3); - } - - // RW1 and RW2 were written incorrectly. a rewards cap of 0.1 was placed against the total rewards amount which was incorrect - // fixed by creating distinct mappings to house rewards: updateRewardsClaimed for updating and rewardsClaimed for staking - function test_regression_rewards_RW1_RW2_combined_accum() external { - _erc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 87088279133912395360162508437887139725077665220, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 564626589538129677125005778268696423, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.takeReserves(11684, 194771708143610511040376640, 2726053605342047396811); - _erc20poolrewardsHandler.repayDebt(3262, 43081368297850871705277077223467592454899175043611071, 10274); - _erc20poolrewardsHandler.redeemPositions(127647, 176264227116073539466710292640534, 3642, 6424); - _erc20poolrewardsHandler.unstake(15694742330810166545782643648487796809086809379390, 607818605291333492717424880577475155800497188006507929455743410345480887752, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); - - invariant_rewards_RW1_RW2(); - } - - // staker already claimed for existing epoch error because the mapping of already claimed rewards was being altered in another test. - // fixed by removing the mapping once the check was performed, to reduce interference in other tests - function test_regression_failure_staker_multiple_claims() external { - _erc20poolrewardsHandler.removeQuoteToken(24285633761882022498, 1087578245407996, 6663358518051573788202107245824545840942246519100783976433621551356294723, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.moveQuoteToken(11189536869195702264148707856867561997664222332845405361, 3328728726287, 4818513330572085618, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.drawDebt(147725477328679114917217631961569282438136190, 3, 780472003275470496134709650710074636727788); - _erc20poolrewardsHandler.lenderKickAuction(919064247875031136583359099106204830246792228137453488870, 1142457080388403685288317708444374, 4671787121933361676687432014984357526); - _erc20poolrewardsHandler.kickAuction(203912244895332759271129822, 4693281693470198349449305071, 1643664758545948144732945329396, 1000004561414141810); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.transferLps(1000038693989240313671379334981, 2064846640417648425220112605606, 4776864955275099928806866, 6232424780589094815714662395270, 1000068114008626106); - _erc20poolrewardsHandler.claimRewards(1000036940761117130, 15003867908887127997315, 3476353371620033073265076493, 2724312429953097381534815815, 5); - _erc20poolrewardsHandler.burn(688021852742675773311740551529319527808439204801695657427445806654554112, 30320319961996759187294, 7002942661907890346192131385494, 4372348210670480168); - _erc20poolrewardsHandler.unstake(1356091896433556140, 20806050335329426573872365432402, 5853329116210293074909437460260, 202213678846911363250835224523544374961057849761087685126829207099, 0); - _erc20poolrewardsHandler.removeQuoteToken(11944716614558445837844163345350475870007169059677226591038156, 9999999999900006, 2613391316561261247247566287419, 4364050756734297123000000000000); - _erc20poolrewardsHandler.memorializePositions(267426811547115, 20523234942372868849155805716884, 660538126174426773503894024918, 1020371850849496789); - _erc20poolrewardsHandler.stake(1009570841568842278, 8707191874572311188045452143575, 1710745869, 4085931245162069848956376); - _erc20poolrewardsHandler.transferLps(5683740793368242368410, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 263051426251); - _erc20poolrewardsHandler.pullCollateral(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.unstake(4318031226528307865, 2427656545187034005147981107428, 1999999999999245325259195647033, 3241340219561149539730512456599, 2); - _erc20poolrewardsHandler.stake(10032989871238071275035296997, 2017261180517741466821728, 2211627002267302216727501639610812218, 548909584864737399169449); - _erc20poolrewardsHandler.drawDebt(27796260741388465380354085173951821931976153684318037320868618, 0, 1672262194402336308934191620772703213726098465095081105360392328585273); - _erc20poolrewardsHandler.bucketTake(1000043044918731278, 989512172161706009835325237367, false, 1000000005789793860, 718039675495668253370172541641380612269183998166480256112884969954061103); - _erc20poolrewardsHandler.claimRewards(1674960979, 1000564244419437928, 8087677654804602510627745801, 4446820520587650728200, 2); - _erc20poolrewardsHandler.claimRewards(226258926917592116664863093705619544, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 18029537521280273078473, 64387518121614299931212379232668997590869195864587409918593738, 3); - _erc20poolrewardsHandler.removeQuoteToken(3165456173686488430468312904346908679008474143924097052287399491, 15313716, 1, 15552668823196538810190871817386173988612672596735983713269529192153445604); - _erc20poolrewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 2); - _erc20poolrewardsHandler.addCollateral(10945914945614266, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 239408596493925146571027857511336345824311692975188481875, 16168911541889819611465250007078558808000491263581406139030); - _erc20poolrewardsHandler.pledgeCollateral(43390517402447252786570881, 1000007721712886379, 312183671006043540); - _erc20poolrewardsHandler.burn(1001000021343878223399528504368, 726228322825731430757899965868487151749079834114138594667272479585189079, 7830602496179727327668297777390, 9148487490087675901121950); - _erc20poolrewardsHandler.addCollateral(2, 125397281674915775936395560595460719614532516542110165807175343, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.claimRewards(18775690215791444885292093480688, 208511828163843, 4213106861723786168510998809808, 4611795088561515898132575771125, 0); - _erc20poolrewardsHandler.redeemPositions(2479835579104654494942210452716501545070460863704620515865, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 1); - _erc20poolrewardsHandler.mint(2647711055765730795283609134451, 1709697543); - _erc20poolrewardsHandler.removeQuoteToken(1000031404174607617, 5000000000000000000099999999998628859607877633, 999999999999999999999999999999912337547565207, 3682474236458075670320739768); - _erc20poolrewardsHandler.moveQuoteToken(1692705698, 34709306640687381, 7111844725028768215861322, 22408667914897973235640361397760, 4814072800199917128); - _erc20poolrewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, false, 454902037913297664707697112174539827120540854483325325297181451700, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.emergencyUnstake(1050599261156147113, 1074376691263000000000000, 7002651109185164, 4921048347176326540998962106120, 3); - _erc20poolrewardsHandler.redeemPositions(1605595040568071691761529272186, 6374589932811962143806364569626, 504869791, 703741879815086064785063845794263063501986986299046618128871452969759630); - _erc20poolrewardsHandler.stake(9240016643022332539182984, 695264275347035435556335000, 999952379124307148259328110510, 3501569749230777430235792877533); - _erc20poolrewardsHandler.claimRewards(290604600286948252496463313490999079578398159220189531705245153689, 1229050267483794368236552210802835, 37012905065727386300525031553852696, 2, 3); - _erc20poolrewardsHandler.redeemPositions(710948940482212513086987224336033101275209864506038053434815275674467459, 8721353501337744379589622994550, 1714490698, 9015569170803075570277970519); - _erc20poolrewardsHandler.burn(1011903686256170066, 989528036602738431304462409919, 1672529967, 778713523685173616557020855939); - _erc20poolrewardsHandler.updateExchangeRate(1596809363560413962396693305, 989525800646794783000000000000, 0, 1674388995); - _erc20poolrewardsHandler.unstake(10883531334787, 40877128, 480770847296080066987299717351378237725553372592098, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); - } - - // Didn't have InsufficentLP error in positionManager revert catch - function test_regression_failure_insufficientlp_error() external { - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.settleAuction(577241166000000000000, 1674403539, 1706636259141011266423401777, 116931836105284395); - _erc20poolrewardsHandler.withdrawBonds(9867747248697291458, 2276637134958475186531688328, 957911724802440729806437351); - _erc20poolrewardsHandler.kickReserveAuction(3477102777457, 445872926603948273480371969570494); - _erc20poolrewardsHandler.repayDebt(1, 30620519668269882565012117691493200000602, 6550083307387093662714640700181574056143163767381275378557906085492018639); - _erc20poolrewardsHandler.unstake(1, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1006408, 1); - _erc20poolrewardsHandler.kickReserveAuction(60878538920082033291777355178031898195946345, 151301); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.updateExchangeRate(3723, 14193362190521867625362174086119, 2984847556915278249, 1431948565575439403); - _erc20poolrewardsHandler.unstake(620475720165697999262823248208783049842251523083896535779413924216, 115545045573751618433375484275813400274137417951043663590237066664176780, 600099763819723634604346206, 26269036480442907031637331641942418161332430845896343, 9); - _erc20poolrewardsHandler.removeCollateral(38252916900474233, 249205319962072693799202680012, 2639762320817925557558, 342293190484942334564171294066); - _erc20poolrewardsHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 1, 2, 1); - _erc20poolrewardsHandler.burn(27593814869135792628606584912009895150018454871563189731202218872765, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 220258602523965891502051337036531641825438574592631248310796994083256, 940112205671188795347696630567324480120976919568865373617259559426); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.removeQuoteToken(0, 22430497766563836710873950591723, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); - _erc20poolrewardsHandler.unstake(12201, 3685, 695142502617607473790470735635663635795256298354491111178867333663833632, 1015432342463301638549343, 4); - _erc20poolrewardsHandler.transferLps(3536960038764358210048752718460, 134319387439720762165052351935, 723, 869949153720793397042, 21774); - _erc20poolrewardsHandler.moveLiquidity(24860115440580498809182, 67836324731985777005501908631161678093421222411927620708449, 0, 1229559121211985463778197658805966); - } - - // index was out of bounds when randomizing exchange rate indexes to update - // fixed by instantiating the array inside of the method before checking an index - function test_regression_failure_randomize_exchange() external { - _erc20poolrewardsHandler.unstake(1, 112388744220239594704909030506775277176, 172139421382441356491809044903526131290304748473444116242693216651191924227, 28057247583020499196416174332822000099943039439312840, 19193968625018413852484821283626022164578951788319907594245211069); - _erc20poolrewardsHandler.addCollateral(3089, 6608, 7726, 1175); - _erc20poolrewardsHandler.pledgeCollateral(0, 1665266719324436960156414842270616355276732647419460846735970026, 261171399028389597729832); - _erc20poolrewardsHandler.memorializePositions(532834, 1191186008960962857163939357544250199378526932, 0, 3964251013291355791); - _erc20poolrewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 20543339646991900614943637491556); - _erc20poolrewardsHandler.updateExchangeRate(532615289845430253976060604679719389, 185170833230037194672314349443140570721508655843569337357873544151, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); - _erc20poolrewardsHandler.updateExchangeRate(0, 32523919344517383004763068842174082041281550880745738003778749916186211, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc20poolrewardsHandler.unstake(3, 1, 40471187361674907757381069960028812369118729117842876515089342, 187437312729308548672478773757885237512598946528820032027388592, 15292170957369665004671092050); - _erc20poolrewardsHandler.redeemPositions(10322, 12257, 102312660311860849886587252792220939221079621309292995924587083492940358543873, 8449); - _erc20poolrewardsHandler.removeQuoteToken(7307, 82098259114364813849184226979458795540998210065007809242601931750567529450336, 24962334191555090884200901697709326249765046066909050188293351411730598993972, 660); - _erc20poolrewardsHandler.memorializePositions(2, 124382490368454372603243034072, 0, 78029022644745228072748180572258279953915991346870); - _erc20poolrewardsHandler.kickReserveAuction(114723343247932036926669170356582718294728929122856003892178842867945751327943, 3590); - _erc20poolrewardsHandler.pullCollateral(2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.claimRewards(3, 2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - } - - // add quote token was failing silently when the NFT position was being created in _preMemorializePositions - // FIX: altered positionManager and rewardsManager tests to return when interacting with NFTs that don't have positions - function test_regression_failure_fresh() external { - _erc20poolrewardsHandler.lenderKickAuction(1336817465042025253525338004928960182841058778, 193634307182211386319599413, 28); - _erc20poolrewardsHandler.bucketTake(7140164611582533744197731518, 1225291445688823278840, false, 140447174498926838356202241, 1217313358793411649232935169); - _erc20poolrewardsHandler.addQuoteToken(1291248035585293274352616, 1220647486761758905436054955871, 695236879708740352902415512815644621354794330678696591333991698318844416, 999999999999999999999999920707795539823417845); - _erc20poolrewardsHandler.emergencyUnstake(11243347270444025656631825589360306986122538308103875103758903630802, 104436231145294692791434209686384137220761282736602704, 113991909435395201759228253179123476630107324300769445, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 34424191262358238003767015512550467320952787658814634693105516384280765757, 1); - _erc20poolrewardsHandler.stake(1393087899760396821662448, 0, 2, 0); - _erc20poolrewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5116902771599276991193476659475872307811128145867445833445550672, 39432975197416494829678821326411300701120551523826226104277956561932827108228, 1400506682660594660722797942017241426449513741223482862482308212423, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.removeQuoteToken(8151756038911522518596857433114495226239328159, 47718147729935650247434891866219939127577592936506349, 31281067, 58833763171183168469062794048547362119753425028657390195355011723); - _erc20poolrewardsHandler.stampLoan(42688, 2472758713701048910); - _erc20poolrewardsHandler.failed(); - _erc20poolrewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); - _erc20poolrewardsHandler.transferLps(388259788415458780615966376818706719808364924038993605557593712571442, 1, 11183636888477495872920172827726679899364321814783075254674028639735567434261, 2970326540500071539162, 25810338262282535177150005108491212819545); - _erc20poolrewardsHandler.emergencyUnstake(100948, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 12892899796738577129141986151703117590492, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc20poolrewardsHandler.kickReserveAuction(150771469208542706010213463867, 43354246406661751231666714345663189); - _erc20poolrewardsHandler.takeAuction(3534600738871654532093694, 710900971556109763949049343751907780671963860281451036129946241395772330, 32791, 92899073076001134670575647915681268872801635774755826272901748142573588803419); - _erc20poolrewardsHandler.removeQuoteToken(1999999571196206119106253024650, 999999999999999359435426300823017114351704074, 847975398478536617553572420, 997892034638190564617566391041); - _erc20poolrewardsHandler.unstake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 15705207428248257128809996708067820574434789987097242585735992570899338201, 3, 120654062796568739935506875947855859740423212347571712122719); - _erc20poolrewardsHandler.lenderKickAuction(114769084034992770447742921711671102586, 1495429900, 15541); - _erc20poolrewardsHandler.moveLiquidity(948940574329580087951488104576612006868387916754938, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3); - } - - // failing due to incorrect pool address in unstake method, pool address should be same as pool address of tokenId to unstake - // FIX: updated pool and token addresses based on tokenId to unstake in preUnstake() - function test_regression_RW6() external { - _erc20poolrewardsHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 30, 7937264668853329259734574622120402716440078198445632208870457818390589259870, 3905090263574485332, 98520786143889757752); - _erc20poolrewardsHandler.removeCollateral(0, 12914635772715594038022333474288390302, 33036928970, 0); - _erc20poolrewardsHandler.moveLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2173708464260757496236493323181810612712643363763069005045015006605160, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); - _erc20poolrewardsHandler.claimRewards(3, 204824519854559151272183568403323963838533447236674344175, 8128368621, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639933, 185312326738089679086868027267035943621524169115518093619922476847701738477, 2468568485094682193138868077495556956028403863483); - _erc20poolrewardsHandler.mint(5417536198306694560626611691203471936493038576, 771309297653609570118032036213); - _erc20poolrewardsHandler.redeemPositions(152786948827985473729237919813798641528052689079492781987234074973909112743, 25603437052847163719931693033704902493181265100606856672867853758689669, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7226558); - _erc20poolrewardsHandler.updateExchangeRate(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 21559449969852085953095936138781740802414, 264732153479287345532546); - _erc20poolrewardsHandler.unstake(4050642, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 8892829320164456166791550031746506994275533728408336, 246340250953839466985, 11341956622236675999658625115096869676828742321101392662755); - } - - // failing due to incorrect rewards cap in Rewards Manager, RewardsManager was only storing rewardsClaimed per epoch which is incorrect as there can be multiple pools - // and they have same epoch. rewardsClaimed should be stored per pool per epoch as rewards as capped at 90%(80% staking + 10% update reward) of total ajna burned in a epoch in a pool. - // FIX: updated rewardsClaimed and updateRewardsClaimed to store rewards claimed per pool per epoch. - function test_regression_RW1() external { - _erc20poolrewardsHandler.updateExchangeRate(9994379592593378707867855953, 6802, 11256, 20212378015046437120000019184); - _erc20poolrewardsHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25664503794324617359778769380205732978752351, 18823047171411433902881335762598989529741717165738079140168502321220940621876); - _erc20poolrewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 20560514310876, 1, 3); - _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 45577750011170923384933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 38846179312568684719702994040209939337561149703838657605809556504808087062689); - _erc20poolrewardsHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2857785064194277419154868731015232356261750373544245, 2); - _erc20poolrewardsHandler.emergencyUnstake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 909549610873415777793439527310818665651923593512282524101302); - _erc20poolrewardsHandler.settleAuction(331247856886804504509504608993324055, 283007182502687789677372332012164616784607842156265854638293144498, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 7423020557972610998006793); - _erc20poolrewardsHandler.bucketTake(1094646368693794950870295833257682, 3, false, 3, 13881); - _erc20poolrewardsHandler.moveLiquidity(408168798836247915379645, 1672488368, 369791893539084367497, 78889980541899884265252108); - _erc20poolrewardsHandler.kickReserveAuction(44050579754998536532216707239847898482142726457, 1); - _erc20poolrewardsHandler.pledgeCollateral(5812605776188520803024897697439079308580, 39921162168302054503681322938311336802650850841531627569683073248682848, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc20poolrewardsHandler.takeReserves(14501431497782194794973379553, 18216893218210, 27094576513855308857052421141969311399815558155254262620203662580263110052); - _erc20poolrewardsHandler.moveLiquidity(787976169979156486049233163432, 23501, 669397280173193553318051, 4494238041890); - _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 240012279147071339, 13520620793216963296683591292854993002788638861417405850321955024554); - _erc20poolrewardsHandler.updateExchangeRate(10370988, 590874, 7586677065108906044816415430, 719260696647107815835059983121274964572473610083167736699292186633830400); - _erc20poolrewardsHandler.takeAuction(2000148037535591186999999998005, 23642705899866068202470371796725, 695122910006219589520428306956349221062131095164222977567266499472080896, 8018463872318007466775480); - _erc20poolrewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 429251578716754550371, false, 0, 20541004179279223492899594360601985779248378326659949190596702501); - _erc20poolrewardsHandler.unstake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.takeAuction(643551412513838998140054101548, 68826953510296, 62693419942124288283633712549166289024100312842094551123, 812454253172476878472291433041); - _erc20poolrewardsHandler.unstake(1696066615, 353725867821766401501590540, 130031683971585698612393536, 164466116363879431469, 3000449431973070438096647); - invariant_rewards_RW1_RW2(); - } - - // failing due to invariant PM8 being checked in case of partial positions redeemed. - // FIX: updated PM8 invariant to check only if all positions are redeemed. - function test_regression_PM8() external { - _erc20poolrewardsHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc20poolrewardsHandler.takeAuction(712673822533874336787409707076987835811202462567093932578353166987348355, 1000000000000000000171639873513, 1325445845119572278709533, 811517146854243541018847838031); - _erc20poolrewardsHandler.moveQuoteToken(687805612960569459095, 16146797278491100307608027792, 1000001216528530412451249109241, 1115690845648766668369611549294, 49500); - _erc20poolrewardsHandler.addCollateral(2248757331093900089956861530007045996752918194364509, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 495375528); - _erc20poolrewardsHandler.memorializePositions(16306, 6624, 1709864537, 241661987585285051682434); - _erc20poolrewardsHandler.updateExchangeRate(3017068451, 28520822275817161570312, 1712923140, 300476407847917070821640784539769403464067957526); - _erc20poolrewardsHandler.repayDebt(22815415, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); - _erc20poolrewardsHandler.emergencyUnstake(23616031102654201957157486989262107337414973820430337426659449044518214776352, 148054568871453946616612907, 22268, 14676261577771457517045780567161278491254518589865437910367412672514025336877, 130971774557406521921636313569); - _erc20poolrewardsHandler.removeCollateral(183746662119737242067562539680081132182181903131020756043145689232908930, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 57220674576762203107, 5911773981854233788026033559636244102533733546548886); - _erc20poolrewardsHandler.drawDebt(80080, 65546250511531452774318211, 50372); - _erc20poolrewardsHandler.burn(152, 700567494190439235857785598714992932151711660989520372732698465205248296, 1000000000012658174, 702337442086788554758386090135692660485321847483412323155253644042207233); - invariant_positions_PM1_PM2_PM3(); - } - -} diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol deleted file mode 100644 index 23b988fbd..000000000 --- a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import { ERC721PoolRewardsInvariants } from "../../invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol"; - -contract RegressionTestERC721PoolRewardsManager is ERC721PoolRewardsInvariants { - - function setUp() public override { - super.setUp(); - } - - // issue in invariants totalling amount of rewards that caller of claimRewards was receiving. - // fix: claimrewards and update rewards now go to caller of claimRewards - function test_regression_failure_rewards_exceeded_claim() external { - _erc721poolrewardsHandler.settleAuction(17873, 2208, 326, 1944); - _erc721poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 53134310333307170138, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2340533661754158540520179666008670241532871916995373825004189326661505987844); - _erc721poolrewardsHandler.pledgeCollateral(8132, 11716, 1057); - _erc721poolrewardsHandler.kickReserveAuction(2985325127, 23214); - _erc721poolrewardsHandler.removeCollateral(3461, 514, 17285, 838); - _erc721poolrewardsHandler.kickAuction(18170, 652, 11342, 1168); - _erc721poolrewardsHandler.pullCollateral(20130, 1209987167530552461153974115173428229758989546163, 150941); - _erc721poolrewardsHandler.moveLiquidity(63198806135952229891699111929727509482991997027848329114178785250303971081388, 77371051183995213971267347974759461809434770063921461351617080426027329266071, 4805, 2289); - _erc721poolrewardsHandler.moveLiquidity(63198806135952229891699111929727509482991997027848329114178785250303971081388, 77371051183995213971267347974759461809434770063921461351617080426027329266071, 4805, 2289); - _erc721poolrewardsHandler.moveQuoteToken(276169773153138481519606288636310061814657663456104947149, 1, 0, 108537837119796081908394324659000725292282331478997011952318493996290, 155532253556112179854090944828383440910501711771906801208685755840667262568); - _erc721poolrewardsHandler.mergeCollateral(173, 22406963037383631220938302497939718111833223267188040374368716127276); - _erc721poolrewardsHandler.burn(1328065707762407283002828802143541176473931677425004844, 1, 1, 37613208758526068006052551033711685); - _erc721poolrewardsHandler.takeAuction(0, 9352381759360299323960711216326149317387010227218710, 2546377053981808421495007542941590246694727231217, 3663797758192519198918); - _erc721poolrewardsHandler.takeAuction(148878580729371224992950595085688885987, 52018, 3863548495672151022795311051855, 1224829895266858456828928840866630331525272263026827096173292323394330361); - _erc721poolrewardsHandler.claimRewards(339802229099465406190265268924204103831957337149846935, 1, 2641, 1084164255431, 3); - } - - // issue in _preDrawDebt when borrower is in auction and tried to repayDebt and pull collateral, and check all debt is repaid. - // fix: return _preDrawDebt when borrower is in auction. - function test_regression_RW1_RW2() external { - _erc721poolrewardsHandler.stampLoan(3097, 99133); - _erc721poolrewardsHandler.kickAuction(31354931781638678607228669297131712859126084785867252355217498662940140921971, 1058, 11754, 12849); - _erc721poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 33731052920955697617409005891040394080922214120333458396693390120882665651,1720188968454217720935353179268130063921306460048647700482); - _erc721poolrewardsHandler.pledgeCollateral(1757924641683012822782278927906643733124399771812893540782608051864, 146672722799504441441256193696, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc721poolrewardsHandler.mint(12138, 7557); - _erc721poolrewardsHandler.addQuoteToken(13384168457563664686794224199997478429074004894884217417626102307452469562, 399627080535825658763553985697630307858997509589356607284924675010621,15021260382761, 2149748001246586660242584607929003545953); - _erc721poolrewardsHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _erc721poolrewardsHandler.settleAuction(1735287903719074628042764789671363295, 3, 23993967057076184216275526949268, 4106476); - _erc721poolrewardsHandler.drawDebt(77622297016072599381603815616169164633892036937355547901, 10261965, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _erc721poolrewardsHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 15628038388); - _erc721poolrewardsHandler.redeemPositions(22801150734449629332972378409816953484259939113298558, 563212509531357473751756674, 236487328781308137707, 114005983); - _erc721poolrewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 209638772009545859528, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1852809668170365878555741120106, 8537278537524035545583862060040379261058217549); - _erc721poolrewardsHandler.emergencyUnstake(5762, 4833, 23085, 23329, 10160); - _erc721poolrewardsHandler.lenderKickAuction(38567162678744729883825485304193880641, 1436018647533119237198979383384378157898748977466826312550, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc721poolrewardsHandler.mergeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 40700253390048296022217103829550); - _erc721poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 13666289603396405051, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 105); - _erc721poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 28190); - _erc721poolrewardsHandler.kickReserveAuction(1886, 65412); - _erc721poolrewardsHandler.takeReserves(7740, 4448, 3713); - _erc721poolrewardsHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _erc721poolrewardsHandler.repayDebt(110349606679412691172957834289542550319383271247755660854362242977991410020198, 6715, 4023); - _erc721poolrewardsHandler.mergeCollateral(0, 59747238056737534481206780725787707244999); - _erc721poolrewardsHandler.emergencyUnstake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 51729897709415, 23006395802429129288475054106, 1); - _erc721poolrewardsHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc721poolrewardsHandler.bucketTake(17736, 12855, false, 3289, 1123); - _erc721poolrewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _erc721poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1347071909069112433439054986249189622, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _erc721poolrewardsHandler.lenderKickAuction(3, 1, 37246476355849); - _erc721poolrewardsHandler.failed(); - _erc721poolrewardsHandler.burn(143, 1108823922,48884, 5811); - _erc721poolrewardsHandler.memorializePositions(7222, 6164, 14919869490272923636577259832825010352693700464430964509126832818182799243080, 26284); - _erc721poolrewardsHandler.takeAuction(1110452889, 6058, 3016184996, 12922961544511690602711642372921216522520321844072048399134131509470247863750); - _erc721poolrewardsHandler.mergeCollateral(5967, 3326); - _erc721poolrewardsHandler.bucketTake(1, 1714375381109265815411514882158434660321706149315054174553444757, true, 2, 2); - _erc721poolrewardsHandler.unstake(3, 28372160064709526166669973508287087795611038423150717571367, 54636530394327258458081903942670329383, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _erc721poolrewardsHandler.updateExchangeRate(36456, 17137, 1560275421, 17005); - _erc721poolrewardsHandler.stampLoan(3352512690189013572483301109122336596527121909930416357921778362671464454374, 5992531996617362563537972); - _erc721poolrewardsHandler.pledgeCollateral(174922928606654802364580162287611825, 4, 56551201532130900086); - _erc721poolrewardsHandler.emergencyUnstake(2247288760962719055600016280767970105290, 0, 2, 11596164422216101546875614140375574915418729056483, 61337865928763100451538345828); - _erc721poolrewardsHandler.emergencyUnstake(1023240505530161435702165, 18496758270674070880, 45978599603359075781444831263900707496437331655382222738127705004512629605795, 110349606679412691172957834289542550319383271247755660854362242977991410020756, 4078); - } -} diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol b/tests/forge/regression/PositionManager/RegressionTestERC20PoolPositionManager.t.sol similarity index 85% rename from tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol rename to tests/forge/regression/PositionManager/RegressionTestERC20PoolPositionManager.t.sol index a5bacaa9f..882fdc279 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol +++ b/tests/forge/regression/PositionManager/RegressionTestERC20PoolPositionManager.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.18; -import { ERC20PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol"; +import { ERC20PoolPositionsInvariants } from "../../invariants/PositionManager/ERC20PoolPositionsInvariants.t.sol"; contract RegressionTestERC20PoolPositionManager is ERC20PoolPositionsInvariants { @@ -117,6 +117,27 @@ contract RegressionTestERC20PoolPositionManager is ERC20PoolPositionsInvariants invariant_positions_PM1_PM2_PM3(); } + // Test was failing because of incorrect borrower index from borrowers array + // Fixed with bounding index to use from 0 to `length - 1` instead of `length` + function test_regression_index_out_of_bounds() external { + _erc20positionHandler.moveQuoteTokenToLowerBucket(8350, 38563772714580316601477528168172448197192851223481495804140163882250050756970, 2631419556349366366777984756718, 1211945352); + _erc20positionHandler.takeOrSettleAuction(211495175470613993028534000000, 278145600165504025408587, 27529661686764881266950946609980959649419024772429123428587103668572353435463); + _erc20positionHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 6893553321768, 0); + _erc20positionHandler.lenderKickAuction(999993651401512530, 102781931937447242982, 270951946802940031780297034197); + _erc20positionHandler.moveQuoteTokenToLowerBucket(142908941962660588271918613275457408417799350540, 2, 7499, 21259944100462201457856802765711375950508); + _erc20positionHandler.takeOrSettleAuction(10312411154, 11741, 808194882698130156430790172156918); + + invariant_positions_PM1_PM2_PM3(); + } + + // Test was failing because of unbounded bucket used for `fromBucketIndex` + // Fixed with bounding `fromBucketIndex` + function test_regression_max_less_than_min() external { + _erc20positionHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 47501406159061048326781, 110986208267306903569458210414739750843311008184499947884172946209775740554); + _erc20positionHandler.takeOrSettleAuction(1881514382560036936235, 3, 14814387297039010985037823532); + _erc20positionHandler.moveQuoteTokenToLowerBucket(797766346153846154214, 41446531673892822322, 11701, 27835018298679073652989722292632508325056543016077421626954570959368347669749); + } + function test_regression_position_manager() external { _erc20positionHandler.redeemPositions(79335468733065507138817566659594782917024872257218805, 1889027018179489664211573893, 43578107449528230070726540147644518395094194018887636259089111851, 0); } diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol b/tests/forge/regression/PositionManager/RegressionTestERC721PoolPositionManager.t.sol similarity index 92% rename from tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol rename to tests/forge/regression/PositionManager/RegressionTestERC721PoolPositionManager.t.sol index 2e3d1ea97..3959649d7 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol +++ b/tests/forge/regression/PositionManager/RegressionTestERC721PoolPositionManager.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.18; -import { ERC721PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol"; +import { ERC721PoolPositionsInvariants } from "../../invariants/PositionManager/ERC721PoolPositionsInvariants.t.sol"; contract RegressionTestERC721PoolPositionsManager is ERC721PoolPositionsInvariants { diff --git a/tests/forge/unit/Auctions.t.sol b/tests/forge/unit/Auctions.t.sol index 68e51296e..4237ad302 100644 --- a/tests/forge/unit/Auctions.t.sol +++ b/tests/forge/unit/Auctions.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.18; import '../utils/DSTestPlus.sol'; +import '../utils/AuctionQueueInstance.sol'; contract AuctionsTest is DSTestPlus { - /** * @notice Tests bond penalty/reward factor calculation for varying parameters */ @@ -15,12 +15,12 @@ contract AuctionsTest is DSTestPlus { uint256 neutralPrice = 15 * 1e18; uint256 bondFactor = 0.1 * 1e18; - assertEq(_bpf(debt, collateral, neutralPrice, bondFactor, price), 0.1 * 1e18); - assertEq(_bpf(9000 * 1e18, collateral, neutralPrice, bondFactor, price), 0.083333333333333333 * 1e18); - assertEq(_bpf(debt, collateral, neutralPrice, bondFactor, 9.5 * 1e18), 0.1 * 1e18); - assertEq(_bpf(9000 * 1e18, collateral, neutralPrice, bondFactor, 9.5 * 1e18), 0.091666666666666667 * 1e18); - assertEq(_bpf(9000 * 1e18, collateral, 10 * 1e18, bondFactor, 10.5 * 1e18), -0.05 * 1e18); - assertEq(_bpf(debt, collateral, 5 * 1e18, bondFactor, 10.5 * 1e18), -0.1 * 1e18); + assertEq(_bpf(Maths.wdiv(debt, collateral), neutralPrice, bondFactor, price), 0.1 * 1e18); + assertEq(_bpf(Maths.wdiv(9000 * 1e18, collateral), neutralPrice, bondFactor, price), 0.083333333333333333 * 1e18); + assertEq(_bpf(Maths.wdiv(debt, collateral), neutralPrice, bondFactor, 9.5 * 1e18), 0.1 * 1e18); + assertEq(_bpf(Maths.wdiv(9000 * 1e18, collateral), neutralPrice, bondFactor, 9.5 * 1e18), 0.091666666666666667 * 1e18); + assertEq(_bpf(Maths.wdiv(9000 * 1e18, collateral), 10 * 1e18, bondFactor, 10.5 * 1e18), -0.05 * 1e18); + assertEq(_bpf(Maths.wdiv(debt, collateral), 5 * 1e18, bondFactor, 10.5 * 1e18), -0.1 * 1e18); } /** @@ -74,13 +74,38 @@ contract AuctionsTest is DSTestPlus { */ function testReserveAuctionPrice() external { skip(5 days); - assertEq(_reserveAuctionPrice(block.timestamp), 1e27); - assertEq(_reserveAuctionPrice(block.timestamp - 1 hours), 500000000 * 1e18); - assertEq(_reserveAuctionPrice(block.timestamp - 2 hours), 250000000 * 1e18); - assertEq(_reserveAuctionPrice(block.timestamp - 4 hours), 62500000 * 1e18); - assertEq(_reserveAuctionPrice(block.timestamp - 16 hours), 15258.789062500000000000 * 1e18); - assertEq(_reserveAuctionPrice(block.timestamp - 24 hours), 59.604644775390625000 * 1e18); - assertEq(_reserveAuctionPrice(block.timestamp - 90 hours), 0); + + // test a single unit of quote token + uint256 lastKickedReserves = 1e18; + assertEq(_reserveAuctionPrice(block.timestamp, lastKickedReserves), 1e27); + assertEq(_reserveAuctionPrice(block.timestamp - 1 hours, lastKickedReserves), 500000000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 2 hours, lastKickedReserves), 250000000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 4 hours, lastKickedReserves), 62500000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 16 hours, lastKickedReserves), 15258.789062500000000000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 24 hours, lastKickedReserves), 59.604644775390625000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 90 hours, lastKickedReserves), 0); + + // test a reasonable reserve quantity for dollar-pegged stablecoin as quote token + lastKickedReserves = 5_000 * 1e18; + assertEq(_reserveAuctionPrice(block.timestamp, lastKickedReserves), 200_000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 1 hours, lastKickedReserves), 100_000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 2 hours, lastKickedReserves), 50_000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 4 hours, lastKickedReserves), 12_500 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 8 hours, lastKickedReserves), 781.25 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 16 hours, lastKickedReserves), 3.051757812500000000 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 24 hours, lastKickedReserves), 0.011920928955078125 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 90 hours, lastKickedReserves), 0); + + // test a potential reserve quantity for a shitcoin shorting pool + lastKickedReserves = 3_000_000_000 * 1e18; + assertEq(_reserveAuctionPrice(block.timestamp, lastKickedReserves), 0.333333333333333333 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 4 hours, lastKickedReserves), 0.020833333333333333 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 16 hours, lastKickedReserves), 0.000005086263020833 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 32 hours, lastKickedReserves), 0.000000000077610214 * 1e18); + assertEq(_reserveAuctionPrice(block.timestamp - 64 hours, lastKickedReserves), 0); + + // ensure it handles zeros properly + assertEq(_reserveAuctionPrice(0, 0), 0); } /** @@ -103,5 +128,57 @@ contract AuctionsTest is DSTestPlus { assertEq(_claimableReserves(debt, 11_000 * 1e18, 11_000 * 1e18, reserveAuctionUnclaimed, 0), 0); assertEq(_claimableReserves(debt, poolSize, 11_000 * 1e18, 10_895 * 1e18, quoteTokenBalance), 0); } - } + +contract AuctionQueueTest is DSTestPlus { + AuctionQueueInstance private _auctions; + + function setUp() public { + _auctions = new AuctionQueueInstance(); + } + + function testAuctionsQueueAddRemove() external { + address b1 = makeAddr("b1"); + address b2 = makeAddr("b2"); + address b3 = makeAddr("b3"); + assertEq(_auctions.count(), 0); + + _auctions.add(b1); + assertEq(_auctions.count(), 1); + _auctions.add(b2); + assertEq(_auctions.count(), 2); + _auctions.add(b3); + assertEq(_auctions.count(), 3); + + _auctions.remove(b2); + assertEq(_auctions.count(), 2); + _auctions.remove(b1); + assertEq(_auctions.count(), 1); + _auctions.remove(b3); + assertEq(_auctions.count(), 0); + } + + function testAuctionsQueueRemoveOnlyAuction() external { + address b1 = makeAddr("b1"); + address b2 = makeAddr("b2"); + address b3 = makeAddr("b3"); + + // add and remove the only auction on the queue + _auctions.add(b1); + assertEq(_auctions.count(), 1); + _auctions.remove(b1); + assertEq(_auctions.count(), 0); + + // add new auctions + _auctions.add(b2); + assertEq(_auctions.count(), 1); + _auctions.add(b3); + assertEq(_auctions.count(), 2); + + // remove new auctions + _auctions.remove(b2); + assertEq(_auctions.count(), 1); + _auctions.remove(b3); + assertEq(_auctions.count(), 0); + } +} \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20BorrowerTpLessThanMinPrice.t.sol b/tests/forge/unit/ERC20Pool/ERC20BorrowerTpLessThanMinPrice.t.sol new file mode 100644 index 000000000..f26afeda3 --- /dev/null +++ b/tests/forge/unit/ERC20Pool/ERC20BorrowerTpLessThanMinPrice.t.sol @@ -0,0 +1,54 @@ +pragma solidity 0.8.18; + +import { ERC20HelperContract, ERC20FuzzyHelperContract } from './ERC20DSTestPlus.sol'; + +import 'src/libraries/helpers/PoolHelper.sol'; +import 'src/interfaces/pool/commons/IPoolErrors.sol'; + +contract ERC20PoolBorrowerTPLessThanMinPrice is ERC20HelperContract { + + address internal _borrower; + address internal _lender; + + function setUp() external { + _startTest(); + + _borrower = makeAddr("borrower"); + _lender = makeAddr("lender"); + + _mintQuoteAndApproveTokens(_lender, 110 * 1e18); + _mintCollateralAndApproveTokens(_borrower, 100_000 * 1e18); + } + + function testTpLessThanMinPriceBorrowerKickable() external tearDown { + _addInitialLiquidity({ + from: _lender, + amount: 1100 * 1e9, + index: 2550 + }); + + // Borrower adds collateral token and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + amount: 10 * 1e18 + }); + + _borrow({ + from: _borrower, + amount: 900 * 1e9, + indexLimit: 2550, + newLup: 3_010.892022197881557845 * 1e18 + }); + + (uint256 debt, uint256 collateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + uint256 debtToCollateral = Maths.wdiv(debt, collateral); + + // Ensure borrower tp is less than min price + assertLt(Maths.wmul(debtToCollateral, COLLATERALIZATION_FACTOR), MIN_PRICE); + + // Lender can kick borrower with tp less than min price + changePrank(_lender); + _pool.lenderKick(2550, MAX_FENWICK_INDEX); + } +} \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index 26da8704a..8bacf2689 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -110,7 +110,7 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { uint256 pledgedCollateral = 0; for (uint i = 0; i < borrowers.length(); i++) { - (, uint256 collateral,) = _poolUtils.borrowerInfo(address(_pool), borrowers.at(i)); + (, uint256 collateral, , ) = _poolUtils.borrowerInfo(address(_pool), borrowers.at(i)); pledgedCollateral += collateral; } @@ -177,13 +177,13 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { // Settle any auctions and then repay debt for (uint i = 0; i < borrowers.length(); i++) { address borrower = borrowers.at(i); - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); + (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower); if (kickTime != 0) { changePrank(borrower); _pool.settle(borrower, bucketsUsed.length() + 1); // Settle again if not settled, this can happen when less reserves calculated with DEPOSIT_BUFFER and borrower is not fully settled - (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); + (,,, kickTime,,,,,,) = _pool.auctionInfo(borrower); if (kickTime != 0) { _pool.settle(borrower, bucketsUsed.length() + 1); } @@ -212,16 +212,15 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { uint256 amount ) internal override { vm.expectEmit(true, true, false, true); - uint256 transferAmount = Maths.ceilDiv(amount, _pool.quoteTokenScale()); emit Transfer(from, to, transferAmount); } - function _assertQuoteTokenTransferEventDrawDebt( + function _assertQuoteTokenTransferEventRoundingDown( address from, address to, uint256 amount - ) internal { + ) internal override { vm.expectEmit(true, true, false, true); emit Transfer(from, to, amount / _pool.quoteTokenScale()); } @@ -322,7 +321,7 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { // borrow quote if (amountToBorrow != 0) { - _assertQuoteTokenTransferEventDrawDebt(address(_pool), from, amountToBorrow); + _assertQuoteTokenTransferEventRoundingDown(address(_pool), from, amountToBorrow); } ERC20Pool(address(_pool)).drawDebt(borrower, amountToBorrow, limitIndex, collateralToPledge); @@ -390,7 +389,7 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { vm.expectEmit(true, true, true, true); emit RemoveCollateral(from, index, amount, lpRedeem); vm.expectEmit(true, true, true, true); - emit Transfer(address(_pool), from, amount); + emit Transfer(address(_pool), from, amount / ERC20Pool(address(_pool)).collateralScale()); (uint256 collateralRemoved, uint256 lpAmount) = ERC20Pool(address(_pool)).removeCollateral(type(uint256).max, index); assertEq(collateralRemoved, amount); assertEq(lpAmount, lpRedeem); @@ -728,6 +727,16 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { _pool.removeQuoteToken(amount, index); } + function _assertRemoveQuoteDustRevert( + address from, + uint256 amount, + uint256 index + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); + _pool.removeQuoteToken(amount, index); + } + function _assertBorrowAuctionActiveRevert( address from, uint256 amount, @@ -797,9 +806,29 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.LUPBelowHTP.selector); - ERC20Pool(address(_pool)).moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + ERC20Pool(address(_pool)).moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + } + + function _assertMoveQuoteDustRevert( + address from, + uint256 amount, + uint256 toIndex, + uint256 fromIndex + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); + _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 { @@ -896,4 +925,4 @@ abstract contract ERC20FuzzyHelperContract is ERC20DSTestPlus { _collateral.approve(address(_pool), type(uint256).max); _quote.approve(address(_pool), type(uint256).max); } -} +} \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol index 817847215..b3d3f4c72 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol @@ -36,47 +36,37 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _mintQuoteAndApproveTokens(_lender1, 200_000 * 1e18); // lender deposits 10000 quote in 5 buckets each - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: highest, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: highest }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: high, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: high }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: med, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: med }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: low, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: low }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: lowest, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: lowest }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -107,11 +97,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 210.201923076923077020 * 1e18, + htp: 218.610000000000000101 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 7.051372011699988577 * 1e18, + encumberedCollateral: 7.333426892167988121 * 1e18, poolDebt: 21_020.192307692307702000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -127,71 +117,72 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { assertEq(_quote.balanceOf(address(_pool)), 29_000 * 1e18); assertEq(_quote.balanceOf(_lender), 150_000 * 1e18); + uint256 depositLessFee = 9_999.543378995433790000 * 1e18; _assertLenderLpBalance({ lender: _lender, index: highest, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: high, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: med, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: low, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: lowest, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); // check buckets _assertBucket({ index: highest, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertBucket({ index: high, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertBucket({ index: med, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertBucket({ index: low, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertBucket({ index: lowest, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); @@ -205,11 +196,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 400.384615384615384800 * 1e18, + htp: 416.400000000000000192 * 1e18, lup: 2_951.419442869698640451 * 1e18, // FIMXE: actual is 2_995.912459898389633881, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 13.565832411651963522 * 1e18, + encumberedCollateral: 14.108465708118042062 * 1e18, poolDebt: 40_038.461538461538480000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -237,11 +228,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 300.384615384615384800 * 1e18, + htp: 312.400000000000000192 * 1e18, lup: 2_966.176540084047110076 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 10.126997207526425123 * 1e18, + encumberedCollateral: 10.532077095827482128 * 1e18, poolDebt: 30_038.461538461538480000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -272,7 +263,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -300,11 +291,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 80.076923076923076960 * 1e18, + htp: 83.280000000000000038 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 2.659574720267410143 * 1e18, + encumberedCollateral: 2.765957709078106549 * 1e18, poolDebt: 8_007.692307692307696000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -331,19 +322,18 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { newLup: 2_981.007422784467321543 * 1e18 }); - uint256 expectedDebt = 21_046.123595032677924434 * 1e18; - + uint256 expectedDebt = 21_020.192307692307702000 * 1e18; _assertPool( PoolParams({ - htp: 420.403846153846154040 * 1e18, + htp: 437.220000000000000202 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.060070845235984474 * 1e18, + encumberedCollateral: 7.333426892167988121 * 1e18, poolDebt: expectedDebt, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 2_104.612359503267792443 * 1e18, + minDebtAmount: 2_102.0192307692307702000 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.045 * 1e18, @@ -354,8 +344,8 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 484.222578900118175410 * 1e18, - borrowerCollateralization: 7.082081907682151400 * 1e18 + borrowert0Np: 486.102682056122902418 * 1e18, + borrowerCollateralization: 6.818094832771756370 * 1e18 }); skip(10 days); @@ -366,19 +356,18 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { amount: 10 * 1e18 }); - expectedDebt = 21_072.086872169016071673 * 1e18; - + expectedDebt = 21_046.123595032677924434 * 1e18; _assertPool( PoolParams({ - htp: 351.201447869483601195 * 1e18, + htp: 364.799475647233084023 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_044.110379805202100000 * 1e18, + poolSize: 50_019.758489216483593404 * 1e18, pledgedCollateral: 60 * 1e18, - encumberedCollateral: 7.068780409975037237 * 1e18, + encumberedCollateral: 7.342473679045423853 * 1e18, poolDebt: expectedDebt, - actualUtilization: 0.420403445225801443 * 1e18, + actualUtilization: 0.420422642606742390 * 1e18, targetUtilization: 0.141027440233999772 * 1e18, - minDebtAmount: 2_107.208687216901607167 * 1e18, + minDebtAmount: 2_104.612359503267792443 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.0495 * 1e18, @@ -389,10 +378,10 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 60 * 1e18, - borrowert0Np: 403.518815750098479508 * 1e18, - borrowerCollateralization: 8.488027144729466085 * 1e18 + borrowert0Np: 405.085568380102418682 * 1e18, + borrowerCollateralization: 8.171632970402482385 * 1e18 }); - _assertLenderInterest(liquidityAdded, 44.110379805202100000 * 1e18); + _assertLenderInterest(liquidityAdded, 22.041594239314643404 * 1e18); skip(10 days); @@ -404,19 +393,18 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { collateralToPull: 10 * 1e18 }); - expectedDebt = 21_100.683472334824303370 * 1e18; - + expectedDebt = 21_074.684960840362729425 * 1e18; _assertPool( PoolParams({ - htp: 422.013669446696486067 * 1e18, + htp: 438.353447185479544772 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_069.130567554535450000 * 1e18, + poolSize: 50_044.747888604073744487 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.078373341528054648 * 1e18, + encumberedCollateral: 7.352438035461633905 * 1e18, poolDebt: expectedDebt, - actualUtilization: 0.421070265420802644 * 1e18, - targetUtilization: 0.120628314442263426 * 1e18, - minDebtAmount: 2_110.068347233482430337 * 1e18, + actualUtilization: 0.420756201445180819 * 1e18, + targetUtilization: 0.120500759095098154 * 1e18, + minDebtAmount: 2_107.468496084036272943 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.05445 * 1e18, @@ -427,10 +415,10 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 483.986975517230275430 * 1e18, - borrowerCollateralization: 7.063769822178689107 * 1e18 + borrowert0Np: 485.857654537919486439 * 1e18, + borrowerCollateralization: 6.800465336646754158 * 1e18 }); - _assertLenderInterest(liquidityAdded, 69.130567554535450000 * 1e18); + _assertLenderInterest(liquidityAdded, 47.030993626904794487 * 1e18); skip(10 days); @@ -439,19 +427,18 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { emit LoanStamped(_borrower); _pool.stampLoan(); - expectedDebt = 21_132.184557783880298441 * 1e18; - + expectedDebt = 21_106.147233265508423039 * 1e18; _assertPool( PoolParams({ - htp: 422.643691155677605969 * 1e18, + htp: 439.007862451922575199 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_096.693504733499050000 * 1e18, + poolSize: 50_072.276153888476772676 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.088940603188755848 * 1e18, + encumberedCollateral: 7.363414446681565743 * 1e18, poolDebt: expectedDebt, - actualUtilization: 0.421430993826609139 * 1e18, - targetUtilization: 0.138725200998853604 * 1e18, - minDebtAmount: 2_113.218455778388029844 * 1e18, + actualUtilization: 0.421116817104339390 * 1e18, + targetUtilization: 0.138557135730267727 * 1e18, + minDebtAmount: 2_110.614723326550842304 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.059895 * 1e18, @@ -462,28 +449,27 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 486.269617724627962428 * 1e18, - borrowerCollateralization: 7.053240081812639175 * 1e18 + borrowert0Np: 488.231602433613080917 * 1e18, + borrowerCollateralization: 6.790328096027958520 * 1e18 }); - _assertLenderInterest(liquidityAdded, 96.693504733499050000 * 1e18); + _assertLenderInterest(liquidityAdded, 74.559258911307822676 * 1e18); skip(10 days); _updateInterest(); - expectedDebt = 21_166.890071570436649845 * 1e18; - + expectedDebt = 21_140.809985797421809167 * 1e18; _assertPool( PoolParams({ - htp: 423.337801431408732997 * 1e18, + htp: 439.728847704586373630 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_127.061165904636850000 * 1e18, + poolSize: 50_102.605614470717226695 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.100582812973708010 * 1e18, + encumberedCollateral: 7.375507426510350408 * 1e18, poolDebt: expectedDebt, - actualUtilization: 0.421827930356991768 * 1e18, - targetUtilization: 0.141358334848097873 * 1e18, - minDebtAmount: 2_116.689007157043664985 * 1e18, + actualUtilization: 0.421513636597238694 * 1e18, + targetUtilization: 0.141184558710452235 * 1e18, + minDebtAmount: 2_114.080998579742180917 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.0658845 * 1e18, @@ -494,26 +480,25 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 486.269617724627962428 * 1e18, - borrowerCollateralization: 7.041675495797803839 * 1e18 + borrowert0Np: 488.231602433613080917 * 1e18, + borrowerCollateralization: 6.779194583993119727 * 1e18 }); - _assertLenderInterest(liquidityAdded, 127.061165904636850000 * 1e18); + _assertLenderInterest(liquidityAdded, 104.888719493548276695 * 1e18); skip(10 days); - expectedDebt = 21_205.131971958652447704 * 1e18; - + expectedDebt = 21_179.004767688830766408 * 1e18; _assertPool( PoolParams({ - htp: 423.337801431408732997 * 1e18, + htp: 440.523299167927679941 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 50_127.061165904636850000 * 1e18, + poolSize: 50_102.605614470717226695 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.113411328627820409 * 1e18, + encumberedCollateral: 7.388832644308688421 * 1e18, poolDebt: expectedDebt, - actualUtilization: 0.421827930356991768 * 1e18, - targetUtilization: 0.141358334848097873 * 1e18, - minDebtAmount: 2_120.513197195865244770 * 1e18, + actualUtilization: 0.421513636597238694 * 1e18, + targetUtilization: 0.141184558710452235 * 1e18, + minDebtAmount: 2_117.900476768883076641 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.0658845 * 1e18, @@ -524,8 +509,8 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 486.269617724627962428 * 1e18, - borrowerCollateralization: 7.028976350457301320 * 1e18 + borrowert0Np: 488.231602433613080917 * 1e18, + borrowerCollateralization: 6.766968803727464027 * 1e18 }); } @@ -671,11 +656,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 0.332446840033426268 * 1e18, + encumberedCollateral: 0.345744713634763319 * 1e18, poolDebt: 1_000.961538461538462000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -702,11 +687,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 100.096153846153846200 * 1e18, + htp: 104.100000000000000048 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 1.994681040200557607 * 1e18, + encumberedCollateral: 2.074468281808579912 * 1e18, poolDebt: 6_005.769230769230772000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -743,11 +728,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 100.096153846153846200 * 1e18, + htp: 104.100000000000000048 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 1.994681006987808939 * 1e18, + encumberedCollateral: 2.074468247267321297 * 1e18, poolDebt: 6_005.769130769230772000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -803,11 +788,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 0.332446840033426268 * 1e18, + encumberedCollateral: 0.345744713634763319 * 1e18, poolDebt: 1_000.961538461538462000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -831,11 +816,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019228769230769240 * 1e18, + htp: 20.819997920000000010 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 0.332446806820677600 * 1e18, + encumberedCollateral: 0.345744679093504704 * 1e18, poolDebt: 1_000.961438461538462000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -853,7 +838,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { * Reverts: * Attempts to borrow with a TP of 0. */ - function testZeroThresholdPriceLoan() external tearDown { + function testZeroDebtToCollateralLoanBeforeRepay() external tearDown { // borrower 1 initiates a highly overcollateralized loan with a TP of 0 that won't be inserted into the Queue _pledgeCollateral({ from: _borrower, @@ -861,7 +846,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { amount: 50 * 1e18 }); - vm.expectRevert(abi.encodeWithSignature('ZeroThresholdPrice()')); + vm.expectRevert(abi.encodeWithSignature('ZeroDebtToCollateral()')); IERC20Pool(address(_pool)).drawDebt(_borrower, 0.00000000000000001 * 1e18, 3000, 0); // borrower 1 borrows 500 quote from the pool after using a non 0 TP @@ -876,11 +861,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 5.004807692307692310 * 1e18, + htp: 5.205000000000000002 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 0.166223420016713134 * 1e18, + encumberedCollateral: 0.172872356817381659 * 1e18, poolDebt: 500.48076923076923100 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -898,7 +883,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { * Reverts: * Attempts to repay with a subsequent TP of 0. */ - function testZeroThresholdPriceLoanAfterRepay() external tearDown { + function testZeroDebtToCollateralLoanAfterRepay() external tearDown { // borrower 1 borrows 500 quote from the pool _drawDebt({ @@ -912,11 +897,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 10.009615384615384620 * 1e18, + htp: 10.410000000000000005 * 1e18, lup: 3_010.892022197881557845 * 1e18, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 0.166223420016713134 * 1e18, + encumberedCollateral: 0.172872356817381659 * 1e18, poolDebt: 500.480769230769231000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -932,14 +917,14 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 500.480769230769231 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 11.529109021431385128 * 1e18, - borrowerCollateralization: 300.799971477982403259 * 1e18 + borrowert0Np: 11.573873382288640533 * 1e18, + borrowerCollateralization: 289.230741805752310899 * 1e18 }); deal(address(_quote), _borrower, _quote.balanceOf(_borrower) + 10_000 * 1e18); // should revert if borrower repays most, but not all of their debt resulting in a 0 tp loan remaining on the book - vm.expectRevert(abi.encodeWithSignature('ZeroThresholdPrice()')); + vm.expectRevert(abi.encodeWithSignature('ZeroDebtToCollateral()')); IERC20Pool(address(_pool)).repayDebt(_borrower, 500.480769230769231000 * 1e18 - 1, 0, _borrower, MAX_FENWICK_INDEX); // should be able to pay back all pendingDebt @@ -956,7 +941,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 50 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -978,7 +963,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: highest, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); @@ -1002,28 +987,21 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { assertEq(_collateral.balanceOf(_borrower), 0); _assertPoolPrices({ - htp: 210.201923076923077020 * 1e18, - htpIndex: 3_083, + htp: 218.610000000000000101 * 1e18, + htpIndex: 3_075, hpb: 3_010.892022197881557845 * 1e18, hpbIndex: 2550, lup: 2_981.007422784467321543 * 1e18, lupIndex: 2_552 }); - // tx should revert if revert if deposit below LUP specified - _assertAddLiquidityPriceBelowLUPRevert({ - from: _lender, - amount: 10_000 * 1e18, - index: _indexOf(200 * 1e18) - }); - // add liquidity below LUP, ensuring fee is levied _addLiquidityWithPenalty({ from: _lender, amount: 10_000 * 1e18, - amountAdded: 9_998.630136986301370000 * 1e18, + amountAdded: 9_999.543378995433790000 * 1e18, index: _indexOf(200 * 1e18), - lpAward: 9_998.630136986301370000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: 2_981.007422784467321543 * 1e18 }); @@ -1031,13 +1009,13 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _removeAllLiquidity({ from: _lender, - amount: 9_998.630136986301370000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: _indexOf(200 * 1e18), newLup: 2_981.007422784467321543 * 1e18, - lpRedeem: 9_998.630136986301370000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 149_998.630136986301370000 * 1e18); + assertEq(_quote.balanceOf(_lender), 149_999.543378995433790000 * 1e18); // repay entire loan deal(address(_quote), _borrower, _quote.balanceOf(_borrower) + 40 * 1e18); @@ -1068,13 +1046,13 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _removeAllLiquidity({ from: _lender, - amount: 10_000.000000000000000000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: highest, newLup: MAX_PRICE, - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 159_998.630136986301370000 * 1e18); + assertEq(_quote.balanceOf(_lender), 159_999.086757990867580000 * 1e18); vm.revertTo(snapshot); @@ -1092,27 +1070,110 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { _removeAllLiquidity({ from: _lender, - amount: 10_000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: highest, newLup: MAX_PRICE, - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 159_998.630136986301370000 * 1e18); + assertEq(_quote.balanceOf(_lender), 159_999.086757990867580000 * 1e18); // lender removes everything from price above PTP after 24 hours skip(1 days); _removeAllLiquidity({ from: _lender, - amount: 10_000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: med, newLup: MAX_PRICE, - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); assertEq(_quote.balanceOf(_lender), 169_998.630136986301370000 * 1e18); } + + + function testPOCOverCollateralized_SingleBorrower() external { + // _borrower borrows 1,000 USDC collateralized by 100 eth + _drawDebt({ + from: _borrower, + borrower: _borrower, + amountToBorrow: 1000 * 1e18, + limitIndex: 3_000, + collateralToPledge: 100 * 1e18, + newLup:0 + }); + (uint interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.05 * 1e18); // 5% initial interest rate + + //pay down a little ($10) every 12 hours to trigger interestRate update + for (uint index; index < 8; ++index) { + skip(12.01 hours); // actually needs to be > 12 hours to trigger interestRate update + _repayDebt({ + from: _borrower, + borrower: _borrower, + amountToRepay: 10 * 1e18, + amountRepaid: 10 * 1e18, + collateralToPull: 0, + newLup: 0 + }); + } + (interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.107179440500000000 * 1e18); // interest rate increased over 10% to 10.7% + + // lender can reset interest rate to 10% (even if 12 hours not passed) by triggering any action + changePrank(_lender); + vm.expectEmit(true, true, true, true); + emit ResetInterestRate(0.107179440500000000 * 1e18, 0.1 * 1e18); + _pool.updateInterest(); + (interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.1 * 1e18); // interest rate resetted to 10% + } + + function testPOCOverCollateralized_MultipleBorrowers_LowDebt() external { + + // 10 borrowers borrow 120 usdc collateralized by 10 eth + address[] memory otherBorrowers = new address[](10); + for (uint index; index < 10; ++index) { + otherBorrowers[index] = address(bytes20(keccak256(abi.encodePacked(index + 0x1000)))); + + _mintCollateralAndApproveTokens(otherBorrowers[index], 100 * 1e18); + _drawDebt({ + from: otherBorrowers[index], + borrower: otherBorrowers[index], + amountToBorrow: 120 * 1e18, // borrow 120 usdc + limitIndex: 3_000, + collateralToPledge: 10 * 1e18, // collateralized by 10 eth + newLup:0 + }); + } + + (uint interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.05 * 1e18); // 5% initial interest rate + + //pay down a little ($1) every 12 hours to trigger interestRate update + for (uint index; index < 8; ++index) { + skip(12.01 hours); // actually needs to be > 12 hours to trigger interestRate update + _repayDebt({ + from: otherBorrowers[0], + borrower: otherBorrowers[0], + amountToRepay: 1 * 1e18, + amountRepaid: 1 * 1e18, + collateralToPull: 0, + newLup: 0 + }); + } + (interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.107179440500000000 * 1e18); // interest rate increased over 10% to 10.7% + + // lender can reset interest rate to 10% (even if 12 hours not passed) by triggering any action + changePrank(_lender); + vm.expectEmit(true, true, true, true); + emit ResetInterestRate(0.107179440500000000 * 1e18, 0.1 * 1e18); + _pool.updateInterest(); + (interestRate,) = _pool.interestRateInfo(); + assertEq(interestRate, 0.1 * 1e18); // interest rate resetted to 10% + } } contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { @@ -1143,47 +1204,37 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { _mintQuoteAndApproveTokens(_lender1, 200_000 * 1e18); // lender deposits 10000 quote tokens in 5 buckets each - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: highest, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: highest }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: high, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: high }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: med, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: med }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: low, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: low }); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, - index: lowest, - lpAward: 10_000 * 1e18, - newLup: MAX_PRICE + index: lowest }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50_000 * 1e18, + poolSize: 49_997.716894977168950000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -1199,30 +1250,29 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { } function testDrawRepayDebtFuzzy(uint256 numIndexes, uint256 mintAmount_) external tearDown { - numIndexes = bound(numIndexes, 3, 20); // number of indexes to add liquidity to + numIndexes = bound(numIndexes, 3, 20); // number of indexes to add liquidity to mintAmount_ = bound(mintAmount_, 1 * 1e18, 100_000 * 1e18); // lender adds liquidity to random indexes changePrank(_lender); uint256[] memory indexes = new uint256[](numIndexes); + uint256 liqAmount_ = Maths.wmul(mintAmount_, _depositFee()); for (uint256 i = 0; i < numIndexes; ++i) { deal(address(_quote), _lender, mintAmount_); indexes[i] = _randomIndex(); - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: mintAmount_, - index: indexes[i], - lpAward: mintAmount_, - newLup: _calculateLup(address(_pool), 0) + index: indexes[i] }); _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: liqAmount_, collateral: 0, - deposit: mintAmount_, + deposit: liqAmount_, exchangeRate: 1e18 }); } @@ -1231,7 +1281,7 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { changePrank(_borrower); uint256 limitIndex = _findLowestIndexPrice(indexes); uint256 borrowAmount = Maths.wdiv(mintAmount_, Maths.wad(3)); - uint256 requiredCollateral = _requiredCollateral(Maths.wdiv(mintAmount_, Maths.wad(3)), limitIndex); + uint256 requiredCollateral = _requiredCollateral(borrowAmount, limitIndex); deal(address(_collateral), _borrower, requiredCollateral); @@ -1248,15 +1298,15 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { for (uint256 i = 0; i < numIndexes; ++i) { _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: liqAmount_, collateral: 0, - deposit: mintAmount_, + deposit: liqAmount_, exchangeRate: 1e18 }); } // check borrower info - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); assertGt(debt, borrowAmount); // check that initial fees accrued // check pool state @@ -1264,11 +1314,11 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { _assertPool( PoolParams({ - htp: Maths.wdiv(debt, requiredCollateral), + htp: Maths.wdiv(Maths.wmul(debt, COLLATERALIZATION_FACTOR), requiredCollateral), lup: _poolUtils.lup(address(_pool)), - poolSize: (50_000 * 1e18) + (indexes.length * mintAmount_), + poolSize: (49_997.716894977168950000 * 1e18) + (indexes.length * liqAmount_), pledgedCollateral: requiredCollateral, - encumberedCollateral: Maths.wdiv(debt, _poolUtils.lup(address(_pool))), + encumberedCollateral: Maths.wdiv(Maths.wmul(debt, COLLATERALIZATION_FACTOR), _poolUtils.lup(address(_pool))), poolDebt: debt, actualUtilization: poolActualUtilization, targetUtilization: poolTargetUtilization, @@ -1280,7 +1330,7 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { }) ); - assertLt(_htp(), _poolUtils.lup(address(_pool))); + assertLt(_getHtp(), _poolUtils.lup(address(_pool))); assertGt(minDebt, 0); assertEq(_poolUtils.lup(address(_pool)), _calculateLup(address(_pool), debt)); @@ -1288,7 +1338,7 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { skip(1 days); // repay all debt and withdraw collateral - (debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); deal(address(_quote), _borrower, debt); @@ -1306,19 +1356,19 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { (, uint256 deposit, , uint256 lpAccumulator, , uint256 exchangeRate) = _poolUtils.bucketInfo(address(_pool), indexes[i]); // check that only deposits above the htp earned interest - if (indexes[i] <= _poolUtils.priceToIndex(Maths.wdiv(debt, requiredCollateral))) { - assertGt(deposit, mintAmount_); + if (indexes[i] <= _poolUtils.priceToIndex(Maths.wdiv(Maths.wmul(debt, COLLATERALIZATION_FACTOR), requiredCollateral))) { + assertGt(deposit, liqAmount_); assertGt(exchangeRate, 1e18); } else { - assertEq(deposit, mintAmount_); + assertEq(deposit, liqAmount_); assertEq(exchangeRate, 1e18); } - assertEq(lpAccumulator, mintAmount_); + assertEq(lpAccumulator, liqAmount_); _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: liqAmount_, collateral: 0, deposit: deposit, exchangeRate: exchangeRate @@ -1326,94 +1376,11 @@ contract ERC20PoolBorrowFuzzyTest is ERC20FuzzyHelperContract { } // check borrower state after repayment - (debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); assertEq(debt, 0); // check pool state - assertEq(_htp(), 0); + assertEq(_getHtp(), 0); assertEq(_poolUtils.lup(address(_pool)), MAX_PRICE); } - - function testPOCOverCollateralized_SingleBorrower() external { - // _borrower borrows 1,000 USDC collateralized by 100 eth - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 1000 * 1e18, - limitIndex: 3_000, - collateralToPledge: 100 * 1e18, - newLup:0 - }); - (uint interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.05 * 1e18); // 5% initial interest rate - - //pay down a little ($10) every 12 hours to trigger interestRate update - for (uint index; index < 8; ++index) { - skip(12.01 hours); // actually needs to be > 12 hours to trigger interestRate update - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 10 * 1e18, - amountRepaid: 10 * 1e18, - collateralToPull: 0, - newLup: 0 - }); - } - (interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.107179440500000000 * 1e18); // interest rate increased over 10% to 10.7% - - // lender can reset interest rate to 10% (even if 12 hours not passed) by triggering any action - changePrank(_lender); - vm.expectEmit(true, true, true, true); - emit ResetInterestRate(0.107179440500000000 * 1e18, 0.1 * 1e18); - _pool.updateInterest(); - (interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.1 * 1e18); // interest rate resetted to 10% - } - - function testPOCOverCollateralized_MultipleBorrowers_LowDebt() external { - - // 10 borrowers borrow 120 usdc collateralized by 10 eth - address[] memory otherBorrowers = new address[](10); - for (uint index; index < 10; ++index) { - otherBorrowers[index] = address(bytes20(keccak256(abi.encodePacked(index + 0x1000)))); - - _mintCollateralAndApproveTokens(otherBorrowers[index], 100 * 1e18); - _drawDebt({ - from: otherBorrowers[index], - borrower: otherBorrowers[index], - amountToBorrow: 120 * 1e18, // borrow 120 usdc - limitIndex: 3_000, - collateralToPledge: 10 * 1e18, // collateralized by 10 eth - newLup:0 - }); - } - - (uint interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.05 * 1e18); // 5% initial interest rate - - //pay down a little ($1) every 12 hours to trigger interestRate update - for (uint index; index < 8; ++index) { - skip(12.01 hours); // actually needs to be > 12 hours to trigger interestRate update - _repayDebt({ - from: otherBorrowers[0], - borrower: otherBorrowers[0], - amountToRepay: 1 * 1e18, - amountRepaid: 1 * 1e18, - collateralToPull: 0, - newLup: 0 - }); - } - (interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.107179440500000000 * 1e18); // interest rate increased over 10% to 10.7% - - // lender can reset interest rate to 10% (even if 12 hours not passed) by triggering any action - changePrank(_lender); - vm.expectEmit(true, true, true, true); - emit ResetInterestRate(0.107179440500000000 * 1e18, 0.1 * 1e18); - _pool.updateInterest(); - (interestRate,) = _pool.interestRateInfo(); - assertEq(interestRate, 0.1 * 1e18); // interest rate resetted to 10% - } - } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol index 45139395f..df1d1b030 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol @@ -57,7 +57,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.63013698630137 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -88,11 +88,11 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 210.201923076923077020 * 1e18, + htp: 218.610000000000000101 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_000 * 1e18, + poolSize: 29_998.63013698630137 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 7.051372011699988577 * 1e18, + encumberedCollateral: 7.333426892167988121 * 1e18, poolDebt: 21_020.192307692307702000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -107,8 +107,8 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_020.192307692307702000 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 242.111289450059087705 * 1e18, - borrowerCollateralization: 14.181637252165253251 * 1e18 + borrowert0Np: 243.051341028061451209 * 1e18, + borrowerCollateralization: 13.63618966554351274 * 1e18 }); assertEq(_collateral.balanceOf(_borrower), 50 * 1e18); @@ -127,13 +127,13 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 420.980136462780058369 * 1e18, + htp: 437.819341921291260704 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_024.492338129690910000 * 1e18, + poolSize: 30_023.122475115992296048 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 7.061038044473493202 * 1e18, + encumberedCollateral: 7.343479566252432930 * 1e18, poolDebt: 21_049.0068231390029184310 * 1e18, - actualUtilization: 0.700672854184962757 * 1e18, + actualUtilization: 0.700704849840206602 * 1e18, targetUtilization: 0.070513720116999886 * 1e18, minDebtAmount: 2_104.900682313900291843 * 1e18, loans: 1, @@ -146,8 +146,8 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 484.222578900118175410 * 1e18, - borrowerCollateralization: 7.081111825921092812 * 1e18 + borrowert0Np: 486.102682056122902418 * 1e18, + borrowerCollateralization: 6.808761371077973858 * 1e18 }); assertEq(_collateral.balanceOf(_borrower), 100 * 1e18); @@ -163,13 +163,13 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 2_981.007422784467321393 * 1e18, + htp: 2_981.007422784467321425 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_024.492338129690910000 * 1e18, - pledgedCollateral: 7.061038044473493202 * 1e18, - encumberedCollateral: 7.061038044473493202 * 1e18, + poolSize: 30_023.122475115992296048 * 1e18, + pledgedCollateral: 7.343479566252432930 * 1e18, + encumberedCollateral: 7.343479566252432930 * 1e18, poolDebt: 21_049.0068231390029184310 * 1e18, - actualUtilization: 0.700672854184962757 * 1e18, + actualUtilization: 0.700704849840206602 * 1e18, targetUtilization: 0.070513720116999886 * 1e18, minDebtAmount: 2_104.900682313900291843 * 1e18, loans: 1, @@ -181,12 +181,12 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, - borrowerCollateral: 7.061038044473493202 * 1e18, - borrowert0Np: 3_445.079304012847629269 * 1e18, + borrowerCollateral: 7.343479566252432930 * 1e18, + borrowert0Np: 3_326.002238146339160048 * 1e18, borrowerCollateralization: 1 * 1e18 }); - assertEq(_collateral.balanceOf(_borrower), 142.938961955526506798 * 1e18); + assertEq(_collateral.balanceOf(_borrower), 142.656520433747567070 * 1e18); } /** @@ -231,11 +231,11 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 210.201923076923077020 * 1e18, + htp: 218.610000000000000101 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_000 * 1e18, + poolSize: 29_998.63013698630137 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 7.051372011699988577 * 1e18, + encumberedCollateral: 7.333426892167988121 * 1e18, poolDebt: 21_020.192307692307702000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -250,8 +250,8 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_020.192307692307702000 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 242.111289450059087705 * 1e18, - borrowerCollateralization: 14.181637252165253251 * 1e18 + borrowert0Np: 243.051341028061451209 * 1e18, + borrowerCollateralization: 13.63618966554351274 * 1e18 }); assertEq(_collateral.balanceOf(collateralReceiver), 0); @@ -275,8 +275,8 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 484.222578900118175410 * 1e18, - borrowerCollateralization: 7.081111825921092812 * 1e18 + borrowert0Np: 486.102682056122902418 * 1e18, + borrowerCollateralization: 6.808761371077973858 * 1e18 }); assertEq(_collateral.balanceOf(collateralReceiver), 50 * 1e18); @@ -296,12 +296,12 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, - borrowerCollateral: 7.061038044473493202 * 1e18, - borrowert0Np: 3_445.079304012847629269 * 1e18, + borrowerCollateral: 7.343479566252432930 * 1e18, + borrowert0Np: 3_326.002238146339160048 * 1e18, borrowerCollateralization: 1 * 1e18 }); - assertEq(_collateral.balanceOf(collateralReceiver), 92.938961955526506798 * 1e18); + assertEq(_collateral.balanceOf(collateralReceiver), 92.656520433747567070 * 1e18); assertEq(_collateral.balanceOf(_borrower), 50 * 1e18); } @@ -1045,13 +1045,13 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _mintQuoteAndApproveTokens(actor, 1000000000000 * 1e18); changePrank(actor); - _pool.addQuoteToken(913597152782868931694946846442, 2572, block.timestamp + 100, false); - ERC20Pool(address(_pool)).drawDebt(actor, 456798576391434465847473423221, 7388, 170152459663184217402759609); + _pool.addQuoteToken(913597152782868931694946846442, 2572, block.timestamp + 100); + ERC20Pool(address(_pool)).drawDebt(actor, 436798576391434465847473423221, 7388, 170152459663184217402759609); skip(100 days); // borrower is undercollateralized and pledged collateral is lower than encumbered collateral, tx should revert with InsufficientCollateral vm.expectRevert(IPoolErrors.InsufficientCollateral.selector); - ERC20Pool(address(_pool)).repayDebt(actor, 0, 149220, actor, 7388); + ERC20Pool(address(_pool)).repayDebt(actor, 0, 100000000, actor, 7388); } function testPullBorrowerWithDebtCollateralEncumberedCalculatedAsZero() external { @@ -1061,7 +1061,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _mintQuoteAndApproveTokens(actor, 1000000000000 * 1e18); changePrank(actor); - _pool.addQuoteToken(200, 2572, block.timestamp + 100, false); + _pool.addQuoteToken(200, 2572, block.timestamp + 100); ERC20Pool(address(_pool)).drawDebt(actor, 100, 7388, 1); // actor should not be able to pull his collateral without repaying the debt diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol new file mode 100644 index 000000000..1ebd6eee0 --- /dev/null +++ b/tests/forge/unit/ERC20Pool/ERC20PoolDebtExceedsDeposit.t.sol @@ -0,0 +1,467 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.18; + +import { ERC20HelperContract, ERC20FuzzyHelperContract } from './ERC20DSTestPlus.sol'; + +import 'src/libraries/helpers/PoolHelper.sol'; +import 'src/interfaces/pool/erc20/IERC20Pool.sol'; +import '@std/console.sol'; + +import 'src/ERC20Pool.sol'; + +contract ERC20PoolDebtExceedsDepositTest is ERC20HelperContract { + + address internal _borrower; + address internal _borrower2; + address internal _lender; + address internal _attacker; + + function setUp() external { + _startTest(); + + _borrower = makeAddr("borrower"); + _borrower2 = makeAddr("borrower2"); + _lender = makeAddr("lender"); + _attacker = makeAddr("attacker"); + + _mintCollateralAndApproveTokens(_borrower, 1_000 * 1e18); + _mintCollateralAndApproveTokens(_borrower2, 1_000 * 1e18); + _mintCollateralAndApproveTokens(_attacker, 11_000 * 1e18); + + _mintQuoteAndApproveTokens(_lender, 200_000 * 1e18); + _mintQuoteAndApproveTokens(_attacker, 2_000_000 * 1e18); + + // fund reserves + deal(address(_quote), address(_pool), 50 * 1e18); + + // lender deposits 100 quote in price of 1.0 + _addInitialLiquidity({ + from: _lender, + amount: 100 * 1e18, + index: 4156 // 1.000000000000000000 + }); + + // 1b. Legit borrower posts 75 collateral and borrows 50 quote token + // first borrower adds collateral token and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + amount: 75.0 * 1e18 + }); + _borrow({ + from: _borrower, + amount: 50.0 * 1e18, + indexLimit: 7388, + newLup: 1.0 * 1e18 + }); + + // assert prices used in the attacks + assertEq(_priceAt(3231), 100.834029983998419124 * 1e18); + assertEq(_priceAt(3232), 100.332368143282009890 * 1e18); + } + + function testStealReservesWithMargin() external tearDown { + // Pool's reserves are already seeded with 50 quote token in setUp() + + // assert attacker's balances + assertEq(2_000_000.0 * 1e18, _quote.balanceOf(address(_attacker))); + assertEq(11_000.0 * 1e18, _collateral.balanceOf(address(_attacker))); + + _assertPool( + PoolParams({ + htp: 0.694000000000000000 * 1e18, + lup: 1 * 1e18, + poolSize: 99.995433789954337900 * 1e18, + pledgedCollateral: 75.000000000000000000 * 1e18, + encumberedCollateral: 52.050000000000000024 * 1e18, + poolDebt: 50.048076923076923100 * 1e18, + actualUtilization: 0, + targetUtilization: 1.0 * 1e18, + minDebtAmount: 5.004807692307692310 * 1e18, + loans: 1, + maxBorrower: address(_borrower), + interestRate: 0.05 * 1e18, + interestRateUpdate: block.timestamp + }) + ); + + _assertReserveAuction({ + reserves: 50.052643133122585200 * 1e18, + claimableReserves : 50.052643033127151410 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + _assertPool( + PoolParams({ + htp: 0.694000000000000000 * 1e18, + lup: 1 * 1e18, + poolSize: 99.995433789954337900 * 1e18, + pledgedCollateral: 75.000000000000000000 * 1e18, + encumberedCollateral: 52.050000000000000024 * 1e18, + poolDebt: 50.048076923076923100 * 1e18, + actualUtilization: 0, + targetUtilization: 1.0 * 1e18, + minDebtAmount: 5.004807692307692310 * 1e18, + loans: 1, + maxBorrower: address(_borrower), + interestRate: 0.05 * 1e18, + interestRateUpdate: block.timestamp + }) + ); + + // Attacker does the following in quick succession (ideally same block): + + // 2a. deposits 100 quote token at price 100 + _addLiquidity({ + from: _attacker, + amount: 100 * 1e18, + index: 3232, + lpAward: 99.995433789954337900 * 1e18, + newLup: 100.332368143282009890 * 1e18 + }); + + // deposits 100 quote token at price 100.5 + _addLiquidity({ + from: _attacker, + amount: 100 * 1e18, + index: 3231, + lpAward: 99.995433789954337900 * 1e18, + newLup: 100.834029983998419124 * 1e18 + }); + + // 2b. posts 1.04 collateral and borrows 99.9 quote token + _pledgeCollateral({ + from: _attacker, + borrower: _attacker, + amount: 1.04 * 1e18 + }); + + _borrow({ + from: _attacker, + amount: 98.7 * 1e18, + indexLimit: 7388, + newLup: 100332368143282009890 + }); + + // 2c. lenderKicks the loan in 2b using deposit in 2a + _lenderKick({ + from: _attacker, + index: 3232, + borrower: _attacker, + debt: 98.794903846153846199 * 1e18, + collateral: 1.040000000000000000 * 1e18, + bond: 1.104560604152777078 * 1e18 + }); + + // 2d. withdraws 100 of the deposit from 2a + _removeLiquidity({ + from: _attacker, + amount: 99.995433789954337900 * 1e18, + index: 3232, + newLup: 1.000000000000000000 * 1e18, + lpRedeem: 99.995433789954337900 * 1e18 + }); + + // Now wait until auction price drops to about $50 + skip(8 hours); + _assertAuction( + AuctionParams({ + borrower: _attacker, + active: true, + kicker: _attacker, + bondSize: 1.104560604152777078 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp - 8 hours, + referencePrice: 109.840509887681617373 * 1e18, + totalBondEscrowed: 1.104560604152777078 * 1e18, + auctionPrice: 54.920254943840808688 * 1e18, + debtInAuction: 98.794903846153846199 * 1e18, + debtToCollateral: 94.995099852071005961 * 1e18, + neutralPrice: 109.840509887681617373 * 1e18 + }) + ); + + _assertBucket({ + index: 3231, + lpBalance: 99.995433789954337900 * 1e18, + collateral: 0 * 1e18, + deposit: 99.995433789954337900 * 1e18, + exchangeRate: 1.0 * 1e18 + }); + + // In a single block finish the attack: + + // 2a. Call arbtake using 100.5 price bucket + _arbTake({ + from: _attacker, + borrower: _attacker, + kicker: _attacker, + index: 3231, + collateralArbed: 1.040000000000000000 * 1e18, + quoteTokenAmount: 57.117065141594441036 * 1e18, + bondChange: 0.387421552599669399 * 1e18, + isReward: true, + lpAwardTaker: 47.748946716418152522 * 1e18, + lpAwardKicker: 0.387410361464209340 * 1e18 + }); + + _assertBucket({ + index: 3231, + lpBalance: 148.131790867836699762 * 1e18, + collateral: 1.040000000000000000 * 1e18, + deposit: 43.268678772242743031 * 1e18, + exchangeRate: 1.000028887031874320 * 1e18 + }); + + _assertReserveAuction({ + reserves: 50.471657206439477747 * 1e18, + claimableReserves : 50.471657063172476614 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + // 2b. Call settle + _settle({ + from: _attacker, + borrower: _attacker, + maxDepth: 10, + settledDebt: 42.383729854304427546 * 1e18 + }); + + _assertBucket({ + index: 3232, + lpBalance: 0 * 1e18, + collateral: 0, + deposit: 0 * 1e18, + exchangeRate: 1 * 1e18 + }); + + uint256 depositRemaining = 0.932448636751764778 * 1e18; + _assertBucket({ + index: 3231, + lpBalance: 148.131790867836699762 * 1e18, + collateral: 1.040000000000000000 * 1e18, + deposit: depositRemaining, + + exchangeRate: 0.714227777847530521 * 1e18 + }); + + // 2c. Withdraw the deposit remaing (should be about 50) + // the collateral moved (should be 1.04) from the 100 price bucket (all go to the attacker) + _removeAllLiquidity({ + from: _attacker, + amount: depositRemaining, + index: 3231, + newLup: 1.0 * 1e18, + lpRedeem: 1.305533984637067512 * 1e18 + }); + + _removeAllCollateral({ + from: _attacker, + amount: 1.040000000000000000 * 1e18, + index: 3231, + lpRedeem: 146.826256883199632250 * 1e18 + }); + + _assertReserveAuction({ + reserves: 50.424157487626028454 * 1e18, + claimableReserves : 50.424157387627706093 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + // assert attacker's balances + // attacker does not profit in QT + assertEq(_quote.balanceOf(address(_attacker)), 1_999_998.523321822553325600 * 1e18); + assertEq(_collateral.balanceOf(address(_attacker)), 11_000.0 * 1e18); + } + + function testSpendOrigFeePushBadDebtToBorrowers() external tearDown { + // Starts like the other test: For background, set up a nice normal looking pool with some reserves. + // Pool's reserves are already seeded with 50 quote token in setUp() + + // assert attacker's balances + assertEq(2_000_000.0 * 1e18, _quote.balanceOf(address(_attacker))); + assertEq(11_000.0 * 1e18, _collateral.balanceOf(address(_attacker))); + + // Like other attack, but bigger: Attacker does the following in quick succession (ideally same block): + + // 2a. deposits 100 quote token at price 100.3 + _addLiquidity({ + from: _attacker, + amount: 100.0 * 1e18, + index: 3232, + lpAward: 99.995433789954337900 * 1e18, + newLup: 100.332368143282009890 * 1e18 + }); + + // 2aa. deposits 1,000,000 quote token at price 100.8 + _addLiquidity({ + from: _attacker, + amount: 1_000_000.0 * 1e18, + index: 3231, + lpAward: 999_954.337899543379000000 * 1e18, + newLup: 100.834029983998419124 * 1e18 + }); + + // 2b. posts 10,400 collateral and borrows ~999,000 quote token + _pledgeCollateral({ + from: _attacker, + borrower: _attacker, + amount: 10_400.0 * 1e18 + }); + + _borrow({ + from: _attacker, + amount: 998_980.0 * 1e18, + indexLimit: 7388, + newLup: 100.332368143282009890 * 1e18 + }); + + // 2c. lenderKicks the loan in 2b using deposit in 2a + _lenderKick({ + from: _attacker, + index: 3232, + borrower: _attacker, + debt: 999_940.557692307692768760 * 1e18, + collateral: 10_400.000000000000000000 * 1e18, + bond: 11_179.675302295250711919 * 1e18 + }); + + // 2d. withdraws 100 of the deposit from 2a + _removeAllLiquidity({ + from: _attacker, + amount: 99.9954337899543379 * 1e18, + index: 3232, + newLup: 1.000000000000000000 * 1e18, + lpRedeem: 99.9954337899543379 * 1e18 + }); + + // There now is a loan for about 1,000,000 quote token in auction + _assertBorrower({ + borrower: _attacker, + borrowerDebt: 999_940.557692307692768760 * 1e18, + borrowerCollateral: 10_400 * 1e18, + borrowert0Np: 111.173731071526020388 * 1e18, + borrowerCollateralization: 0.010000594458412903 * 1e18 + }); + + // Now wait until auction price drops to about $50 + skip(8 hours + 10 minutes); + _assertAuction( + AuctionParams({ + borrower: _attacker, + active: true, + kicker: _attacker, + bondSize: 11_179.675302295250711919 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp - 8 hours - 10 minutes, + referencePrice: 111.173731071526020388 * 1e18, + totalBondEscrowed: 11_179.675302295250711919 * 1e18, + auctionPrice: 52.467014501698027340 * 1e18, + debtInAuction: 999_940.55769230769276876 * 1e18, + debtToCollateral: 96.148130547337278151 * 1e18, + neutralPrice: 111.173731071526020388 * 1e18 + }) + ); + + // In a single block finish the attack: + // 2a. Call arbtake using 100.8 price bucket + _arbTake({ + from: _attacker, + borrower: _attacker, + kicker: _attacker, + index: 3231, + collateralArbed: 10_400.000000000000000000 * 1e18, + quoteTokenAmount: 545_656.950817659484336000 * 1e18, + bondChange: 4_198.081289576618325539 * 1e18, + isReward: true, + lpAwardTaker: 502_997.032382326677733665 * 1e18, + lpAwardKicker: 4_197.914969093779952491 * 1e18 + }); + + // borrower now has bad debt + _assertBorrower({ + borrower: _attacker, + borrowerDebt: 460_906.485977166188721281 * 1e18, + borrowerCollateral: 0, + borrowert0Np: 0, + borrowerCollateralization: 0 + }); + + _assertBucket({ + index: 3231, + lpBalance: 1_507_149.285250963836686156 * 1e18, + collateral: 10_400.000000000000000000 * 1e18, + deposit: 458_535.086345983632095884 * 1e18, + exchangeRate: 1.000039619783645661 * 1e18 + }); + + _assertReserveAuction({ + reserves: 3_441.455211693385224306 * 1e18, + claimableReserves : 1_120.0045662100456621 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + // 2b. Call settle + _settle({ + from: _attacker, + borrower: _attacker, + maxDepth: 10, + settledDebt: 459_115.848803783573911464 * 1e18 + }); + + _assertBucket({ + index: 3232, + lpBalance: 0 * 1e18, + collateral: 0, + deposit: 0 * 1e18, + exchangeRate: 1 * 1e18 + }); + + // 2c. There is no deposit remaing to withdraw + _assertBucket({ + index: 3231, + lpBalance: 1_507_149.285250963836686156 * 1e18, + collateral: 10_400.000000000000000000 * 1e18, + deposit: 0, + exchangeRate: 0.695799627877581494 * 1e18 + }); + + // wait for auction to end and settle again + skip(16 hours); + _settle({ + from: _attacker, + borrower: _attacker, + maxDepth: 10, + settledDebt: 1_790.800709358882040227 * 1e18 + }); + + _removeAllCollateral({ + from: _attacker, + amount: 10_400.000000000000000000 * 1e18, + index: 3231, + lpRedeem: 1_507_149.285250963836686156 * 1e18 + }); + + _assertReserveAuction({ + reserves: 1_170.059547120642975304 * 1e18, + claimableReserves : 1_120.004566210045662100 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + // assert attacker's balances + // attacker does not profit in QT + assertEq(_quote.balanceOf(address(_attacker)), 1_987_800.320131494703625981 * 1e18); + assertEq(_collateral.balanceOf(address(_attacker)), 11_000.000000000000000000 * 1e18); + // End result: attack is out the origination fee (should be about 1000), but pushed a small amount of bad debt (should be small amount with these paramters, but could be made a bit larger by waiting longer and making bigger loan) that get pushed to the legit borrower at price of 1. This can be measured by looking at the exchange rate of that bucket + } +} \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolFactory.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolFactory.t.sol index ab19a4bb2..7f0ef14af 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolFactory.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolFactory.t.sol @@ -12,7 +12,8 @@ import { IPoolErrors } from 'src/interfaces/pool/commons/IPoolErrors.sol'; import { IPoolFactory } from 'src/interfaces/pool/IPoolFactory.sol'; contract ERC20PoolFactoryTest is ERC20HelperContract { - address immutable poolAddress = 0x3Cd0C8d97cD0291E178560E5675dD27AeD0A90d1; + address immutable poolAddress = 0x9Fd7552Da37D2D296CB4a84d507c35Dcc926220a; + bytes32 constant ERC20_NON_SUBSET_HASH = keccak256("ERC20_NON_SUBSET_HASH"); function setUp() external { // deploy new pool factory for factory tests @@ -94,7 +95,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { quote: address(_quote), interestRate: 2 * 10**18 }); - + // check tracking of deployed pools assertEq(_poolFactory.getDeployedPoolsList().length, 0); } @@ -144,7 +145,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { skip(333); vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); ERC20Pool pool = ERC20Pool(_poolFactory.deployPool(address(_collateral), address(_quote), 0.0543 * 10**18)); assertEq(address(pool), poolAddress); @@ -175,7 +176,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { address compAddress = 0xc00e94Cb662C3520282E6f5717214004A7f26888; address daiAddress = 0x6B175474E89094C44Da98b954EedeAC495271d0F; vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); ERC20Pool pool = ERC20Pool(_poolFactory.deployPool(compAddress, daiAddress, 0.0543 * 10**18)); assertEq(address(pool), poolAddress); @@ -200,7 +201,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { address wbtcAddress = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address daiAddress = 0x6B175474E89094C44Da98b954EedeAC495271d0F; vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); ERC20Pool pool = ERC20Pool(_poolFactory.deployPool(wbtcAddress, daiAddress, 0.0543 * 10**18)); assertEq(address(pool), poolAddress); @@ -225,7 +226,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { address wbtcAddress = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address usdcAddress = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); ERC20Pool pool = ERC20Pool(_poolFactory.deployPool(wbtcAddress, usdcAddress, 0.0543 * 10**18)); assertEq(address(pool), poolAddress); @@ -250,7 +251,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { address compAddress = 0xc00e94Cb662C3520282E6f5717214004A7f26888; address usdcAddress = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); ERC20Pool pool = ERC20Pool(_poolFactory.deployPool(compAddress, usdcAddress, 0.0543 * 10**18)); assertEq(address(pool), poolAddress); @@ -271,7 +272,7 @@ contract ERC20PoolFactoryTest is ERC20HelperContract { function testPoolAlreadyInitialized() external { vm.expectEmit(true, true, false, true); - emit PoolCreated(poolAddress); + emit PoolCreated(poolAddress, ERC20_NON_SUBSET_HASH); address pool = _poolFactory.deployPool(address(_collateral), address(_quote), 0.05 * 10**18); vm.expectRevert(IPoolErrors.AlreadyInitialized.selector); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol index 8be2b0cc4..22927eb84 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol @@ -45,8 +45,8 @@ contract ERC20PoolGasLoadTest is ERC20DSTestPlus { _mintQuoteAndApproveTokens(lender, 200_000 * 1e18); vm.startPrank(lender); - _pool.addQuoteToken(100_000 * 1e18, 7388 - i, block.timestamp + 2 minutes, false); - _pool.addQuoteToken(100_000 * 1e18, 1 + i, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(100_000 * 1e18, 7388 - i, block.timestamp + 2 minutes); + _pool.addQuoteToken(100_000 * 1e18, 1 + i, block.timestamp + 2 minutes); vm.stopPrank(); _lenders.push(lender); @@ -119,7 +119,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { skip(15 hours); address borrower = _borrowers[borrowerId_]; - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), borrower); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), borrower); vm.prank(borrower); ERC20Pool(address(_pool)).repayDebt(borrower, debt, 0, borrower, MAX_FENWICK_INDEX); @@ -220,7 +220,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { assertEq(_noOfLoans(), LOANS_COUNT); address borrower = _borrowers[i]; - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), borrower); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), borrower); vm.prank(borrower); ERC20Pool(address(_pool)).repayDebt(borrower, debt, 0, borrower, MAX_FENWICK_INDEX); @@ -272,13 +272,13 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { vm.startPrank(lender); skip(15 hours); - _pool.addQuoteToken(10_000 * 1e18, index_, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(10_000 * 1e18, index_, block.timestamp + 2 minutes); skip(15 hours); _pool.removeQuoteToken(5_000 * 1e18, index_); skip(15 hours); - _pool.moveQuoteToken(1_000 * 1e18, index_, index_ + 1, block.timestamp + 2 minutes, false); + _pool.moveQuoteToken(1_000 * 1e18, index_, index_ + 1, block.timestamp + 2 minutes); skip(15 hours); _pool.removeQuoteToken(type(uint256).max, index_); @@ -296,10 +296,10 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { vm.startPrank(lender); skip(15 hours); - _pool.addQuoteToken(10_000 * 1e18, 7388 - i, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(10_000 * 1e18, 7388 - i, block.timestamp + 2 minutes); skip(15 hours); - _pool.addQuoteToken(10_000 * 1e18, 1 + i, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(10_000 * 1e18, 1 + i, block.timestamp + 2 minutes); skip(15 hours); _pool.removeQuoteToken(5_000 * 1e18, 7388 - i); @@ -361,7 +361,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { vm.startPrank(kicker); - _pool.addQuoteToken(500_000_000_000_000 * 1e18, 3_000, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(500_000_000_000_000 * 1e18, 3_000, block.timestamp + 2 minutes); vm.warp(100_000 days); _pool.lenderKick(3_000, MAX_FENWICK_INDEX); // worst case scenario, pool interest accrues @@ -410,7 +410,7 @@ contract ERC20PoolGasArbTakeLoadTest is ERC20PoolGasLoadTest { } // add quote tokens in bucket to arb - _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes); vm.stopPrank(); @@ -440,7 +440,7 @@ contract ERC20PoolGasArbTakeLoadTest is ERC20PoolGasLoadTest { } // add quote tokens in bucket to arb - _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes); vm.stopPrank(); @@ -472,7 +472,7 @@ contract ERC20PoolGasArbTakeLoadTest is ERC20PoolGasLoadTest { vm.startPrank(lender); - _pool.addQuoteToken(200_000 * 1e18, 5000 - i, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(200_000 * 1e18, 5000 - i, block.timestamp + 2 minutes); vm.stopPrank(); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol index c2814230a..e8b99a875 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol @@ -44,45 +44,45 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: highest, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: high, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: med, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: low, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: lowest, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: MAX_PRICE }); _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 21_000 * 1e18, - limitIndex: 3_000, + from: _borrower, + borrower: _borrower, + amountToBorrow: 21_000 * 1e18, + limitIndex: 3_000, collateralToPledge: 100 * 1e18, - newLup: 2_981.007422784467321543 * 1e18 + newLup: 2_981.007422784467321543 * 1e18 }); } @@ -94,11 +94,115 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { assertEq(_indexOf(price_), _poolUtils.priceToIndex(price_)); } + function testPoolInfoUtilsAuctionStatusNoLiquidation() external { + ( + uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 neutralPrice, + uint256 referencePrice, + uint256 debtToCollateral, + uint256 bondFactor + ) = _poolUtils.auctionStatus(address(_pool), _borrower); + // since loan is not in auction values are 0 + assertEq(kickTime, 0); + assertEq(collateral, 0); + assertEq(debtToCover, 0); + assertEq(isCollateralized, false); + assertEq(price, 0); + assertEq(neutralPrice, 0); + assertEq(referencePrice, 0); + assertEq(debtToCollateral, 0); + assertEq(bondFactor, 0); + } + + function testPoolInfoUtilsAuctionStatusMatureLiquidation() external { + _removeAndKick(); + skip(6 hours); + ( + uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 neutralPrice, + uint256 referencePrice, + uint256 debtToCollateral, + uint256 bondFactor + ) = _poolUtils.auctionStatus(address(_pool), _borrower); + // at 6 hours, auction price should match reference price + assertEq(kickTime, _startTime); + assertEq(collateral, 100 * 1e18); + assertEq(debtToCover, 21_020.912189618561131155 * 1e18); + assertEq(isCollateralized, true); + assertEq(price, 243.051341028061451208 * 1e18); + assertEq(neutralPrice, 243.051341028061451209 * 1e18); + assertEq(referencePrice, 243.051341028061451209 * 1e18); + assertEq(debtToCollateral, 210.201923076923077020 * 1e18); + assertEq(bondFactor, 0.011180339887498948 * 1e18); + } + + + function testPoolInfoUtilsAuctionInfoNoLiquidation() external { + ( + address kicker, + uint256 bondFactor, + uint256 bondSize, + uint256 kickTime, + uint256 referencePrice, + uint256 neutralPrice, + uint256 debtToCollateral, + address head, + address next, + address prev + ) = _poolUtils.auctionInfo(address(_pool), _borrower); + // since loan is not in auction values are 0 + assertEq(kicker, address(0)); + assertEq(bondFactor, 0); + assertEq(bondSize, 0); + assertEq(kickTime, 0); + assertEq(referencePrice, 0); + assertEq(neutralPrice, 0); + assertEq(debtToCollateral, 0); + assertEq(head, address(0)); + assertEq(next, address(0)); + assertEq(prev, address(0)); + } + + function testPoolInfoUtilsAuctionInfoSingleLiquidation() external { + _removeAndKick(); + ( + address kicker, + uint256 bondFactor, + uint256 bondSize, + uint256 kickTime, + uint256 referencePrice, + uint256 neutralPrice, + uint256 debtToCollateral, + address head, + address next, + address prev + ) = _poolUtils.auctionInfo(address(_pool), _borrower); + assertEq(kicker, _lender); + assertEq(bondFactor, 0.011180339887498948 * 1e18); + assertEq(bondSize, 235.012894500590867635 * 1e18); + assertEq(kickTime, _startTime); + assertEq(referencePrice, 243.051341028061451209 * 1e18); + assertEq(neutralPrice, 243.051341028061451209 * 1e18); + assertEq(debtToCollateral, 210.201923076923077020 * 1e18); + assertEq(head, _borrower); + assertEq(next, address(0)); + assertEq(prev, address(0)); + } + function testPoolInfoUtilsBorrowerInfo() external { - (uint256 debt, uint256 collateral, uint256 npTpRatio) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 debt, uint256 collateral, uint256 npTpRatio, uint256 thresholdPrice) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertEq(debt, 21_020.192307692307702000 * 1e18); assertEq(collateral, 100 * 1e18); - assertEq(npTpRatio, 242.111289450059087705 * 1e18); + assertEq(thresholdPrice, 218.610000000000000101 * 1e18); + assertEq(npTpRatio, 243.051341028061451209 * 1e18); } function testPoolInfoUtilsBucketInfo() external { @@ -127,9 +231,9 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { exchangeRate ) = _poolUtils.bucketInfo(address(_pool), high); assertEq(price, 2_995.912459898389633881 * 1e18); - assertEq(quoteTokens, 10_000 * 1e18); + assertEq(quoteTokens, 9_999.54337899543379 * 1e18); assertEq(collateral, 0); - assertEq(bucketLP, 10_000 * 1e18); + assertEq(bucketLP, 9_999.54337899543379 * 1e18); assertEq(scale, 1 * 1e18); assertEq(exchangeRate, 1 * 1e18); } @@ -142,7 +246,7 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { uint256 pendingInflator, uint256 pendingInterestFactor ) = _poolUtils.poolLoansInfo(address(_pool)); - assertEq(poolSize, 50_000 * 1e18); + assertEq(poolSize, 49_997.71689497716895 * 1e18); assertEq(loansCount, 1); assertEq(maxBorrower, _borrower); assertEq(pendingInflator, 1 * 1e18); @@ -161,8 +265,8 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { assertEq(hpb, 3_010.892022197881557845 * 1e18); assertEq(hpbIndex, 2550); - assertEq(htp, 210.201923076923077020 * 1e18); - assertEq(htpIndex, 3083); + assertEq(htp, 218.610000000000000101 * 1e18); + assertEq(htpIndex, 3075); assertEq(lup, 2981.007422784467321543 * 1e18); assertEq(lupIndex, 2552); @@ -182,8 +286,8 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { uint256 timeRemaining ) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 20.192307692307702000 * 1e18); - assertEq(claimableReserves, 0); + assertEq(reserves, 22.475412715138752000 * 1e18); + assertEq(claimableReserves, 22.475362717421857023 * 1e18); assertEq(claimableReservesRemaining, 0); assertEq(auctionPrice, 0); assertEq(timeRemaining, 0); @@ -198,7 +302,7 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { ) = _poolUtils.poolUtilizationInfo(address(_pool)); assertEq(poolMinDebtAmount, 2_102.019230769230770200 * 1e18); - assertEq(poolCollateralization, 14.181637252165253251 * 1e18); + assertEq(poolCollateralization, 13.636189665543512740 * 1e18); assertEq(poolActualUtilization, 0); assertEq(poolTargetUtilization, 1 * 1e18); } @@ -212,8 +316,8 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { assertEq(_poolUtils.borrowFeeRate(address(_pool)), 0.000961538461538462 * 1e18); } - function testUnutilizedDepositFeeRate() external { - assertEq(_poolUtils.unutilizedDepositFeeRate(address(_pool)), 0.000136986301369863 * 1e18); + function testDepositFeeRate() external { + assertEq(_poolUtils.depositFeeRate(address(_pool)), 0.000045662100456621 * 1e18); } function testPoolInfoUtilsLPToCollateralAndQuote() external { @@ -265,41 +369,31 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { ); } - function testPoolInfoUtilsMulticall() external { - PoolInfoUtilsMulticall poolUtilsMulticall = new PoolInfoUtilsMulticall(_poolUtils); - - string[] memory functionSignatures = new string[](2); - functionSignatures[0] = "hpb(address)"; - functionSignatures[1] = "htp(address)"; - - string[] memory args = new string[](2); - args[0] = Strings.toHexString(address(_pool)); - args[1] = Strings.toHexString(address(_pool)); - - bytes[] memory result = poolUtilsMulticall.multicall(functionSignatures, args); - - assertEq(abi.decode(result[0], (uint256)), _poolUtils.hpb(address(_pool))); - assertEq(abi.decode(result[1], (uint256)), _poolUtils.htp(address(_pool))); - } - - function testPoolInfoMulticallBorrowerInfo() external { - PoolInfoUtilsMulticall poolUtilsMulticall = new PoolInfoUtilsMulticall(_poolUtils); - - string[] memory functionSignatures = new string[](2); - functionSignatures[0] = "borrowerInfo(address,address)"; - functionSignatures[1] = "htp(address)"; - - string[] memory args = new string[](3); - args[0] = Strings.toHexString(address(_pool)); - args[1] = Strings.toHexString(_borrower); - args[2] = Strings.toHexString(address(_pool)); - - bytes[] memory result = poolUtilsMulticall.multicall(functionSignatures, args); - - (uint256 debt,,) = abi.decode(result[0], (uint256, uint256, uint256)); - - assertEq(debt, 21_020.192307692307702000 * 1e18); - assertEq(abi.decode(result[1], (uint256)), _poolUtils.htp(address(_pool))); + // Helps test liquidation functions + function _removeAndKick() internal { + uint256 amountLessFee = 9_999.543378995433790000 * 1e18; + _removeAllLiquidity({ + from: _lender, + amount: amountLessFee, + index: lowest, + newLup: _priceAt(med), + lpRedeem: amountLessFee + }); + _removeAllLiquidity({ + from: _lender, + amount: amountLessFee, + index: low, + newLup: _priceAt(med), + lpRedeem: amountLessFee + }); + _lenderKick({ + from: _lender, + index: med, + borrower: _borrower, + debt: 21_020.192307692307702000 * 1e18, + collateral: 100 * 1e18, + bond: 235.012894500590867635 * 1e18 + }); } function testPoolInfoUtilsMulticallRatesAndFees() external { @@ -307,9 +401,9 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { (uint256 lim, uint256 bfr, uint256 dfr) = poolUtilsMulticall.poolRatesAndFeesMulticall(address(_pool)); - assertGe(lim, 0.000136986301369863 * 1e18); - assertGe(bfr, 0.000961538461538462 * 1e18); - assertGe(dfr, 0.000136986301369863 * 1e18); + assertEq(lim, 0.849999999999999999 * 1e18); + assertEq(bfr, 0.000961538461538462 * 1e18); + assertEq(dfr, 0.000045662100456621* 1e18); } function testPoolInfoUtilsMulticallPoolDetails() external { @@ -323,22 +417,22 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { PoolInfoUtilsMulticall.PoolUtilizationInfo memory poolUtilizationInfo ) = poolUtilsMulticall.poolDetailsMulticall(address(_pool)); - assertEq(poolLoansInfo.poolSize, 50_000 * 1e18); + assertEq(poolLoansInfo.poolSize, 49_997.716894977168950000 * 1e18); assertEq(poolPriceInfo.hpb, 3_010.892022197881557845 * 1e18); assertEq(poolPriceInfo.hpbIndex, 2550); - assertEq(poolPriceInfo.htp, 210.201923076923077020 * 1e18); - assertEq(poolPriceInfo.htpIndex, 3083); + assertEq(poolPriceInfo.htp, 218.610000000000000101 * 1e18); + assertEq(poolPriceInfo.htpIndex, 3075); assertEq(poolPriceInfo.lup, 2981.007422784467321543 * 1e18); assertEq(poolPriceInfo.lupIndex, 2552); - assertGe(poolRatesAndFees.lenderInterestMargin, 0.000136986301369863 * 1e18); - assertGe(poolRatesAndFees.borrowFeeRate, 0.000961538461538462 * 1e18); - assertGe(poolRatesAndFees.depositFeeRate, 0.000136986301369863 * 1e18); + assertEq(poolRatesAndFees.lenderInterestMargin, 0.849999999999999999 * 1e18); + assertEq(poolRatesAndFees.borrowFeeRate, 0.000961538461538462 * 1e18); + assertEq(poolRatesAndFees.depositFeeRate, 0.000045662100456621 * 1e18); - assertEq(poolReservesInfo.reserves, 20.192307692307702000 * 1e18); + assertEq(poolReservesInfo.reserves, 22.475412715138752000 * 1e18); - assertEq(poolUtilizationInfo.poolMinDebtAmount, 2_102.019230769230770200 * 1e18); + assertEq(poolUtilizationInfo.poolMinDebtAmount, 2_102.019230769230770200 * 1e18); } function testPoolInfoUtilsMulticallPoolBalanceDetails() external { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol index fcb3e5632..6da637a08 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol @@ -8,33 +8,33 @@ import 'src/interfaces/pool/commons/IPoolErrors.sol'; import 'src/ERC20Pool.sol'; -contract ERC20PoolBorrowTest is ERC20HelperContract { +contract ERC20PooInputValidationTest is ERC20HelperContract { function testValidateAddQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.addQuoteToken(0, 1000, block.timestamp + 1, false); + _pool.addQuoteToken(0, 1000, block.timestamp + 1); // revert on zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, 0, block.timestamp + 1, false); + _pool.addQuoteToken(1000, 0, block.timestamp + 1); // revert on index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); + _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1); } function testValidateMoveQuoteTokenInput() external tearDown { - // revert on zero amount - vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1, false); + // revert on dust amount if amount is below quote token scale + vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); + _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1); // revert on move to same index vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1); // revert on to zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1); // revert on to index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1); } function testValidateRemoveQuoteTokenInput() external tearDown { @@ -52,7 +52,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { function testValidateTakeReservesInput() external tearDown { // revert on zero amount - vm.expectRevert(IPoolErrors.InvalidAmount.selector); + vm.expectRevert(IPoolErrors.NoReservesAuction.selector); _pool.takeReserves(0); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInterestRateAndEMAs.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInterestRateAndEMAs.t.sol index 3971cd081..be9cb64ae 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInterestRateAndEMAs.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInterestRateAndEMAs.t.sol @@ -67,7 +67,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 110_000 * 1e18, + poolSize: 109_994.977168949771690000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -95,15 +95,15 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 460.442307692307692520 * 1e18, + htp: 478.860000000000000221 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 110_000 * 1e18, + poolSize: 109_994.977168949771690000 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 15.464917089564537419 * 1e18, - poolDebt: 46_101.032636738246882092 * 1e18, + encumberedCollateral: 16.063697001891783502 * 1e18, + poolDebt: 46_044.230769230769252000 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 4_610.103263673824688209 * 1e18, + minDebtAmount: 4_604.423076923076925200 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.045 * 1e18, @@ -114,7 +114,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 109_999.904632568359400000 * 1e18 + depositEma: 109_994.881805872808333863 * 1e18 }); skip(14 hours); @@ -125,15 +125,15 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 461.043482411861952490 * 1e18, + htp: 478.894439800046459253 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 110_051.099851162112050000 * 1e18, + poolSize: 109_997.791960299722618973 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 15.466029332500467905 * 1e18, - poolDebt: 46_104.348241186195248997 * 1e18, - actualUtilization: 0.332788778646025592 * 1e18, + encumberedCollateral: 16.064852309315147443 * 1e18, + poolDebt: 46_047.542288466005697371 * 1e18, + actualUtilization: 0.332803975174572376 * 1e18, targetUtilization: 0.154458625018190226 * 1e18, - minDebtAmount: 4_610.434824118619524900 * 1e18, + minDebtAmount: 4_604.754228846600569737 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.045 * 1e18, @@ -144,7 +144,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 2_313_024.841496349382919830 * 1e18, lupt0DebtEma: 14_975_044.878354639842735067 * 1e18, debtEma: 25_533.857684197937318785 * 1e18, - depositEma: 76_726.919062848880206510 * 1e18 + depositEma: 76_723.415550562905372147 * 1e18 }); vm.revertTo(snapshot); @@ -156,7 +156,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { from: _borrower, borrower: _borrower, amountToRepay: 46_200 * 1e18, - amountRepaid: 46_104.348241186195248997 * 1e18, + amountRepaid: 46_047.542288466005697371 * 1e18, collateralToPull: 0, newLup: MAX_PRICE }); @@ -165,11 +165,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 110_051.099851162112050000 * 1e18, + poolSize: 109_997.791960299722618973 * 1e18, pledgedCollateral: 100 * 1e18, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.332788778646025592 * 1e18, + actualUtilization: 0.332803975174572376 * 1e18, targetUtilization: 0.154458625018190226 * 1e18, minDebtAmount: 0, loans: 0, @@ -183,7 +183,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 2_313_024.841496349382919830 * 1e18, lupt0DebtEma: 14_975_044.878354639842735067 * 1e18, debtEma: 25_533.857684197937318785 * 1e18, - depositEma: 76_726.919062848880206510 * 1e18 + depositEma: 76_723.415550562905372147 * 1e18 }); } @@ -210,11 +210,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.663971153846153846 * 1e18, + htp: 0.690530000000000000 * 1e18, lup: 100.332368143282009890 * 1e18, - poolSize: 1_000 * 1e18, + poolSize: 999.954337899543379 * 1e18, pledgedCollateral: 1_500 * 1e18, - encumberedCollateral: 9.926574536214785829 * 1e18, + encumberedCollateral: 10.323637517663377262 * 1e18, poolDebt: 995.956730769230769690 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -233,13 +233,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.664020422940018855 * 1e18, + htp: 0.690581239857619609 * 1e18, lup: 100.332368143282009890 * 1e18, - poolSize: 1_000.062818094677886000 * 1e18, + poolSize: 1_000.017155994221264894 * 1e18, pledgedCollateral: 1_500 * 1e18, - encumberedCollateral: 9.927311124438159308 * 1e18, + encumberedCollateral: 10.324403569415685680 * 1e18, poolDebt: 996.030634410028283604 * 1e18, - actualUtilization: 0.525927743411473669 * 1e18, + actualUtilization: 0.525951759473550087 * 1e18, targetUtilization: 0.006617716357476524 * 1e18, minDebtAmount: 99.603063441002828360 * 1e18, loans: 1, @@ -276,11 +276,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 500.480769230769231000 * 1e18, + htp: 520.500000000000000240 * 1e18, lup: 601.252968524772188572 * 1e18, - poolSize: 10_000 * 1e18, + poolSize: 9_999.54337899543379 * 1e18, pledgedCollateral: 10 * 1e18, - encumberedCollateral: 8.323963380317995918 * 1e18, + encumberedCollateral: 8.656921915530715754 * 1e18, poolDebt: 5_004.807692307692310000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -305,13 +305,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 500.515049909493508659 * 1e18, + htp: 520.535651905873249005 * 1e18, lup: 601.252968524772188572 * 1e18, - poolSize: 11_000.291385769156360000 * 1e18, + poolSize: 10_999.789102664133521092 * 1e18, pledgedCollateral: 10 * 1e18, - encumberedCollateral: 8.324533534321699024 * 1e18, + encumberedCollateral: 8.657514875694566985 * 1e18, poolDebt: 5_005.150499094935086587 * 1e18, - actualUtilization: 0.250240384615384603 * 1e18, + actualUtilization: 0.250251811638747103 * 1e18, targetUtilization: 0.832396338031799592 * 1e18, minDebtAmount: 500.515049909493508659 * 1e18, loans: 1, @@ -342,11 +342,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // confirm interest rate starts out at 5% _assertPool( PoolParams({ - htp: 1.0009615384615 * 1e18, + htp: 1.040999999999960000 * 1e18, lup: _p1505_26, - poolSize: 10_000 * 1e18, + poolSize: 9_999.54337899543379 * 1e18, pledgedCollateral: 0.00001 * 1e18, - encumberedCollateral: 0.000000006649741966 * 1e18, + encumberedCollateral: 0.000000006915731644 * 1e18, poolDebt: 0.000010009615384615 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -371,13 +371,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // show the rate bottoms out at 10 bps _assertPool( PoolParams({ - htp: 1.002309975983935259 * 1e18, + htp: 1.042402375023292669 * 1e18, lup: _p1505_26, - poolSize: 10_000.000000011461360000 * 1e18, + poolSize: 9_999.543379006895126627 * 1e18, pledgedCollateral: 0.00001 * 1e18, - encumberedCollateral: 0.000000006658700114 * 1e18, + encumberedCollateral: 0.000000006925048118 * 1e18, poolDebt: 0.000010023099759840 * 1e18, - actualUtilization: 0.000000001002307157 * 1e18, + actualUtilization: 0.000000001002352927 * 1e18, targetUtilization: 0.000665852030273875 * 1e18, minDebtAmount: 0.000001002309975984 * 1e18, loans: 1, @@ -408,11 +408,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // confirm interest rate starts out at 5% _assertPool( PoolParams({ - htp: 0.000000001000961538 * 1e18, + htp: 0.000000001041000000 * 1e18, lup: _p1505_26, - poolSize: 10_000 * 1e18, + poolSize: 9_999.54337899543379 * 1e18, pledgedCollateral: 10_000 * 1e18, - encumberedCollateral: 0.000000006649741966 * 1e18, + encumberedCollateral: 0.000000006915731644 * 1e18, poolDebt: 0.000010009615384615 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -437,13 +437,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // show the rate reset to 10% _assertPool( PoolParams({ - htp: 1028117286, + htp: 1069241977, lup: _p1505_26, - poolSize: 10_000.000000230822950000 * 1e18, + poolSize: 9_999.543379226256659662 * 1e18, pledgedCollateral: 10_000.0 * 1e18, - encumberedCollateral: 0.000000006830147214 * 1e18, + encumberedCollateral: 0.000000007103353103 * 1e18, poolDebt: 0.000010281172862061 * 1e18, - actualUtilization: 0.000000001027819578 * 1e18, + actualUtilization: 0.000000001027866512 * 1e18, targetUtilization: 0.000000000000681949 * 1e18, minDebtAmount: 0.000001028117286206 * 1e18, loans: 1, @@ -489,11 +489,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 300.288461538461538600 * 1e18, + htp: 312.300000000000000144 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_000 * 1e18, + poolSize: 29_998.63013698630137 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 5.036694294071420412 * 1e18, + encumberedCollateral: 5.238162065834277229 * 1e18, poolDebt: 15_014.423076923076930000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -510,11 +510,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // ensure pendingInflator increases as time passes _assertPool( PoolParams({ - htp: 300.288461538461538600 * 1e18, + htp: 312.301782539333725867 * 1e18, lup: 2_981.007422784467321543 * 1e18, - poolSize: 30_000 * 1e18, + poolSize: 29_998.63013698630137 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 5.036723042408567816 * 1e18, + encumberedCollateral: 5.238191964104910529 * 1e18, poolDebt: 15_014.508775929506051308 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -545,7 +545,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 20_000 * 1e18, + poolSize: 19_999.08675799086758 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -562,7 +562,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 10_000 * 1e18 + depositEma: 9_999.54337899543379 * 1e18 }); // borrower 1 borrows 500 quote from the pool @@ -580,11 +580,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 10.009615384615384620 * 1e18, + htp: 10.410000000000000005 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 20_000 * 1e18, + poolSize: 19_999.08675799086758 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 1.529641632103338099 * 1e18, + encumberedCollateral: 1.590827297387471623 * 1e18, poolDebt: 500.480769230769231000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -599,7 +599,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 10_000 * 1e18 + depositEma: 9_999.54337899543379 * 1e18 }); _pledgeCollateral({ @@ -616,11 +616,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 10.009615384615384620 * 1e18, + htp: 10.410000000000000005 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 20_000 * 1e18, + poolSize: 19_999.08675799086758 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 3.059283264206676197 * 1e18, + encumberedCollateral: 3.181654594774943245 * 1e18, poolDebt: 1000.961538461538462000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -635,7 +635,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 10_000 * 1e18 + depositEma: 9_999.54337899543379 * 1e18 }); skip(10 days); @@ -650,13 +650,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 10.223528890139451939 * 1e18, + htp: 10.632470045745030017 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 20_001.166301815699560000 * 1e18, + poolSize: 20_000.253059806567146479 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 3.094069767562214045 * 1e18, + encumberedCollateral: 3.217832558264702607 * 1e18, poolDebt: 1_012.343273629329809309 * 1e18, - actualUtilization: 0.050048053058282770 * 1e18, + actualUtilization: 0.050050338461865504 * 1e18, targetUtilization: 0.030592832642066762 * 1e18, minDebtAmount: 50.617163681466490466 * 1e18, loans: 2, @@ -669,7 +669,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 8_636.472785378662688101 * 1e18, lupt0DebtEma: 282_303.796004265917437005 * 1e18, debtEma: 1_000.960583870227520994 * 1e18, - depositEma: 19_999.990463256835940000 * 1e18 + depositEma: 19_999.077221683171244387 * 1e18 }); } @@ -691,7 +691,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 40_000 * 1e18, + poolSize: 39_998.17351598173516 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -708,7 +708,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 20_000 * 1e18 + depositEma: 19_999.08675799086758 * 1e18 }); // borrower 1 borrows 10000 quote from the pool @@ -726,11 +726,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 200.192307692307692400 * 1e18, + htp: 208.200000000000000096 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 40_000 * 1e18, + poolSize: 39_998.17351598173516 * 1e18, pledgedCollateral: 50 * 1e18, - encumberedCollateral: 30.592832642066761971 * 1e18, + encumberedCollateral: 31.816545947749432450 * 1e18, poolDebt: 10009.615384615384620000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -745,7 +745,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 20_000 * 1e18 + depositEma: 19_999.08675799086758 * 1e18 }); // borrower 2 borrows 9000 quote from the pool @@ -763,11 +763,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 200.192307692307692400 * 1e18, + htp: 208.200000000000000096 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 40_000 * 1e18, + poolSize: 39_998.17351598173516 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 58.126382019926847745 * 1e18, + encumberedCollateral: 60.451437300723921655 * 1e18, poolDebt: 19_018.269230769230778000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -782,7 +782,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 20_000 * 1e18 + depositEma: 19_999.08675799086758 * 1e18 }); skip(10 days); @@ -797,13 +797,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 200.666923956635192629 * 1e18, + htp: 208.693600914900600334 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 40_022.159734498291760000 * 1e18, + poolSize: 40_020.333250480026923092 * 1e18, pledgedCollateral: 100 * 1e18, - encumberedCollateral: 58.236654596124865142 * 1e18, + encumberedCollateral: 60.566120779969859747 * 1e18, poolDebt: 19_054.349122034189453678 * 1e18, - actualUtilization: 0.475456504053686315 * 1e18, + actualUtilization: 0.475478215387722284 * 1e18, targetUtilization: 0.582873969285693044 * 1e18, minDebtAmount: 952.717456101709472684 * 1e18, loans: 2, @@ -816,7 +816,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 3_126_403.148307075893092949 * 1e18, lupt0DebtEma: 5_363_772.124081052431303092 * 1e18, debtEma: 19_018.251093534322898890 * 1e18, - depositEma: 39_999.980926513671880000 * 1e18 + depositEma: 39_998.154443366342488772 * 1e18 }); skip(10 days); @@ -835,13 +835,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { }); _assertPool( PoolParams({ - htp: 200.941998518054562716 * 1e18, + htp: 208.979678458776745225 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 40_045.119710562067080000 * 1e18, + poolSize: 40_043.293270139495569883 * 1e18, pledgedCollateral: 50_100 * 1e18, - encumberedCollateral: 58.353196900686720280 * 1e18, + encumberedCollateral: 60.687324776714189092 * 1e18, poolDebt: 19_092.480394752519489739 * 1e18, - actualUtilization: 0.476094973986474284 * 1e18, + actualUtilization: 0.476116702437763762 * 1e18, targetUtilization: 0.583872645876088990 * 1e18, minDebtAmount: 954.624019737625974487 * 1e18, loans: 2, @@ -854,7 +854,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 3_565_623.757561586266590894 * 1e18, lupt0DebtEma: 6_106_851.867005073649467356 * 1e18, debtEma: 19_054.349087608426800462 * 1e18, - depositEma: 40_022.159713346932216568 * 1e18 + depositEma: 40_020.333229328668210248 * 1e18 }); skip(1 days); @@ -867,13 +867,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { }); _assertPool( PoolParams({ - htp: 200.969526704670605713 * 1e18, + htp: 209.008307772857429942 * 1e18, lup: 327.188250324085203338 * 1e18, - poolSize: 40_047.419013400059920000 * 1e18, + poolSize: 40_045.592577350080602020 * 1e18, pledgedCollateral: 50_100 * 1e18, - encumberedCollateral: 58.370797186283932430 * 1e18, + encumberedCollateral: 60.705629073735289727 * 1e18, poolDebt: 19_098.239001402275530021 * 1e18, - actualUtilization: 0.476604475533389646 * 1e18, + actualUtilization: 0.476626217493207138 * 1e18, targetUtilization: 0.584103777552299209 * 1e18, // big col. deposit barely affects minDebtAmount: 954.911950070113776501 * 1e18, loans: 2, @@ -886,7 +886,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { debtColEma: 3_579_931.895052572545685861 * 1e18, // big col. deposit barely affects lupt0DebtEma: 6_128_931.249262523887589579 * 1e18, debtEma: 19_082.947567966496316465 * 1e18, - depositEma: 40_039.379711258283363568 * 1e18 + depositEma: 40_037.553259936788729400 * 1e18 }); } @@ -902,22 +902,22 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { borrower: _borrower3, amountToBorrow: 90_000_000_000_000_000 * 1e18, limitIndex: 5000, - collateralToPledge: 90_100_000 * 1e18 + collateralToPledge: 95_000_000 * 1e18 }); skip(100 days); - assertGt(MAX_PRICE, _htp()); + assertGt(MAX_PRICE, _getHtp()); uint256 expectedPoolDebt = 91329091841208027.611736396814389869 * 1e18; _assertPool( PoolParams({ - htp: 999850593.357807564705882353 * 1e18, + htp: 999_813_215.945856302275851081 * 1e18, lup: 999969141.897027226245329498 * 1e18, - poolSize: 100_000_000_000_000_000 * 1e18, - pledgedCollateral: 90_100_000 * 1e18, - encumberedCollateral: 91_331_910.170696775095411340 * 1e18, + poolSize: 99_995_433_789_954_337.9 * 1e18, + pledgedCollateral: 95_000_000 * 1e18, + encumberedCollateral: 94_985_186.577524646099227793 * 1e18, poolDebt: 91329091841208027.611736396814389869 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -996,11 +996,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // Assert that HTP < LUP, meaning on accual interest should accrue between HTP - LUP _assertPool( PoolParams({ - htp: 0.100096153846153846 * 1e18, + htp: 0.104100000000000000 * 1e18, lup: _p9_91, - poolSize: 104_000.00 * 1e18, + poolSize: 103_995.251141552511416 * 1e18, pledgedCollateral: 1_000 * 1e18, - encumberedCollateral: 10.093202398300210588 * 1e18, + encumberedCollateral: 10.496930494232219012 * 1e18, poolDebt: 100.096153846153846200 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -1026,10 +1026,10 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // Proof that interest accrued between HTP and LUP _assertBucket({ index: _i9_62, - lpBalance: 25_000.00 * 1e18, + lpBalance: 24_998.858447488584475 * 1e18, collateral: 0, - deposit: 25_000.396460350119775000 * 1e18, - exchangeRate: 1.000015858414004791 * 1e18 + deposit: 24_999.254907838704247316 * 1e18, + exchangeRate: 1.000015859138166351 * 1e18 }); vm.revertTo(snapshot); @@ -1042,7 +1042,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 9_500 * 1e18, + amount: 9_000 * 1e18, indexLimit: _i9_72, newLup: _p9_72 }); @@ -1063,15 +1063,15 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // Assert that HTP < LUP, meaning on accual interest should accrue between HTP - LUP _assertPool( PoolParams({ - htp: 9.509134615384615389 * 1e18, + htp: 9.369000000000000004 * 1e18, lup: 0.014854015662334135 * 1e18, - poolSize: 104_000.00 * 1e18, + poolSize: 103_995.251141552511416 * 1e18, pledgedCollateral: 10_001_000.0 * 1e18, - encumberedCollateral: 5_020_301.332014790293374287 * 1e18, - poolDebt: 74_571.634615384615419000 * 1e18, + encumberedCollateral: 5_186_072.355863869274873626 * 1e18, + poolDebt: 74_071.153846153846188000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, - minDebtAmount: 3_728.581730769230770950 * 1e18, + minDebtAmount: 3_703.557692307692309400 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -1084,9 +1084,9 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // Proof that no interest accrued since no actions have been called against the book _assertBucket({ index: 4_000, - lpBalance: 1_000.00 * 1e18, + lpBalance: 999.954337899543379 * 1e18, collateral: 0, - deposit: 1_000.00 * 1e18, + deposit: 999.954337899543379 * 1e18, exchangeRate: 1.0 * 1e18 }); @@ -1102,14 +1102,14 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // Proof that interest accrued between LUP and HTP _assertBucket({ index: 4_000, - lpBalance: 1000.00 * 1e18, + lpBalance: 999.954337899543379 * 1e18, collateral: 0, - deposit: 1_008.406484270040092000 * 1e18, - exchangeRate: 1.008406484270040092 * 1e18 + deposit: 1_008.304402812066423762 * 1e18, + exchangeRate: 1.008350446211436809 * 1e18 }); } - function testAccruePoolInterestRevertDueToExpLimit() external { + function testAccruePoolInterestInterestUpdateFailureDueToExpLimit() external tearDown { _mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18); @@ -1131,11 +1131,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.80076923076923077 * 1e18, + htp: 0.832800000000000001 * 1e18, lup: _p1505_26, - poolSize: 1_000_000_000 * 1e18, + poolSize: 999_954_337.899543379 * 1e18, pledgedCollateral: 1_000_000_000 * 1e18, - encumberedCollateral: 531_979.357254329691641573 * 1e18, + encumberedCollateral: 553_258.531544502879307236 * 1e18, poolDebt: 800_769_230.7692307696 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1161,13 +1161,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // confirm we hit 400% max rate _assertPool( PoolParams({ - htp: 0.897414066911426240 * 1e18, + htp: 0.933310629587883290 * 1e18, lup: _p1505_26, - poolSize: 1_088_327_685.946146186000000000 * 1e18, + poolSize: 1_088_282_545.280982499467572293 * 1e18, pledgedCollateral: 1_000_000_000 * 1e18, - encumberedCollateral: 596_183.944340533059305233 * 1e18, + encumberedCollateral: 620_031.302114154381677443 * 1e18, poolDebt: 897_414_066.911426239994562461 * 1e18, - actualUtilization: 0.822492351372651041 * 1e18, + actualUtilization: 0.822526771547753414 * 1e18, targetUtilization: 0.000573363809855153 * 1e18, minDebtAmount: 89_741_406.691142623999456246 * 1e18, loans: 1, @@ -1180,12 +1180,27 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // wait 32 years skip(365 days * 32); - // Reverts with PRBMathUD60x18__ExpInputTooBig - vm.expectRevert(); + // Interest update should fail + vm.expectEmit(true, true, false, true); + emit InterestUpdateFailure(); _updateInterest(); + + // repay all borrower debt based on last inflator + (uint256 inflator, ) = _pool.inflatorInfo(); + (uint256 debt, , ) = _pool.borrowerInfo(_borrower); + + _mintQuoteAndApproveTokens(_borrower, Maths.ceilWmul(inflator, debt)); + _repayDebt({ + from: _borrower, + borrower: _borrower, + amountToRepay: type(uint256).max, + amountRepaid: Maths.ceilWmul(inflator, debt), + collateralToPull: 0, + newLup: MAX_PRICE + }); } - function testAccrueInterestNewInterestLimit() external { + function testAccrueInterestInterestUpdateFailure() external tearDown { _mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18); @@ -1207,11 +1222,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.80076923076923077 * 1e18, + htp: 0.832800000000000001 * 1e18, lup: _p1505_26, - poolSize: 1_000_000_000 * 1e18, + poolSize: 999_954_337.899543379000000000 * 1e18, pledgedCollateral: 1_000_000_000 * 1e18, - encumberedCollateral: 531_979.357254329691641573 * 1e18, + encumberedCollateral: 553_258.531544502879307236 * 1e18, poolDebt: 800_769_230.7692307696 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1252,12 +1267,13 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { skip(13 hours); - // Revert with Arithmetic overflow in `Maths.wmul(pendingFactor - Maths.WAD, poolState_.debt)` in accrue interest - vm.expectRevert(); + // Interest update should fail + vm.expectEmit(true, true, false, true); + emit InterestUpdateFailure(); _updateInterest(); } - function testUpdateInterestZeroThresholdPrice() external { + function testUpdateInterestZeroDebtToCollateral() external { _mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18); @@ -1279,11 +1295,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.80076923076923077 * 1e18, + htp: 0.832800000000000001 * 1e18, lup: _p1505_26, - poolSize: 1_000_000_000 * 1e18, + poolSize: 999_954_337.899543379 * 1e18, pledgedCollateral: 1_000_000_000 * 1e18, - encumberedCollateral: 531_979.357254329691641573 * 1e18, + encumberedCollateral: 553_258.531544502879307236 * 1e18, poolDebt: 800_769_230.7692307696 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1302,14 +1318,14 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { skip(1 days); // check borrower collateralization and pledge more collateral if undercollateralized - (uint256 debt, uint256 collateralPledged, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 debt, uint256 collateralPledged, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); uint256 requiredCollateral = _requiredCollateral(debt, _lupIndex()); if (requiredCollateral > collateralPledged ) { uint256 collateralToPledge = requiredCollateral - collateralPledged; _mintCollateralAndApproveTokens(_borrower, collateralToPledge); - // Pledge collateral reverts with `ZeroThresholdPrice()` + // Pledge collateral reverts with `ZeroDebtToCollateral()` if (i == 103) { vm.expectRevert(); } @@ -1324,7 +1340,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { } } - function testUpdateInterestTuLimit() external { + function testTuLimitInterestUpdateFailure() external tearDown { _mintQuoteAndApproveTokens(_lender, 1_000_000_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, 1_000_000_000 * 1e18); @@ -1346,11 +1362,11 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.80076923076923077 * 1e18, + htp: 0.832800000000000001 * 1e18, lup: _p1505_26, - poolSize: 1_000_000_000 * 1e18, + poolSize: 999_954_337.899543379 * 1e18, pledgedCollateral: 1_000_000_000 * 1e18, - encumberedCollateral: 531_979.357254329691641573 * 1e18, + encumberedCollateral: 553_258.531544502879307236 * 1e18, poolDebt: 800_769_230.7692307696 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1371,7 +1387,7 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { // stop pledging more collateral to avoid t0Tp becoming 0, i = 103 is the limit where t0tp becomes 0 if (i < 100) { // check borrower collateralization and pledge more collateral if undercollateralized to avoid `(((tu + mau102 - 1e18) / 1e9) ** 2)` overflow - (uint256 debt, uint256 collateralPledged, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 debt, uint256 collateralPledged, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); (uint256 poolDebt,,,) = _pool.debtInfo(); uint256 lupIndex = _pool.depositIndex(poolDebt); uint256 requiredCollateral = _requiredCollateral(debt, lupIndex); @@ -1393,8 +1409,9 @@ contract ERC20PoolInterestRateTestAndEMAs is ERC20HelperContract { skip(1 days); - // Revert with Arithmetic overflow in `(((tu + mau102 - 1e18) / 1e9) ** 2)` in update interest - vm.expectRevert(); + // Interest update should fail + vm.expectEmit(true, true, false, true); + emit InterestUpdateFailure(); _updateInterest(); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol index f3ab8cbcd..ea8d69029 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol @@ -64,7 +64,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 18.55 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -88,15 +88,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.655275000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + encumberedCollateral: 856.520639388314730224 * 1e18, + poolDebt: 8_006.240913461538465230 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.312045673076923262 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -105,22 +105,22 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 18.567836538461538470 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 1.006837802655209676 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.217037273735858713 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.170228147822941070 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 11.02424679487179823 * 1e18, + claimableReserves : 11.024173798205131563 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -150,25 +150,25 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.823940596160099025 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993139541901194031 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.534277977147272573 * 1e18, + debt: 18.823940596160099024 * 1e18, collateral: 2 * 1e18, - bond: 0.296536979149981005 * 1e18, - transferAmount: 0.296536979149981005 * 1e18 + bond: 0.210458053887159482 * 1e18, + transferAmount: 0.210458053887159482 * 1e18 }); _assertAuction( @@ -176,25 +176,35 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 2_879.954914386826585856 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767138988573636287 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 2_786.004733495419094016 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.296536979149981005 * 1e18 + locked: 0.210458053887159482 * 1e18 }); } 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({ @@ -206,44 +216,34 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758 * 1e18, depositTime: _startTime }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758 * 1e18, collateral: 0, - deposit: 2_010.430334387621616000 * 1e18, - exchangeRate: 1.005215167193810808 * 1e18 + deposit: 2_010.338097446880098916 * 1e18, + exchangeRate: 1.005214948949419476 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534930245606410328 * 1e18, + borrowerDebt: 18.824569145766177224 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995273158676181149 * 1e18 - }); - - // add liquidity to accrue interest and update reserves before arb take - _addLiquidityWithPenalty({ - from: _lender1, - amount: 1 * 1e18, - amountAdded: 0.999876712328767123 * 1e18, - index: _i9_52, - lpAward: 0.999873539625283938 * 1e18, - newLup: 9.721295865031779605 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993106381117379594 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758 * 1e18, collateral: 0, - deposit: 2_010.436713693675662000 * 1e18, - exchangeRate: 1.005218356846837831 * 1e18 + deposit: 2_010.338097446880098916 * 1e18, + exchangeRate: 1.005214948949419476 * 1e18 }); _assertReserveAuction({ - reserves: 24.296647707318004711 * 1e18, - claimableReserves : 0, + reserves: 27.588663449022222983 * 1e18, + claimableReserves : 27.588590357490802582 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -254,23 +254,23 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, // should be the same after arb take, kicker will be rewarded with LP - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, // should be the same after arb take, kicker will be rewarded with LP + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 9.459936576563284516 * 1e18, - debtInAuction: 19.534930245606410328 * 1e18, - thresholdPrice: 9.767465122803205164 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 9.151333567485071268 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534930245606410328 * 1e18, + borrowerDebt: 18.824569145766177224 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995273158676181149 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993106381117379594 * 1e18 }); // Amount is restricted by the collateral in the loan @@ -280,43 +280,43 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { kicker: _lender, index: _i9_91, collateralArbed: 2 * 1e18, - quoteTokenAmount: 18.919873153126569032 * 1e18, - bondChange: 0.287210105092827748 * 1e18, + quoteTokenAmount: 18.302667134970142536 * 1e18, + bondChange: 0.134343252311202302 * 1e18, isReward: true, - lpAwardTaker: 0.909749138101538138 * 1e18, - lpAwardKicker: 0.285719120762723106 * 1e18 + lpAwardTaker: 1.523751406140849351 * 1e18, + lpAwardKicker: 0.133645869663517583 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i9_91, - lpBalance: 0.909749138101538138 * 1e18, + lpBalance: 1.523751406140849351 * 1e18, depositTime: _startTime + 100 days + 6.5 hours }); _assertLenderLpBalance({ lender: _lender, index: _i9_91, - lpBalance: 2_000.285719120762723106 * 1e18, // rewarded with LP in bucket + lpBalance: 2_000.042321668750275583 * 1e18, // rewarded with LP in bucket depositTime: _startTime + 100 days + 6.5 hours }); _assertBucket({ index: _i9_91, - lpBalance: 2_001.195468258864261244 * 1e18, + lpBalance: 2_001.566073074891124934 * 1e18, collateral: 2 * 1e18, - deposit: 1_991.804050645641920716 * 1e18, - exchangeRate: 1.005218356846837832 * 1e18 + deposit: 1_992.176152221875865791 * 1e18, + exchangeRate: 1.005218138423884933 * 1e18 }); // reserves should remain the same after arb take _assertReserveAuction({ - reserves: 24.296647707318004709 * 1e18, - claimableReserves : 0, + reserves: 27.715631254749296954 * 1e18, + claimableReserves : 27.715558181154286283 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 0.902267197572669045 * 1e18, + borrowerDebt: 0.744103746989137588 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -326,15 +326,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, // bond size remains the same, kicker was rewarded with LP - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, // bond size remains the same, kicker was rewarded with LP + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 9.459936576563284516 * 1e18, - debtInAuction: 0.902267197572669045 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 9.151333567485071268 * 1e18, + debtInAuction: 0.744103746989137588 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); @@ -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( @@ -354,32 +362,24 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 15.909653511519124956 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767389860091370755 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 15.390647183378366864 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); - _addLiquidity({ - from: _lender, - amount: 25_000 * 1e18, - index: _i1505_26, - lpAward: 25_000 * 1e18, - newLup: 1_505.263728469068226832 * 1e18 - }); - _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534779720182741511 * 1e18, + borrowerDebt: 18.824424093994278183 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 154.111154569495900146 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 153.775644073335900060 * 1e18 }); // Amount is restricted by the debt in the loan @@ -388,43 +388,43 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 1.256467421916368415 * 1e18, - quoteTokenAmount: 19.989961331201132696 * 1e18, - bondChange: 0.296536979149981005 * 1e18, + collateralArbed: 1.243970037659931995 * 1e18, + quoteTokenAmount: 19.145503956317913312 * 1e18, + bondChange: 0.210458053887159482 * 1e18, isReward: false, - lpAwardTaker: 1_871.324874882549437558 * 1e18, + lpAwardTaker: 1_853.354102351073019651 * 1e18, lpAwardKicker: 0 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 0.743532578083631585 * 1e18, + borrowerCollateral: 0.756029962340068005 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_871.324874882549437558 * 1e18, + lpBalance: 1_853.354102351073019651 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ lender: _lender, index: _i1505_26, - lpBalance: 25_000 * 1e18, - depositTime: block.timestamp + lpBalance: 24_998.972602739726025 * 1e18, + depositTime: block.timestamp - 5 hours }); _assertBucket({ index: _i1505_26, - lpBalance: 26_871.324874882549437558 * 1e18, - collateral: 1.256467421916368415 * 1e18, - deposit: 24_980.010038668798867303 * 1e18, - exchangeRate: 1.000000000000000000 * 1e18 + lpBalance: 26_852.326705090799044651 * 1e18, + collateral: 1.243970037659931995 * 1e18, + deposit: 24_979.872564270547957318 * 1e18, + exchangeRate: 1.000001818694226453 * 1e18 }); _assertReserveAuction({ - reserves: 25.039216891441214202 * 1e18, - claimableReserves : 0, + reserves: 29.177641507437069649 * 1e18, + claimableReserves : 29.177543436900114554 * 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( @@ -439,32 +447,24 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 15.909653511519124956 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767389860091370755 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 15.390647183378366864 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 15.0 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534779720182741511 * 1e18, + borrowerDebt: 18.824424093994278183 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995280827762601466 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993114033507675628 * 1e18 }); // Amount is restricted by the deposit in the bucket @@ -473,11 +473,11 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.942823801231088711 * 1e18, - quoteTokenAmount: 14.999999999999999998 * 1e18, - bondChange: 0.227705098312484220 * 1e18, + collateralArbed: 0.974580209979236584 * 1e18, + quoteTokenAmount: 14.999420163693234878 * 1e18, + bondChange: 0.167698615545495474 * 1e18, isReward: false, - lpAwardTaker: 1_404.198470330488271279 * 1e18, + lpAwardTaker: 1_451.997277184470359043 * 1e18, lpAwardKicker: 0 }); @@ -486,73 +486,73 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.068831880837496785 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.042759438341664008 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.068831880837496785 * 1e18, - auctionPrice: 15.909653511519124956 * 1e18, - debtInAuction: 4.876337367651467845 * 1e18, - thresholdPrice: 4.612606085276981381 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.042759438341664008 * 1e18, + auctionPrice: 15.390647183378366864 * 1e18, + debtInAuction: 4.076551853619286517 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); _assertBucket({ index: _i1505_26, - lpBalance: 1_419.198470330488271279 * 1e18, - collateral: 0.942823801231088711 * 1e18, - deposit: 0.000000000000000003 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 1_466.996660746114194658 * 1e18, + collateral: 0.974580209979236584 * 1e18, + deposit: 0.000000000000000015 * 1e18, + exchangeRate: 1.000002440236910328 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4.876337367651467845 * 1e18, - borrowerCollateral: 1.057176198768911289 * 1e18, - borrowert0Np: 5.240398686048708221 * 1e18, - borrowerCollateralization: 2.107549546895251001 * 1e18 + borrowerDebt: 4.076551853619286517 * 1e18, + borrowerCollateral: 1.025419790020763416 * 1e18, + borrowert0Np: 4.534111736408620697 * 1e18, + borrowerCollateralization: 2.351253990220725286 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_404.198470330488271279 * 1e18, + lpBalance: 1_451.997277184470359043 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ lender: _lender, index: _i1505_26, - lpBalance: 15.0 * 1e18, - depositTime: block.timestamp + lpBalance: 14.999383561643835615 * 1e18, + depositTime: block.timestamp - 5 hours }); } function testArbTakeGTNeutralPrice() external tearDown { - skip(3 hours); - _addLiquidity({ from: _lender, amount: 1_000 * 1e18, - index: _i10016, - lpAward: 1_000 * 1e18, + 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, - lpBalance: 1_000 * 1e18, - depositTime: block.timestamp + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, + depositTime: block.timestamp - 3 hours }); _assertBucket({ - index: _i10016, - lpBalance: 1_000 * 1e18, + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, collateral: 0, - deposit: 1_000 * 1e18, + deposit: 999.958904109589041 * 1e18, exchangeRate: 1.0 * 1e18 }); _assertAuction( @@ -560,49 +560,49 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 31.819307023038249912 * 1e18, - debtInAuction: 19.534579021422084350 * 1e18, - thresholdPrice: 9.767289510711042175 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 30.781294366756733728 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534579021422084350 * 1e18, + borrowerDebt: 18.824230693370372191 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995291053303086302 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993124236786461296 * 1e18 }); _arbTake({ from: _taker, borrower: _borrower, kicker: _lender, - index: _i10016, - collateralArbed: 0.628227256535406044 * 1e18, - quoteTokenAmount: 19.989755955941097815 * 1e18, - bondChange: 0.296536979149981005 * 1e18, + index: _i100_33, + collateralArbed: 0.621978628605749775 * 1e18, + quoteTokenAmount: 19.145307256945244190 * 1e18, + bondChange: 0.210458053887159482 * 1e18, isReward: false, - lpAwardTaker: 6_272.649557567888341455 * 1e18, + lpAwardTaker: 43.259218990266946936 * 1e18, lpAwardKicker: 0 }); _assertLenderLpBalance({ lender: _taker, - index: _i10016, - lpBalance: 6_272.649557567888341455 * 1e18, // arb taker was rewarded LPBs in arbed bucket + index: _i100_33, + lpBalance: 43.259218990266946936 * 1e18, // arb taker was rewarded LPBs in arbed bucket depositTime: _startTime + 100 days + 3 hours }); _assertLenderLpBalance({ lender: _lender, - index: _i10016, - lpBalance: 1_000 * 1e18, - depositTime: _startTime + 100 days + 3 hours + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, + 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_272.649557567888341455 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker - collateral: 0.628227256535406044 * 1e18, // arbed collateral added to the arbed bucket - deposit: 980.010244044058902179 * 1e18, // quote token amount is diminished in arbed bucket - exchangeRate: 1.000000000000000001 * 1e18 + index: _i100_33, + lpBalance: 1_043.218123099855987936 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker + collateral: 0.621978628605749775 * 1e18, // arbed collateral added to the arbed bucket + deposit: 980.815041463682283937 * 1e18, // quote token amount is diminished in arbed bucket + exchangeRate: 1.000001444670408504 * 1e18 }); _assertAuction( AuctionParams({ @@ -628,14 +628,14 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.371772743464593956 * 1e18, + borrowerCollateral: 1.378021371394250225 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -663,23 +663,23 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.210458053887159482 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 2.5 hours, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 37.839746306253138192 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767264423527051292 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.882830990216480836 * 1e18, + totalBondEscrowed: 0.210458053887159482 * 1e18, + auctionPrice: 36.605334269940285200 * 1e18, + debtInAuction: 18.823940596160099025 * 1e18, + debtToCollateral: 9.411970298080049512 * 1e18, + neutralPrice: 10.882830990216480836 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534528847054102585 * 1e18, + borrowerDebt: 18.824182343524862490 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995293609704622699 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.993126787622537163 * 1e18 }); // borrower cannot repay amidst auction diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol index 3a5f7a027..39ac2fe35 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol @@ -66,7 +66,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 18.55 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -90,15 +90,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.655275000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + encumberedCollateral: 856.520639388314730224 * 1e18, + poolDebt: 8_006.24091346153846523 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.312045673076923262 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -107,21 +107,21 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 18.567836538461538470 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 1.006837802655209676 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.217037273735858713 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.170228147822941070 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 11.024246794871798230 * 1e18, + claimableReserves : 11.024173798205131563 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -133,7 +133,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertDepositTakeNoAuctionRevert({ from: _lender, borrower: _borrower, - index: _i9_91 + index: _i9_62 }); // Skip to make borrower undercollateralized @@ -151,25 +151,25 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.969909752188970169 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.939819504377940339 * 1e18, + borrowerDebt: 19.214735158764197054 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.975063576969429891 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.972940797048596589 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.939819504377940339 * 1e18, + debt: 19.214735158764197053 * 1e18, collateral: 2 * 1e18, - bond: 0.302693237371837952 * 1e18, - transferAmount: 0.302693237371837952 * 1e18 + bond: 0.214827269923259784 * 1e18, + transferAmount: 0.214827269923259784 * 1e18 }); _assertAuction( @@ -177,74 +177,73 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 2_939.744240396328951808 * 1e18, - debtInAuction: 19.939819504377940339 * 1e18, - thresholdPrice: 9.969909752188970169 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 2_843.843606056533345792 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.302693237371837952 * 1e18 + locked: 0.214827269923259784 * 1e18 }); } 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({ lender: _taker, - index: _i9_91, + index: _i9_62, lpBalance: 0, depositTime: 0 }); _assertLenderLpBalance({ lender: _lender, - index: _i9_91, - lpBalance: 2_000 * 1e18, + index: _i9_62, + lpBalance: 24_998.858447488584475 * 1e18, depositTime: _startTime }); _assertBucket({ - index: _i9_91, - lpBalance: 2_000 * 1e18, + index: _i9_62, + lpBalance: 24_998.858447488584475 * 1e18, collateral: 0, - deposit: 2_026.346200779800152000 * 1e18, - exchangeRate: 1.013173100389900076 * 1e18 + deposit: 24_998.858447488584475000 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.940485314261408832 * 1e18, + borrowerDebt: 19.215376757379175783 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.975031019739436493 * 1e18 - }); - - // add liquidity to accrue interest and update reserves before deposit take - _addLiquidityWithPenalty({ - from: _lender1, - amount: 1 * 1e18, - amountAdded: 0.999876712328767123 * 1e18, - index: _i9_52, - lpAward: 0.999873480092787187 * 1e18, - newLup: 9.721295865031779605 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.972908310697913772 * 1e18 }); _assertBucket({ - index: _i9_91, - lpBalance: 2_000 * 1e18, + index: _i9_62, + lpBalance: 24_998.858447488584475 * 1e18, collateral: 0, - deposit: 2_026.352751237661440000 * 1e18, - exchangeRate: 1.013176375618830720 * 1e18 + deposit: 24_998.858447488584475000 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); _assertReserveAuction({ - reserves: 49.575600446873147197 * 1e18, - claimableReserves : 8.144637039662123068 * 1e18, + reserves: 52.864592144847100955 * 1e18, + claimableReserves : 52.864518910085417944 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -255,23 +254,23 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 9.656329662156355672 * 1e18, - debtInAuction: 19.940485314261408832 * 1e18, - thresholdPrice: 9.970242657130704416 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 9.341319897949748632 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.940485314261408832 * 1e18, + borrowerDebt: 19.215376757379175783 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.975031019739436493 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.972908310697913772 * 1e18 }); // Amount is restricted by the collateral in the loan @@ -279,38 +278,38 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { from: _taker, borrower: _borrower, kicker: _lender, - index: _i9_91, + index: _i9_62, collateralArbed: 2 * 1e18, - quoteTokenAmount: 19.834369686871824148 * 1e18, - bondChange: 0.301092473301020371 * 1e18, + quoteTokenAmount: 19.249614346242478674 * 1e18, + bondChange: 0.212717357770326637 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 0.297176760677150868 * 1e18 + lpAwardKicker: 0.212716670171123034 * 1e18 }); _assertLenderLpBalance({ lender: _taker, - index: _i9_91, + index: _i9_62, lpBalance: 0, depositTime: 0 }); _assertLenderLpBalance({ lender: _lender, - index: _i9_91, - lpBalance: 2_000.297176760677150868 * 1e18, + index: _i9_62, + lpBalance: 24_999.071164158755598034 * 1e18, depositTime: _startTime + 250 days + 6.5 hours }); _assertBucket({ - index: _i9_91, - lpBalance: 2_000.297176760677150868 * 1e18, + index: _i9_62, + lpBalance: 24_999.071164158755598034 * 1e18, collateral: 2 * 1e18, - deposit: 2_006.819474024090636225 * 1e18, - exchangeRate: 1.013176375618830721 * 1e18 + deposit: 24_979.902358436536042836 * 1e18, + exchangeRate: 1.000003232465058094 * 1e18 }); // reserves should remain the same after deposit take _assertReserveAuction({ - reserves: 49.575600446873147192 * 1e18, - claimableReserves : 8.242303445263254296 * 1e18, + reserves: 52.907638237722207634 * 1e18, + claimableReserves : 52.907565021760692804 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -320,20 +319,20 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 9.656329662156355672 * 1e18, - debtInAuction: 0.407208100690605057 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 9.341319897949748632 * 1e18, + debtInAuction: 0.181604610561948914 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 0.407208100690605057 * 1e18, + borrowerDebt: 0.181604610561948914 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -343,11 +342,19 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertDepositTakeInsufficentCollateralRevert({ from: _taker, borrower: _borrower, - index: _i9_91 + index: _i9_62 }); } 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( @@ -355,38 +362,30 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 16.239945994830783896 * 1e18, - debtInAuction: 19.939819504377940339 * 1e18, - thresholdPrice: 9.970165831926765787 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 15.710164831848276420 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); - _addLiquidity({ - from: _lender, - amount: 25_000 * 1e18, - index: _i1505_26, - lpAward: 25_000 * 1e18, - newLup: 1_505.263728469068226832 * 1e18 - }); - _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.940331663853531575 * 1e18, + borrowerDebt: 19.215228694258857699 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 150.976799568254654687 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 150.648112776741761951 * 1e18 }); _assertBucket({ index: _i1505_26, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.972602739726025 * 1e18, collateral: 0.0 * 1e18, - deposit: 25_000 * 1e18, + deposit: 24_998.972602739726025 * 1e18, exchangeRate: 1.0 * 1e18 }); @@ -396,9 +395,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.013555739562620698 * 1e18, - quoteTokenAmount: 20.404963076186087933 * 1e18, - bondChange: 0.302693237371837952 * 1e18, + collateralArbed: 0.012983089918332295 * 1e18, + quoteTokenAmount: 19.542974337518040881 * 1e18, + bondChange: 0.214827269923259784 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -407,7 +406,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.986444260437379302 * 1e18, + borrowerCollateral: 1.987016910081667705 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -420,19 +419,19 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i1505_26, - lpBalance: 25_000 * 1e18, - depositTime: block.timestamp + lpBalance: 24_998.972602739726025 * 1e18, + depositTime: block.timestamp - 5 hours }); _assertBucket({ index: _i1505_26, - lpBalance: 25_000 * 1e18, - collateral: 0.013555739562620698 * 1e18, - deposit: 24_979.595036923813911959 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 24_998.972602739726025 * 1e18, + collateral: 0.012983089918332295 * 1e18, + deposit: 24_979.475970107797282691 * 1e18, + exchangeRate: 1.000001853744404849 * 1e18 }); _assertReserveAuction({ - reserves: 50.333588303732929197 * 1e18, - claimableReserves : 9.002620819943559986 * 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( @@ -447,32 +454,24 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 16.239945994830783896 * 1e18, - debtInAuction: 19.939819504377940339 * 1e18, - thresholdPrice: 9.970165831926765787 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 15.710164831848276420 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 15.0 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.940331663853531575 * 1e18, + borrowerDebt: 19.215228694258857699 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.975038532849870233 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.972915807451793593 * 1e18 }); // Amount is restricted by the deposit in the bucket in the loan @@ -481,9 +480,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.009965031187761219 * 1e18, - quoteTokenAmount: 14.999999999999999995 * 1e18, - bondChange: 0.227705098312484220 * 1e18, + collateralArbed: 0.009964646438247887 * 1e18, + quoteTokenAmount: 14.999420850513035210 * 1e18, + bondChange: 0.167698623224374284 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -494,30 +493,30 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.074988139059353732 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.047128646698885500 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.074988139059353732 * 1e18, - auctionPrice: 16.239945994830783896 * 1e18, - debtInAuction: 5.281889311322257910 * 1e18, - thresholdPrice: 2.654169094563588010 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.047128646698885500 * 1e18, + auctionPrice: 15.710164831848276420 * 1e18, + debtInAuction: 4.467355778582383914 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); _assertBucket({ index: _i1505_26, - lpBalance: 15 * 1e18, - collateral: 0.009965031187761219 * 1e18, - deposit: 0.000000000000000005 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 14.999383561643835615 * 1e18, + collateral: 0.009964646438247887 * 1e18, + deposit: 0.000000000000000931 * 1e18, + exchangeRate: 1.000002486026778853 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5.281889311322257910 * 1e18, - borrowerCollateral: 1.990034968812238781 * 1e18, - borrowert0Np: 2.954082977863112822 * 1e18, - borrowerCollateralization: 3.662651292618643252 * 1e18 + borrowerDebt: 4.467355778582383914 * 1e18, + borrowerCollateral: 1.990035353561752113 * 1e18, + borrowert0Np: 2.508226963507480943 * 1e18, + borrowerCollateralization: 4.163907494183249766 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -528,39 +527,39 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i1505_26, - lpBalance: 15.0 * 1e18, - depositTime: block.timestamp + lpBalance: 14.999383561643835615 * 1e18, + depositTime: block.timestamp - 5 hours }); } function testDepositTakeGTNeutralPrice() external tearDown { - skip(3 hours); - _addLiquidity({ from: _lender, amount: 1_000 * 1e18, - index: _i10016, - lpAward: 1_000 * 1e18, + 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, - lpBalance: 1_000 * 1e18, - depositTime: block.timestamp + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, + depositTime: block.timestamp - 3 hours }); _assertBucket({ - index: _i10016, - lpBalance: 1_000 * 1e18, + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, collateral: 0, - deposit: 1_000 * 1e18, + deposit: 999.958904109589041 * 1e18, exchangeRate: 1.0 * 1e18 }); _assertAuction( @@ -568,33 +567,33 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 32.479891989661567792 * 1e18, - debtInAuction: 19.940126798484719991 * 1e18, - thresholdPrice: 9.970063399242359995 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 31.420329663696552836 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.940126798484719991 * 1e18, + borrowerDebt: 19.215031278539821082 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.975048550420503383 * 1e18 + borrowert0Np: 10.734767562072714095 * 1e18, + borrowerCollateralization: 0.972925803213492128 * 1e18 }); _depositTake({ from: _taker, borrower: _borrower, kicker: _lender, - index: _i10016, - collateralArbed: 0.002037113782225481 * 1e18, - quoteTokenAmount: 20.404753437231397559 * 1e18, - bondChange: 0.302693237371837952 * 1e18, + index: _i100_33, + collateralArbed: 0.194780347720468645 * 1e18, + quoteTokenAmount: 19.542773554566540930 * 1e18, + bondChange: 0.214827269923259784 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -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, - lpBalance: 1_000 * 1e18, - depositTime: _startTime + 250 days + 3 hours + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, + depositTime: _startTime + 250 days }); _assertKicker({ kicker: _lender, @@ -619,11 +618,11 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { locked: 0 // kicker was penalized }); _assertBucket({ - index: _i10016, - lpBalance: 1_000 * 1e18, // LP balance in arbed bucket increased with LP awarded for deposit taker - collateral: 0.002037113782225481 * 1e18, // arbed collateral added to the arbed bucket - deposit: 979.595246562768594325 * 1e18, // quote token amount is diminished in arbed bucket - exchangeRate: 1.000000000000000001 * 1e18 + index: _i100_33, + lpBalance: 999.958904109589041 * 1e18, // LP balance in arbed bucket is same + 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({ @@ -637,14 +636,14 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.997962886217774519 * 1e18, + borrowerCollateral: 1.805219652279531355 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -665,15 +664,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.302693237371837952 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.214827269923259784 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 2.5 hours, - referencePrice: 11.483375939048159968 * 1e18, - totalBondEscrowed: 0.302693237371837952 * 1e18, - auctionPrice: 38.625318648625422832 * 1e18, - debtInAuction: 19.939819504377940339 * 1e18, - thresholdPrice: 9.970037791235694161 * 1e18, - neutralPrice: 11.483375939048159968 * 1e18 + referencePrice: 11.108764086158333382 * 1e18, + totalBondEscrowed: 0.214827269923259784 * 1e18, + auctionPrice: 37.365279591798994668 * 1e18, + debtInAuction: 19.214735158764197054 * 1e18, + debtToCollateral: 9.607367579382098527 * 1e18, + neutralPrice: 11.108764086158333382 * 1e18 }) ); @@ -688,7 +687,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertDepositTakeAuctionPriceGreaterThanBucketPriceRevert({ from: _taker, borrower: _borrower, - index: _i9_91 + index: _i9_62 }); skip(4 hours); @@ -702,7 +701,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertDepositTakeDebtUnderMinPoolDebtRevert({ from: _taker, borrower: _borrower, - index: _i9_91 + index: _i9_62 }); } } @@ -762,13 +761,13 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { active: true, kicker: actor1, bondSize: 13_799_909_500.935435603423349661 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, referencePrice: 3_137.845063437099084063 * 1e18, totalBondEscrowed: 13_799_909_500.935435603423349661 * 1e18, auctionPrice: 0, debtInAuction: 920_341_611_662.285708998644615657 * 1e18, - thresholdPrice: 2_758.083788017359002804 * 1e18, + debtToCollateral: 2_758.083788017359002804 * 1e18, neutralPrice: 3_137.845063437099084063 * 1e18 // was 2_860.503207254858101199 }) ); @@ -790,13 +789,13 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { active: true, kicker: actor1, bondSize: 13_799_909_500.935435603423349661 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, referencePrice: 3_137.845063437099084063 * 1e18, totalBondEscrowed: 13_799_909_500.935435603423349661 * 1e18, auctionPrice: 0, debtInAuction: 33_716_280_531.11637887639485531 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 3_137.845063437099084063 * 1e18 // was 2_860.503207254858101199 }) ); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol index 689ff75c1..8a7a3fd33 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol @@ -68,7 +68,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -92,15 +92,15 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.707325000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + encumberedCollateral: 856.531347837213447051 * 1e18, + poolDebt: 8_006.341009615384619076 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.317050480769230954 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -109,21 +109,21 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 18.667932692307692316 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 1.001439208539095951 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.217037273735858713 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.170228147822941070 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 11.024342948717952076 * 1e18, + claimableReserves : 11.024269952051285409 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -149,16 +149,16 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.925417364872552389 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.987814396904404787 * 1e18 }); // should revert if NP goes below limit @@ -170,10 +170,10 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 19.534277977147272573 * 1e18, + debt: 18.925417364872552388 * 1e18, collateral: 2 * 1e18, - bond: 0.296536979149981005 * 1e18, - transferAmount: 0.296536979149981005 * 1e18 + bond: 0.211592598652049829 * 1e18, + transferAmount: 0.211592598652049829 * 1e18 }); /******************************/ @@ -182,15 +182,15 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 8.097846143253778448 * 1e18, + htp: 8.421759988983929586 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_093.873009488594544000 * 1e18, + poolSize: 73_090.532635019443083793 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 835.010119425512354679 * 1e18, - poolDebt: 8_117.380421230925720814 * 1e18, - actualUtilization: 0.109684131322444679 * 1e18, - targetUtilization: 0.822075127292417292 * 1e18, - minDebtAmount: 811.738042123092572081* 1e18, + encumberedCollateral: 868.345387306633668354 * 1e18, + poolDebt: 8_116.771560618651000629 * 1e18, + actualUtilization: 0.109680912502151486 * 1e18, + targetUtilization: 0.821990428412900408 * 1e18, + minDebtAmount: 811.677156061865100063 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -199,45 +199,45 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.925417364872552389 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.987814396904404787 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 8_097.846143253778448241 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.200479200648987171 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.154306923700949203 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.703463020850018995 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.788407401347950171 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.211592598652049829 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 2_879.954914386826585856 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767138988573636287 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.941498542724386393 * 1e18, + totalBondEscrowed: 0.211592598652049829 * 1e18, + auctionPrice: 2_801.023626937442916608 * 1e18, + debtInAuction: 18.925417364872552389 * 1e18, + debtToCollateral: 9.462708682436276194 * 1e18, + neutralPrice: 10.941498542724386393 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.296536979149981005 * 1e18 + locked: 0.211592598652049829 * 1e18 }); _assertReserveAuction({ - reserves: 24.257411742331176814 * 1e18, - claimableReserves : 0, + reserves: 27.588925599207916836 * 1e18, + claimableReserves : 27.588852508675281817 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -286,25 +286,25 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.925417364872552389 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.987814396904404787 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.534277977147272573 * 1e18, + debt: 18.925417364872552388 * 1e18, collateral: 2 * 1e18, - bond: 0.296536979149981005 * 1e18, - transferAmount: 0.296536979149981005 * 1e18 + bond: 0.211592598652049829 * 1e18, + transferAmount: 0.211592598652049829 * 1e18 }); _assertAuction( @@ -312,15 +312,15 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.296536979149981005 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.211592598652049829 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.249823884323541351 * 1e18, - totalBondEscrowed: 0.296536979149981005 * 1e18, - auctionPrice: 2_879.954914386826585856 * 1e18, - debtInAuction: 19.534277977147272574 * 1e18, - thresholdPrice: 9.767138988573636287 * 1e18, - neutralPrice: 11.249823884323541351 * 1e18 + referencePrice: 10.941498542724386393 * 1e18, + totalBondEscrowed: 0.211592598652049829 * 1e18, + auctionPrice: 2_801.023626937442916608 * 1e18, + debtInAuction: 18.925417364872552389 * 1e18, + debtToCollateral: 9.462708682436276194 * 1e18, + neutralPrice: 10.941498542724386393 * 1e18 }) ); @@ -353,25 +353,25 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.925417364872552389 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.987814396904404787 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.534277977147272573 * 1e18, + debt: 18.925417364872552388 * 1e18, collateral: 2 * 1e18, - bond: 0.296536979149981005 * 1e18, - transferAmount: 0.296536979149981005 * 1e18 + bond: 0.211592598652049829 * 1e18, + transferAmount: 0.211592598652049829 * 1e18 }); // skip enough time to take collateral close to 0 price @@ -381,14 +381,14 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, maxCollateral: 2 * 1e18, bondChange: 0, - givenAmount: 18, + givenAmount: 16, collateralTaken: 2 * 1e18, isReward: true }); // entire borrower collateral is taken but auction not settled as there's still bad debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.541303552517827759 * 1e18, + borrowerDebt: 18.932223961270518842 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -405,7 +405,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { // Borrower2 borrows _borrow({ from: _borrower2, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -415,65 +415,65 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, + borrowerDebt: 18.925417364872552389 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.987814396904404787 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); _assertLoans({ - noOfLoans: 2, - maxBorrower: _borrower2, - maxThresholdPrice: 9.719336538461538466 * 1e18 + noOfLoans: 2, + maxBorrower: _borrower, + maxT0DebtToCollateral: 9.333966346153846158 * 1e18 }); // kick first loan _kick({ from: _lender, borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); _assertLoans({ - noOfLoans: 1, - maxBorrower: _borrower, - maxThresholdPrice: 9.767138988573636287 * 1e18 + noOfLoans: 1, + maxBorrower: _borrower, + maxT0DebtToCollateral: 9.333966346153846158 * 1e18 }); // kick 2nd loan _kick({ from: _lender, borrower: _borrower, - debt: 19.534277977147272573 * 1e18, + debt: 18.925417364872552388 * 1e18, collateral: 2 * 1e18, - bond: 0.296536979149981005 * 1e18, - transferAmount: 0.296536979149981005 * 1e18 + bond: 0.211592598652049829 * 1e18, + transferAmount: 0.211592598652049829 * 1e18 }); _assertLoans({ - noOfLoans: 0, - maxBorrower: address(0), - maxThresholdPrice: 0 + noOfLoans: 0, + maxBorrower: address(0), + maxT0DebtToCollateral: 0 }); _assertPool( PoolParams({ htp: 0, lup: 9.721295865031779605 * 1e18, - poolSize: 73_114.174951097528944000 * 1e18, + poolSize: 73_105.788429292052758482 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_015.597987863945504486 * 1e18, - poolDebt: 9_872.928519956368918240 * 1e18, - actualUtilization: 0.541033613782051282 * 1e18, - targetUtilization: 0.999781133426980224 * 1e18, + encumberedCollateral: 1_009.475328421524777337 * 1e18, + poolDebt: 9_435.969553880544732799 * 1e18, + actualUtilization: 0.517112001843252414 * 1e18, + targetUtilization: 0.955532425687922567 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), @@ -485,24 +485,22 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { // force pool interest accumulation skip(14 hours); - _addLiquidity({ + _addCollateralWithoutCheckingLP({ from: _lender1, amount: 1 * 1e18, - index: _i9_91, - lpAward: 0.993688394051845486 * 1e18, - newLup: 9.721295865031779605 * 1e18 + index: _i9_91 }); _assertPool( PoolParams({ htp: 0, lup: 9.721295865031779605 * 1e18, - poolSize: 73_115.802858058164606426 * 1e18, + poolSize: 73_106.387204998685760269 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_015.671030071750751166 * 1e18, - poolDebt: 9_873.638584869078854771 * 1e18, - actualUtilization: 0.100677654461506314 * 1e18, - targetUtilization: 0.999781133426980224 * 1e18, + encumberedCollateral: 1_009.547930285248351849 * 1e18, + poolDebt: 9_436.648192532092411327 * 1e18, + actualUtilization: 0.095694819083490222 * 1e18, + targetUtilization: 0.955532425687922567 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), @@ -529,6 +527,7 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { totalPoolLiquidity = bound(totalPoolLiquidity, 100 * 1e18, 1_000_000_000 * 1e18); startingBucket = bound(startingBucket, 1, 7300); noOfBuckets = bound(noOfBuckets, 5, 10); + uint256 poolRate = 0.05 * 1e18; _mintQuoteAndApproveTokens(_lender, totalPoolLiquidity); @@ -538,15 +537,15 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { from: _lender, amount: totalPoolLiquidity / noOfBuckets, index: startingBucket + i, - lpAward: totalPoolLiquidity / noOfBuckets, + lpAward: Maths.wmul(totalPoolLiquidity / noOfBuckets, Maths.WAD - _depositFeeRate(poolRate)), newLup: MAX_PRICE }); _assertBucket({ index: startingBucket + i, - lpBalance: totalPoolLiquidity / noOfBuckets, + lpBalance: Maths.wmul(totalPoolLiquidity / noOfBuckets, Maths.WAD - _depositFeeRate(poolRate)), collateral: 0, - deposit: totalPoolLiquidity / noOfBuckets, + deposit: Maths.wmul(totalPoolLiquidity / noOfBuckets, Maths.WAD - _depositFeeRate(poolRate)), exchangeRate: 1 * 1e18 }); } @@ -566,7 +565,7 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { (uint256 poolDebt, , , ) = _pool.debtInfo(); uint256 depositIndex = _pool.depositIndex(amountToBorrow + poolDebt); uint256 price = _poolUtils.indexToPrice(depositIndex); - uint256 collateralToPledge = Maths.wdiv(amountToBorrow, price) * 101 / 100 + 1; + uint256 collateralToPledge = Maths.wdiv(Maths.wmul(amountToBorrow, COLLATERALIZATION_FACTOR), price) * 101 / 100 + 1; _mintCollateralAndApproveTokens(_borrowers[i], collateralToPledge); @@ -580,7 +579,7 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { uint256 borrowerDebt = Maths.wmul(amountToBorrow, _poolUtils.borrowFeeRate(address(_pool)) + Maths.WAD); - (,, uint256 borrowert0Np) = _poolUtils.borrowerInfo(address(_pool), _borrowers[i]); + (,, uint256 borrowert0Np, ) = _poolUtils.borrowerInfo(address(_pool), _borrowers[i]); uint256 lup = _poolUtils.lup(address(_pool)); @@ -602,7 +601,7 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { // kick all borrowers for (uint256 i = 0; i < noOfBorrowers; i++) { _pool.kick(_borrowers[i], 7_388); - (uint256 kickTime,,,,,) = _poolUtils.auctionStatus(address(_pool), _borrowers[i]); + (uint256 kickTime,,,,,,,,) = _poolUtils.auctionStatus(address(_pool), _borrowers[i]); // ensure borrower is kicked assertEq(kickTime, block.timestamp); @@ -634,12 +633,12 @@ contract ERC20PoolLiquidationKickHighThresholdPriceBorrower is ERC20HelperContra _pledgeCollateral({ from: _borrower, borrower: _borrower, - amount: 0.00000105 * 1e18 + amount: 0.0000011 * 1e18 }); _borrow({ from: _borrower, - amount: 999 * 1e18, + amount: 998 * 1e18, indexLimit: 7388, newLup: _priceAt(1) }); @@ -661,10 +660,10 @@ contract ERC20PoolLiquidationKickHighThresholdPriceBorrower is ERC20HelperContra _kick({ from: _lender, borrower: _borrower, - debt: 102_216_005.616368048436296920 * 1e18, - collateral: 0.00000105 * 1e18, - bond: 1_551_673.707198968377320142 * 1e18, - transferAmount: 1_551_673.707198968377320142 * 1e18 + debt: 108_328_580.483857986778697590 * 1e18, + collateral: 0.0000011 * 1e18, + bond: 1_211_150.349339817537800651 * 1e18, + transferAmount: 1_211_150.349339817537800651 * 1e18 }); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol index 795bc719e..2c740d853 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol @@ -107,7 +107,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender2, amount: 10_000 * 1e18, index: 2500, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: 3_844.432207828138682757 * 1e18 }); @@ -117,11 +117,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 111_000 * 1e18, + poolSize: 110_994.931506849315069 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.036654682669472623 * 1e18, + encumberedCollateral: 27.078120869976251528 * 1e18, poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -161,9 +161,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { // assert bucket state pre kick with deposit _assertBucket({ index: 2500, - lpBalance: 60_000 * 1e18, + lpBalance: 59_997.26027397260274 * 1e18, collateral: 0, - deposit: 60_000 * 1e18, + deposit: 59_997.26027397260274 * 1e18, exchangeRate: 1 * 1e18 }); @@ -179,7 +179,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.8987273632000937560 * 1e18 + bond: 223.821804286277016796 * 1e18 }); /******************************/ @@ -188,11 +188,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 111_000 * 1e18, + poolSize: 110_994.931506849315069 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.036654682669472623 * 1e18, + encumberedCollateral: 27.078120869976251528 * 1e18, poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -205,8 +205,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - assertEq(_quote.balanceOf(address(_pool)), 11_303.898727363200093756 * 1e18); - assertEq(_quote.balanceOf(_lender1), 48_696.101272636799906244 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 11_223.821804286277016796 * 1e18); + assertEq(_quote.balanceOf(_lender1), 48_776.178195713722983204 * 1e18); assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -218,28 +218,28 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 50_000 * 1e18, + lpBalance: 49_997.71689497716895 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender2, index: 2500, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.54337899543379 * 1e18, depositTime: _startTime }); // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 60_000 * 1e18, + lpBalance: 59_997.26027397260274 * 1e18, collateral: 0, - deposit: 60_000 * 1e18, + deposit: 59_997.26027397260274 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender1 as a kicker _assertKicker({ kicker: _lender1, claimable: 0, - locked: 303.898727363200093756 * 1e18 + locked: 223.821804286277016796 * 1e18 }); // assert kicked auction _assertAuction( @@ -247,15 +247,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 303.898727363200093756 * 1e18, - auctionPrice: 5_902.903818972869185792 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 223.821804286277016796 * 1e18, + auctionPrice: 5_925.823171731783953152 * 1e18, debtInAuction: 20_019.230769230769240000 * 1e18, - thresholdPrice: 20.019230769230769240 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -267,7 +267,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { - bond auction is not covered entirely by removed deposit (bucket still contains LP), difference to cover bond is sent by lender */ - // borrower 1 draws more debt from pool, bond size will increase from 303.8987273632000937560 in prev scenario to 440.653154676640135945 + // borrower 1 draws more debt from pool, bond size will increase from 303.8987273632000937560 in prev scenario to 324.541616215101674353 * 1e18 _drawDebt({ from: _borrower1, borrower: _borrower1, @@ -309,7 +309,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, debt: 29_027.884615384615398000 * 1e18, collateral: 1_000 * 1e18, - bond: 440.653154676640135945 * 1e18 + bond: 324.541616215101674353 * 1e18 }); /******************************/ @@ -318,11 +318,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 111_000 * 1e18, + poolSize: 110_994.931506849315069 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 28.379953604109725159 * 1e18, + encumberedCollateral: 29.515151748274114165 * 1e18, poolDebt: 109_104.807692307692358000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -335,10 +335,10 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 2_440.653154676640135945 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 2_324.541616215101674353 * 1e18); // increased with the amount sent to cover bond assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); - assertEq(_quote.balanceOf(_lender3), 149_559.346845323359864055 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender3), 149_675.458383784898325647 * 1e18); // decreased with the amount sent to cover bond assertEq(_quote.balanceOf(_borrower1), 29_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower3), 20_000 * 1e18); @@ -349,7 +349,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 50_000 * 1e18, + lpBalance: 49_997.71689497716895 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -361,16 +361,16 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 63_863.654368867279344664 * 1e18, + lpBalance: 63_860.914642839882084664 * 1e18, collateral: 1 * 1e18, - deposit: 60_000 * 1e18, + deposit: 59_997.26027397260274 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender3 as a kicker _assertKicker({ kicker: _lender3, claimable: 0, - locked: 440.653154676640135945 * 1e18 + locked: 324.541616215101674353 * 1e18 }); // assert kicked auction _assertAuction( @@ -378,15 +378,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender3, - bondSize: 440.653154676640135945 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 324.541616215101674353 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 33.434416162151016873 * 1e18, - totalBondEscrowed: 440.653154676640135945 * 1e18, - auctionPrice: 8_559.210537510660319488 * 1e18, + referencePrice: 33.564232808637057547 * 1e18, + totalBondEscrowed: 324.541616215101674353 * 1e18, + auctionPrice: 8_592.443599011086732032 * 1e18, debtInAuction: 29_027.884615384615398000 * 1e18, - thresholdPrice: 29.027884615384615398 * 1e18, - neutralPrice: 33.434416162151016873 * 1e18 + debtToCollateral: 29.027884615384615398 * 1e18, + neutralPrice: 33.564232808637057547 * 1e18 }) ); } @@ -402,7 +402,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender2, amount: 10_000 * 1e18, index: 2499, - lpAward: 10_000 * 1e18, + lpAward: 9_999.54337899543379 * 1e18, newLup: 3_844.432207828138682757 * 1e18 }); @@ -440,7 +440,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, debt: 35_033.653846153846170000 * 1e18, collateral: 1_000 * 1e18, - bond: 531.8227728856001640720 * 1e18 + bond: 391.688157500984779392 * 1e18 }); /******************************/ @@ -449,11 +449,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 121_000 * 1e18, + poolSize: 120_994.474885844748859 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 29.942152885069893516 * 1e18, + encumberedCollateral: 31.139839000472689257 * 1e18, poolDebt: 115_110.576923076923130000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -466,9 +466,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 6_531.822772885600164072 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 6_391.688157500984779392 * 1e18); // increased with the amount sent to cover bond assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); - assertEq(_quote.balanceOf(_lender2), 129_468.177227114399835928 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender2), 129_608.311842499015220608 * 1e18); // decreased with the amount sent to cover bond assertEq(_quote.balanceOf(_lender3), 150_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 35_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -480,22 +480,22 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: 2499, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.54337899543379 * 1e18, depositTime: _startTime }); // assert bucket - LP and deposit obliterated _assertBucket({ index: 2499, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.54337899543379 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.54337899543379 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender2 as a kicker _assertKicker({ kicker: _lender2, claimable: 0, - locked: 531.822772885600164072 * 1e18 + locked: 391.688157500984779392 * 1e18 }); // assert kicked auction _assertAuction( @@ -503,15 +503,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender2, - bondSize: 531.822772885600164072 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 391.688157500984779392 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 40.351881575009847950 * 1e18, - totalBondEscrowed: 531.822772885600164072 * 1e18, - auctionPrice: 10_330.081683202521075200 * 1e18, + referencePrice: 40.508556838010241868 * 1e18, + totalBondEscrowed: 391.688157500984779392 * 1e18, + auctionPrice: 10_370.190550530621918208 * 1e18, debtInAuction: 35_033.653846153846170000 * 1e18, - thresholdPrice: 35.033653846153846170 * 1e18, - neutralPrice: 40.351881575009847950 * 1e18 + debtToCollateral: 35.033653846153846170 * 1e18, + neutralPrice: 40.508556838010241868 * 1e18 }) ); } @@ -528,21 +528,21 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, amount: 10 * 1e18, index: 2500, - lpAward: 38636.54368867279344664 * 1e18 + lpAward: 38_636.54368867279344664 * 1e18 }); // assert lender and bucket LP balances pre kick _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 88_636.54368867279344664 * 1e18, + lpBalance: 88_634.26058364996239664 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2500, - lpBalance: 98_636.54368867279344664 * 1e18, + lpBalance: 98_633.80396264539618664 * 1e18, collateral: 10 * 1e18, - deposit: 60_000 * 1e18, + deposit: 59_997.26027397260274 * 1e18, exchangeRate: 1 * 1e18 }); @@ -558,7 +558,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); /******************************/ @@ -567,11 +567,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 20.019230769230769240 * 1e18, + htp: 20.820000000000000010 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 111_000 * 1e18, + poolSize: 110_994.931506849315069 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.036654682669472623 * 1e18, + encumberedCollateral: 27.078120869976251528 * 1e18, poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -584,8 +584,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - assertEq(_quote.balanceOf(address(_pool)), 11_303.898727363200093756 * 1e18); // increased by amount used to cover auction bond - assertEq(_quote.balanceOf(_lender1), 48_696.101272636799906244 * 1e18); // reduced by amount used to cover auction bond + assertEq(_quote.balanceOf(address(_pool)), 11_223.821804286277016796 * 1e18); // increased by amount used to cover auction bond + assertEq(_quote.balanceOf(_lender1), 48_776.178195713722983204 * 1e18); // reduced by amount used to cover auction bond assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -597,28 +597,28 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 88_636.543688672793446640 * 1e18, + lpBalance: 88_634.260583649962396640 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender2, index: 2500, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.54337899543379 * 1e18, depositTime: _startTime }); // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 98_636.543688672793446640 * 1e18, + lpBalance: 98_633.803962645396186640 * 1e18, collateral: 10 * 1e18, - deposit: 60_000 * 1e18, + deposit: 59_997.26027397260274 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender1 as a kicker _assertKicker({ kicker: _lender1, claimable: 0, - locked: 303.898727363200093756 * 1e18 + locked: 223.821804286277016796 * 1e18 }); // assert kicked auction _assertAuction( @@ -626,15 +626,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 303.898727363200093756 * 1e18, - auctionPrice: 5_902.903818972869185792 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 223.821804286277016796 * 1e18, + auctionPrice: 5_925.823171731783953152 * 1e18, debtInAuction: 20_019.230769230769240000 * 1e18, - thresholdPrice: 20.019230769230769240 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -643,22 +643,22 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { function testLenderKickAuctionAllBorrowersAndSettle() external tearDown { // assert loans positions in heap address borrower; - uint256 thresholdPrice; - (borrower, thresholdPrice) = _pool.loanInfo(1); + uint256 t0DebtToCollateral; + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, _borrower1); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, _borrower2); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, _borrower3); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, _borrower4); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, _borrower5); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); // kick borrower 1 _lenderKick({ @@ -667,31 +667,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); - (borrower, thresholdPrice) = _pool.loanInfo(1); + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, _borrower5); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, _borrower2); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, _borrower3); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, _borrower4); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); + assertEq(t0DebtToCollateral, 0); address head; address next; address prev; - (, , , , , , head, next, prev) = _pool.auctionInfo(address(0)); + (, , , , , , , head, next, prev) = _pool.auctionInfo(address(0)); assertEq(head, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -703,30 +703,30 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower5, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); - (borrower, thresholdPrice) = _pool.loanInfo(1); + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, _borrower4); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, _borrower2); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, _borrower3); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); + assertEq(t0DebtToCollateral, 0); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower1); @@ -738,34 +738,34 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower4, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); - (borrower, thresholdPrice) = _pool.loanInfo(1); + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, _borrower3); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, _borrower2); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); + assertEq(t0DebtToCollateral, 0); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower5); @@ -777,38 +777,38 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower3, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); - (borrower, thresholdPrice) = _pool.loanInfo(1); + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, _borrower2); - assertEq(thresholdPrice, 20.019230769230769240 * 1e18); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 20.019230769230769240 * 1e18); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); + assertEq(t0DebtToCollateral, 0); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower4); @@ -820,42 +820,42 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower2, debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 303.898727363200093756 * 1e18 + bond: 223.821804286277016796 * 1e18 }); - (borrower, thresholdPrice) = _pool.loanInfo(1); + (borrower, t0DebtToCollateral) = _pool.loanInfo(1); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(2); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(2); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(3); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(3); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(4); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(4); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); - (borrower, thresholdPrice) = _pool.loanInfo(5); + assertEq(t0DebtToCollateral, 0); + (borrower, t0DebtToCollateral) = _pool.loanInfo(5); assertEq(borrower, address(0)); - assertEq(thresholdPrice, 0); + assertEq(t0DebtToCollateral, 0); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, _borrower2); assertEq(prev, _borrower4); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower3); @@ -865,9 +865,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { PoolParams({ htp: 0, lup: 3_844.432207828138682757 * 1e18, - poolSize: 111_000 * 1e18, + poolSize: 110_994.931506849315069 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.036654682669472623 * 1e18, + encumberedCollateral: 27.078120869976251528 * 1e18, poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -888,15 +888,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 100_096.153846153846200000 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -904,7 +904,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower2, maxDepth: 1, - settledDebt: 20_019.230769230769240000 * 1e18 + settledDebt: 20_028.374057845207515293 * 1e18 }); _assertAuction( @@ -916,31 +916,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 80_113.496231380830061171 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower4); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -951,15 +951,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower4, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 80_113.496231380830061171 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -967,7 +967,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower4, maxDepth: 5, - settledDebt: 20_019.230769230769240000 * 1e18 + settledDebt: 20_028.374057845207515293 * 1e18 }); _assertAuction( @@ -979,31 +979,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 60_085.122173535622545879 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower1); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower5); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1014,15 +1014,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 60_085.122173535622545879 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -1030,7 +1030,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower1, maxDepth: 5, - settledDebt: 20_019.230769230769240000 * 1e18 + settledDebt: 20_028.374057845207515293 * 1e18 }); _assertAuction( @@ -1042,31 +1042,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 40_056.748115690415030586 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower5); assertEq(next, _borrower3); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, _borrower5); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1077,15 +1077,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower5, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 40_056.748115690415030586 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); @@ -1093,7 +1093,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower5, maxDepth: 5, - settledDebt: 20_019.230769230769240000 * 1e18 + settledDebt: 20_028.374057845207515293 * 1e18 }); _assertAuction( @@ -1105,31 +1105,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 20_028.374057845207515293 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1140,25 +1140,23 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower3, active: true, kicker: _lender1, - bondSize: 303.898727363200093756 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 223.821804286277016796 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 23.058218042862770257 * 1e18, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + referencePrice: 23.147746764577281067 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 20_028.374057845207515293 * 1e18, - thresholdPrice: 20.028374057845207515 * 1e18, - neutralPrice: 23.058218042862770257 * 1e18 + debtToCollateral: 20.019230769230769240 * 1e18, + neutralPrice: 23.147746764577281067 * 1e18 }) ); - - _settle({ from: _lender1, borrower: _borrower3, maxDepth: 5, - settledDebt: 20_019.230769230769240000 * 1e18 + settledDebt: 20_028.374057845207515293 * 1e18 }); _assertAuction( @@ -1170,31 +1168,31 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 1_519.493636816000468780 * 1e18, + totalBondEscrowed: 1_119.109021431385083980 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); + (, , , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1204,8 +1202,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 10_896.988687385325019536 * 1e18, - pledgedCollateral: 4_974.029127598743052356 * 1e18, + poolSize: 10_891.920194234640150529 * 1e18, + pledgedCollateral: 4_974.029124053231774906 * 1e18, encumberedCollateral: 0, poolDebt: 0, actualUtilization: 0, @@ -1221,20 +1219,20 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 50_000.000000000000000000 * 1e18, + lpBalance: 49_997.716894977168950000 * 1e18, depositTime: _startTime }); // assert lender1 as a kicker _assertKicker({ kicker: _lender1, - claimable: 1_519.493636816000468780 * 1e18, + claimable: 1_119.109021431385083980 * 1e18, locked: 0 }); // assert borrowers after settle _assertBorrower({ borrower: _borrower1, borrowerDebt: 0, - borrowerCollateral: 994.816126720381654072 * 1e18, + borrowerCollateral: 994.816123174870376622 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -1285,9 +1283,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _addLiquidityWithPenalty({ from: _lender3, amount: 150_000 * 1e18, - amountAdded: 149_979.452054794520550000 * 1e18, + amountAdded: 149_993.150684931506850000 * 1e18, index: 7000, - lpAward: 149_979.452054794520550000 * 1e18, + lpAward: 149_993.150684931506850000 * 1e18, newLup: 3_844.432207828138682757 * 1e18 }); @@ -1301,7 +1299,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender4, amount: 5_000 * 1e18, index: 2499, - lpAward: 5_000 * 1e18, + lpAward: 4_999.771689497716895000 * 1e18, newLup: 3_844.432207828138682757 * 1e18 }); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index bf934eace..70f167d8c 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -44,11 +44,6 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { amount: 11_000 * 1e18, index: _i9_72 }); - _addInitialLiquidity({ - from: _lender, - amount: 25_000 * 1e18, - index: _i9_62 - }); _addInitialLiquidity({ from: _lender, amount: 30_000 * 1e18, @@ -63,7 +58,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -87,15 +82,15 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.707325000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 47_997.808219178082192000 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + encumberedCollateral: 856.531347837213447051 * 1e18, + poolDebt: 8_006.341009615384619076 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.317050480769230954 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -104,27 +99,27 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 18.667932692307692316 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 1.001439208539095951 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.217037273735858713 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.170228147822941070 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 9.882790437302427076 * 1e18, + claimableReserves : 9.882742439494207898 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); + assertEq(_quote.balanceOf(_lender), 72_000 * 1e18); // should revert if there's no auction started _assertTakeNoAuctionRevert({ @@ -142,24 +137,24 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { // Lender attempts to withdraw entire position _removeLiquidity({ from: _lender, - amount: 2_000.00 * 1e18, + amount: 1_999.935282868211813754 * 1e18, index: _i9_91, newLup: 9.721295865031779605 * 1e18, - lpRedeem: 1_999.892091281103336057 * 1e18 + lpRedeem: 1_999.827380807531781086 * 1e18 }); _removeLiquidity({ from: _lender, - amount: 5_000 * 1e18, + amount: 4_999.838207170529534384 * 1e18, index: _i9_81, newLup: 9.721295865031779605 * 1e18, - lpRedeem: 4_999.730228202758340143 * 1e18 + lpRedeem: 4_999.568452018829452712 * 1e18 }); _removeLiquidity({ from: _lender, - amount: 2_992.8 * 1e18, + amount: 2_980 * 1e18, index: _i9_72, newLup: 9.721295865031779605 * 1e18, - lpRedeem: 2_992.638525393043032076 * 1e18 + lpRedeem: 2_979.839220727000051551 * 1e18 }); // Lender amount to withdraw is restricted by HTP @@ -170,13 +165,13 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertBucket({ index: _i9_72, - lpBalance: 8_007.361474606956967924 * 1e18, + lpBalance: 8_019.658496167977117449 * 1e18, collateral: 0, - deposit: 8_007.793529977461399000 * 1e18, - exchangeRate: 1.000053957270678310 * 1e18 + deposit: 8_020.091202353516607669 * 1e18, + exchangeRate: 1.000053955687233597 * 1e18 }); - skip(16 hours); + skip(400 hours); _assertAuction( AuctionParams({ @@ -190,48 +185,48 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.636421658861206949 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.272843317722413899 * 1e18, + borrowerDebt: 18.709000367642488138 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.998794730435100100 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.979503487849002840 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.272843317722413898 * 1e18, + debt: 18.709000367642488138 * 1e18, collateral: 2 * 1e18, - bond: 0.292568312161539120 * 1e18, - transferAmount: 0.292568312161539120 * 1e18 + bond: 0.209172983065585793 * 1e18, + transferAmount: 0.209172983065585793 * 1e18 }); _assertBucket({ index: _i9_72, - lpBalance: 8_007.361474606956967924 * 1e18, + lpBalance: 8_019.658496167977117449 * 1e18, collateral: 0, - deposit: 8_008.356713096000609696 * 1e18, - exchangeRate: 1.000124290441014779 * 1e18 + deposit: 8_034.234589314746482090 * 1e18, + exchangeRate: 1.001817545367266480 * 1e18 }); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.292568312161539120 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.209172983065585793 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.099263219668902589 * 1e18, - totalBondEscrowed: 0.292568312161539120 * 1e18, - auctionPrice: 2_841.411384235239062784 * 1e18, - debtInAuction: 19.272843317722413899 * 1e18, - thresholdPrice: 9.636421658861206949 * 1e18, - neutralPrice: 11.099263219668902589 * 1e18 + referencePrice: 10.816379703115139992 * 1e18, + totalBondEscrowed: 0.209172983065585793 * 1e18, + auctionPrice: 2_768.993203997475837952 * 1e18, + debtInAuction: 18.709000367642488138 * 1e18, + debtToCollateral: 9.354500183821244069 * 1e18, + neutralPrice: 10.816379703115139992 * 1e18 }) ); @@ -265,7 +260,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { // lender can add / remove liquidity in buckets that are not within liquidation debt changePrank(_lender1); - _pool.addQuoteToken(2_000 * 1e18, 5000, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(2_000 * 1e18, 5000, block.timestamp + 1 minutes); _pool.removeQuoteToken(2_000 * 1e18, 5000); skip(3 hours); @@ -275,32 +270,32 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.292568312161539120 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.209172983065585793 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - referencePrice: 11.099263219668902589 * 1e18, - totalBondEscrowed: 0.292568312161539120 * 1e18, - auctionPrice: 31.393457155209254668 * 1e18, - debtInAuction: 19.272843317722413899 * 1e18, - thresholdPrice: 9.636555315636456019 * 1e18, - neutralPrice: 11.099263219668902589 * 1e18 + referencePrice: 10.816379703115139992 * 1e18, + totalBondEscrowed: 0.209172983065585793 * 1e18, + auctionPrice: 30.593341743845004656 * 1e18, + debtInAuction: 18.709000367642488138 * 1e18, + debtToCollateral: 9.354500183821244069 * 1e18, + neutralPrice: 10.816379703115139992 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.273110631272912039 * 1e18, + borrowerDebt: 18.709259860714273064 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.998780877385080338 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 0.999227114253786894 * 1e18 }); _take({ from: _lender, borrower: _borrower, maxCollateral: 2.0 * 1e18, - bondChange: 0.292568312161539120 * 1e18, - givenAmount: 19.722195067961733839 * 1e18, - collateralTaken: 0.628226288377708765 * 1e18, + bondChange: 0.209172983065585793 * 1e18, + givenAmount: 19.028375417729999837 * 1e18, + collateralTaken: 0.621977670077779898 * 1e18, isReward: false }); @@ -317,28 +312,28 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.371773711622291235 * 1e18, + borrowerCollateral: 1.378022329922220102 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertPool( PoolParams({ - htp: 7.989580407145861718 * 1e18, + htp: 8.325570479144230295 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 63_008.829556315248414267 * 1e18, - pledgedCollateral: 1_001.371773711622291235 * 1e18, - encumberedCollateral: 821.863722498661263922 * 1e18, - poolDebt: 7_989.580407145861717463 * 1e18, - actualUtilization: 0.121389232097000537 * 1e18, - targetUtilization: 0.822758145478171949 * 1e18, - minDebtAmount: 798.958040714586171746 * 1e18, + poolSize: 38_033.245639566817177597 * 1e18, + pledgedCollateral: 1_001.378022329922220102 * 1e18, + encumberedCollateral: 856.425994510867961912 * 1e18, + poolDebt: 8_005.356229946375284147 * 1e18, + actualUtilization: 0.210612566139746491 * 1e18, + targetUtilization: 0.822141283593523235 * 1e18, + minDebtAmount: 800.535622994637528415 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.0405 * 1e18, @@ -346,12 +341,12 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { }) ); - _removeLiquidity({ + _removeAllLiquidity({ from: _lender, - amount: 8_008.368802228565193289 * 1e18, + amount: 8_034.254839833419530359 * 1e18, index: _i9_72, - newLup: 9.624807173121239337 * 1e18, - lpRedeem: 8_007.361474606956967924 * 1e18 + newLup: 9.529276179422528643 * 1e18, + lpRedeem: 8_019.658496167977117449 * 1e18 }); _assertBucket({ @@ -364,34 +359,18 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _removeLiquidity({ from: _lender, - amount: 25_000.037739117392250000 * 1e18, - index: _i9_62, - newLup: 9.529276179422528643 * 1e18, - lpRedeem: 25_000.000000000000000000 * 1e18 - }); - - _assertBucket({ - index: _i9_62, - lpBalance: 0.000000000000000000 * 1e18, - collateral: 0, - deposit: 0.000000000000000000 * 1e18, - exchangeRate: 1.000000000000000000 * 1e18 - }); - - _removeLiquidity({ - from: _lender, - amount: 22_000 * 1e18, + amount: 21_000 * 1e18, index: _i9_52, newLup: 9.529276179422528643 * 1e18, - lpRedeem: 21_999.966789626828026872 * 1e18 + lpRedeem: 20_999.947069031215483677 * 1e18 }); _assertBucket({ index: _i9_52, - lpBalance: 8_000.033210373171973128 * 1e18, + lpBalance: 8_998.683067955085886323 * 1e18, collateral: 0, - deposit: 8_000.045286940870700000 * 1e18, - exchangeRate: 1.000001509564695691 * 1e18 + deposit: 8_998.705749393805991615 * 1e18, + exchangeRate: 1.000002520528676122 * 1e18 }); _assertRemoveAllLiquidityLupBelowHtpRevert({ @@ -403,15 +382,15 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 7.989580407145861718 * 1e18, + htp: 8.326532822441837927 * 1e18, lup: 9.529276179422528643 * 1e18, - poolSize: 8_000.423014969290972838 * 1e18, - pledgedCollateral: 1_001.371773711622291235 * 1e18, - encumberedCollateral: 838.521600516187410670 * 1e18, - poolDebt: 7_990.503913730158190391 * 1e18, - actualUtilization: 0.121389232097000537 * 1e18, - targetUtilization: 0.822758145478171949 * 1e18, - minDebtAmount: 799.050391373015819039 * 1e18, + poolSize: 8_998.990799733397644463 * 1e18, + pledgedCollateral: 1_001.378022329922220102 * 1e18, + encumberedCollateral: 873.784395127733970987 * 1e18, + poolDebt: 8_006.281560040228775697 * 1e18, + actualUtilization: 0.210612566139746491 * 1e18, + targetUtilization: 0.822141283593523235 * 1e18, + minDebtAmount: 800.628156004022877570 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.0405 * 1e18, @@ -420,10 +399,10 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_990.503913730158190391 * 1e18, + borrowerDebt: 8_006.281560040228775697 * 1e18, borrowerCollateral: 1_000.00 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.192575121957988603 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.144447080510994053 * 1e18 }); // trigger accrual of pool interest that will push the lup back up @@ -431,15 +410,15 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 7.990503913730158191 * 1e18, + htp: 8.326532822441837927 * 1e18, lup: 9.529276179422528643 * 1e18, - poolSize: 8_001.213844211612533894 * 1e18, - pledgedCollateral: 1_001.371773711622291235 * 1e18, - encumberedCollateral: 838.521600516187410670 * 1e18, - poolDebt: 7_990.503913730158190391 * 1e18, - actualUtilization: 0.383637856267925676 * 1e18, - targetUtilization: 0.829403289225492236 * 1e18, - minDebtAmount: 799.050391373015819039 * 1e18, + poolSize: 8_999.787852072874979370 * 1e18, + pledgedCollateral: 1_001.378022329922220102 * 1e18, + encumberedCollateral: 873.784395127733970987 * 1e18, + poolDebt: 8_006.281560040228775697 * 1e18, + actualUtilization: 0.505203542638556630 * 1e18, + targetUtilization: 0.825505559884289307 * 1e18, + minDebtAmount: 800.628156004022877570 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.03645 * 1e18, @@ -451,10 +430,10 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_084.412285638162564830 * 1e18, + borrowerDebt: 8_100.375358686460903420 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 0.000000012349231999 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.131153206043881494 * 1e18 }); // kick borrower 2 @@ -464,18 +443,18 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertPool( PoolParams({ htp: 0, - lup: 0.000000099836282890 * 1e18, - poolSize: 8_083.134377459926771461 * 1e18, - pledgedCollateral: 1_001.371773711622291235 * 1e18, - encumberedCollateral: 80_976_695_562.129442225570824234 * 1e18, - poolDebt: 8_084.412285638162564830 * 1e18, - actualUtilization: 0.998661461786925952 * 1e18, - targetUtilization: 0.838521600515840801 * 1e18, + lup: 9.529276179422528643 * 1e18, + poolSize: 9_082.718302945104923507 * 1e18, + pledgedCollateral: 1_001.378022329922220102 * 1e18, + encumberedCollateral: 884.053543460678137147 * 1e18, + poolDebt: 8_100.375358686460903420 * 1e18, + actualUtilization: 0.889607809832559887 * 1e18, + targetUtilization: 0.840177303006175138 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.040095 * 1e18, - interestRateUpdate: block.timestamp + interestRate: 0.03645 * 1e18, + interestRateUpdate: block.timestamp - 117 days }) ); @@ -492,31 +471,31 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 122.724126286659537773 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 90.564949726435836850 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 9.311653548504757974 * 1e18, - totalBondEscrowed: 122.724126286659537773 * 1e18, - auctionPrice: 2.327913387126189492 * 1e18, - debtInAuction: 8_084.412285638162564830 * 1e18, - thresholdPrice: 8.084782322086612071 * 1e18, - neutralPrice: 9.311653548504757974 * 1e18 + referencePrice: 9.366265850188852076 * 1e18, + totalBondEscrowed: 90.564949726435836850 * 1e18, + auctionPrice: 2.341566462547213020 * 1e18, + debtInAuction: 8_100.375358686460903420 * 1e18, + debtToCollateral: 8.100375358686460903 * 1e18, + neutralPrice: 9.366265850188852076 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_084.782322086612071679 * 1e18, + borrowerDebt: 8_100.712418988636152518 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 0.000000012348666781 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.131106140203037430 * 1e18 }); _take({ from: _lender, borrower: _borrower2, maxCollateral: 1_000.0 * 1e18, - bondChange: 35.338516445234474376 * 1e18, - givenAmount: 2_327.913387126189492000 * 1e18, + bondChange: 26.179508920446417251 * 1e18, + givenAmount: 2_341.566462547213020000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -525,22 +504,22 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 0, lup: 9.529276179422528643 * 1e18, - poolSize: 8_083.498296802166583218 * 1e18, - pledgedCollateral: 1.371773711622291235 * 1e18, - encumberedCollateral: 607.832887025912931068 * 1e18, - poolDebt: 5_792.207451405657054680 * 1e18, - actualUtilization: 0.998661461786925952 * 1e18, - targetUtilization: 0.838521600515840801 * 1e18, + poolSize: 9_083.031109529777711575 * 1e18, + pledgedCollateral: 1.378022329922220102 * 1e18, + encumberedCollateral: 631.395120751024022658 * 1e18, + poolDebt: 5_785.325465361869550519 * 1e18, + actualUtilization: 0.819662267320821453 * 1e18, + targetUtilization: 0.840177303006175138 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.040095 * 1e18, - interestRateUpdate: block.timestamp - 10 hours + interestRate: 0.03645 * 1e18, + interestRateUpdate: block.timestamp - 117 days - 10 hours }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 5_792.207451405657054680 * 1e18, + borrowerDebt: 5_785.325465361869550519 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -556,24 +535,24 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 5_722.635152359337569948 * 1e18 + settledDebt: 5_785.325465361869550518 * 1e18 }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 2_312.355002439841726602 * 1e18, - pledgedCollateral: 1.371773711622291235 * 1e18, + poolSize: 3_300.544788087832541103 * 1e18, + pledgedCollateral: 1.378022329922220102 * 1e18, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.998661461786925952 * 1e18, - targetUtilization: 0.838521600515840801 * 1e18, + actualUtilization: 0.819662267320821453 * 1e18, + targetUtilization: 0.840177303006175138 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.040095 * 1e18, - interestRateUpdate: block.timestamp - 10 hours + interestRate: 0.032805 * 1e18, + interestRateUpdate: block.timestamp }) ); _assertBucket({ @@ -597,19 +576,12 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { deposit: 0, exchangeRate: 1 * 1e18 }); - _assertBucket({ - index: _i9_62, - lpBalance: 0, - collateral: 0, - deposit: 0, - exchangeRate: 1 * 1e18 - }); _assertBucket({ index: _i9_52, - lpBalance: 8_000.033210373171973128 * 1e18, + lpBalance: 8_998.683067955085886323 * 1e18, collateral: 0, - deposit: 2_312.355002439841725846 * 1e18, - exchangeRate: 0.289043175401015481 * 1e18 + deposit: 3_300.544788087832540727 * 1e18, + exchangeRate: 0.366780868174065821 * 1e18 }); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol index f6416a7b4..8b8abbc74 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol @@ -74,6 +74,8 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 lpBalance; for (uint i=0; i<4; ++i) { + uint256 depositFee = Maths.WAD - _poolUtils.depositFeeRate(address(_pool)); + _addInitialLiquidity({ from: _lender, amount: 50_000 * 1e18, @@ -81,9 +83,10 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { }); (lpBalance, ) = _pool.lenderInfo(startBucketId + i, _lender); - assertEq(lpBalance, 50_000 * 1e18); + + assertEq(lpBalance, Maths.wmul(50_000 * 1e18, depositFee)); } - assertEq(_pool.depositSize(), 200_000 * 1e18); + assertEq(_pool.depositSize(), 199_991.552511415525100000 * 1e18); } function drawDebt( @@ -133,8 +136,8 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { init(boundColPrecision, boundQuotePrecision); addLiquidity(startBucketId); - // Borrow half the pool's liquidity at 101% collateralization, leaving room for origination fee - (uint256 collateralPledged) = drawDebt(_borrower, 99_000 * 1e18, 1.01 * 1e18); + // Borrow half the pool's liquidity at 105% collateralization, leaving room for origination fee + (uint256 collateralPledged) = drawDebt(_borrower, 99_000 * 1e18, 1.05 * 1e18); assertGt(_borrowerCollateralization(_borrower), 1e18); // Wait until borrower is undercollateralized @@ -175,7 +178,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_, uint16 startBucketId_ - ) external tearDown { + ) external { uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 6, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 6, 18); uint256 startBucketId = bound(uint256(startBucketId_), 1000, 6388); @@ -184,7 +187,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 collateralDust = ERC20Pool(address(_pool)).bucketCollateralDust(0); // Borrow everything from the first bucket, with origination fee tapping into the second bucket - drawDebt(_borrower, 50_000 * 1e18, 1.01 * 1e18); + drawDebt(_borrower, 50_000 * 1e18, 1.05 * 1e18); assertGt(_borrowerCollateralization(_borrower), 1e18); // Wait until borrower is undercollateralized @@ -243,7 +246,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { addLiquidity(startBucketId); // Draw debt from all four buckets - drawDebt(_borrower, 151_000 * 1e18, 1.02 * 1e18); + drawDebt(_borrower, 151_000 * 1e18, 1.06 * 1e18); assertGt(_borrowerCollateralization(_borrower), 1e18); // Wait until borrower is undercollateralized @@ -317,6 +320,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 auctionNeutralPrice, , , + , ) = _pool.auctionInfo(_borrower); assertEq(auctionKicker, kicker); @@ -330,20 +334,20 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } function _take(uint256 collateralToTake, address bidder) internal { - (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertGt(lastAuctionDebt, 0); assertGt(lastAuctionCollateral, 0); changePrank(bidder); _pool.take(_borrower, collateralToTake, bidder, new bytes(0)); - (uint256 auctionDebt, uint256 auctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 auctionDebt, uint256 auctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertLt(auctionDebt, lastAuctionDebt); assertLt(auctionCollateral, lastAuctionCollateral); } function _depositTake(uint256 bucketId) internal { - (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertGt(lastAuctionDebt, 0); assertGt(lastAuctionCollateral, 0); (, uint256 lastBucketDeposit, uint256 lastBucketCollateral, uint256 lastBucketLP, , ) = _poolUtils.bucketInfo(address(_pool), bucketId); @@ -356,7 +360,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { // confirm auction debt and collateral have decremented uint256 bucketLP; { - (uint256 auctionDebt, uint256 auctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 auctionDebt, uint256 auctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertLt(auctionDebt, lastAuctionDebt); assertLt(auctionCollateral, lastAuctionCollateral); uint256 collateralTaken = lastAuctionCollateral - auctionCollateral; @@ -370,7 +374,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } // confirm LP were awarded to the kicker - (address kicker, , , uint256 kickTime, uint256 referencePrice, uint256 neutralPrice, , ,) = _pool.auctionInfo(_borrower); + (address kicker, , , uint256 kickTime, uint256 referencePrice, uint256 neutralPrice, , , ,) = _pool.auctionInfo(_borrower); uint256 auctionPrice = _auctionPrice(referencePrice, kickTime); if (auctionPrice < neutralPrice) { uint256 kickerLP = _kickerLP(bucketId); @@ -386,7 +390,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } function _arbTake(uint256 bucketId, address bidder) internal { - (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertGt(lastAuctionDebt, 0); assertGt(lastAuctionCollateral, 0); (, uint256 lastBucketDeposit, uint256 lastBucketCollateral, , , ) = _poolUtils.bucketInfo(address(_pool), bucketId); @@ -397,7 +401,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { _pool.bucketTake(_borrower, false, bucketId); // confirm auction debt and collateral have decremented - (uint256 auctionDebt, uint256 auctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 auctionDebt, uint256 auctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertLt(auctionDebt, lastAuctionDebt); assertLt(auctionCollateral, lastAuctionCollateral); uint256 collateralTaken = lastAuctionCollateral - auctionCollateral; @@ -441,13 +445,13 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 auctionDebt_, uint256 auctionCollateral_ ){ - (, , , uint256 kickTime, uint256 referencePrice, , , , ) = _pool.auctionInfo(_borrower); + (, , , uint256 kickTime, uint256 referencePrice, , , , , ) = _pool.auctionInfo(_borrower); uint256 lastAuctionPrice = _auctionPrice(referencePrice, kickTime); - (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); if (secondsToSkip != 0) { skip(secondsToSkip); auctionPrice_ = _auctionPrice(referencePrice, kickTime); - (uint256 auctionDebt, uint256 auctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 auctionDebt, uint256 auctionCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // ensure auction price decreases and auction debt increases as time passes assertLt(auctionPrice_, lastAuctionPrice); assertGt(auctionDebt, lastAuctionDebt); @@ -462,12 +466,12 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } function _borrowerCollateralization(address borrower) internal view returns (uint256) { - (uint256 debt, uint256 collateral, ) = _poolUtils.borrowerInfo(address(_pool), borrower); + (uint256 debt, uint256 collateral, , ) = _poolUtils.borrowerInfo(address(_pool), borrower); return _collateralization(debt, collateral, _lup()); } function _kickerLP(uint256 bucketId) internal view returns (uint256) { - (address kicker, , , , , , , , ) = _pool.auctionInfo(_borrower); + (address kicker, , , , , , , , , ) = _pool.auctionInfo(_borrower); (uint256 kickerLP, ) = _pool.lenderInfo(bucketId, kicker); return kickerLP; } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 9ad4e9a1c..026669e03 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -65,7 +65,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -89,15 +89,15 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.707325000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + encumberedCollateral: 856.531347837213447051 * 1e18, + poolDebt: 8_006.341009615384619076 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.317050480769230954 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -106,21 +106,21 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 18.667932692307692316 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.792636928984157297 * 1e18, + borrowerCollateralization: 1.001439208539095951 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, - borrowerCollateralization: 1.217037273735858713 * 1e18 + borrowert0Np: 9.235950959066335145 * 1e18, + borrowerCollateralization: 1.170228147822941070 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 11.024342948717952076 * 1e18, + claimableReserves : 11.024269952051285409 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -134,7 +134,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // Borrower2 borrows _borrow({ from: _borrower2, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -154,25 +154,25 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.853394241979221645 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); _assertAuction( @@ -180,50 +180,50 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2_787.506622839621476352 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 2_012.686105677503216000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 2_012.033316090796323720 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 }); _assertBucket({ index: _i9_81, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 5_031.715264193758040000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 5_030.083290226990809301 * 1e18, + exchangeRate: 1.006062596976766965 * 1e18 }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 11_069.773581226267688000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 11_066.183238499379780461 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, + deposit: 24_998.858447488584475000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -235,23 +235,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853900422492752583 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2.722174436366817848 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.900422492752583093 * 1e18, + borrowerDebt: 9_417.527901208315548003 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986542937133981323 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992553456520532021 * 1e18 }); // take partial 800 collateral @@ -259,8 +259,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 800 * 1e18, - bondChange: 34.456860650725712362 * 1e18, - givenAmount: 2_269.834595673383616 * 1e18, + bondChange: 24.347868345313520351 * 1e18, + givenAmount: 2_177.739549093454278400 * 1e18, collateralTaken: 800 * 1e18, isReward: true }); @@ -270,50 +270,50 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 184.034734289495351885 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 129.633622527137778568 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 184.034734289495351885 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 7_618.522687470094679893 * 1e18, - thresholdPrice: 38.092613437350473399 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 129.633622527137778568 * 1e18, + auctionPrice: 2.722174436366817848 * 1e18, + debtInAuction: 7_264.136220460174790403 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_618.522687470094679893 * 1e18, + borrowerDebt: 7_264.136220460174790403 * 1e18, borrowerCollateral: 200 * 1e18, - borrowert0Np: 43.276046239860018335 * 1e18, - borrowerCollateralization: 0.255201599150450493 * 1e18 + borrowert0Np: 41.423212004652813045 * 1e18, + borrowerCollateralization: 0.257357505050496364 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 2_012.735939051273346000 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 2_012.080837484034115925 * 1e18, + exchangeRate: 1.006086358758398720 * 1e18 }); _assertBucket({ index: _i9_81, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 5_031.839847628183365000 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 5_030.202093710085289813 * 1e18, + exchangeRate: 1.006086358758398721 * 1e18 }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 11_070.047664782003403000 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 11_066.444606162187637588 * 1e18, + exchangeRate: 1.006086358758398720 * 1e18 }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, + deposit: 24_998.858447488584475000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -322,24 +322,24 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_621.380169222238377339 * 1e18, + borrowerDebt: 7_266.860782366276289457 * 1e18, borrowerCollateral: 200 * 1e18, - borrowert0Np: 43.276046239860018335 * 1e18, - borrowerCollateralization: 0.255105916492388742 * 1e18 + borrowert0Np: 41.423212004652813045 * 1e18, + borrowerCollateralization: 0.257261014079290282 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 2_012.735939051273346000 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 2_012.080837484034115925 * 1e18, + exchangeRate: 1.006086358758398720 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 7_514.484899441934449285 * 1e18 + settledDebt: 7_266.860782366276289457 * 1e18 }); _assertAuction( @@ -351,10 +351,10 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 184.034734289495351885 * 1e18, + totalBondEscrowed: 129.633622527137778568 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -367,10 +367,10 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 200 * 1e18, deposit: 0, - exchangeRate: 0.991718484343591208 * 1e18 + exchangeRate: 0.991763770360502646 * 1e18 }); _assertBucket({ index: _i9_81, @@ -381,29 +381,29 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 10_525.670272469343333339 * 1e18, - exchangeRate: 0.956879115679031213 * 1e18 + deposit: 10_848.806394658411625913 * 1e18, + exchangeRate: 0.986300163324266424 * 1e18 }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, - exchangeRate: 1 * 1e18 + deposit: 24_998.858447488584475000 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); _assertPool( PoolParams({ - htp: 9.771304290202671377 * 1e18, + htp: 9.845413922741351377 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 65_525.670272469343333339 * 1e18, + poolSize: 65_846.294979133297470913 * 1e18, pledgedCollateral: 2 * 1e18, - encumberedCollateral: 2.010288427770370775 * 1e18, - poolDebt: 19.542608580405342754 * 1e18, - actualUtilization: 0.593847771807726236 * 1e18, - targetUtilization: 0.999790809254532429 * 1e18, - minDebtAmount: 1.954260858040534275 * 1e18, + encumberedCollateral: 2.025535290651122678 * 1e18, + poolDebt: 18.933488312964137265 * 1e18, + actualUtilization: 0.571142885809255306 * 1e18, + targetUtilization: 0.955567693408119411 * 1e18, + minDebtAmount: 1.893348831296413727 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.0405 * 1e18, @@ -416,7 +416,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // Borrower2 borrows _borrow({ from: _borrower2, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -436,25 +436,25 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.853394241979221645 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); _assertAuction( @@ -462,50 +462,50 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2_787.506622839621476352 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 2_012.686105677503216000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 2_012.033316090796323720 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 }); _assertBucket({ index: _i9_81, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 5_031.715264193758040000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 5_030.083290226990809301 * 1e18, + exchangeRate: 1.006062596976766965 * 1e18 }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 11_069.773581226267688000 * 1e18, - exchangeRate: 1.006343052838751608 * 1e18 + deposit: 11_066.183238499379780461 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, + deposit: 24_998.858447488584475000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -518,30 +518,30 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 73 hours, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 0, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.857089957723356708 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_857.089957723356708150 * 1e18, + borrowerDebt: 9_420.576190285556153618 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986223713766031127 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992232288282095723 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_719.336538461538466020 * 1e18 + settledDebt: 9_420.576190285556153618 * 1e18 }); _assertAuction( @@ -553,46 +553,46 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 149.577873638769639523 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 0, + borrowerCollateral: 40.159651907487263058 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBucket({ index: _i9_91, - lpBalance: 2_000 * 1e18, - collateral: 202.986026776638220827 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, + collateral: 202.918500579787987864 * 1e18, deposit: 0, - exchangeRate: 1.006524974089276386 * 1e18 + exchangeRate: 1.006236086054551886 * 1e18 }); _assertBucket({ index: _i9_81, - lpBalance: 5_000 * 1e18, - collateral: 512.552404237685039184 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, + collateral: 512.381896370250897817 * 1e18, deposit: 0, - exchangeRate: 1.006524974089276386 * 1e18 + exchangeRate: 1.006236086054551886 * 1e18 }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, - collateral: 284.461568985676739989 * 1e18, - deposit: 8_290.291541398624686508 * 1e18, - exchangeRate: 1.005056965067230573 * 1e18 + lpBalance: 10_999.497716894977169000 * 1e18, + collateral: 244.539951142473851261 * 1e18, + deposit: 8_690.846315337976774916 * 1e18, + exchangeRate: 1.006236086054551886 * 1e18 }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, + deposit: 24_998.858447488584475000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -607,11 +607,11 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); } - function testSettleAuctionReverts() external { + function testSettleAuctionReverts() external tearDown { // Borrower2 borrows _borrow({ from: _borrower2, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -629,10 +629,10 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); _assertAuction( @@ -640,23 +640,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: kickTime, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2_787.506622839621476352 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992604445165255887 * 1e18 }); // settle should revert on an kicked auction but 72 hours not passed (there's still debt to settle and collateral to be auctioned) @@ -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); @@ -673,40 +690,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: kickTime, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 1.192934859200383004 * 1e18, - debtInAuction: 9853.394241979221645667 * 1e18, - thresholdPrice: 9.854026971684066190 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 1.144533362618078976 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_854.026971684066190794 * 1e18, + borrowerDebt: 9_417.648846264483444961 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986530267571451282 * 1e18 - }); - - _addLiquidityWithPenalty({ - from: _lender1, - amount: 100 * 1e18, - amountAdded: 99.987671232876712300 * 1e18, - index: _i9_52, - lpAward: 99.987671232876712300 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - _addLiquidity({ - from: _lender1, - amount: 100 * 1e18, - index: _i9_91, - lpAward: 99.366617416827728755 * 1e18, - newLup: 9.721295865031779605 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992540709768608251 * 1e18 }); // take entire collateral @@ -714,8 +714,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 18.109156626307515503 * 1e18, - givenAmount: 1_192.934859200383004000 * 1e18, + bondChange: 12.796272006652205754 * 1e18, + givenAmount: 1_144.533362618078976000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -748,15 +748,15 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.366617416827728755 * 1e18, - depositTime: _startTime + 100 days + 12.5 hours + lpBalance: 99.393308837291078044 * 1e18, + depositTime: _startTime + 100 days }); // settle to make buckets insolvent // settle should work because there is still debt to settle but no collateral left to auction (even if 72 hours didn't pass from kick) _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8679.201269109990702794 * 1e18, + borrowerDebt: 8_285.911755653056674961 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -767,14 +767,14 @@ 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.366617416827728755 * 1e18); + emit BucketBankruptcy(_i9_91, 2_099.301984636377836044 * 1e18); vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_81, 5_000 * 1e18); + emit BucketBankruptcy(_i9_81, 4_999.771689497716895000 * 1e18); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 8_560.569020353099739628 * 1e18 + settledDebt: 8_285.911755653056674961 * 1e18 }); // bucket is insolvent, balances are resetted @@ -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 @@ -825,7 +825,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { skip(1 hours); // move quote token in a bankrupt bucket should set deposit time to time of bankruptcy + 1 to prevent losing deposit - _pool.moveQuoteToken(10 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); + _pool.moveQuoteToken(10 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes); (, , uint256 bankruptcyTime, , ) = _pool.bucketInfo(_i9_91); _assertLenderLpBalance({ lender: _lender1, @@ -834,21 +834,21 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: bankruptcyTime + 1 }); - _pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes); ERC20Pool(address(_pool)).addCollateral(4 * 1e18, _i9_91, block.timestamp + 1 minutes); _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 149.668739373743648296 * 1e18, + lpBalance: 149.665040743606661996 * 1e18, depositTime: _startTime + 100 days + 12.5 hours + 1 hours }); // bucket is healthy again _assertBucket({ index: _i9_91, - lpBalance: 149.668739373743648296 * 1e18, + lpBalance: 149.665040743606661996 * 1e18, collateral: 4 * 1e18, - deposit: 110 * 1e18, + deposit: 109.996301369863013700 * 1e18, exchangeRate: 1 * 1e18 }); @@ -861,7 +861,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime }); - _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); + _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes); _assertLenderLpBalance({ lender: _lender, @@ -870,8 +870,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime + 100 days + 12.5 hours + 1 // _i9_91 bucket insolvency time + 1 (since deposit in _i9_52 from bucket was done before _i9_91 target bucket become insolvent) }); - _pool.addQuoteToken(1_000 * 1e18, _i9_52, block.timestamp + 1 minutes, false); - _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(1_000 * 1e18, _i9_52, block.timestamp + 1 minutes); + _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes); _assertLenderLpBalance({ lender: _lender, @@ -883,13 +883,13 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // ensure bucket bankruptcy when moving amounts from an unbalanced bucket leave bucket healthy _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0 * 1e18, - deposit: 9_565.123570257669797761 * 1e18, - exchangeRate: 0.869556688205242709 * 1e18 + deposit: 9_927.446391683186115164 * 1e18, + exchangeRate: 0.902536338221594909 * 1e18 }); - _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max, false); + _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max); _assertBucket({ index: _i9_72, @@ -904,7 +904,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // Borrower2 borrows _borrow({ from: _borrower2, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -922,10 +922,10 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); _assertAuction( @@ -933,23 +933,31 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: kickTime, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2_787.506622839621476352 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.394241979221645667 * 1e18, + borrowerDebt: 9_417.044136515672180411 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986593617011217057 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + 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 @@ -960,32 +968,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 105.285754181824258217 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: kickTime, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853900422492752583 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.888697745467271392 * 1e18, + totalBondEscrowed: 105.285754181824258217 * 1e18, + auctionPrice: 2.722174436366817848 * 1e18, + debtInAuction: 9_417.044136515672180411 * 1e18, + debtToCollateral: 9.417044136515672180 * 1e18, + neutralPrice: 10.888697745467271392 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_853.900422492752583093 * 1e18, + borrowerDebt: 9_417.527901208315548003 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986542937133981323 * 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.367232491646341844 * 1e18, - newLup: 9.721295865031779605 * 1e18 + borrowert0Np: 10.740554498763858415 * 1e18, + borrowerCollateralization: 0.992553456520532021 * 1e18 }); // take entire collateral @@ -993,8 +992,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 43.071075813407140453 * 1e18, - givenAmount: 2_837.29324459172952 * 1e18, + bondChange: 30.434835431641900439 * 1e18, + givenAmount: 2_722.174436366817848000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -1002,13 +1001,13 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.367232491646341844 * 1e18, - depositTime: _startTime + 100 days + 10 hours + lpBalance: 99.393308837291078044 * 1e18, + depositTime: _startTime + 100 days }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_059.678253714430204093 * 1e18, + borrowerDebt: 6_725.788300273139601003 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -1016,20 +1015,20 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertBucket({ index: _i9_91, - lpBalance: 2_099.367232491646341844 * 1e18, + lpBalance: 2_099.301984636377836044 * 1e18, collateral: 0, - deposit: 2_112.735939051273346000 * 1e18, - exchangeRate: 1.006367969525636674 * 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.367232491646341844 * 1e18); + emit BucketBankruptcy(_i9_91, 2_099.301984636377836044 * 1e18); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 6_963.271989687033445101 * 1e18 + settledDebt: 6_725.788300273139601003 * 1e18 }); // bucket is insolvent, balances are resetted @@ -1085,37 +1084,6 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { _mintCollateralAndApproveTokens(actor8, type(uint256).max); } - function test_regression_bankruptcy_on_hpb_with_tiny_deposit() external { - // add liquidity to bucket 2572 - changePrank(actor6); - _pool.addQuoteToken(2_000_000 * 1e18, 2572, block.timestamp + 100, false); - skip(100 days); - - // borrower 6 draws debt and becomes undercollateralized due to interest accrual - ERC20Pool(address(_pool)).drawDebt(actor6, 1_000_000 * 1e18, 7388, 372.489032271806320214 * 1e18); - skip(100 days); - - // borrower 1 kicks borrower 6 and draws debt before auction 6 is settled - changePrank(actor1); - _pool.kick(actor6, 7388); - skip(100 hours); - ERC20Pool(address(_pool)).drawDebt(actor1, 1_000_000 * 1e18, 7388, 10_066_231_386_838.450530455239517417 * 1e18); - skip(100 days); - - // another actor kicks borrower 1 - changePrank(actor2); - _pool.kick(actor1, 7388); - skip(10 days); - - // attempt to deposit tiny amount into bucket 2571, creating new HPB - changePrank(actor3); - vm.expectRevert(abi.encodeWithSignature('AuctionNotCleared()')); - _pool.addQuoteToken(2, 2571, block.timestamp + 100, false); - - // Previous test added quote token successfully, then settled auction 1, bankrupting bucket 2571. - // This is not possible because we prevent depositing into bucket when an uncleared auction exists. - } - function test_regression_settle_with_reserves() external tearDown { changePrank(actor2); _addInitialLiquidity({ @@ -1126,29 +1094,29 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { // no reserves (uint256 reserves, uint256 claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 0); - assertEq(claimableReserves, 0); + assertEq(reserves, 5_151_045.274739797778316842 * 1e18); + assertEq(claimableReserves, 5_150_932.471999326251474014 * 1e18); _drawDebtNoLupCheck({ from: actor2, borrower: actor2, amountToBorrow: 56_403_945_758.4007913129639934 * 1e18, limitIndex: 7388, - collateralToPledge: 21_009_851.171858165566322122 * 1e18 + collateralToPledge: 22_009_851.171858165566322122 * 1e18 }); // origination fee goes to reserves (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 54_234_563.229231556141209574 * 1e18); - assertEq(claimableReserves, 0); + assertEq(reserves, 59_385_608.503971353919526416 * 1e18); + assertEq(claimableReserves, 59_385_495.701230882392683588 * 1e18); // skip some time to make actor2 undercollateralized skip(200 days); ERC20Pool(address(_pool)).updateInterest(); // check reserves after interest accrual (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 289_462_063.392449001089942144 * 1e18); - assertEq(claimableReserves, 0); + assertEq(reserves, 294_613_108.667188773539633581 * 1e18); + assertEq(claimableReserves, 294_612_994.531492467754559135 * 1e18); // kick actor2 changePrank(actor4); @@ -1156,14 +1124,14 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { from: actor4, borrower: actor2, debt: 58_026_363_656.051471906282127718 * 1e18, - collateral: 21_009_851.171858165566322122 * 1e18, - bond: 880_859_922.734477445997454079 * 1e18, - transferAmount: 880_859_922.734477445997454079 * 1e18 + collateral: 22_009_851.171858165566322122 * 1e18, + bond: 648_754_468.110271558372325568 * 1e18, + transferAmount: 648_754_468.110271558372325568 * 1e18 }); // ensure reserves did not increase as result of kick (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 289_462_063.392449001089942144 * 1e18); - assertEq(claimableReserves, 0); + assertEq(reserves, 294_613_108.667188773539633581 * 1e18); + assertEq(claimableReserves, 294_612_994.531492467754559135 * 1e18); changePrank(actor7); _drawDebtNoLupCheck({ @@ -1171,32 +1139,45 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { borrower: actor7, amountToBorrow: 1_000_000 * 1e18, limitIndex: 7388, - collateralToPledge: 372.489032271806320214 * 1e18 + collateralToPledge: 390.489032271806320214 * 1e18 }); // skip some time to make actor7 undercollateralized skip(200 days); - (uint256 borrowerDebt, , ) = _poolUtils.borrowerInfo(address(_pool), actor2); + (uint256 borrowerDebt, , , ) = _poolUtils.borrowerInfo(address(_pool), actor2); assertEq(borrowerDebt, 59_474_936_428.593370593619524964 * 1e18); // reserves increase slightly due to interest accrual (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 289_462_928.777064385704942145 * 1e18); - assertEq(claimableReserves, 0); - + assertEq(reserves, 294_613_974.051804158154633582 * 1e18); + assertEq(claimableReserves, 294_613_859.916107852369559136 * 1e18); + + // test reserves auction cannot be kicked until auction settled + _assertReserveAuctionUnsettledLiquidation(); + // settle auction with reserves changePrank(actor6); _settle({ from: actor6, borrower: actor2, maxDepth: 2, - settledDebt: 56_458_180_321.630022869105202974 * 1e18 + settledDebt: 59_474_936_428.593370593619524963 * 1e18 }); // almost all the reserves are used to settle debt (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 58.732475079196632424 * 1e18); - assertEq(claimableReserves, 0); + assertEq(reserves, 374_644_181.841827555572267504 * 1e18); + assertEq(claimableReserves, 374_644_125.812500127979859369 * 1e18); + + // test reserves auction can be kicked after auction settled + _pool.kickReserveAuction(); + _assertReserveAuction({ + reserves: 56.029327427592408135 * 1e18, + claimableReserves : 0, + claimableReservesRemaining: 374_644_125.812500127979859369 * 1e18, + auctionPrice: 2.669199731428525342 * 1e18, + timeRemaining: 3 days + }); } } @@ -1218,19 +1199,17 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { // lender deposits all liquidity in 3 buckets for(uint i = 0; i < 3; i++) { - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 100_000 * 1e18, - index: _buckets[i], - lpAward: 100_000 * 1e18, - newLup: MAX_PRICE + index: _buckets[i] }); _assertBucket({ index: _buckets[i], - lpBalance: 100_000 * 1e18, + lpBalance: 99_995.433789954337900000 * 1e18, collateral: 0, - deposit: 100_000 * 1e18, + deposit: 99_995.433789954337900000 * 1e18, exchangeRate: 1 * 1e18 }); } @@ -1242,17 +1221,17 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { }); _borrow({ from: _borrower, - amount: 290_000 * 1e18, + amount: 280_000 * 1e18, indexLimit: 7_388, newLup: 2981.007422784467321543 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 290_278.84615384615398 * 1e18, + borrowerDebt: 280_269.230769230769360000 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 3_343.441616215101687356 * 1e18, - borrowerCollateralization: 1.026946145846449373 * 1e18 + borrowert0Np: 3_240.684547040819349457 * 1e18, + borrowerCollateralization: 1.022714224915763456 * 1e18 }); // skip to make borrower undercollateralized @@ -1261,17 +1240,28 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { _kick({ from: _kicker, borrower: _borrower, - debt: 306_628.378237887861419289 * 1e18, + debt: 296_054.985884857245508279 * 1e18, collateral: 100 * 1e18, - bond: 4_654.723000803723493401 * 1e18, - transferAmount: 4_654.723000803723493401 * 1e18 + bond: 3_309.995367581407494354 * 1e18, + transferAmount: 3_309.995367581407494354 * 1e18 }); } - 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, @@ -1282,12 +1272,12 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { // skip some time to make auction settleable skip(73 hours); - (uint256 beforeDebt, uint256 beforeCollateral,) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 beforeDebt, uint256 beforeCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // settle auction with deposits _pool.settle(_borrower, 2); - (uint256 afterDebt, uint256 afterCollateral,) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 afterDebt, uint256 afterCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // ensure some borrower debt is settled assertLt(afterDebt, beforeDebt); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol index 568f5dff9..9690ae6b8 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol @@ -62,7 +62,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); _borrow({ from: _borrower, - amount: 19.25 * 1e18, + amount: 19 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -71,7 +71,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _pledgeCollateral({ from: _borrower2, borrower: _borrower2, - amount: 1_000 * 1e18 + amount: 1_040 * 1e18 }); _borrow({ from: _borrower2, @@ -86,15 +86,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.634254807692307697 * 1e18, + htp: 9.889500000000000005 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000 * 1e18, - pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 823.649613971736296163 * 1e18, - poolDebt: 8_006.941586538461542154 * 1e18, + poolSize: 72_996.666666666666667000 * 1e18, + pledgedCollateral: 1_042 * 1e18, + encumberedCollateral: 856.568827408358955944 * 1e18, + poolDebt: 8_006.691346153846157538 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 400.347079326923077108 * 1e18, + minDebtAmount: 400.334567307692307877 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -103,21 +103,21 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.268509615384615394 * 1e18, + borrowerDebt: 19.018269230769230778 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 1.009034539679184679 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.982991644171270499 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 9.200228999102245332 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 8.880722076025322255 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ - reserves: 7.691586538461542154 * 1e18, - claimableReserves : 0, + reserves: 11.024679487179490538 * 1e18, + claimableReserves : 11.024606490512823871 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -140,14 +140,14 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: _i1505_26, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: _p1505_26 }); _pledgeCollateral({ from: _borrower, borrower: _borrower, - amount: 1_000 * 1e18 + amount: 1_040 * 1e18 }); _borrow({ from: _borrower, @@ -168,13 +168,13 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { PoolParams({ htp: 9.689307692307692312 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_927.443577377932263894 * 1e18, - poolDebt: 18_737.249278846153854794 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_082.000000000000000000 * 1e18, + encumberedCollateral: 2_004.514549350802762384 * 1e18, + poolDebt: 18_736.999038461538470178 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 936.862463942307692740 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 936.849951923076923509 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -184,8 +184,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -193,15 +193,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.689307692307692312 * 1e18, + htp: 9.822951211365485637 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.028587437074993946 * 1e18, - poolDebt: 18_995.690027205926343012 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_082.000000000000000000 * 1e18, + encumberedCollateral: 2_032.162590561266668491 * 1e18, + poolDebt: 18_995.436335284145209602 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 949.784501360296317151 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 949.771816764207260480 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -220,15 +220,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.822951211365485636 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); @@ -236,26 +236,26 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.115738086847591203 * 1e18 + locked: 109.823933241385648657 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 56.765391100119755012 * 1e18, - claimableReserves : 0, + reserves: 60.554587322829041789 * 1e18, + claimableReserves : 60.554504106947293828 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -265,15 +265,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.154429955928583539 * 1e18, + htp: 9.155493589919282477 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_219.674636105806588000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.159641123343178119 * 1e18, - poolDebt: 18_996.964038864342413928 * 1e18, - actualUtilization: 0.225749991311399444 * 1e18, - targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_899.696403886434241393 * 1e18, + poolSize: 83_215.881747961316167813 * 1e18, + pledgedCollateral: 2_082.000000000000000000 * 1e18, + encumberedCollateral: 2_032.298884574722565768 * 1e18, + poolDebt: 18_996.710329927835017232 * 1e18, + actualUtilization: 0.225757284918829265 * 1e18, + targetUtilization: 0.926900343290412163 * 1e18, + minDebtAmount: 1_899.671032992783501723 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -285,22 +285,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 47000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 0.980964776869723804 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 0.946897685981543764 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.823610021566400073 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_823.610021566400073017 * 1e18, - borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040.000000000000000 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989584871924882640 * 1e18 }); @@ -308,10 +308,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _take({ from: _lender, borrower: _borrower2, - maxCollateral: 1_001 * 1e18, - bondChange: 14.891378730546973678 * 1e18, - givenAmount: 980.964776869723804000 * 1e18, - collateralTaken: 1_000 * 1e18, + maxCollateral: 1_100 * 1e18, + bondChange: 11.010103486678303484 * 1e18, + givenAmount: 984.773593420805514560 * 1e18, + collateralTaken: 1_040 * 1e18, isReward: true }); @@ -321,21 +321,21 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: address(0xb012341CA6E91C00A290F658fbaA5211F2559fB1), - bondSize: 164.007116817394564881 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 120.834036728063952141 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 47000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 164.007116817394564881 * 1e18, - auctionPrice: 0.980964776869723804 * 1e18, - debtInAuction: 8_857.536623427223243018 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.314108592233961587 * 1e18 + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 120.834036728063952141 * 1e18, + auctionPrice: 0.946897685981543764 * 1e18, + debtInAuction: 8_849.846531632272862778 * 1e18, + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); // Bad debt remains _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_857.536623427223243018 * 1e18, + borrowerDebt: 8_849.846531632272862778 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -343,15 +343,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.155043929439064212 * 1e18, + htp: 9.155493589919282477 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_220.773168797860489236 * 1e18, - pledgedCollateral: 1_002.0 * 1e18, - encumberedCollateral: 1_854.782622714283711888 * 1e18, - poolDebt: 18_030.890640725165583929 * 1e18, - actualUtilization: 0.175476347926803679 * 1e18, - targetUtilization: 0.962794543732489691 * 1e18, - minDebtAmount: 1_803.089064072516558393 * 1e18, + poolSize: 83_216.980266533218143247 * 1e18, + pledgedCollateral: 1_042.0 * 1e18, + encumberedCollateral: 1_928.124086935418161702 * 1e18, + poolDebt: 18_022.946839993707806992 * 1e18, + actualUtilization: 0.175481652108616020 * 1e18, + targetUtilization: 0.925786822077092381 * 1e18, + minDebtAmount: 1_802.294683999370780699 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.0405 * 1e18, @@ -367,7 +367,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: _i1505_26, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: _p1505_26 }); @@ -395,13 +395,13 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { PoolParams({ htp: 9.689307692307692312 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_927.443577377932263894 * 1e18, - poolDebt: 18_737.249278846153854794 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_004.514549350802762384 * 1e18, + poolDebt: 18_736.999038461538470178 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 936.862463942307692740 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 936.849951923076923509 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -411,8 +411,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_689.307692307692312160 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -420,15 +420,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.689307692307692312 * 1e18, + htp: 9.822951211365485637 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.028587437074993946 * 1e18, - poolDebt: 18_995.690027205926343012 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.162590561266668491 * 1e18, + poolDebt: 18_995.436335284145209602 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 949.784501360296317151 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 949.771816764207260480 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -447,15 +447,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.822951211365485636 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); @@ -463,26 +463,26 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.115738086847591203 * 1e18 + locked: 109.823933241385648657 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 56.765391100119755012 * 1e18, - claimableReserves : 0, + reserves: 60.554587322829041789 * 1e18, + claimableReserves : 60.554504106947293828 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -492,15 +492,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.154429955928583539 * 1e18, + htp: 9.520928012632416038 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_219.674636105806588000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.148487275944809732 * 1e18, - poolDebt: 18_996.855609013749459851 * 1e18, - actualUtilization: 0.225749991311399444 * 1e18, - targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_899.685560901374945985 * 1e18, + poolSize: 83_215.881747961316167813 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.287284728349016606 * 1e18, + poolDebt: 18_996.601901525348298620 * 1e18, + actualUtilization: 0.353544427325713755 * 1e18, + targetUtilization: 0.944118073902160936 * 1e18, + minDebtAmount: 1_899.660190152534829862 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -512,22 +512,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 43000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 1.441757768272869640 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 1.391688189743023672 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.823553950892962846 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_823.553950892962846875 * 1e18, - borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040.000000000000000 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989590520256481315 * 1e18 }); @@ -536,8 +536,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 10 * 1e18, - bondChange: 0.218863729578241083 * 1e18, - givenAmount: 14.417577682728696400 * 1e18, + bondChange: 0.155595469787451318 * 1e18, + givenAmount: 13.916881897430236720 * 1e18, collateralTaken: 10.0 * 1e18, isReward: true }); @@ -548,23 +548,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: address(0xb012341CA6E91C00A290F658fbaA5211F2559fB1), - bondSize: 149.334601816425832286 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.979528711173099975 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 43000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.334601816425832286 * 1e18, - auctionPrice: 1.441757768272869640 * 1e18, - debtInAuction: 9_809.355236939812391565 * 1e18, - thresholdPrice: 9.908439633272537769 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.979528711173099975 * 1e18, + auctionPrice: 1.391688189743023672 * 1e18, + debtInAuction: 9_809.792664465320061476 * 1e18, + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_809.355236939812391565 * 1e18, - borrowerCollateral: 990 * 1e18, - borrowert0Np: 11.256613027484040114 * 1e18, - borrowerCollateralization: 0.981112690275436564 * 1e18 + borrowerDebt: 9_809.792664465320061476 * 1e18, + borrowerCollateral: 1_030 * 1e18, + borrowert0Np: 10.861956351927329673 * 1e18, + borrowerCollateralization: 0.981450087238343546 * 1e18 }); } @@ -574,7 +574,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: _i1505_26, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: _p1505_26 }); @@ -602,13 +602,13 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { PoolParams({ htp: 9.689307692307692312 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_927.443577377932263894 * 1e18, - poolDebt: 18_737.249278846153854794 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_004.514549350802762384 * 1e18, + poolDebt: 18_736.999038461538470178 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 936.862463942307692740 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 936.849951923076923509 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -618,8 +618,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -627,15 +627,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.689307692307692312 * 1e18, + htp: 9.822951211365485637 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.028587437074993946 * 1e18, - poolDebt: 18_995.690027205926343012 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.162590561266668491 * 1e18, + poolDebt: 18_995.436335284145209602 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 949.784501360296317151 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 949.771816764207260480 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -654,15 +654,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.822951211365485636 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); @@ -670,26 +670,26 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.115738086847591203 * 1e18 + locked: 109.823933241385648657 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 56.765391100119755012 * 1e18, - claimableReserves : 0.000000000000000000 * 1e18, + reserves: 60.554587322829041789 * 1e18, + claimableReserves : 60.554504106947293828 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -699,15 +699,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.154429955928583539 * 1e18, + htp: 9.520642715125814291 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_219.674636105806588000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.089930621571444937 * 1e18, - poolDebt: 18_996.286362451719573593 * 1e18, - actualUtilization: 0.225749991311399444 * 1e18, - targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_899.628636245171957359 * 1e18, + poolSize: 83_215.881747961316167813 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.226386621120168430 * 1e18, + poolDebt: 18_996.032662565740545058 * 1e18, + actualUtilization: 0.353544427325713755 * 1e18, + targetUtilization: 0.944118073902160936 * 1e18, + minDebtAmount: 1_899.603266256574054506 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -719,22 +719,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 22000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 10.886704980656377540 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 10.508629868487414000 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.823259585107984853 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_823.259585107984853687 * 1e18, - borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040.000000000000000 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989620174526306750 * 1e18 }); @@ -743,8 +743,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 577 * 1e18, - bondChange: 27.337468146252670459 * 1e18, - givenAmount: 6_281.628773838729840580 * 1e18, + bondChange: 18.948075348653218429 * 1e18, + givenAmount: 6_063.479434117237878000 * 1e18, collateralTaken: 577 * 1e18, isReward: true }); @@ -755,23 +755,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 176.453206233100261662 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 128.772008590038867086 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 22000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 176.453206233100261662 * 1e18, - auctionPrice: 10.886704980656377540 * 1e18, - debtInAuction: 3_653.993019025148320626 * 1e18, - thresholdPrice: 8.638281368853778535 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 128.772008590038867086 * 1e18, + auctionPrice: 10.508629868487414000 * 1e18, + debtInAuction: 3_839.782833371446802894 * 1e18, + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 3_653.993019025148320626 * 1e18, - borrowerCollateral: 423.000000000000000000 * 1e18, - borrowert0Np: 9.813927120521769770 * 1e18, - borrowerCollateralization: 1.136655711572588218 * 1e18 + borrowerDebt: 3_839.782833371446802894 * 1e18, + borrowerCollateral: 463.000000000000000000 * 1e18, + borrowert0Np: 9.458540661328534467 * 1e18, + borrowerCollateralization: 1.138406255550587998 * 1e18 }); } @@ -786,17 +786,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.689307692307692312 * 1e18, + htp: 9.889500000000000005 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_000.000000000000000000 * 1e18, - pledgedCollateral: 1_002.000000000000000000 * 1e18, - encumberedCollateral: 998.691567123838268658 * 1e18, - poolDebt: 9_708.576201923076927554 * 1e18, + poolSize: 72_996.666666666666667000 * 1e18, + pledgedCollateral: 1_042.000000000000000000 * 1e18, + encumberedCollateral: 1_038.612458686545007338 * 1e18, + poolDebt: 9_708.325961538461542938 * 1e18, actualUtilization: 0, targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 485.428810096153846378 * 1e18, + minDebtAmount: 485.416298076923077147 * 1e18, loans: 2, - maxBorrower: address(_borrower2), + maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, interestRateUpdate: block.timestamp }) @@ -804,8 +804,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_689.307692307692312160 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -815,9 +815,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); _assertAuction( @@ -825,32 +825,32 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 2_896.411799611894166272 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 2_795.824779207511593472 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.822951211365485636 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.115738086847591203 * 1e18 + locked: 109.823933241385648657 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 29.412595036010327036 * 1e18, - claimableReserves : 0 * 1e18, + reserves: 32.745170254153414999 * 1e18, + claimableReserves : 32.745097143666787832 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -860,15 +860,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.767138988573636287 * 1e18, + htp: 10.025973419606037281 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_113.822894306622582000 * 1e18, - pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_012.473341055493309162 * 1e18, - poolDebt: 9_842.552903857677844743 * 1e18, - actualUtilization: 0.539365344551282052 * 1e18, - targetUtilization: 0.996698234880015451 * 1e18, - minDebtAmount: 984.255290385767784474 * 1e18, + poolSize: 73_110.486627166698360626 * 1e18, + pledgedCollateral: 1_042 * 1e18, + encumberedCollateral: 1_052.945134138528111945 * 1e18, + poolDebt: 9_842.299210198274857970 * 1e18, + actualUtilization: 0.539376071352046283 * 1e18, + targetUtilization: 0.958413284343188833 * 1e18, + minDebtAmount: 984.229921019827485797 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -880,22 +880,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 80 minutes, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 181.025737475743385344 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 174.739048700469474560 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.823018492083647863 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_823.018492083647863197 * 1e18, - borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040.000000000000000 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989644463447376554 * 1e18 }); @@ -904,23 +904,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 10.0 * 1e18, - bondChange: 27.480322232669404372 * 1e18, - givenAmount: 1_810.257374757433853440 * 1e18, + bondChange: 19.536419560894800810 * 1e18, + givenAmount: 1_747.390487004694745600 * 1e18, collateralTaken: 10.0 * 1e18, isReward: false }); _assertPool( PoolParams({ - htp: 9.767205887014990773 * 1e18, + htp: 10.025973419606037281 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_113.882499196138656000 * 1e18, - pledgedCollateral: 992.0 * 1e18, - encumberedCollateral: 830.497921731842609849 * 1e18, - poolDebt: 8_073.516012449248097864 * 1e18, - actualUtilization: 0.539405362783948025 * 1e18, - targetUtilization: 0.996698410914855915 * 1e18, - minDebtAmount: 807.351601244924809786 * 1e18, + poolSize: 73_110.546230580506993313 * 1e18, + pledgedCollateral: 1_032.0 * 1e18, + encumberedCollateral: 869.141522276742086572 * 1e18, + poolDebt: 8_124.213352534922313590 * 1e18, + actualUtilization: 0.539415570795639499 * 1e18, + targetUtilization: 0.958414005019059000 * 1e18, + minDebtAmount: 812.421335253492231359 * 1e18, loans: 1, // TODO: is this test still relevant like this? maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -933,23 +933,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 121.635415854178186831 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 90.287513680490847847 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 80 minutes, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 121.635415854178186831 * 1e18, - auctionPrice: 181.025737475743385344 * 1e18, - debtInAuction: 8_053.981600675218116317 * 1e18, - thresholdPrice: 8.135334950176987996 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 90.287513680490847847 * 1e18, + auctionPrice: 174.739048700469474560 * 1e18, + debtInAuction: 8_104.932634420295318817 * 1e18, + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_053.981600675218116317 * 1e18, - borrowerCollateral: 990.000000000000000000 * 1e18, - borrowert0Np: 9.242757957291237631 * 1e18, - borrowerCollateralization: 1.194947217854906920 * 1e18 + borrowerDebt: 8_104.932634420295318817 * 1e18, + borrowerCollateral: 1_030.000000000000000000 * 1e18, + borrowert0Np: 8.974728252382013189 * 1e18, + borrowerCollateralization: 1.187896593420381978 * 1e18 }); } @@ -960,7 +960,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: _i1505_26, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: _p1505_26 }); @@ -988,13 +988,13 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { PoolParams({ htp: 9.689307692307692312 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_927.443577377932263894 * 1e18, - poolDebt: 18_737.249278846153854794 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_004.514549350802762384 * 1e18, + poolDebt: 18_736.999038461538470178 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 936.862463942307692740 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 936.849951923076923509 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -1004,8 +1004,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -1013,15 +1013,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.689307692307692312 * 1e18, + htp: 9.822951211365485637 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.000000000000000000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.028587437074993946 * 1e18, - poolDebt: 18_995.690027205926343012 * 1e18, + poolSize: 82_996.210045662100457000 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.162590561266668491 * 1e18, + poolDebt: 18_995.436335284145209602 * 1e18, actualUtilization: 0, - targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 949.784501360296317151 * 1e18, + targetUtilization: 1 * 1e18, + minDebtAmount: 949.771816764207260480 * 1e18, loans: 2, maxBorrower: address(_borrower2), interestRate: 0.05 * 1e18, @@ -1040,15 +1040,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.822951211365485636 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); @@ -1056,26 +1056,26 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.115738086847591203 * 1e18 + locked: 109.823933241385648657 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 56.765391100119755012 * 1e18, - claimableReserves : 0, + reserves: 60.554587322829041789 * 1e18, + claimableReserves : 60.554504106947293828 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1085,15 +1085,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 9.154429955928583539 * 1e18, + htp: 9.520642715125814291 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_219.674636105806588000 * 1e18, - pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_954.089930621571444937 * 1e18, - poolDebt: 18_996.286362451719573593 * 1e18, - actualUtilization: 0.225749991311399444 * 1e18, - targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_899.628636245171957359 * 1e18, + poolSize: 83_215.881747961316167813 * 1e18, + pledgedCollateral: 2_042.000000000000000000 * 1e18, + encumberedCollateral: 2_032.226386621120168430 * 1e18, + poolDebt: 18_996.032662565740545058 * 1e18, + actualUtilization: 0.353544427325713755 * 1e18, + targetUtilization: 0.944118073902160936 * 1e18, + minDebtAmount: 1_899.603266256574054506 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -1105,22 +1105,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.115738086847591203 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 109.823933241385648657 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 22000 seconds, - referencePrice: 11.314108592233961587 * 1e18, - totalBondEscrowed: 149.115738086847591203 * 1e18, - auctionPrice: 10.886704980656377540 * 1e18, + referencePrice: 10.921190543779342162 * 1e18, + totalBondEscrowed: 109.823933241385648657 * 1e18, + auctionPrice: 10.508629868487414000 * 1e18, debtInAuction: 9_822.951211365485636463 * 1e18, - thresholdPrice: 9.823259585107984853 * 1e18, - neutralPrice: 11.314108592233961587 * 1e18 + debtToCollateral: 9.445145395543736189 * 1e18, + neutralPrice: 10.921190543779342162 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_823.259585107984853687 * 1e18, - borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateral: 1_040.000000000000000 * 1e18, + borrowert0Np: 10.772605225053273112 * 1e18, borrowerCollateralization: 0.989620174526306750 * 1e18 }); @@ -1129,9 +1129,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_001 * 1e18, - bondChange: 43.529168844258845077 * 1e18, - givenAmount: 10_002.172770738542860841 * 1e18, - collateralTaken: 918.751154597329341626 * 1e18, + bondChange: 31.107643684582954716 * 1e18, + givenAmount: 9_954.602473053939912630 * 1e18, + collateralTaken: 947.278817279990525519 * 1e18, isReward: true }); @@ -1145,17 +1145,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 192.644906931106436280 * 1e18, + totalBondEscrowed: 140.931576925968603373 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 81.248845402670658374 * 1e18, + borrowerCollateral: 92.721182720009474481 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -1177,8 +1177,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.805991398271413421 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); @@ -1186,9 +1186,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_853.394241979221645666 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + collateral: 1_040 * 1e18, + bond: 110.164296670852752941 * 1e18, + transferAmount: 110.164296670852752941 * 1e18 }); _assertAuction( @@ -1196,106 +1196,37 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 2_804.489525424063798784 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.577873638769639523 * 1e18 + locked: 110.164296670852752941 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.805991398271413421 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertReserveAuction({ - reserves: 29.503568858839974240 * 1e18, - claimableReserves : 0, + reserves: 32.836144076983058586 * 1e18, + claimableReserves : 32.836070966144374628 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - uint256 preTakeSnapshot = vm.snapshot(); - - skip(500 minutes); - - _assertAuction( - AuctionParams({ - borrower: _borrower2, - active: true, - kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, - kickTime: block.timestamp - 500 minutes, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 5.055481829190032044 * 1e18, - debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853816057268096589 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 - }) - ); - _assertBorrower({ - borrower: _borrower2, - borrowerDebt: 9_853.816057268096589430 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, - borrowerCollateralization: 0.986551383599395369 * 1e18 - }); - - _take({ - from: _lender, - borrower: _borrower2, - maxCollateral: 1_000 * 1e18, - bondChange: 76.743932462179586888 * 1e18, - givenAmount: 5_055.481829190032044 * 1e18, - collateralTaken: 1000.0 * 1e18, - isReward: true - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower2, - active: true, - kicker: _lender, - bondSize: 226.321806100949226411 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, - kickTime: block.timestamp - 500 minutes, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 226.321806100949226411 * 1e18, - auctionPrice: 5.055481829190032044 * 1e18, - debtInAuction: 4_875.078160540244132430 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.34917297836691808 * 1e18 - }) - ); - _assertBorrower({ - borrower: _borrower2, - borrowerDebt: 4_875.078160540244132430 * 1e18, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 0 - }); - _assertKicker({ - kicker: _lender, - claimable: 0, - locked: 226.321806100949226411 * 1e18 - }); - - vm.revertTo(preTakeSnapshot); - // skip ahead so take can be called on the loan skip(10 hours); @@ -1304,22 +1235,22 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 11.34917297836691808 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 2.738759302171937304 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853900422492752583 * 1e18, - neutralPrice: 11.34917297836691808 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.900422492752583093 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.805991398271413421 * 1e18, borrowerCollateralization: 0.986542937133981323 * 1e18 }); @@ -1329,8 +1260,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 20 * 1e18, - bondChange: 0.861421516268142809 * 1e18, - givenAmount: 56.745864891834590400 * 1e18, + bondChange: 0.612405197366633896 * 1e18, + givenAmount: 54.775186043438746080 * 1e18, collateralTaken: 20 * 1e18, isReward: true }); @@ -1340,33 +1271,33 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 150.439295155037782332 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.776701868219386837 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 150.439295155037782332 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 9_798.015979117186135514 * 1e18, - thresholdPrice: 9.997975488895087893 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.776701868219386837 * 1e18, + auctionPrice: 2.738759302171937304 * 1e18, + debtInAuction: 9_799.737641646680470914 * 1e18, + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_798.015979117186135514 * 1e18, - borrowerCollateral: 980 * 1e18, - borrowert0Np: 11.358444866850947120 * 1e18, - borrowerCollateralization: 0.972326435069717785 * 1e18 + borrowerDebt: 9_799.737641646680470914 * 1e18, + borrowerCollateral: 1_020 * 1e18, + borrowert0Np: 10.957312926703812841 * 1e18, + borrowerCollateralization: 0.972918685813433277 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 150.439295155037782332 * 1e18 // locked bond + reward, auction is not yet finished + locked: 110.776701868219386837 * 1e18 // locked bond + reward, auction is not yet finished }); // reserves should increase after take action _assertReserveAuction({ - reserves: 29.562252507398080560 * 1e18, - claimableReserves : 0, + reserves: 32.894825757206621408 * 1e18, + claimableReserves : 32.894752645919448151 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1376,10 +1307,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _take({ from: _lender, borrower: _borrower2, - maxCollateral: 981 * 1e18, - bondChange: 42.209654297138997644 * 1e18, - givenAmount: 2_780.547379699894929600 * 1e18, - collateralTaken: 980 * 1e18, + maxCollateral: 1_021 * 1e18, + bondChange: 31.232665065698328745 * 1e18, + givenAmount: 2_793.534488215376050080 * 1e18, + collateralTaken: 1_020 * 1e18, isReward: true }); @@ -1388,20 +1319,20 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 192.648949452176779976 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 142.009366933917715582 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 192.648949452176779976 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 7_059.678253714430204094 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 142.009366933917715582 * 1e18, + auctionPrice: 2.738759302171937304 * 1e18, + debtInAuction: 7_037.435818497002749734 * 1e18, + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_059.678253714430204094 * 1e18, + borrowerDebt: 7_037.435818497002749734 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -1409,12 +1340,12 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertKicker({ kicker: _lender, claimable: 0, - locked: 192.648949452176779976 * 1e18 // locked bond + reward, auction is not yet finalized + locked: 142.009366933917715582 * 1e18 // locked bond + reward, auction is not yet finalized }); // reserves should increase after take action _assertReserveAuction({ - reserves: 29.562252507398081096 * 1e18, - claimableReserves : 0, + reserves: 32.894825757206621563 * 1e18, + claimableReserves : 32.894752645919448306 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1432,17 +1363,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBucket({ index: 3_696, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 2_012.735939051273346000 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 2_012.644287642503398926 * 1e18, + exchangeRate: 1.006368096702379663 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 6_963.271989687033445102 * 1e18 + settledDebt: 7_037.435818497002749733 * 1e18 }); _assertAuction( @@ -1454,10 +1385,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 192.648949452176779976 * 1e18, + totalBondEscrowed: 142.009366933917715582 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -1470,7 +1401,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); _assertKicker({ kicker: _lender, - claimable: 192.648949452176779976 * 1e18, + claimable: 142.009366933917715582 * 1e18, locked: 0 }); _assertBucket({ @@ -1488,77 +1419,77 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); _assertBucket({ index: _i9_81, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 14.459712357801136539 * 1e18, - exchangeRate: 0.002891942471560228 * 1e18 + deposit: 11.556640377957587523 * 1e18, + exchangeRate: 0.002311433620505696 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: _i9_81, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); _assertBucket({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 11_070.047664782003403 * 1e18, - exchangeRate: 1.006367969525636673 * 1e18 + deposit: 11_069.543582033768694092 * 1e18, + exchangeRate: 1.006368096702379662 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, depositTime: _startTime }); _assertBucket({ index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, collateral: 0, - deposit: 25_000 * 1e18, + deposit: 24_998.858447488584475000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: _i9_62, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, depositTime: _startTime }); _assertBucket({ index: _i9_52, - lpBalance: 30_000 * 1e18, + lpBalance: 29_998.630136986301370000 * 1e18, collateral: 0, - deposit: 30_000 * 1e18, + deposit: 29_998.630136986301370000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: _i9_52, - lpBalance: 30_000 * 1e18, + lpBalance: 29_998.630136986301370000 * 1e18, depositTime: _startTime }); - // done - + vm.revertTo(postTakeSnapshot); _assertReserveAuction({ - reserves: 29.562252507398081096 * 1e18, - claimableReserves : 0, + reserves: 32.894825757206621563 * 1e18, + claimableReserves : 32.894752645919448306 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); + // partial clears / debt settled - max buckets to use is 0, settle only from reserves _settle({ from: _lender, borrower: _borrower2, maxDepth: 0, - settledDebt: 29.158481211449497738 * 1e18 + settledDebt: 4.737452126198441015 * 1e18 }); _assertReserveAuction({ - reserves: 0.000073114623451463 * 1e18, - claimableReserves : 0, + reserves: 28.157373631008180548 * 1e18, + claimableReserves : 28.157300519721007291 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1569,7 +1500,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 1_985.25021726848337055 * 1e18 + settledDebt: 2_012.644287642503398926 * 1e18 }); _assertAuction( @@ -1577,20 +1508,20 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 192.648949452176779976 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 142.009366933917715582 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 192.648949452176779976 * 1e18, - auctionPrice: 2.837293244591729520 * 1e18, - debtInAuction: 5_017.380135270382228461 * 1e18, - thresholdPrice: 0, - neutralPrice: 11.349172978366918080 * 1e18 + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 142.009366933917715582 * 1e18, + auctionPrice: 2.738759302171937304 * 1e18, + debtInAuction: 5_020.054078728300909793 * 1e18, + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 5_017.380135270382228461 * 1e18, + borrowerDebt: 5_020.054078728300909793 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -1598,7 +1529,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertKicker({ kicker: _lender, claimable: 0, - locked: 192.648949452176779976 * 1e18 // locked bond + reward, auction is not yet finalized + locked: 142.009366933917715582 * 1e18 // locked bond + reward, auction is not yet finalized }); // clear remaining debt @@ -1606,7 +1537,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 5, - settledDebt: 4_948.863291207100576814 * 1e18 + settledDebt: 5_020.054078728300909792 * 1e18 }); _assertAuction( @@ -1618,10 +1549,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 192.648949452176779976 * 1e18, + totalBondEscrowed: 142.009366933917715582 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -1634,16 +1565,16 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); _assertKicker({ kicker: _lender, - claimable: 192.648949452176779976 * 1e18, + claimable: 142.009366933917715582 * 1e18, locked: 0 }); // kicker withdraws his auction bonds - assertEq(_quote.balanceOf(_lender), 44_013.128881769500840477 * 1e18); + assertEq(_quote.balanceOf(_lender), 44_041.526029070332450899 * 1e18); _pool.withdrawBonds(_lender, type(uint256).max); - assertEq(_quote.balanceOf(_lender), 44_205.777831221677620453 * 1e18); + assertEq(_quote.balanceOf(_lender), 44_183.535396004250166481 * 1e18); _assertKicker({ kicker: _lender, @@ -1669,9 +1600,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_853.394241979221645666 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + collateral: 1_040 * 1e18, + bond: 110.164296670852752941 * 1e18, + transferAmount: 110.164296670852752941 * 1e18 }); _assertAuction( @@ -1679,32 +1610,32 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 2_804.489525424063798784 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.805991398271413421 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.577873638769639523 * 1e18 + locked: 110.164296670852752941 * 1e18 }); _assertReserveAuction({ - reserves: 29.503568858839974240 * 1e18, - claimableReserves : 0, + reserves: 32.836144076983058586 * 1e18, + claimableReserves : 32.836070966144374628 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1722,28 +1653,28 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 149.577873638769639523 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, auctionPrice: 0, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.888301125810259647 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.776602251620519295 * 1e18, + borrowerDebt: 19.519763261339733329 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.096767433127708186 * 1e18, - borrowerCollateralization: 0.983110823724556080 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.957737011978628772 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.776602251620519294 * 1e18, + debt: 19.519763261339733329 * 1e18, collateral: 2 * 1e18, - bond: 0.300215543999476476 * 1e18, - transferAmount: 0.300215543999476476 * 1e18 + bond: 0.218237587785293172 * 1e18, + transferAmount: 0.218237587785293172 * 1e18 }); _assertAuction( @@ -1751,21 +1682,21 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.300215543999476476 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.218237587785293172 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.389378845807642064 * 1e18, - totalBondEscrowed: 149.878089182769115999 * 1e18, - auctionPrice: 2_915.680984526756368384 * 1e18, - debtInAuction: 9_995.402984757347394196 * 1e18, - thresholdPrice: 9.888301125810259647 * 1e18, - neutralPrice: 11.389378845807642064 * 1e18 + referencePrice: 11.285112352380185868 * 1e18, + totalBondEscrowed: 110.382534258638046113 * 1e18, + auctionPrice: 2_888.988762209327582208 * 1e18, + debtInAuction: 9_995.146145767066608231 * 1e18, + debtToCollateral: 9.759881630669866665 * 1e18, + neutralPrice: 11.285112352380185868 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.878089182769115999 * 1e18 + locked: 110.382534258638046113 * 1e18 }); skip(2 hours); @@ -1788,7 +1719,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender1, amount: 1 * 1e18, index: _i9_91, - lpAward: 1 * 1e18, + lpAward: 0.999954337899543379 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -1807,37 +1738,37 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_853.394241979221645666 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + collateral: 1_040 * 1e18, + bond: 110.164296670852752941 * 1e18, + transferAmount: 110.164296670852752941 * 1e18 }); _assertAuction( AuctionParams({ borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 2_905.388282461931028480 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 2_804.489525424063798784 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853394241979221645 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, - borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateral: 1_040 * 1e18, + borrowert0Np: 10.805991398271413421 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 149.577873638769639523 * 1e18 + locked: 110.164296670852752941 * 1e18 }); // after 6 hours, auction price should equal neutral price @@ -1847,15 +1778,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6 hours, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 11.349172978366918080 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 10.955037208687749216 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853697947167044034 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); @@ -1866,15 +1797,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 149.577873638769639523 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 110.164296670852752941 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 7 hours, - referencePrice: 11.349172978366918080 * 1e18, - totalBondEscrowed: 149.577873638769639523 * 1e18, - auctionPrice: 8.025077173862374200 * 1e18, + referencePrice: 10.955037208687749214 * 1e18, + totalBondEscrowed: 110.164296670852752941 * 1e18, + auctionPrice: 7.746381098414054648 * 1e18, debtInAuction: 9_853.394241979221645667 * 1e18, - thresholdPrice: 9.853748565608429470 * 1e18, - neutralPrice: 11.349172978366918080 * 1e18 + debtToCollateral: 9.474417540364636198 * 1e18, + neutralPrice: 10.955037208687749214 * 1e18 }) ); @@ -1882,17 +1813,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _take({ from: _lender, borrower: _borrower2, - maxCollateral: 1_001 * 1e18, - bondChange: 121.823399122640329123 * 1e18, - givenAmount: 8_025.0771738623742 * 1e18, - collateralTaken: 1_000 * 1e18, + maxCollateral: 1_041 * 1e18, + bondChange: 90.071460521501231737 * 1e18, + givenAmount: 8_056.236342350616833920 * 1e18, + collateralTaken: 1_040 * 1e18, isReward: true }); // borrower left with bad debt to be settled _assertBorrower({ borrower: _borrower2, - borrowerDebt: 1950.49479086869560036 * 1e18, + borrowerDebt: 1_887.583683779313868200 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -1905,7 +1836,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: _i1505_26, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: _p1505_26 }); @@ -1935,9 +1866,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, debt: 9_822.951211365485636462 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.115738086847591203 * 1e18, - transferAmount: 149.115738086847591203 * 1e18 + collateral: 1_040 * 1e18, + bond: 109.823933241385648657 * 1e18, + transferAmount: 109.823933241385648657 * 1e18 }); skip(43000 seconds); // 11.94 hrs @@ -1951,10 +1882,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _take({ from: _lender, borrower: _borrower2, - maxCollateral: 1_001 * 1e18, - bondChange: 21.886372957824108251 * 1e18, - givenAmount: 1_441.75776827286964 * 1e18, - collateralTaken: 1000 * 1e18, + maxCollateral: 1_041 * 1e18, + bondChange: 16.181928857894937154 * 1e18, + givenAmount: 1_447.355717332744618880 * 1e18, + collateralTaken: 1040 * 1e18, isReward: true }); @@ -1998,7 +1929,7 @@ contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { borrower: _borrower, amountToBorrow: 750 * 1e18, limitIndex: _i0_00016+1, - collateralToPledge: Maths.wmul(Maths.wdiv(750 * 1e18, _p0_00016), 1.01 * 1e18), + collateralToPledge: Maths.wmul(Maths.wdiv(750 * 1e18, _p0_00016), 1.05 * 1e18), newLup: _p0_00016 }); @@ -2009,9 +1940,9 @@ contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { from: _lender, borrower: _borrower, debt: 761.075765343400230098 * 1e18, - collateral: 47_084_428.598115880943744161 * 1e18, - bond: 11.553388798051207996 * 1e18, - transferAmount: 11.553388798051207996 * 1e18 + collateral: 48_949_158.443585816822704326 * 1e18, + bond: 8.509085736677607076 * 1e18, + transferAmount: 8.509085736677607076 * 1e18 }); _assertAuction( @@ -2019,23 +1950,23 @@ contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 11.553388798051207996 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 8.509085736677607076 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 0.000018617825030991 * 1e18, - totalBondEscrowed: 11.553388798051207996 * 1e18, - auctionPrice: 0.004766163207933696 * 1e18, + referencePrice: 0.000017978108625356 * 1e18, + totalBondEscrowed: 8.509085736677607076 * 1e18, + auctionPrice: 0.004602395808091136 * 1e18, debtInAuction: 761.075765343400230098 * 1e18, - thresholdPrice: 0.000016164065021144 * 1e18, - neutralPrice: 0.000018617825030991 * 1e18 + debtToCollateral: 0.000015548291115577 * 1e18, + neutralPrice: 0.000017978108625356 * 1e18 }) ); _assertBorrower({ borrower: _borrower, borrowerDebt: 761.075765343400230098 * 1e18, - borrowerCollateral: 47_084_428.598115880943744161 * 1e18, - borrowert0Np: 0.000018364525223142 * 1e18, - borrowerCollateralization: 0.995301695959551634 * 1e18 + borrowerCollateral: 48_949_158.443585816822704326 * 1e18, + borrowert0Np: 0.000017733512306898 * 1e18, + borrowerCollateralization: 0.994922677796581507 * 1e18 }); // should revert if take occurs at 0 price @@ -2045,15 +1976,15 @@ contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 11.553388798051207996 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 8.509085736677607076 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime + 100 days, - referencePrice: 0.000018617825030991 * 1e18, - totalBondEscrowed: 11.553388798051207996 * 1e18, + referencePrice: 0.000017978108625356 * 1e18, + totalBondEscrowed: 8.509085736677607076 * 1e18, auctionPrice: 0 * 1e18, debtInAuction: 761.075765343400230098 * 1e18, - thresholdPrice: 0.000016169961551610 * 1e18, - neutralPrice: 0.000018617825030991 * 1e18 + debtToCollateral: 0.000015548291115577 * 1e18, + neutralPrice: 0.000017978108625356 * 1e18 }) ); _assertTakeZeroBidRevert({ @@ -2106,7 +2037,7 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra borrower: _borrower, amountToBorrow: 635.189921955815900534 * 1e18, limitIndex: 7000, - collateralToPledge: 0.428329945169804100 * 1e18 + collateralToPledge: 0.448329945169804100 * 1e18 }); skip(3276); @@ -2116,7 +2047,7 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra borrower: _borrower, amountToRepay: type(uint256).max, amountRepaid: 635.803983894118939950 * 1e18, - collateralToPull: 0.428329945169804100 * 1e18 + collateralToPull: 0.448329945169804100 * 1e18 }); _drawDebtNoLupCheck({ @@ -2124,7 +2055,7 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra borrower: _borrower, amountToBorrow: 100 * 1e18, limitIndex: 7000, - collateralToPledge: 0.067433366047580170 * 1e18 + collateralToPledge: 0.07 * 1e18 }); skip(964); @@ -2134,9 +2065,9 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra from: _kicker, borrower: _borrower, debt: 102.876583480271499176 * 1e18, - collateral: 0.067433366047580170 * 1e18, - bond: 1.561701503695180782 * 1e18, - transferAmount: 1.561701503695180782 * 1e18 + collateral: 0.070000000000000000 * 1e18, + bond: 1.150195169774094785 * 1e18, + transferAmount: 1.150195169774094785 * 1e18 }); skip(964); @@ -2148,9 +2079,9 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra from: _taker, borrower: _borrower, maxCollateral: 0.067433366047580170 * 1e18, - bondChange: 1.561701503695180782 * 1e18, - givenAmount: 105.275486946083517714 * 1e18, - collateralTaken: 0.023241640918094312 * 1e18, + bondChange: 1.150195169774094785 * 1e18, + givenAmount: 104.633060200351870411 * 1e18, + collateralTaken: 0.023886288632228204 * 1e18, isReward: false }); @@ -2175,34 +2106,32 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { // lender deposits all liquidity in 5 buckets for(uint i = 0; i < 5; i++) { - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 100_000 * 1e18, - index: _buckets[i], - lpAward: 100_000 * 1e18, - newLup: MAX_PRICE + index: _buckets[i] }); } _pledgeCollateral({ from: _borrower, borrower: _borrower, - amount: 100 * 1e18 + amount: 102 * 1e18 }); _borrow({ from: _borrower, - amount: 290_000 * 1e18, + amount: 280_000 * 1e18, indexLimit: 7_388, - newLup: 2981.007422784467321543 * 1e18 + newLup: 2_981.007422784467321543 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 290_278.84615384615398 * 1e18, - borrowerCollateral: 100 * 1e18, - borrowert0Np: 3_343.441616215101687356 * 1e18, - borrowerCollateralization: 1.026946145846449373 * 1e18 + borrowerDebt: 280_269.230769230769360000 * 1e18, + borrowerCollateral: 102 * 1e18, + borrowert0Np: 3_177.141712785117009272 * 1e18, + borrowerCollateralization: 1.043168509414078725 * 1e18 }); // skip to make borrower undercollateralized @@ -2211,10 +2140,10 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { _kick({ from: _taker, borrower: _borrower, - debt: 306_628.378237887861419289 * 1e18, - collateral: 100 * 1e18, - bond: 4_654.723000803723493401 * 1e18, - transferAmount: 4_654.723000803723493401 * 1e18 + debt: 296_054.985884857245508279 * 1e18, + collateral: 102 * 1e18, + bond: 3_309.995367581407494354 * 1e18, + transferAmount: 3_309.995367581407494354 * 1e18 }); } @@ -2223,7 +2152,7 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { // skip some time to make auction takeable skip(skipTimeToTake); - (,,,, uint256 auctionPrice, ) = _poolUtils.auctionStatus(address(_pool), _borrower); + (,,,, uint256 auctionPrice, , , , ) = _poolUtils.auctionStatus(address(_pool), _borrower); uint256 minCollateralTakeAmount = Maths.max(Maths.wdiv(1, auctionPrice), 1); @@ -2239,12 +2168,12 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { uint256 beforeTakerQuoteBalance = _quote.balanceOf(_taker); - (, uint256 beforeCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (, uint256 beforeCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // taker takes fuzzed amount of collateral _pool.take(_borrower, takeAmount, _taker, bytes("")); - (, uint256 afterCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (, uint256 afterCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // ensure borrower collateral is reduced after take assertLt(afterCollateral, beforeCollateral); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLoanHeap.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLoanHeap.t.sol index e6357db10..dd1a15c66 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLoanHeap.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLoanHeap.t.sol @@ -116,12 +116,12 @@ contract ERC20PoolLoanHeapTest is ERC20HelperContract { }); _assertLoans({ - noOfLoans: 6, - maxBorrower: _borrower6, - maxThresholdPrice: 6.005769230769230772 * 1e18 + noOfLoans: 6, + maxBorrower: _borrower6, + maxT0DebtToCollateral: 6.005769230769230772 * 1e18 }); - // borrower 4 draws debt and becomes loan with highest threshold price in heap + // borrower 4 draws debt and becomes loan with highest t0 debt to collateral in heap _drawDebt({ from: _borrower4, borrower: _borrower4, @@ -132,12 +132,12 @@ contract ERC20PoolLoanHeapTest is ERC20HelperContract { }); _assertLoans({ - noOfLoans: 6, - maxBorrower: _borrower4, - maxThresholdPrice: 14.013461538461538468 * 1e18 + noOfLoans: 6, + maxBorrower: _borrower4, + maxT0DebtToCollateral: 14.013461538461538468 * 1e18 }); - // borrower 4 repays debt, borrower 6 becomes loan with highest threshold price in heap + // borrower 4 repays debt, borrower 6 becomes loan with highest t0 debt to collateral in heap _repayDebt({ from: _borrower4, borrower: _borrower4, @@ -148,12 +148,12 @@ contract ERC20PoolLoanHeapTest is ERC20HelperContract { }); _assertLoans({ - noOfLoans: 6, - maxBorrower: _borrower6, - maxThresholdPrice: 6.005769230769230772 * 1e18 + noOfLoans: 6, + maxBorrower: _borrower6, + maxT0DebtToCollateral: 6.005769230769230772 * 1e18 }); - // borrower 6 repays debt, borrower 5 becomes loan with highest threshold price in heap + // borrower 6 repays debt, borrower 5 becomes loan with highest t0 debt to collateral in heap _repayDebt({ from: _borrower6, borrower: _borrower6, @@ -164,12 +164,12 @@ contract ERC20PoolLoanHeapTest is ERC20HelperContract { }); _assertLoans({ - noOfLoans: 6, - maxBorrower: _borrower5, - maxThresholdPrice: 5.004807692307692310 * 1e18 + noOfLoans: 6, + maxBorrower: _borrower5, + maxT0DebtToCollateral: 5.004807692307692310 * 1e18 }); - // borrower 6 draws more debt and becomes loan with highest threshold price in heap + // borrower 6 draws more debt and becomes loan with highest t0 debt to collateral in heap _drawDebt({ from: _borrower6, borrower: _borrower6, @@ -180,9 +180,9 @@ contract ERC20PoolLoanHeapTest is ERC20HelperContract { }); _assertLoans({ - noOfLoans: 6, - maxBorrower: _borrower6, - maxThresholdPrice: 12.016346153846153854 * 1e18 + noOfLoans: 6, + maxBorrower: _borrower6, + maxT0DebtToCollateral: 12.016346153846153854 * 1e18 }); } } \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol index b64a6c9e6..942d58a2d 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol @@ -33,40 +33,38 @@ contract ERC20PoolMulticallTest is ERC20HelperContract { bytes[] memory callsToExecute = new bytes[](3); callsToExecute[0] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256,bool)", + "addQuoteToken(uint256,uint256,uint256)", 10_000 * 1e18, 2550, - block.timestamp + 5 minutes, - false + block.timestamp + 5 minutes ); callsToExecute[1] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256,bool)", + "addQuoteToken(uint256,uint256,uint256)", 10_000 * 1e18, 2551, - block.timestamp + 5 minutes, - false + block.timestamp + 5 minutes ); callsToExecute[2] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256,bool)", + "addQuoteToken(uint256,uint256,uint256)", 10_000 * 1e18, 2552, - block.timestamp + 5 minutes, - false + block.timestamp + 5 minutes ); + uint256 depositLessFee = 9_999.543378995433790000 * 1e18; changePrank(_lender); vm.expectEmit(true, true, false, true); - emit AddQuoteToken(_lender, 2550, 10_000 * 1e18, 10_000 * 1e18, MAX_PRICE); + emit AddQuoteToken(_lender, 2550, depositLessFee, depositLessFee, MAX_PRICE); vm.expectEmit(true, true, false, true); emit Transfer(_lender, address(_pool), 10_000 * 1e18); vm.expectEmit(true, true, false, true); - emit AddQuoteToken(_lender, 2551, 10_000 * 1e18, 10_000 * 1e18, MAX_PRICE); + emit AddQuoteToken(_lender, 2551, depositLessFee, depositLessFee, MAX_PRICE); vm.expectEmit(true, true, false, true); emit Transfer(_lender, address(_pool), 10_000 * 1e18); vm.expectEmit(true, true, false, true); - emit AddQuoteToken(_lender, 2552, 10_000 * 1e18, 10_000 * 1e18, MAX_PRICE); + emit AddQuoteToken(_lender, 2552, depositLessFee, depositLessFee, MAX_PRICE); vm.expectEmit(true, true, false, true); emit Transfer(_lender, address(_pool), 10_000 * 1e18); ERC20Pool(address(_pool)).multicall(callsToExecute); @@ -84,48 +82,48 @@ contract ERC20PoolMulticallTest is ERC20HelperContract { assertEq(_quote.balanceOf(address(_pool)), 30_000 * 1e18); assertEq(_quote.balanceOf(_lender), 170_000 * 1e18); - assertEq(_pool.depositSize(), 30_000 * 1e18); + assertEq(_pool.depositSize(), 29_998.630136986301370000 * 1e18); // check buckets _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertBucket({ index: 2551, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); _assertBucket({ index: 2552, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, collateral: 0, - deposit: 10_000 * 1e18, + deposit: depositLessFee, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2552, - lpBalance: 10_000 * 1e18, + lpBalance: depositLessFee, depositTime: _startTime }); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol index 607ed97f2..e15d8dd06 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol @@ -8,17 +8,16 @@ import 'src/ERC20Pool.sol'; import 'src/ERC20PoolFactory.sol'; import 'src/PoolInfoUtils.sol'; -import { MAX_PRICE } from 'src/libraries/helpers/PoolHelper.sol'; +import { MAX_PRICE, COLLATERALIZATION_FACTOR } from 'src/libraries/helpers/PoolHelper.sol'; import 'src/interfaces/pool/IPool.sol'; import 'src/libraries/internal/Maths.sol'; +import "forge-std/console.sol"; contract ERC20PoolPrecisionTest is ERC20DSTestPlus { uint256 internal constant MAX_DEPOSIT = 1e22 * 1e18; uint256 internal constant MAX_COLLATERAL = 1e12 * 1e18; - uint256 internal constant POOL_PRECISION = 1e18; - uint256 internal constant LP_PRECISION = 1e18; uint256 internal _collateralPrecision; uint256 internal _quotePrecision; @@ -75,14 +74,17 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { changePrank(_lender); _quote.approve(address(_pool), _lenderDepositDenormalized); - skip(1 days); // to avoid deposit time 0 equals bucket bankruptcy time + skip(1 minutes); // to avoid deposit time 0 equals bucket bankruptcy time } /********************/ /*** Test Methods ***/ /********************/ - function testAddRemoveQuotePrecision(uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_) external virtual tearDown { + function testAddRemoveQuotePrecision( + uint8 collateralPrecisionDecimals_, + uint8 quotePrecisionDecimals_ + ) external virtual tearDown { // setup fuzzy bounds and initialize the pool uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 1, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 1, 18); @@ -93,17 +95,17 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { // deposit 50_000 quote tokens into each of 3 buckets _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2549 }); _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2550 }); _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2551 }); @@ -121,32 +123,31 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { lupIndex: 0 }); _assertLoans({ - noOfLoans: 0, - maxBorrower: address(0), - maxThresholdPrice: 0 + noOfLoans: 0, + maxBorrower: address(0), + maxT0DebtToCollateral: 0 }); - assertEq(_pool.depositSize(), 150_000 * POOL_PRECISION); + assertEq(_pool.depositSize(), 149_993.150684931506850000 * 1e18); // check bucket balance _assertBucket({ index: 2549, - lpBalance: 50_000 * 1e18, + lpBalance: 49_997.716894977168950000 * 1e18, collateral: 0, - deposit: 50_000 * POOL_PRECISION, - exchangeRate: 1 * LP_PRECISION + deposit: 49_997.716894977168950000 * 1e18, + exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 50_000 * 1e18, + lpBalance: 49_997.716894977168950000 * 1e18, depositTime: start }); - skip(1 days); // skip to avoid penalty // lender removes some quote token from highest priced bucket _removeLiquidity({ from: _lender, - amount: 25_000 * POOL_PRECISION, + amount: 25_000 * 1e18, index: 2549, newLup: MAX_PRICE, lpRedeem: 25_000 * 1e18 @@ -166,24 +167,24 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { lupIndex: 0 }); _assertLoans({ - noOfLoans: 0, - maxBorrower: address(0), - maxThresholdPrice: 0 + noOfLoans: 0, + maxBorrower: address(0), + maxT0DebtToCollateral: 0 }); - assertEq(_pool.depositSize(), 125_000 * POOL_PRECISION); + assertEq(_pool.depositSize(), 124_993.150684931506850000 * 1e18); // check bucket balance _assertBucket({ index: 2549, - lpBalance: 25_000 * 1e18, + lpBalance: 24_997.716894977168950000 * 1e18, collateral: 0, - deposit: 25_000 * POOL_PRECISION, + deposit: 24_997.716894977168950000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 25_000 * LP_PRECISION, + lpBalance: 24_997.716894977168950000 * 1e18, depositTime: start }); } @@ -241,7 +242,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { function testBorrowRepayPrecision( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_ - ) external { + ) external tearDown { // setup fuzzy bounds and initialize the pool uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 1, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 1, 18); @@ -251,17 +252,17 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2549 }); _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2550 }); _addInitialLiquidity({ from: _lender, - amount: 50_000 * POOL_PRECISION, + amount: 50_000 * 1e18, index: 2551 }); @@ -269,7 +270,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { _pledgeCollateral({ from: _borrower, borrower: _borrower, - amount: 50 * POOL_PRECISION + amount: 50 * 1e18 }); // check balances @@ -288,24 +289,24 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { lupIndex: 0 }); _assertLoans({ - noOfLoans: 0, - maxBorrower: address(0), - maxThresholdPrice: 0 + noOfLoans: 0, + maxBorrower: address(0), + maxT0DebtToCollateral: 0 }); - assertEq(_pool.depositSize(), 150_000 * POOL_PRECISION); + assertEq(_pool.depositSize(), 149_993.150684931506850000 * 1e18); // check bucket balance _assertBucket({ index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, collateral: 0, - deposit: 50_000 * POOL_PRECISION, - exchangeRate: 1 * LP_PRECISION + deposit: 49_997.716894977168950000 * 1e18, + exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, depositTime: start }); @@ -314,7 +315,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { _borrow({ from: _borrower, - amount: 10_000 * POOL_PRECISION, + amount: 10_000 * 1e18, indexLimit: 3_000, newLup: price }); @@ -325,49 +326,48 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { assertEq(_quote.balanceOf(address(_pool)), 140_000 * _quotePrecision); assertEq(_quote.balanceOf(_borrower), 10_000 * _quotePrecision); - // check pool state - uint256 debt = 10_008.653846153846150000 * 1e18; - uint256 col = 50 * 1e18; - // 50 collateral @ 3025.9 = 151295, so borrower is 15_116% collateralized + // 50 collateral @ 3025.9 = 151295, so borrower is heavily overcollateralized + uint256 debt = 10_009.615384615384620000 * 1e18; + uint256 col = 50 * 1e18; _assertBorrower({ borrower: _borrower, borrowerDebt: debt, borrowerCollateral: col, - borrowert0Np: 229.411561015492614726 * 1e18, - borrowerCollateralization: 15.116650694597107214 * 1e18 + borrowert0Np: 231.477467645772810675 * 1e18, + borrowerCollateralization: 14.533844775739053504 * 1e18 }); _assertPoolPrices({ - htp: 200.173076923076923000 * 1e18, - htpIndex: 3093, + htp: 208.200000000000000096 * 1e18, + htpIndex: 3085, hpb: 3_025.946482308870940904 * 1e18, hpbIndex: 2549, lup: price, lupIndex: 2549 }); _assertLoans({ - noOfLoans: 1, - maxBorrower: _borrower, - maxThresholdPrice: 200.173076923076923000 * 1e18 + noOfLoans: 1, + maxBorrower: _borrower, + maxT0DebtToCollateral: 200.192307692307692400 * 1e18 }); (uint256 poolDebt,,,) = _pool.debtInfo(); - assertEq(_pool.depositSize(), 150_000 * POOL_PRECISION); + assertEq(_pool.depositSize(), 149_993.150684931506850000 * 1e18); assertEq(poolDebt, debt); assertEq(_pool.pledgedCollateral(), col); _assertBucket({ index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, collateral: 0, - deposit: 50_000 * POOL_PRECISION, - exchangeRate: 1 * LP_PRECISION + deposit: 49_997.716894977168950000 * 1e18, + exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, depositTime: start }); @@ -375,8 +375,8 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { _repayDebt({ from: _borrower, borrower: _borrower, - amountToRepay: 5_000 * POOL_PRECISION, - amountRepaid: 5_000 * POOL_PRECISION, + amountToRepay: 5_000 * 1e18, + amountRepaid: 5_000 * 1e18, collateralToPull: 0, newLup: 3_025.946482308870940904 * 1e18 }); @@ -389,53 +389,50 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { assertEq(_quote.balanceOf(_borrower), 5_000 * _quotePrecision); // check pool state - debt = 5_008.653846153846150000 * 1e18; + debt = 5_009.615384615384620000 * 1e18; col = 50 * 1e18; - _assertBorrower({ borrower: _borrower, borrowerDebt: debt, borrowerCollateral: col, - borrowert0Np: 114.804959297694401926 * 1e18, - borrowerCollateralization: 30.207183159927296805 * 1e18 + borrowert0Np: 115.849914162773904339 * 1e18, + borrowerCollateralization: 29.039793496246362170 * 1e18 }); _assertPoolPrices({ - htp: 100.173076923076923000 * 1e18, - htpIndex: 3232, + htp: 104.200000000000000096 * 1e18, + htpIndex: 3224, hpb: 3_025.946482308870940904 * 1e18, hpbIndex: 2549, lup: price, lupIndex: 2549 }); _assertLoans({ - noOfLoans: 1, - maxBorrower: _borrower, - maxThresholdPrice: 100.173076923076923000 * 1e18 + noOfLoans: 1, + maxBorrower: _borrower, + maxT0DebtToCollateral: 100.192307692307692400 * 1e18 }); (poolDebt,,,) = _pool.debtInfo(); - - assertEq(_pool.depositSize(), 150_000 * 1e18); + assertEq(_pool.depositSize(), 149_993.150684931506850000 * 1e18); assertEq(poolDebt, debt); assertEq(_pool.pledgedCollateral(), col); _assertBucket({ index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, collateral: 0, - deposit: 50_000 * 1e18, + deposit: 49_997.716894977168950000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 50_000 * LP_PRECISION, + lpBalance: 49_997.716894977168950000 * 1e18, depositTime: start }); - // remove all of the remaining claimable collateral + // remove all remaining claimable collateral uint256 unencumberedCollateral = col - _encumberedCollateral(debt, _lup()); - _repayDebtNoLupCheck({ from: _borrower, borrower: _borrower, @@ -470,15 +467,16 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { skip(3 hours); // borrower draws debt + uint256 collateralToPledge = _calculateCollateralToPledge(25_000 * 1e18, bucketId, 1.1 * 1e18); + _mintAndApproveCollateral(_borrower, collateralToPledge); _drawDebt({ from: _borrower, borrower: _borrower, amountToBorrow: 25_000 * 1e18, limitIndex: bucketId, - collateralToPledge: 150 * 1e18, + collateralToPledge: collateralToPledge, newLup: bucketPrice }); - skip(12 hours); // borrower attempts to repay less than token precision assertGt(_quoteDust, 1); @@ -501,82 +499,22 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { init(boundColPrecision, boundQuotePrecision); uint256 bucketId = bound(uint256(bucketId_), 1, 7388); - - // ensure half of deposits are below the scale limit - uint256 maxColAmountBound = collateralAmount_ % 2 == 0 ? MAX_COLLATERAL : uint256(10) ** boundColPrecision; - uint256 maxQuoteAmountBound = quoteAmount_ % 2 == 0 ? MAX_DEPOSIT : uint256(10) ** boundQuotePrecision; - uint256 collateralAmount = bound(uint256(collateralAmount_), 1, maxColAmountBound); - uint256 quoteAmount = bound(uint256(quoteAmount_), 1, maxQuoteAmountBound); - + uint256 quoteAmount; uint256 quoteScale = _pool.quoteTokenScale(); - uint256 quoteDust = _pool.quoteTokenScale(); - if (quoteAmount < quoteDust) quoteAmount = quoteDust; - + uint256 collateralAmount; uint256 colScale = ERC20Pool(address(_pool)).collateralScale(); - uint256 colDustAmount = ERC20Pool(address(_pool)).bucketCollateralDust(bucketId); - if (collateralAmount < colDustAmount) collateralAmount = colDustAmount; - assertEq(ERC20Pool(address(_pool)).collateralScale(), 10 ** (18 - boundColPrecision)); - assertEq(_pool.quoteTokenScale(), 10 ** (18 - boundQuotePrecision)); - - // mint and run approvals, ignoring amounts already init approved above - changePrank(_lender); - deal(address(_quote), _lender, quoteAmount * _quotePrecision); - _quote.approve(address(_pool), quoteAmount * _quotePrecision); - changePrank(_bidder); - deal(address(_collateral), _bidder, collateralAmount * _collateralPrecision); - _collateral.approve(address(_pool), collateralAmount * _collateralPrecision); + { + // ensure half of deposits are below the scale limit + uint256 maxColAmountBound = collateralAmount_ % 2 == 0 ? MAX_COLLATERAL : uint256(10) ** boundColPrecision; + uint256 maxQuoteAmountBound = quoteAmount_ % 2 == 0 ? MAX_DEPOSIT : uint256(10) ** boundQuotePrecision; + collateralAmount = bound(uint256(collateralAmount_), 1, maxColAmountBound); + quoteAmount = bound(uint256(quoteAmount_), 1, maxQuoteAmountBound); - _assertBucket({ - index: bucketId, - lpBalance: 0, - collateral: 0, - deposit: 0, - exchangeRate: 1e18 - }); - - // addQuoteToken should add scaled quote token amount validate LP - _addLiquidityNoEventCheck(_lender, quoteAmount, bucketId); - - // deposit collateral and sanity check bidder LP - _addCollateralWithoutCheckingLP(_bidder, collateralAmount, bucketId); - - // check bucket quantities and LP - (, uint256 curDeposit, uint256 availableCollateral, uint256 bucketLpBalance,,) = _poolUtils.bucketInfo(address(_pool), bucketId); - assertEq(curDeposit, _roundToScale(quoteAmount, quoteScale)); - assertEq(availableCollateral, _roundToScale(collateralAmount, colScale)); - - (uint256 lenderLpBalance, ) = _pool.lenderInfo(bucketId, _lender); - assertEq(lenderLpBalance, _roundToScale(quoteAmount, quoteScale)); - (uint256 bidderLpBalance, ) = _pool.lenderInfo(bucketId, _bidder); - assertGt(bidderLpBalance, 0); - assertEq(bucketLpBalance, lenderLpBalance + bidderLpBalance); - } - -/*********************************************************************************************************/ -/*********************************************************************************************************/ -/*********************************************************************************************************/ - - function testDepositTwoActorSameBucketSimplified( - ) external tearDown { - // setup fuzzy bounds and initialize the pool - uint256 boundColPrecision = 14; - uint256 boundQuotePrecision = 7; - - init(boundColPrecision, boundQuotePrecision); - - uint256 bucketId = 2161; - - uint256 collateralAmount = 3150; - uint256 quoteAmount = 10795; - - uint256 quoteScale = _pool.quoteTokenScale(); - uint256 quoteDust = _pool.quoteTokenScale(); - if (quoteAmount < quoteDust) quoteAmount = quoteDust; - - uint256 colScale = ERC20Pool(address(_pool)).collateralScale(); - uint256 colDustAmount = ERC20Pool(address(_pool)).bucketCollateralDust(bucketId); - if (collateralAmount < colDustAmount) collateralAmount = colDustAmount + colDustAmount / 2; + if (quoteAmount < quoteScale) quoteAmount = quoteScale; + uint256 colDustAmount = ERC20Pool(address(_pool)).bucketCollateralDust(bucketId); + if (collateralAmount < colDustAmount) collateralAmount = colDustAmount; + } assertEq(ERC20Pool(address(_pool)).collateralScale(), 10 ** (18 - boundColPrecision)); assertEq(_pool.quoteTokenScale(), 10 ** (18 - boundQuotePrecision)); @@ -604,22 +542,21 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { _addCollateralWithoutCheckingLP(_bidder, collateralAmount, bucketId); // check bucket quantities and LP - (, uint256 curDeposit, uint256 availableCollateral, uint256 bucketLpBalance,,) = _poolUtils.bucketInfo(address(_pool), bucketId); - assertEq(curDeposit, _roundToScale(quoteAmount, quoteScale)); - assertEq(availableCollateral, _roundToScale(collateralAmount, colScale)); - - (uint256 lenderLpBalance, ) = _pool.lenderInfo(bucketId, _lender); - assertEq(lenderLpBalance, _roundToScale(quoteAmount, quoteScale)); - (uint256 bidderLpBalance, ) = _pool.lenderInfo(bucketId, _bidder); - assertGt(bidderLpBalance, 0); - assertEq(bucketLpBalance, lenderLpBalance + bidderLpBalance); + { + uint256 depositRoundedToScale = _roundToScale(quoteAmount, quoteScale); + uint256 depositLessPenalty = Maths.wmul(depositRoundedToScale, _depositFee()); + (, uint256 curDeposit, uint256 availableCollateral, uint256 bucketLpBalance,,) = _poolUtils.bucketInfo(address(_pool), bucketId); + assertEq(curDeposit, depositLessPenalty); + assertEq(availableCollateral, _roundToScale(collateralAmount, colScale)); + + (uint256 lenderLpBalance, ) = _pool.lenderInfo(bucketId, _lender); + assertEq(lenderLpBalance, depositLessPenalty); + (uint256 bidderLpBalance, ) = _pool.lenderInfo(bucketId, _bidder); + assertGt(bidderLpBalance, 0); + assertEq(bucketLpBalance, lenderLpBalance + bidderLpBalance); + } } -/*********************************************************************************************************/ -/*********************************************************************************************************/ -/*********************************************************************************************************/ - - function testDepositTwoLendersSameBucket( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_, @@ -664,11 +601,13 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { // check bucket uint256 quoteScale = _pool.quoteTokenScale(); (, uint256 curDeposit, , uint256 bucketLP,,) = _poolUtils.bucketInfo(address(_pool), bucketId); - assertEq(curDeposit, _roundToScale(quoteAmount1, quoteScale) + _roundToScale(quoteAmount2, quoteScale)); + assertEq(curDeposit, + Maths.wmul(_roundToScale(quoteAmount1, quoteScale), _depositFee()) + + Maths.wmul(_roundToScale(quoteAmount2, quoteScale), _depositFee())); assertEq(bucketLP, lpBalance1 + lpBalance2); } - function testMoveQuoteToken( + function testMoveQuoteTokenNoDebt( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_, uint16 fromBucketId_, @@ -681,15 +620,17 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { // init to set lender deposit normalized init(boundColPrecision, boundQuotePrecision); - uint256 fromBucketId = bound(uint256(fromBucketId_), 1, 7388); - uint256 toBucketId = bound(uint256(toBucketId_), 1, 7388); - uint256 amountToMove = bound(uint256(amountToMove_), 1, _lenderDepositNormalized); + uint256 fromBucketId = bound(uint256(fromBucketId_), 1, 7388); + uint256 toBucketId = bound(uint256(toBucketId_), 1, 7388); + uint256 amountToMove = bound(uint256(amountToMove_), 1, _lenderDepositNormalized); + amountToMove = Maths.wmul(amountToMove, _depositFee()); _addInitialLiquidity({ from: _lender, amount: _lenderDepositNormalized, index: fromBucketId }); + uint256 lenderDepositLessFee = Maths.wmul(_lenderDepositNormalized, _depositFee()); if (fromBucketId == toBucketId) { _assertMoveLiquidityToSameIndexRevert({ @@ -698,40 +639,55 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { fromIndex: fromBucketId, toIndex: toBucketId }); - return; } - if (amountToMove != 0 && amountToMove < _quoteDust) { + if (amountToMove < _quoteDust) { _assertMoveLiquidityDustRevert({ from: _lender, amount: amountToMove, fromIndex: fromBucketId, toIndex: toBucketId }); + return; + } + + // if fromBucket deposit - amount to move < _quoteDust + (, uint256 deposit,, uint256 lps,,) = _poolUtils.bucketInfo(address(_pool), fromBucketId); + if (deposit > amountToMove && deposit - amountToMove < _quoteDust) { + _assertMoveLiquidityDustRevert({ + from: _lender, + amount: amountToMove, + fromIndex: fromBucketId, + toIndex: toBucketId + }); return; } + uint256 amountMoved = amountToMove; + if (fromBucketId < toBucketId) { + // if moving to a lower-priced bucket, the deposit fee should be charged again + amountMoved = Maths.wmul(amountToMove, _depositFee()); + } _moveLiquidity({ from: _lender, amount: amountToMove, fromIndex: fromBucketId, toIndex: toBucketId, lpRedeemFrom: amountToMove, - lpAwardTo: amountToMove, + lpAwardTo: amountMoved, newLup: MAX_PRICE }); // validate from and to buckets have appropriate amounts of deposit and LP - (, uint256 deposit,, uint256 lps,,) = _poolUtils.bucketInfo(address(_pool), fromBucketId); - uint256 remaining = _lenderDepositNormalized - amountToMove; - + uint256 remaining = lenderDepositLessFee - amountToMove; + (, deposit,, lps,,) = _poolUtils.bucketInfo(address(_pool), fromBucketId); assertEq(deposit, remaining); - assertEq(lps, remaining); + _validateBucketLp(fromBucketId, lps); (, deposit,, lps,,) = _poolUtils.bucketInfo(address(_pool), toBucketId); - assertEq(deposit, amountToMove); - assertEq(lps, amountToMove); + assertEq(deposit, amountMoved); + _validateBucketLp(toBucketId, lps); } function testDrawMinDebtAmount( @@ -742,7 +698,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { // setup fuzzy bounds and initialize the pool uint256 collateralDecimals = bound(uint256(collateralPrecisionDecimals_), 1, 18); uint256 quoteDecimals = bound(uint256(quotePrecisionDecimals_), 1, 18); - uint256 bucketId = bound(uint256(bucketId_), 1, 7388); + uint256 bucketId = bound(uint256(bucketId_), 1, 7387); init(collateralDecimals, quoteDecimals); _addInitialLiquidity({ @@ -794,7 +750,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { (uint256 minDebtAmount, , , ) = _poolUtils.poolUtilizationInfo(address(_pool)); assertGt(minDebtAmount, 1); - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), borrower); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), borrower); uint256 repayAmount = debt - minDebtAmount / 2; _assertRepayMinDebtRevert({ @@ -804,7 +760,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { }); } - function testCollateralDustPricePrecisionAdjustment() external { + function testCollateralDustPricePrecisionAdjustment() external tearDown { // test the bucket price adjustment used for determining dust amount assertEq(_getCollateralDustPricePrecisionAdjustment(0), 0); assertEq(_getCollateralDustPricePrecisionAdjustment(1), 0); @@ -847,7 +803,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { // setup fuzzy bounds and initialize the pool uint256 collateralDecimals = bound(uint256(collateralPrecisionDecimals_), 1, 18); uint256 quoteDecimals = bound(uint256(quotePrecisionDecimals_), 1, 18); - uint256 bucketId = bound(uint256(bucketId_), 1, 7388); + uint256 bucketId = bound(uint256(bucketId_), 1, 7387); init(collateralDecimals, quoteDecimals); uint256 collateralScale = 10 ** (18 - collateralDecimals); @@ -874,7 +830,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { newLup: _priceAt(bucketId) }); - (uint256 currentDebt, uint256 pledgedCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 currentDebt, uint256 pledgedCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertGt(currentDebt, debtToDraw); // round the collateral amount to token precision @@ -911,6 +867,102 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { assertEq(_pool.maxFlashLoan(address(_quote)), 10_000 * 10 ** quoteDecimals); } + function testRemoveQuoteDust() external tearDown { + // TODO: rework this into a fuzz test + init(18, 6); + + _addInitialLiquidity({ + from: _lender, + amount: 2_000 * 1e18, + index: 3696 + }); + + // check balances + assertEq(_quote.balanceOf(address(_pool)), 2_000.000000 * 1e6); + assertEq(_quote.balanceOf(_lender), 198_000.000000 * 1e6); + + // remove an amount from the bucket which would leave dust behind + (, uint256 curDeposit,,,,) = _poolUtils.bucketInfo(address(_pool), 3696); + _assertRemoveQuoteDustRevert({ + from: _lender, + amount: curDeposit - 1, + index: 3696 + }); + + _removeLiquidity({ + from: _lender, + amount: curDeposit - 0.000001 * 1e18, + index: 3696, + newLup: MAX_PRICE, + lpRedeem: 1_999.908674799086758000 * 1e18 + }); + + _assertBucket({ + index: 3696, + lpBalance: 0.000001000000000000 * 1e18, + collateral: 0, + deposit: 0.000001000000000000 * 1e18, + exchangeRate: 1 * 1e18 + }); + } + + function testMoveQuoteDust() external tearDown { + // TODO: rework this into a fuzz test + init(18, 6); + + _addInitialLiquidity({ + from: _lender, + amount: 2_000 * 1e18, + index: 3696 + }); + + // check balances + assertEq(_quote.balanceOf(address(_pool)), 2_000.000000 * 1e6); + assertEq(_quote.balanceOf(_lender), 198_000.000000 * 1e6); + + // move an amount from the bucket which would leave dust behind + (, uint256 curDeposit,,,,) = _poolUtils.bucketInfo(address(_pool), 3696); + _assertMoveQuoteDustRevert({ + from: _lender, + amount: curDeposit - 1, + fromIndex: 3696, + toIndex: 3698 + }); + + // move an amount smaller than token precision + _assertMoveQuoteDustRevert({ + from: _lender, + amount: 1, + fromIndex: 3696, + toIndex: 3698 + }); + + _moveLiquidity({ + from: _lender, + amount: 0.000001 * 1e18, + fromIndex: 3696, + toIndex: 3701, + lpRedeemFrom: 0.000001 * 1e18, + lpAwardTo: 0.000000999954337900 * 1e18, + newLup: 1004968987.606512354182109771 * 1e18 + }); + + _assertBucket({ + index: 3696, + lpBalance: 1_999.908674799086758000 * 1e18, + collateral: 0, + deposit: 1_999.908674799086758000 * 1e18, + exchangeRate: 1 * 1e18 + }); + + _assertBucket({ + index: 3701, + lpBalance: 0.000000999954337900 * 1e18, + collateral: 0, + deposit: 0.000000999954337900 * 1e18, + exchangeRate: 1 * 1e18 + }); + } /**********************/ /*** Helper Methods ***/ @@ -924,7 +976,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { assertGt(desiredCollateralizationRatio, 1e18); uint256 colScale = ERC20Pool(address(_pool)).collateralScale(); uint256 price = _priceAt(newLupIndex); - uint256 desiredPledge = Maths.wmul(Maths.wdiv(debtToDraw, price), desiredCollateralizationRatio); + uint256 desiredPledge = Maths.wmul(Maths.wdiv(Maths.wmul(debtToDraw, COLLATERALIZATION_FACTOR), price), desiredCollateralizationRatio); uint256 scaledPledge = (desiredPledge / colScale) * colScale; while (Maths.wdiv(Maths.wmul(scaledPledge, price), debtToDraw) < desiredCollateralizationRatio) { @@ -933,8 +985,9 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { return scaledPledge; } - function _encumberedCollateral(uint256 debt_, uint256 price_) internal pure returns (uint256 encumberance_) { - encumberance_ = price_ != 0 && debt_ != 0 ? Maths.wdiv(debt_, price_) : 0; + function _encumberedCollateral(uint256 debt_, uint256 price_) internal view returns (uint256 encumberance_) { + uint256 unscaledEncumberance = price_ != 0 && debt_ != 0 ? Maths.ceilWdiv(Maths.wmul(debt_, COLLATERALIZATION_FACTOR), price_) : 0; + encumberance_ = _roundUpToScale(unscaledEncumberance, ERC20Pool(address(_pool)).quoteTokenScale()); } function _mintAndApproveCollateral( @@ -960,7 +1013,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { function _repayDebtWithoutPullingCollateral( address borrower ) internal { - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), borrower); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), borrower); _mintAndApproveQuoteToken(borrower, debt); _repayDebt({ from: _borrower, @@ -971,5 +1024,4 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { newLup: MAX_PRICE }); } - -} +} \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolPurchaseQuote.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolPurchaseQuote.t.sol index 1a24927d7..f6f9a2cf4 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolPurchaseQuote.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolPurchaseQuote.t.sol @@ -30,7 +30,7 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { /** * @notice 1 lender, 1 bidder tests purchasing quote token with collateral. */ - function testPurchaseQuote() external tearDown { + function testPurchaseQuoteNoDebt() external tearDown { // test setup uint256 testIndex = 2550; @@ -54,15 +54,15 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { // check bucket state and LP _assertBucket({ index: testIndex, - lpBalance: 22_043.56808879152623138 * 1e18, + lpBalance: 22_043.111467786960021380 * 1e18, collateral: collateralToPurchaseWith, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: testIndex, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -74,18 +74,16 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { uint256 availableCollateral = collateralToPurchaseWith; - skip(1 days); // skip to avoid penalty - // bidder uses their LP to purchase all quote token in the bucket - _removeLiquidity({ + _removeAllLiquidity({ from: _bidder, - amount: 10_000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: testIndex, newLup: _lup(), - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); - assertEq(_quote.balanceOf(_bidder), 10_000 * 1e18); + assertEq(_quote.balanceOf(_bidder), 9_999.543378995433790000 * 1e18); // check bucket state _assertBucket({ @@ -98,13 +96,13 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: testIndex, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _bidder, index: testIndex, - lpBalance: 2_043.56808879152623138 * 1e18, + lpBalance: 2_044.024709796092441380 * 1e18, depositTime: _startTime }); @@ -112,22 +110,22 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { assertEq(_collateral.balanceOf(_lender), 0); assertEq(_collateral.balanceOf(address(_pool)), collateralToPurchaseWith); assertGe(_collateral.balanceOf(address(_pool)), availableCollateral); - assertEq(_quote.balanceOf(address(_pool)), 0); + assertEq(_quote.balanceOf(address(_pool)), 0.45662100456621 * 1e18); // lender exchanges their LP for collateral _removeAllCollateral({ from: _lender, - amount: 3.321274866808485287 * 1e18, + amount: 3.321123210421873028 * 1e18, index: testIndex, - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); _assertBucket({ index: testIndex, - lpBalance: 2_043.56808879152623138 * 1e18, - collateral: 0.678725133191514713 * 1e18, + lpBalance: 2_044.024709796092441380 * 1e18, + collateral: 0.678876789578126972 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000002 * 1e18 + exchangeRate: 1.000000000000000001 * 1e18 }); _assertLenderLpBalance({ lender: _lender, @@ -138,23 +136,23 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _bidder, index: testIndex, - lpBalance: 2_043.56808879152623138 * 1e18, + lpBalance: 2_044.024709796092441380 * 1e18, depositTime: _startTime }); - assertEq(_collateral.balanceOf(_lender), 3.321274866808485287 * 1e18); + assertEq(_collateral.balanceOf(_lender), 3.321123210421873028 * 1e18); // bidder removes their _collateral _removeAllCollateral({ from: _bidder, - amount: 0.678725133191514713 * 1e18, + amount: 0.678876789578126972 * 1e18, index: testIndex, - lpRedeem: 2_043.568088791526231380 * 1e18 + lpRedeem: 2_044.024709796092441380 * 1e18 }); // check pool balances assertEq(_collateral.balanceOf(address(_pool)), 0); - assertEq(_quote.balanceOf(address(_pool)), 0); + assertEq(_quote.balanceOf(address(_pool)), 0.45662100456621 * 1e18); // check bucket state _assertBucket({ @@ -214,7 +212,7 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { index: 2552 }); - skip(3600); + skip(1 hours); // borrower draws debt _pledgeCollateral({ @@ -238,7 +236,6 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { // bidder purchases all quote from the highest bucket uint256 amountToPurchase = 10_100 * 1e18; assertGt(_quote.balanceOf(address(_pool)), amountToPurchase); - uint256 amountWithInterest = 10_001.272716138919720000 * 1e18; // adding extra collateral to account for interest accumulation uint256 collateralToPurchaseWith = Maths.wmul(Maths.wdiv(amountToPurchase, p2550), 1.01 * 1e18); assertEq(collateralToPurchaseWith, 3.388032491631335842 * 1e18); @@ -248,27 +245,27 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { from: _bidder, amount: collateralToPurchaseWith, index: 2550, - lpAward: 10_200.405529039248273722 * 1e18 + lpAward: 10_200.405501894798027811 * 1e18 }); skip(25 hours); // remove liquidity after one day to avoid early withdraw penalty + uint256 amountWithInterest = 10_000.816096390378067325 * 1e18; _removeAllLiquidity({ from: _bidder, amount: amountWithInterest, index: 2550, newLup: _priceAt(2552), - lpRedeem: 10_000.348352446860837959 * 1e18 + lpRedeem: 9_999.891739949343600464 * 1e18 }); // bidder withdraws unused collateral - uint256 expectedCollateral = 0.066450628927305146 * 1e18; - + uint256 expectedCollateral = 0.066602287722847519 * 1e18; _removeAllCollateral({ from: _bidder, amount: expectedCollateral, index: 2550, - lpRedeem: 200.057176592387435763 * 1e18 + lpRedeem: 200.513761945454427347 * 1e18 }); _assertLenderLpBalance({ @@ -278,16 +275,15 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { depositTime: _startTime + 3600 + 86400 }); - skip(7200); + skip(2 hours); // lender exchanges their LP for collateral - expectedCollateral = 1.992949117622418417 * 1e18; - + expectedCollateral = 1.992858122345092993 * 1e18; _removeAllCollateral({ from: _lender, amount: expectedCollateral, index: 2550, - lpRedeem: 6_000 * 1e18 + lpRedeem: 5_999.726027397260274000 * 1e18 }); _assertLenderLpBalance({ @@ -297,16 +293,15 @@ contract ERC20PoolPurchaseQuoteTokenTest is ERC20HelperContract { depositTime: _startTime }); - skip(3600); + skip(1 hours); // lender1 exchanges their LP for collateral - expectedCollateral = 1.328632745081612279 * 1e18; - + expectedCollateral = 1.328572081563395330 * 1e18; _removeAllCollateral({ from: _lender1, amount: expectedCollateral, index: 2550, - lpRedeem: 4_000 * 1e18 + lpRedeem: 3_999.817351598173516000 * 1e18 }); _assertLenderLpBalance({ diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index 75a129d05..92086a5aa 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -49,11 +49,12 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { index: 2550 }); + uint256 deposit2550 = 9_999.543378995433790000 * 1e18; _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 10_000 * 1e18, + poolSize: deposit2550, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -68,15 +69,15 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { ); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, collateral: 0, - deposit: 10_000 * 1e18, + deposit: deposit2550, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, depositTime: _startTime }); @@ -95,7 +96,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -110,28 +111,29 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { ); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, collateral: 0, - deposit: 10_000 * 1e18, + deposit: deposit2550, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, depositTime: _startTime }); + uint256 deposit2551 = 19_999.086757990867580000 * 1e18; _assertBucket({ index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: deposit2551, collateral: 0, - deposit: 20_000 * 1e18, + deposit: deposit2551, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: deposit2551, depositTime: _startTime }); @@ -150,7 +152,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 70_000 * 1e18, + poolSize: 69_996.803652968036530000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -163,43 +165,44 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { interestRateUpdate: _startTime }) ); + uint256 deposit2549 = 39_998.173515981735160000 * 1e18; _assertBucket({ index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: deposit2549, collateral: 0, - deposit: 40_000 * 1e18, + deposit: deposit2549, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: deposit2549, depositTime: _startTime }); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, collateral: 0, - deposit: 10_000 * 1e18, + deposit: deposit2550, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: deposit2550, depositTime: _startTime }); _assertBucket({ index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: deposit2551, collateral: 0, - deposit: 20_000 * 1e18, + deposit: deposit2551, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: deposit2551, depositTime: _startTime }); @@ -225,11 +228,10 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { // should revert if passing future timestamp but time has elapsed bytes memory data = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256,bool)", + "addQuoteToken(uint256,uint256,uint256)", 50_000 * 1e18, 3333, - block.timestamp + 5 minutes, - false + block.timestamp + 5 minutes ); // should succeed if time hasn't passed @@ -242,26 +244,26 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { (success, ) = address(_pool).call(data); } - function testPoolRemoveQuoteToken() external tearDown { + function testPoolRemoveQuoteTokenBasic() external tearDown { _addLiquidity({ from: _lender, amount: 40_000 * 1e18, index: 2549, - lpAward: 40_000 * 1e18, + lpAward: 39_998.173515981735160000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: 2550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _addLiquidity( { from: _lender, amount: 20_000 * 1e18, index: 2551, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); @@ -269,7 +271,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 70_000 * 1e18, + poolSize: 69_996.803652968036530000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -284,41 +286,41 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { ); _assertBucket({ index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, collateral: 0, - deposit: 40_000 * 1e18, + deposit: 39_998.173515981735160000 * 1e18, exchangeRate: 1 * 1e18 }); - _assertLenderLpBalance({ + _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, collateral: 0, - deposit: 20_000 * 1e18, + deposit: 19_999.086757990867580000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, depositTime: _startTime }); @@ -326,8 +328,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { assertEq(_quote.balanceOf(address(_pool)), 70_000 * 1e18); assertEq(_quote.balanceOf(_lender), 130_000 * 1e18); - skip(1 days); // skip to avoid penalty - + // partial remove _removeLiquidity({ from: _lender, amount: 5_000 * 1e18, @@ -340,7 +341,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 65_000 * 1e18, + poolSize: 64_996.803652968036530000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -349,47 +350,47 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.045 * 1e18, - interestRateUpdate: _startTime + 1 days + interestRate: 0.05 * 1e18, + interestRateUpdate: _startTime }) ); _assertBucket({ index: 2549, - lpBalance: 35_000 * 1e18, + lpBalance: 34_998.173515981735160000 * 1e18, collateral: 0, - deposit: 35_000 * 1e18, + deposit: 34_998.173515981735160000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 35_000 * 1e18, + lpBalance: 34_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, collateral: 0, - deposit: 20_000 * 1e18, + deposit: 19_999.086757990867580000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, depositTime: _startTime }); @@ -397,19 +398,20 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { assertEq(_quote.balanceOf(address(_pool)), 65_000 * 1e18); assertEq(_quote.balanceOf(_lender), 135_000 * 1e18); - _removeLiquidity({ + // full remove + _removeAllLiquidity({ from: _lender, - amount: 35_000 * 1e18, + amount: 34_998.173515981735160000 * 1e18, index: 2549, newLup: MAX_PRICE, - lpRedeem: 35_000 * 1e18 + lpRedeem: 34_998.173515981735160000 * 1e18 }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -418,8 +420,8 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.045 * 1e18, - interestRateUpdate: _startTime + 1 days + interestRate: 0.05 * 1e18, + interestRateUpdate: _startTime }) ); _assertBucket({ @@ -437,34 +439,34 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { }); _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, collateral: 0, - deposit: 20_000 * 1e18, + deposit: 19_999.086757990867580000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, depositTime: _startTime }); // check balances - assertEq(_quote.balanceOf(address(_pool)), 30_000 * 1e18); - assertEq(_quote.balanceOf(_lender), 170_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 30_001.826484018264840000 * 1e18); + assertEq(_quote.balanceOf(_lender), 169_998.173515981735160000 * 1e18); } /** @@ -480,7 +482,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 11_000 * 1e18, index: 4550, - lpAward: 11_000 * 1e18, + lpAward: 10_999.497716894977169000 * 1e18, newLup: MAX_PRICE }); @@ -497,8 +499,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { { from: _lender, index: 4550 - } - ); + }); } /** @@ -516,28 +517,28 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 41_000 * 1e18, index: 4549, - lpAward: 41_000 * 1e18, + lpAward: 40_998.127853881278539000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: 4550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 20_000 * 1e18, index: 4551, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); _addLiquidity( { from: _lender, amount: 30_000 * 1e18, index: 4990, - lpAward: 30_000 * 1e18, + lpAward: 29_998.630136986301370000 * 1e18, newLup: MAX_PRICE }); @@ -586,23 +587,21 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender1, amount: 20_000 * 1e18, index: 4550, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: _priceAt(4550) }); - skip(1 days); // skip to avoid penalty - // should be able to removeQuoteToken - _removeLiquidity({ + _removeAllLiquidity({ from: _lender, - amount: 10_000 * 1e18, + amount: 29_998.630136986301370000 * 1e18, index: 4990, newLup: _priceAt(4550), - lpRedeem: 10_000 * 1e18 + lpRedeem: 29_998.630136986301370000 * 1e18 }); } - function testPoolRemoveQuoteTokenWithCollateral() external { + function testPoolRemoveQuoteTokenWithCollateral() external tearDown { // add 10 collateral into the 100 bucket, for LP worth 1000 quote tokens _mintCollateralAndApproveTokens(_lender, 10 * 1e18); @@ -620,13 +619,10 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender1, amount: 900 * 1e18, index: i100, - lpAward: 900 * 1e18, + lpAward: 899.958904109589041100 * 1e18, newLup: MAX_PRICE }); - // should be able to remove a small amount of deposit - skip(1 days); - _removeLiquidity({ from: _lender, amount: 100 * 1e18, @@ -638,10 +634,10 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { // should be able to remove the rest _removeAllLiquidity({ from: _lender, - amount: 800 * 1e18, + amount: 799.958904109589041100 * 1e18, index: i100, newLup: MAX_PRICE, - lpRedeem: 800 * 1e18 + lpRedeem: 799.958904109589041100 * 1e18 }); _assertBucket({ @@ -659,45 +655,46 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { // lender adds initial quote token skip(1 minutes); // prevent deposit from having a zero timestamp + uint256 liquidityAdded = 3_399.844748858447488600 * 1e18; _addLiquidity({ from: _lender, amount: 3_400 * 1e18, index: 1606, - lpAward: 3_400 * 1e18, + lpAward: liquidityAdded, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 3_400 * 1e18, index: 1663, - lpAward: 3_400 * 1e18, + lpAward: liquidityAdded, newLup: MAX_PRICE }); _assertBucket({ index: 1606, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, collateral: 0, - deposit: 3_400 * 1e18, + deposit: liquidityAdded, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 1606, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, depositTime: _startTime + 1 minutes }); _assertBucket({ index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, collateral: 0, - deposit: 3_400 * 1e18, + deposit: liquidityAdded, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, depositTime: _startTime + 1 minutes }); @@ -720,13 +717,13 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, depositTime: _startTime + 1 minutes }); _assertLenderLpBalance({ lender: _lender, index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: liquidityAdded, depositTime: _startTime + 1 minutes }); @@ -737,21 +734,21 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { amount: withdrawal1, index: 1606, newLup: _priceAt(1663), - lpRedeem: 1_699.989134088091859893 * 1e18 + lpRedeem: 1_699.992715262243008677 * 1e18 }); // lender removes all quote token, including interest, from the bucket skip(1 days); - assertGt(_priceAt(1606), _htp()); + assertGt(_priceAt(1606), _getHtp()); - uint256 expectedWithdrawal2 = 1_700.138879728085771159 * 1e18; + uint256 expectedWithdrawal2 = 1_699.976461135759488146 * 1e18; _removeAllLiquidity({ from: _lender, amount: expectedWithdrawal2, index: 1606, newLup: _priceAt(1663), - lpRedeem: 1_700.010865911908140107 * 1e18 + lpRedeem: 1_699.852033596204479923 * 1e18 }); assertEq(_quote.balanceOf(_lender), lenderBalanceBefore + withdrawal1 + expectedWithdrawal2); @@ -771,46 +768,46 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { }); _assertBucket({ index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: 3_399.844748858447488600 * 1e18, collateral: 0, - deposit: 3_400.256025995910604600 * 1e18, - exchangeRate: 1.000075301763503119 * 1e18 + deposit: 3_400.093614235320616015 * 1e18, + exchangeRate: 1.000073199041502318 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 1663, - lpBalance: 3_400 * 1e18, + lpBalance: 3_399.844748858447488600 * 1e18, depositTime: _startTime + 1 minutes }); } - function testPoolMoveQuoteToken() external tearDown { + function testPoolMoveQuoteTokenBasic() external tearDown { _addLiquidity({ from: _lender, amount: 40_000 * 1e18, index: 2549, - lpAward: 40_000 * 1e18, + lpAward: 39_998.173515981735160000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: 2550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _addLiquidity( { from: _lender, amount: 20_000 * 1e18, index: 2551, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -826,20 +823,20 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { fromIndex: 2549, toIndex: 2552, lpRedeemFrom: 5_000 * 1e18, - lpAwardTo: 5_000 * 1e18, + lpAwardTo: 4_999.771689497716895000 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 35_000 * 1e18, + lpBalance: 34_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2552, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); @@ -862,13 +859,13 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 30_000 * 1e18, + lpBalance: 29_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2552, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); @@ -878,7 +875,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { fromIndex: 2551, toIndex: 2777, lpRedeemFrom: 15_000 * 1e18, - lpAwardTo: 15_000 * 1e18, + lpAwardTo: 14_999.315068493150685000 * 1e18, newLup: MAX_PRICE }); @@ -891,70 +888,68 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 30_000 * 1e18, + lpBalance: 29_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2551, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.086757990867580000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2552, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2777, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); } - function testPoolMoveQuoteTokenRevertOnHTPLUP() external { - + function testPoolMoveQuoteTokenRevertOnHTPLUP() external tearDown { _addLiquidity({ from: _lender, amount: 40_000 * 1e18, index: 2549, - lpAward: 40_000 * 1e18, + lpAward: 39_998.173515981735160000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: 2550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 20_000 * 1e18, index: 2551, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); - _addLiquidity({ from: _lender, amount: 20_000 * 1e18, index: 2540, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2540, - lpBalance: 20_000 * 1e18, + lpBalance: 19_999.086757990867580000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -963,24 +958,32 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { lpBalance: 0, depositTime: 0 }); + // ignoring deposit fee, book: + // bucket deposit cumulative + // 2540 20k 20k + // 2549 40k 60k + // 2550 10k 70k + // 2551 20k 90k uint256 snapshot = vm.snapshot(); + uint256 newLup = 2_995.912459898389633881 * 1e18; + assertEq(_indexOf(newLup), 2551); _drawDebt({ from: _borrower, borrower: _borrower, - amountToBorrow: 89_000 * 1e18, + amountToBorrow: 85_000 * 1e18, limitIndex: 7_388, collateralToPledge: 30 * 1e18, - newLup: 2_995.912459898389633881 * 1e18 + newLup: newLup }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 89_085.576923076923118000 * 1e18, + borrowerDebt: 85_081.730769230769270000 * 1e18, borrowerCollateral: 30.0 * 1e18, - borrowert0Np: 3_420.302343024644254882 * 1e18, - borrowerCollateralization: 1.008888047888587643 * 1e18 + borrowert0Np: 3_279.264124981781484570 * 1e18, + borrowerCollateralization: 1.015735704322220591 * 1e18 }); _drawDebt({ @@ -994,15 +997,15 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 2_969.519230769230770600 * 1e18, + htp: 2_949.500000000000001360 * 1e18, lup: 2_995.912459898389633881 * 1e18, - poolSize: 90_000.000000000000000000 * 1e18, + poolSize: 89_995.890410958904110000 * 1e18, pledgedCollateral: 5_030.0 * 1e18, - encumberedCollateral: 30.036405773600046352 * 1e18, - poolDebt: 89_986.442307692307733800 * 1e18, + encumberedCollateral: 29.847968255732299676 * 1e18, + poolDebt: 85_982.596153846153885800 * 1e18, actualUtilization: 0 * 1e18, targetUtilization: 1.0 * 1e18, - minDebtAmount: 4_499.322115384615386690 * 1e18, + minDebtAmount: 4_299.129807692307694290 * 1e18, loans: 2, maxBorrower: _borrower, interestRate: 0.050000000000000000 * 1e18, @@ -1023,7 +1026,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _drawDebt({ from: _borrower, borrower: _borrower, - amountToBorrow: 89_913 * 1e18, + amountToBorrow: 89_900 * 1e18, limitIndex: 7_388, collateralToPledge: 5_000 * 1e18, newLup: 2_995.912459898389633881 * 1e18 @@ -1031,15 +1034,15 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 17.999890961538461547 * 1e18, + htp: 18.717180000000000009 * 1e18, lup: 2_995.912459898389633881 * 1e18, - poolSize: 90_000.000000000000000000 * 1e18, + poolSize: 89_995.890410958904110000 * 1e18, pledgedCollateral: 5000.0 * 1e18, - encumberedCollateral: 30.040749191565083066 * 1e18, - poolDebt: 89_999.454807692307733806 * 1e18, + encumberedCollateral: 31.237862004544048206 * 1e18, + poolDebt: 89_986.442307692307733800 * 1e18, actualUtilization: 0 * 1e18, targetUtilization: 1.0 * 1e18, - minDebtAmount: 8_999.945480769230773381 * 1e18, + minDebtAmount: 8_998.644230769230773380 * 1e18, loans: 1, maxBorrower: _borrower, interestRate: 0.050000000000000000 * 1e18, @@ -1063,7 +1066,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 40_000 * 1e18, index: 2549, - lpAward: 40_000 * 1e18, + lpAward: 39_998.173515981735160000 * 1e18, newLup: MAX_PRICE }); @@ -1072,20 +1075,20 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: 2550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime + 7 days }); @@ -1096,19 +1099,19 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { fromIndex: 2549, toIndex: 2550, lpRedeemFrom: 5_000 * 1e18, - lpAwardTo: 5_000 * 1e18, + lpAwardTo: 4_999.794520547945205000 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 35_000 * 1e18, + lpBalance: 34_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.337899543378995000 * 1e18, depositTime: _startTime + 7 days }); @@ -1125,13 +1128,13 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: 2549, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime + 7 days }); _assertLenderLpBalance({ lender: _lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.337899543378995000 * 1e18, depositTime: _startTime + 7 days }); } @@ -1143,7 +1146,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { * Attempts to move quote token from bucket with available collateral. * Attempts to move quote token when doing so would drive lup below htp. */ - function testPoolMoveQuoteTokenReverts() external tearDown { + function testPoolMoveQuoteTokenReverts() external { // test setup _mintCollateralAndApproveTokens(_lender1, _collateral.balanceOf(_lender1) + 100_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, _collateral.balanceOf(_lender1) + 1_500_000 * 1e18); @@ -1153,28 +1156,28 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 40_000 * 1e18, index: 4549, - lpAward: 40_000 * 1e18, + lpAward: 39_998.173515981735160000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 10_000 * 1e18, index: 4550, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 20_000 * 1e18, index: 4551, - lpAward: 20_000 * 1e18, + lpAward: 19_999.086757990867580000 * 1e18, newLup: MAX_PRICE }); _addLiquidity({ from: _lender, amount: 30_000 * 1e18, index: 4651, - lpAward: 30_000 * 1e18, + lpAward: 29_998.630136986301370000 * 1e18, newLup: MAX_PRICE }); @@ -1223,23 +1226,15 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { expiry: block.timestamp - 20 }); - // should revert if move below LUP with revertIfBelowLup set to true - _assertMoveDepositBelowLUPRevert({ - from: _lender, - amount: 10_000 * 1e18, - fromIndex: 4549, - toIndex: 5000 - }); - - // should be charged unutilized deposit fee if moving below LUP + // should be charged fee for moving to lower bucket _moveLiquidityWithPenalty({ from: _lender, amount: 10_000 * 1e18, - amountMoved: 9_998.630136986301370000 * 1e18, + amountMoved: 9_999.543378995433790000 * 1e18, fromIndex: 4549, toIndex: 5000, lpRedeemFrom: 10_000 * 1e18, - lpAwardTo: 9_998.630136986301370000 * 1e18, + lpAwardTo: 9_999.543378995433790000 * 1e18, newLup: _priceAt(4651) }); @@ -1251,7 +1246,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { fromIndex: 5000, toIndex: 4550, lpRedeemFrom: amountToMove, - lpAwardTo: amountToMove, + lpAwardTo: 9_999.543378995433790000 * 1e18, newLup: 0.139445853940958153 * 1e18 }); } @@ -1264,7 +1259,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 10_000 * 1e18, index: 2873, - lpAward: 10_000 * 1e18, + lpAward: 9_999.543378995433790000 * 1e18, newLup: MAX_PRICE }); @@ -1295,11 +1290,11 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _moveLiquidityWithPenalty({ from: _lender, amount: 2_500 * 1e18, - amountMoved: 2_499.657534246575342500 * 1e18, + amountMoved: 2_499.885844748858447500 * 1e18, fromIndex: lupIndex, toIndex: 2954, - lpRedeemFrom: 2_499.902874075010987321 * 1e18, - lpAwardTo: 2_499.657534246575342500 * 1e18, + lpRedeemFrom: 2_499.902869640007040861 * 1e18, + lpAwardTo: 2_499.885844748858447500 * 1e18, newLup: _lup() }); @@ -1310,7 +1305,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender1, amount: 1_000 * 1e18, index: 2873, - lpAward: 999.958177826584067212 * 1e18, + lpAward: 999.917081697041550606 * 1e18, newLup: 601.252968524772188572 * 1e18 }); @@ -1320,11 +1315,11 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _moveLiquidityWithPenalty({ from: _lender, amount: 2_500 * 1e18, - amountMoved: 2_499.691780821917807500 * 1e18, + amountMoved: 2_499.897260273972602500 * 1e18, fromIndex: lupIndex, toIndex: 2954, - lpRedeemFrom: 2_499.816688122962822235 * 1e18, - lpAwardTo: 2_499.691780821917807500 * 1e18, + lpRedeemFrom: 2_499.816678530752331668 * 1e18, + lpAwardTo: 2_499.897260273972602500 * 1e18, newLup: _lup() }); @@ -1335,7 +1330,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender1, amount: 9_000 * 1e18, index: 2873, - lpAward: 8_994.229791354853043264 * 1e18, + lpAward: 8_993.896659993261260864 * 1e18, newLup: 601.252968524772188572 * 1e18 }); @@ -1344,18 +1339,18 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _removeAllLiquidity({ from: _lender, - amount: 5_003.495432642728075896 * 1e18, + amount: 5_003.038792937182565795 * 1e18, index: 2873, newLup: 601.252968524772188572 * 1e18, - lpRedeem: 5_000.280437802026190444 * 1e18 + lpRedeem: 4_999.823830824674417471 * 1e18 }); _removeAllLiquidity({ from: _lender, - amount: 4_999.349315068493150000 * 1e18, + amount: 4_999.783105022831050000 * 1e18, index: 2954, newLup: 601.252968524772188572 * 1e18, - lpRedeem: 4_999.349315068493150000 * 1e18 + lpRedeem: 4_999.783105022831050000 * 1e18 }); assertGt(_quote.balanceOf(_lender), 200_000 * 1e18); @@ -1395,7 +1390,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 984665640564039457.584007913129639933 * 1e18, index: 2570, - lpAward: 984665651272169776.470215805684254103 * 1e18, + lpAward: 984620689370285202.512316095607611762 * 1e18, newLup: MAX_PRICE }); @@ -1408,25 +1403,24 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: 2570, - lpBalance: 984665651272169776.470215805684254103 * 1e18, + lpBalance: 984620689370285202.512316095607611762 * 1e18, depositTime: _startTime }); _assertBucket({ index: 2570, - lpBalance: 984665651272169776.470215805720134793 * 1e18, + lpBalance: 984620689370285202.512316095643492452 * 1e18, collateral: 13167, - deposit: 984665640564039457.584007913129639933 * 1e18, + deposit: 984620678662643839.348431774140748349 * 1e18, exchangeRate: 0.999999989125110331 * 1e18 // exchange rate should not change }); - skip(48 hours); // to avoid penalty - - _removeAllLiquidity({ + // remove all but 1 gwei from the bucket + _removeLiquidity({ from: _lender, - amount: 984665640564039457.584007913129639932 * 1e18, + amount: 984620678662643839.348431774140748348 * 1e18, index: 2570, newLup: MAX_PRICE, - lpRedeem: 984665651272169776.470215805684254103 * 1e18 + lpRedeem: 984620689370285202.512316095607611762 * 1e18 }); _assertLenderLpBalance({ @@ -1449,22 +1443,40 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { exchangeRate: 1.000000016995254411 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 1); - assertEq(_quote.balanceOf(_lender), 999999999999999999.999999999999999999 * 1e18); + // show the pool only has 1 gwei liquidity, although reserves accumulated due to deposit fee + _assertPool( + PoolParams({ + htp: 0, + lup: MAX_PRICE, + poolSize: 1, + pledgedCollateral: 0, + encumberedCollateral: 0, + poolDebt: 0, + actualUtilization: 0, + targetUtilization: 1 * 1e18, + minDebtAmount: 0, + loans: 0, + maxBorrower: address(0), + interestRate: 0.050000000000000000 * 1e18, + interestRateUpdate: _startTime + }) + ); + assertEq(_quote.balanceOf(address(_pool)), 44961901395618.235576138988891585 * 1e18); + assertEq(_quote.balanceOf(_lender), 999955038098604381.764423861011108415 * 1e18); // bucket can be healed by adding liquidity / collateral _addLiquidity({ from: _lender, amount: 100 * 1e18, index: 2570, - lpAward: 99.999998300474587800 * 1e18, + lpAward: 99.995432090506529601 * 1e18, newLup: MAX_PRICE }); _addCollateral({ from: _borrower, amount: 1 * 1e18, index: 2570, - lpAward: 2725.046631730843547879 * 1e18 + lpAward: 2_725.046631730843547903 * 1e18 }); } @@ -1473,14 +1485,14 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { from: _lender, amount: 0.000000059754288926 * 1e18, index: 852, - lpAward: 0.000000059754288926 * 1e18, + lpAward: 0.000000059751560420 * 1e18, newLup: MAX_PRICE }); _assertLenderLpBalance({ lender: _lender, index: 852, - lpBalance: 0.000000059754288926 * 1e18, + lpBalance: 0.000000059751560420 * 1e18, depositTime: _startTime }); @@ -1488,7 +1500,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 0.000000059754288926 * 1e18, + poolSize: 0.000000059751560420 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -1513,11 +1525,11 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.000000029905872487 * 1e18, + htp: 0.000000031102107386 * 1e18, lup: 14_343_926.246295999585280544 * 1e18, - poolSize: 0.000000059754288926 * 1e18, + poolSize: 0.000000059751560420 * 1e18, pledgedCollateral: 1 * 1e18, - encumberedCollateral: 2085, + encumberedCollateral: 2168, poolDebt: 0.000000029905872487 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1533,11 +1545,11 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _assertPool( PoolParams({ - htp: 0.000000029905872487 * 1e18, + htp: 0.000000031966000026 * 1e18, lup: 14_343_926.246295999585280544 * 1e18, - poolSize: 0.000000059754288926 * 1e18, + poolSize: 0.000000059751560420 * 1e18, pledgedCollateral: 1 * 1e18, - encumberedCollateral: 2143, + encumberedCollateral: 2229, poolDebt: 0.000000030736538488 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1557,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, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 19.280586055366139163 * 1e18, + borrowerCollateral: 2 * 1e18, + borrowert0Np: 10.995179713174208507 * 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: 11.146834976502055842 * 1e18, + totalBondEscrowed: 0.215563505329166046 * 1e18, + auctionPrice: 2_853.589753984526295552 * 1e18, + debtInAuction: 19.280586055366139163 * 1e18, + debtToCollateral: 9.640293027683069581 * 1e18, + neutralPrice: 11.146834976502055842 * 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: 11.146834976502055842 * 1e18, + totalBondEscrowed: 0.215563505329166046 * 1e18, + auctionPrice: 9.373333573165302108 * 1e18, + debtInAuction: 19.280586055366139163 * 1e18, + debtToCollateral: 9.640293027683069581 * 1e18, + neutralPrice: 11.146834976502055842 * 1e18 + }) + ); + + // used to block last minute arbTakes that favor the taker + _assertAddAboveAuctionPriceRevert({ + from: _lender, + amount: 1 * 1e18, + index: _i100_33 + }); + + } + } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol index 6d68900b4..c3629148f 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol @@ -61,7 +61,7 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { }); } - function testStartAndTakeUsdcReserveAuction() external { + function testStartAndTakeUsdcReserveAuction() external tearDown { // skip time to accumulate interest skip(26 weeks); @@ -78,8 +78,8 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { assertEq(USDC.balanceOf(address(_pool)), 1_007.869213 * 1e6); _assertReserveAuction({ - reserves: 1.425574699803092 * 1e18, - claimableReserves : 1.425573693359453700 * 1e18, + reserves: 1.471236800259713756 * 1e18, + claimableReserves : 1.471235793861737556 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -88,18 +88,18 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 1.425573693359453700 * 1e18, - price: 1000000000 * 1e18, + remainingReserves: 1.471235793861737556 * 1e18, + price: 679_700_700.711729067726118823 * 1e18, epoch: 1 }); skip(60 hours); _assertReserveAuction({ - reserves: 0.000001006443638300 * 1e18, + reserves: 0.000001006397976200 * 1e18, claimableReserves : 0, - claimableReservesRemaining: 1.425573693359453700 * 1e18, - auctionPrice: 0.000000000867361737 * 1e18, + claimableReservesRemaining: 1.471235793861737556 * 1e18, + auctionPrice: 0.000000000589546380 * 1e18, timeRemaining: 43200 }); @@ -111,17 +111,17 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { assertEq(USDC.balanceOf(address(_pool)), 1_007.869213 * 1e6); assertEq(AJNA.balanceOf(address(_bidder)), 10 * 1e18); _pool.takeReserves(10 * 1e18); - assertEq(USDC.balanceOf(address(_pool)), 1_006.443640 * 1e6); - assertEq(USDC.balanceOf(address(_bidder)), 1.425573 * 1e6); - assertEq(AJNA.balanceOf(address(_bidder)), 9.999999998763511925 * 1e18); + assertEq(USDC.balanceOf(address(_pool)), 1_006.397978 * 1e6); + assertEq(USDC.balanceOf(address(_bidder)), 1.471235 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999132638263 * 1e18); } - function testZeroBid() external { + function testZeroBid() external tearDown { // mint into the pool to simulate reserves deal(address(USDC), address(_pool), 1_000_000 * 1e6); _assertReserveAuction({ - reserves: 999_300.2884615384615386 * 1e18, - claimableReserves : 999_298.787018230769230907 * 1e18, + reserves: 999_300.334123638918159600 * 1e18, + claimableReserves : 999_300.334122638963821700 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -130,41 +130,61 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 999_298.787018230769230907 * 1e18, - price: 1_000_000_000 * 1e18, + remainingReserves: 999_300.334122638963821700 * 1e18, + price: 1_000.700155752449863388 * 1e18, epoch: 1 }); - // price cannot hit zero, but wait for it to be reasonably small - skip(71 hours); + // wait for price to be reasonably small + skip(64 hours); _assertReserveAuction({ - reserves: 1.501443307692307693 * 1e18, + reserves: 0.000000999954337900 * 1e18, claimableReserves : 0, - claimableReservesRemaining: 999_298.787018230769230907 * 1e18, - auctionPrice: 0.000000000000423516 * 1e18, - timeRemaining: 1 hours + claimableReservesRemaining: 999_300.334122638963821700 * 1e18, + auctionPrice: 0.000000000000000054 * 1e18, + timeRemaining: 72 hours - 64 hours }); // try to take the smallest amount of USDC possible assertEq(USDC.balanceOf(address(_bidder)), 0); assertEq(AJNA.balanceOf(address(_bidder)), 10 * 1e18); - _pool.takeReserves(1 * 1e6); - // bidder got nothing, but burned 1wei of AJNA - assertEq(USDC.balanceOf(address(_bidder)), 0); + _pool.takeReserves(1e12); + // bidder got a quantum of USDC and burned 1wei of AJNA + assertEq(USDC.balanceOf(address(_bidder)), 1); assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999999999 * 1e18); // try to take a smaller-than-possible amount of USDC - _pool.takeReserves(1); - // bidder got nothing, but burned another 1wei of AJNA - assertEq(USDC.balanceOf(address(_bidder)), 0); - assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999999998 * 1e18); + // should revert, because no quote token would be purchased + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.takeReserves(1e11); + // bidder balances unchanged + assertEq(USDC.balanceOf(address(_bidder)), 1); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999999999 * 1e18); // take a reasonable amount of USDC - assertEq(USDC.balanceOf(address(_bidder)), 0); + assertEq(USDC.balanceOf(address(_bidder)), 1); _pool.takeReserves(100 * 1e18); // bidder burned some AJNA - assertEq(USDC.balanceOf(address(_bidder)), 100 * 1e6); - assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999957648398 * 1e18); + assertEq(USDC.balanceOf(address(_bidder)), 100.000001 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999994599 * 1e18); + + // wait for price to be 0 + skip(7 hours); + _assertReserveAuction({ + reserves: 0.000000999954337900 * 1e18, + claimableReserves : 0, + claimableReservesRemaining: 999_200.334121638963821700 * 1e18, + auctionPrice: 0, + timeRemaining: 1 hours + }); + + // take 1 USDC should revert, because no AJNA would be burned + assertEq(USDC.balanceOf(address(_bidder)), 100.000001 * 1e6); + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.takeReserves(1 * 1e18); + // bidder balances unchanged + assertEq(USDC.balanceOf(address(_bidder)), 100.000001 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999994599 * 1e18); } } @@ -198,8 +218,8 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { ERC20Pool pool = ERC20Pool(address(_pool)); changePrank(_actor3); - pool.addQuoteToken(197806, 2572, block.timestamp + 1, false); - pool.drawDebt(_actor3, 98903, 7388, 37); + pool.addQuoteToken(197806, 2572, block.timestamp + 1); + pool.drawDebt(_actor3, 98903, 7388, 40); // pool balance is amount added minus new debt assertEq(_quote.balanceOf(address(pool)), 98903); @@ -218,42 +238,28 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { pool.drawDebt(_actor7, 99266, 7388, 999234524847); // actor 7 draws almost all available quote token - pool.drawDebt(_actor7, 98703, 7388, 999234524847); + pool.drawDebt(_actor7, 98000, 7388, 999234524847); // pool balance decreased by new debt - assertEq(_quote.balanceOf(address(pool)), 200); + assertEq(_quote.balanceOf(address(pool)), 903); // available quote token decreased with new debt - assertEq(_availableQuoteToken(), 200); - - vm.warp(block.timestamp + 86400); - - // attempt to kick reserves and verify pool balance is unchanged - changePrank(_actor2); - pool.updateInterest(); - vm.expectRevert(IPoolErrors.NoReserves.selector); - pool.kickReserveAuction(); - assertEq(_quote.balanceOf(address(pool)), 200); + assertEq(_availableQuoteToken(), 903); vm.warp(block.timestamp + 86400); - changePrank(_actor3); - pool.updateInterest(); - // not enough balance to start new auction - vm.expectRevert(IPoolErrors.NoReserves.selector); - pool.kickReserveAuction(); - + // repay debt to have enough balance to kick new reserves auction ERC20Pool(address(_pool)).repayDebt(_actor3, type(uint256).max, 0, _actor3, MAX_FENWICK_INDEX); ERC20Pool(address(_pool)).repayDebt(_actor7, type(uint256).max, 0, _actor7, MAX_FENWICK_INDEX); - uint256 initialPoolBalance = 200784; - uint256 initialAvailableAmount = 200784; + uint256 initialPoolBalance = 200763; + uint256 initialAvailableAmount = 200763; assertEq(_quote.balanceOf(address(pool)), initialPoolBalance); assertEq(_availableQuoteToken(), initialAvailableAmount); pool.kickReserveAuction(); - uint256 claimableTokens = 591; + uint256 claimableTokens = 599; ( , , uint256 claimable, , ) = _poolUtils.poolReservesInfo(address(_pool)); assertEq(claimable, claimableTokens); @@ -264,6 +270,8 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { deal(address(_ajna), _actor3, 1e45); ERC20(address(_ajna)).approve(address(_pool), type(uint256).max); + assertEq(_quote.balanceOf(address(pool)), 200763); + pool.takeReserves(claimableTokens); // quote token balance diminished by quote token taken from reserve auction @@ -272,4 +280,45 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { assertEq(_availableQuoteToken(), initialAvailableAmount - claimableTokens); } + function testReserveAuctionUnsettledLiquidation() external { + // add reserves to the pool + changePrank(_actor2); + _quote.transfer(address(_pool), 1_000 * 1e18); + _assertReserveAuction({ + reserves: 1_000 * 1e18, + claimableReserves : 1_000 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + skip(2 hours); + + // create an unsettled liquidation + _addInitialLiquidity({ + from: _actor2, + amount: 12_000 * 1e18, + index: _i100_33 + }); + _drawDebt({ + from: _actor3, + borrower: _actor3, + amountToBorrow: 8_000 * 1e18, + limitIndex: _i100_33, + collateralToPledge: 100 * 1e18, + newLup: _p100_33 + }); + _lenderKick({ + from: _actor2, + index: _i100_33, + borrower: _actor3, + debt: 8_007.692307692307696000 * 1e18, + collateral: 100 * 1e18, + bond: 89.528721714510806718 * 1e18 + }); + skip(73 hours); + + // confirm reserve auction may not be kicked + _assertReserveAuctionUnsettledLiquidation(); + } + } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolTransferLPs.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolTransferLPs.t.sol index 57c24cf90..4364a1534 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolTransferLPs.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolTransferLPs.t.sol @@ -136,18 +136,18 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { from: _lender1, to: _lender2, indexes: indexes, - lpBalance: 30_000 * 1e18 + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()) }); _assertLenderLpBalance({ lender: _lender2, index: indexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender2, index: indexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime }); } @@ -175,7 +175,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); @@ -235,7 +235,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ @@ -247,7 +247,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ @@ -259,7 +259,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[2], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ @@ -282,7 +282,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { from: _lender1, to: _lender2, indexes: indexes, - lpBalance: 60_000 * 1e18 + lpBalance: Maths.wmul(60_000 * 1e18, _depositFee()) }); // check that old token ownership was removed - a new transfer should fail @@ -303,7 +303,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ @@ -315,7 +315,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ @@ -327,7 +327,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[2], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); } @@ -362,7 +362,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: depositIndexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ @@ -374,7 +374,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: depositIndexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ @@ -386,7 +386,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: depositIndexes[2], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ @@ -408,7 +408,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { from: _lender1, to: _lender2, indexes: transferIndexes, - lpBalance: 40_000 * 1e18 + lpBalance: Maths.wmul(40_000 * 1e18, _depositFee()) }); // check that old token ownership was removed - transfer with same indexes should fail @@ -429,13 +429,13 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: depositIndexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ lender: _lender1, index: depositIndexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime }); _assertLenderLpBalance({ @@ -453,7 +453,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: depositIndexes[2], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime }); } @@ -504,37 +504,37 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[0], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ lender: _lender2, index: indexes[0], - lpBalance: 5_000 * 1e18, + lpBalance: Maths.wmul(5_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); _assertLenderLpBalance({ lender: _lender1, index: indexes[1], - lpBalance: 20_000 * 1e18, + lpBalance: Maths.wmul(20_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ lender: _lender2, index: indexes[1], - lpBalance: 10_000 * 1e18, + lpBalance: Maths.wmul(10_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); _assertLenderLpBalance({ lender: _lender1, index: indexes[2], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime + 1 hours }); _assertLenderLpBalance({ lender: _lender2, index: indexes[2], - lpBalance: 15_000 * 1e18, + lpBalance: Maths.wmul(15_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); @@ -559,7 +559,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { from: _lender1, to: _lender2, indexes: indexes, - lpBalance: 60_000 * 1e18 + lpBalance: Maths.wmul(60_000 * 1e18, _depositFee()) }); // check that old token ownership was removed - transfer with same indexes should fail @@ -586,7 +586,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[0], - lpBalance: 15_000 * 1e18, + lpBalance: Maths.wmul(15_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); _assertLenderLpBalance({ @@ -598,7 +598,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[1], - lpBalance: 30_000 * 1e18, + lpBalance: Maths.wmul(30_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); _assertLenderLpBalance({ @@ -610,7 +610,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: indexes[2], - lpBalance: 45_000 * 1e18, + lpBalance: Maths.wmul(45_000 * 1e18, _depositFee()), depositTime: _startTime + 2 hours }); } @@ -676,7 +676,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { from: _lender1, to: _lender2, indexes: indexes, - lpBalance: 60_000 * 1e18 + lpBalance: 59_997.260273972602740000 * 1e18 }); } @@ -836,7 +836,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[0], - lpBalance: 4_000 * 1e18, + lpBalance: 3_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -854,7 +854,7 @@ contract ERC20PoolTransferLPTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: indexes[1], - lpBalance: 8_000 * 1e18, + lpBalance: 7_999.086757990867580000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ diff --git a/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol b/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol index 112c48397..772a96ab2 100644 --- a/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol +++ b/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol @@ -38,7 +38,7 @@ contract ERC20SafeTransferTokens is ERC20HelperContract { usdt.approve(address(pool), 1_000 * 1e18); - pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max, false); + pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max); changePrank(_borrower); @@ -56,7 +56,7 @@ contract ERC20SafeTransferTokens is ERC20HelperContract { _quote.approve(address(pool), 1_000 * 1e18); - pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max, false); + pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max); changePrank(_borrower); diff --git a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol index ac5dadf09..31bdb56a5 100644 --- a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol +++ b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol @@ -43,7 +43,7 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { changePrank(borrower); // settle borrower if borrower is kicked - (uint256 kickTime, , , , , ) = _poolUtils.auctionStatus(address(_pool), borrower); + (uint256 kickTime, , , , , , , , ) = _poolUtils.auctionStatus(address(_pool), borrower); if (kickTime != 0) { _pool.settle(borrower, bucketsUsed.length()); } @@ -111,12 +111,13 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { { uint256 fractionOfNftRemaining = lpsAsCollateral % 1e18; assertLt(fractionOfNftRemaining, 1e18); - + depositRequired = Maths.wmul(1e18 - fractionOfNftRemaining, price); + depositRequired += Maths.ceilWdiv(1e18, _depositFee()); } deal(_pool.quoteTokenAddress(), lender, depositRequired); Token(_pool.quoteTokenAddress()).approve(address(_pool) , depositRequired); - _pool.addQuoteToken(depositRequired, bucketIndex, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(depositRequired, bucketIndex, block.timestamp + 1 minutes); (lenderLpBalance, ) = _pool.lenderInfo(bucketIndex, lender); lpsAsCollateral = _poolUtils.lpToCollateral(address(_pool), lenderLpBalance, bucketIndex); } @@ -162,13 +163,13 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { for (uint i = 0; i < borrowers.length(); i++) { address borrower = borrowers.at(i); - (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); + (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower); if (kickTime != 0) { changePrank(borrower); _pool.settle(borrower, bucketsUsed.length() + 1); // Settle again if not settled, this can happen when less reserves calculated with DEPOSIT_BUFFER and borrower is not fully settled - (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); + (,,, kickTime,,,,,,) = _pool.auctionInfo(borrower); if (kickTime != 0) { _pool.settle(borrower, bucketsUsed.length() + 1); } @@ -466,7 +467,7 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { uint256 borrowersCollateral; for (uint256 i = 0; i < borrowers.length(); i++) { - (, uint256 borrowerCollateral, ) = _poolUtils.borrowerInfo(address(_pool), borrowers.at(i)); + (, uint256 borrowerCollateral, , ) = _poolUtils.borrowerInfo(address(_pool), borrowers.at(i)); borrowersCollateral += borrowerCollateral; } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol index b8b41c6d2..3e604cc27 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol @@ -169,7 +169,7 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -185,9 +185,9 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { // check initial bucket state _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -201,6 +201,14 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, tokenIds: tokenIdsToAdd }); + + // check token balances after pledge + uint256[] memory pledgedTokens = ERC721Pool(address(_pool)).getBorrowerTokenIds(_borrower); + assertEq(pledgedTokens.length, 3); + assertEq(pledgedTokens[0], 1); + assertEq(pledgedTokens[1], 3); + assertEq(pledgedTokens[2], 5); + // borrower borrows from the pool uint256 borrowAmount = 3_000 * 1e18; _borrow({ @@ -220,11 +228,11 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { // check pool state after borrow _assertPool( PoolParams({ - htp: 1_000.961538461538462000 * 1e18, + htp: 1_041.000000000000000480 * 1e18, lup: _priceAt(2550), - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: Maths.wad(3), - encumberedCollateral: 0.997340520100278804 * 1e18, + encumberedCollateral: 1.037234140904289956 * 1e18, poolDebt: 3_002.88461538461538600 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1 * 1e18, @@ -238,9 +246,9 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { // check bucket state after borrow _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); // check borrower info after borrow @@ -248,8 +256,8 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, borrowerDebt: 3_002.884615384615386000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_152.910902143138512881 * 1e18, - borrowerCollateralization: 3.007999714779824033 * 1e18 + borrowert0Np: 1_157.387338228864053377 * 1e18, + borrowerCollateralization: 2.892307418057523109 * 1e18 }); // pass time to allow interest to accumulate skip(10 days); @@ -274,13 +282,13 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { // check pool state after partial repay _assertPool( PoolParams({ - htp: 502.333658244714424687 * 1e18, + htp: 522.427004574503001674 * 1e18, lup: _priceAt(2550), - poolSize: 30_003.498905447098680000 * 1e18, + poolSize: 30_002.129042433400069436 * 1e18, pledgedCollateral: 3 * 1e18, - encumberedCollateral: 0.500516446164039921 * 1e18, + encumberedCollateral: 0.520537104010601517 * 1e18, poolDebt: 1_507.000974734143274062 * 1e18, - actualUtilization: 0.100096122026423251 * 1e18, + actualUtilization: 0.100100692834315229 * 1e18, targetUtilization: 0.332446840033426268 * 1e18, minDebtAmount: 150.700097473414327406 * 1e18, loans: 1, @@ -292,18 +300,18 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { // check bucket state after partial repay _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_001.166301815699560000 * 1e18, - exchangeRate: 1.000116630181569956 * 1e18 + deposit: 10_000.709680811133356479 * 1e18, + exchangeRate: 1.000116635507392213 * 1e18 }); // check borrower info after partial repay _assertBorrower({ borrower: _borrower, borrowerDebt: 1_507.000974734143274062 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 577.797569043003579568 * 1e18, - borrowerCollateralization: 5.993809040625961846 * 1e18 + borrowert0Np: 580.040998160987125679 * 1e18, + borrowerCollateralization: 5.763277923678809473 * 1e18 }); // pass time to allow additional interest to accumulate @@ -314,8 +322,8 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, borrowerDebt: 1_508.860066921599065132 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 577.797569043003579568 * 1e18, - borrowerCollateralization: 5.986423966420065589 * 1e18 + borrowert0Np: 580.040998160987125679 * 1e18, + borrowerCollateralization: 5.756176890788524601 * 1e18 }); // mint additional quote to allow borrower to repay their loan plus interest @@ -350,11 +358,11 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_005.088767154245370000 * 1e18, + poolSize: 30_003.718904596374273953 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.050227555333959397 * 1e18, + actualUtilization: 0.050229848666883565 * 1e18, targetUtilization: 0.202597018753257617 * 1e18, minDebtAmount: 0, loans: 0, @@ -367,15 +375,15 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { debtColEma: 1_009_226.137898421530685238 * 1e18, lupt0DebtEma: 4_981_446.144217726231751319 * 1e18, debtEma: 1_507.002401317220586672 * 1e18, - depositEma: 30_003.498902092092525534 * 1e18 + depositEma: 30_002.129039078394745557 * 1e18 }); // check bucket state after fully repay _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_001.696255718081790000 * 1e18, - exchangeRate: 1.000169625571808179 * 1e18 + deposit: 10_001.239634865458091318 * 1e18, + exchangeRate: 1.000169633332816715 * 1e18 }); // check borrower info after fully repay _assertBorrower({ @@ -390,6 +398,65 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { assertEq(_collateral.balanceOf(address(_pool)), 0); } + function testFirstInterestAccrual() external { + // add liquidity + _addInitialLiquidity({ + from: _lender, + amount: 300 * 1e18, + index: _i100_33 + }); + // mint some quote token for borrower to repay + _mintAndApproveQuoteTokens(_borrower, 2 * 1e18); + uint256 snapshot = vm.snapshot(); + + uint loanTerm = 1 hours; + uint loanPrincipal = 150 * 1e18; + ERC721Pool pool = ERC721Pool(address(_pool)); + + // calculate debt if borrower took a 90 day loan shortly after pool creation + uint256[] memory tokenIdsToAdd = new uint256[](3); + tokenIdsToAdd[0] = 1; + tokenIdsToAdd[1] = 3; + tokenIdsToAdd[2] = 5; + changePrank(_borrower); + pool.drawDebt(_borrower, loanPrincipal, _i100_33, tokenIdsToAdd); + skip(loanTerm); + (uint256 borrowRate1, ) = _pool.interestRateInfo(); + assertEq(borrowRate1, 0.05 * 1e18); + uint256 borrowFee1 = Maths.wmul(_poolUtils.borrowFeeRate(address(_pool)), loanPrincipal); + (borrowRate1, ) = _pool.interestRateInfo(); + assertEq(borrowRate1, 0.05 * 1e18); + uint256 repaid1 = pool.repayDebt({ + borrowerAddress_: _borrower, + maxQuoteTokenAmountToRepay_: type(uint256).max, + noOfNFTsToPull_: 3, + collateralReceiver_: _borrower, + limitIndex_: _i100_33 + }); + + vm.revertTo(snapshot); + + // calculate debt if borrower took a 90 day loan long after pool creation + skip(10 hours); + changePrank(_borrower); + pool.drawDebt(_borrower, loanPrincipal, _i100_33, tokenIdsToAdd); + skip(loanTerm); + (uint256 borrowRate2, ) = _pool.interestRateInfo(); + assertEq(borrowRate2, 0.05 * 1e18); + uint256 borrowFee2 = Maths.wmul(_poolUtils.borrowFeeRate(address(_pool)), loanPrincipal); + uint256 repaid2 = pool.repayDebt({ + borrowerAddress_: _borrower, + maxQuoteTokenAmountToRepay_: type(uint256).max, + noOfNFTsToPull_: 3, + collateralReceiver_: _borrower, + limitIndex_: _i100_33 + }); + + // ensure both loans owe the same origination fee and interest + assertEq(borrowFee1, borrowFee2); + assertEq(repaid1, repaid2); + } + function testPoolRepayRequireChecks() external tearDown { // add initial quote to the pool _addInitialLiquidity({ @@ -430,9 +497,9 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { }); _assertLoans({ - noOfLoans: 1, - maxBorrower: _borrower, - maxThresholdPrice: 333.653846153846154 * 1e18 + noOfLoans: 1, + maxBorrower: _borrower, + maxT0DebtToCollateral: 333.653846153846154000 * 1e18 }); // should revert if LUP is below the limit @@ -458,15 +525,15 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { }); _borrow({ from: _borrower2, - amount: 3_000 * 1e18, + amount: 2_850 * 1e18, indexLimit: 3_000, newLup: 3_010.892022197881557845 * 1e18 }); _assertLoans({ - noOfLoans: 2, - maxBorrower: _borrower2, - maxThresholdPrice: 3_002.884615384615386 * 1e18 + noOfLoans: 2, + maxBorrower: _borrower2, + maxT0DebtToCollateral: 2_852.740384615384616700 * 1e18 }); // should be able to repay loan if properly specified @@ -571,7 +638,7 @@ contract ERC721CollectionPoolBorrowTest is ERC721NDecimalsHelperContract(18) { function testMinBorrowAmountCheck() external tearDown { // add initial quote to the pool changePrank(_lender); - _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes); // 10 borrowers draw debt for (uint i=0; i<10; ++i) { @@ -600,7 +667,7 @@ contract ERC721CollectionPoolBorrowTest is ERC721NDecimalsHelperContract(18) { function testMinRepayAmountCheck() external tearDown { // add initial quote to the pool changePrank(_lender); - _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes, false); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes); // 9 other borrowers draw debt for (uint i=0; i<9; ++i) { @@ -648,7 +715,7 @@ contract ERC721ScaledQuoteTokenBorrowTest is ERC721NDecimalsHelperContract(4) { // add initial quote to the pool changePrank(_lender); - _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 30, false); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 30); // borrower pledges a single NFT uint256[] memory tokenIdsToAdd = new uint256[](1); @@ -715,7 +782,7 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra _mintAndApproveCollateralTokens(_borrower, 52); } - function testBorrowAndRepayWith4DecimalQuote() external tearDown { + function testBorrowAndRepayWith4DecimalQuote() external { // lender deposits 10000 Quote into 3 buckets _addInitialLiquidity({ @@ -746,7 +813,7 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -762,9 +829,9 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra // check initial bucket state _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -797,11 +864,11 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra // check pool state after borrow _assertPool( PoolParams({ - htp: 1_000.961538461538462000 * 1e18, + htp: 1041.000000000000000480 * 1e18, lup: _priceAt(2550), - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: Maths.wad(3), - encumberedCollateral: 0.997340520100278804 * 1e18, + encumberedCollateral: 1.037234140904289956 * 1e18, poolDebt: 3_002.88461538461538600 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1 * 1e18, @@ -815,9 +882,9 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra // check bucket state after borrow _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); // check borrower info after borrow @@ -825,13 +892,12 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra borrower: _borrower, borrowerDebt: 3_002.884615384615386000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_152.910902143138512881 * 1e18, - borrowerCollateralization: 3.007999714779824033 * 1e18 + borrowert0Np: 1_157.387338228864053377 * 1e18, + borrowerCollateralization: 2.892307418057523109 * 1e18 }); // pass time to allow interest to accumulate skip(10 days); - // borrower partially repays half their loan _repayDebt({ from: _borrower, @@ -852,13 +918,13 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra // check pool state after partial repay _assertPool( PoolParams({ - htp: 502.333658244714424687 * 1e18, + htp: 522.427004574503001674 * 1e18, lup: _priceAt(2550), - poolSize: 30_003.498905447098680000 * 1e18, + poolSize: 30_002.129042433400069436 * 1e18, pledgedCollateral: 3 * 1e18, - encumberedCollateral: 0.500516446164039921 * 1e18, + encumberedCollateral: 0.520537104010601517 * 1e18, poolDebt: 1_507.000974734143274062 * 1e18, - actualUtilization: 0.100096122026423251 * 1e18, + actualUtilization: 0.100100692834315229 * 1e18, targetUtilization: 0.332446840033426268 * 1e18, minDebtAmount: 150.700097473414327406 * 1e18, loans: 1, @@ -870,18 +936,18 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra // check bucket state after partial repay _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_001.166301815699560000 * 1e18, - exchangeRate: 1.000116630181569956 * 1e18 + deposit: 10_000.709680811133356479 * 1e18, + exchangeRate: 1.000116635507392213 * 1e18 }); // check borrower info after partial repay _assertBorrower({ borrower: _borrower, borrowerDebt: 1_507.000974734143274062 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 577.797569043003579568 * 1e18, - borrowerCollateralization: 5.993809040625961846 * 1e18 + borrowert0Np: 580.040998160987125679 * 1e18, + borrowerCollateralization: 5.763277923678809473 * 1e18 }); // pass time to allow additional interest to accumulate @@ -892,8 +958,8 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra borrower: _borrower, borrowerDebt: 1_508.860066921599065132 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 577.797569043003579568 * 1e18, - borrowerCollateralization: 5.986423966420065589 * 1e18 + borrowert0Np: 580.040998160987125679 * 1e18, + borrowerCollateralization: 5.756176890788524601 * 1e18 }); // mint additional quote to allow borrower to repay their loan plus interest @@ -942,11 +1008,11 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_005.088767154245370000 * 1e18, + poolSize: 30_003.718904596374273953 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.050227555333959397 * 1e18, + actualUtilization: 0.050229848666883565 * 1e18, targetUtilization: 0.202597018753257617 * 1e18, minDebtAmount: 0, loans: 0, @@ -959,15 +1025,15 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra debtColEma: 1_009_226.137898421530685238 * 1e18, lupt0DebtEma: 4_981_446.144217726231751319 * 1e18, debtEma: 1_507.002401317220586672 * 1e18, - depositEma: 30_003.498902092092525534 * 1e18 + depositEma: 30_002.129039078394745557 * 1e18 }); // check bucket state after fully repay _assertBucket({ index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_001.696255718081790000 * 1e18, - exchangeRate: 1.000169625571808179 * 1e18 + deposit: 10_001.239634865458091318 * 1e18, + exchangeRate: 1.000169633332816715 * 1e18 }); // check borrower info after fully repay _assertBorrower({ @@ -1021,6 +1087,7 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { // lender adds liquidity to random indexes changePrank(_lender); uint256[] memory indexes = new uint256[](numIndexes); + uint256 lpAfterFee = Maths.wmul(mintAmount_, _depositFee()); for (uint256 i = 0; i < numIndexes; ++i) { deal(address(_quote), _lender, mintAmount_); @@ -1030,15 +1097,15 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { from: _lender, amount: mintAmount_, index: indexes[i], - lpAward: mintAmount_, + lpAward: lpAfterFee, newLup: _calculateLup(address(_pool), 0) }); _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: lpAfterFee, collateral: 0, - deposit: mintAmount_, + deposit: lpAfterFee, exchangeRate: 1e18 }); } @@ -1062,26 +1129,26 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { for (uint256 i = 0; i < numIndexes; ++i) { _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: lpAfterFee, collateral: 0, - deposit: mintAmount_, + deposit: lpAfterFee, exchangeRate: 1e18 }); } // check borrower info - (uint256 debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (uint256 debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); assertGt(debt, borrowAmount); // check that initial fees accrued // check pool state (uint256 minDebt, , uint256 poolActualUtilization, uint256 poolTargetUtilization) = _poolUtils.poolUtilizationInfo(address(_pool)); _assertPool( PoolParams({ - htp: Maths.wdiv(debt, Maths.wad(tokenIdsToAdd.length)), + htp: Maths.wmul(Maths.wdiv(debt, Maths.wad(tokenIdsToAdd.length)), 1.04 * 1e18), lup: _poolUtils.lup(address(_pool)), - poolSize: (indexes.length * mintAmount_), + poolSize: (indexes.length * lpAfterFee), pledgedCollateral: Maths.wad(tokenIdsToAdd.length), - encumberedCollateral: Maths.wdiv(debt, _poolUtils.lup(address(_pool))), + encumberedCollateral: Maths.wdiv(Maths.wmul(debt, 1.04 * 1e18), _poolUtils.lup(address(_pool))), poolDebt: debt, actualUtilization: poolActualUtilization, targetUtilization: poolTargetUtilization, @@ -1092,7 +1159,7 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { interestRateUpdate: _startTime }) ); - assertLt(_htp(), _poolUtils.lup(address(_pool))); + assertLt(_getHtp(), _poolUtils.lup(address(_pool))); assertGt(minDebt, 0); assertEq(_poolUtils.lup(address(_pool)), _calculateLup(address(_pool), debt)); @@ -1100,7 +1167,7 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { skip(1 days); // repay all debt and withdraw collateral - (debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); deal(address(_quote), _borrower, debt); _repayDebt({ @@ -1117,19 +1184,19 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { (, uint256 deposit, , uint256 lpAccumulator, , uint256 exchangeRate) = _poolUtils.bucketInfo(address(_pool), indexes[i]); // check that only deposits above the htp earned interest - if (indexes[i] <= _poolUtils.priceToIndex(Maths.wdiv(debt, Maths.wad(tokenIdsToAdd.length)))) { - assertGt(deposit, mintAmount_); + if (indexes[i] <= _poolUtils.priceToIndex(Maths.wmul(Maths.wdiv(debt, Maths.wad(tokenIdsToAdd.length)), 1.04 * 1e18))) { + assertGt(deposit, lpAfterFee); assertGt(exchangeRate, 1e18); } else { - assertEq(deposit, mintAmount_); + assertEq(deposit, lpAfterFee); assertEq(exchangeRate, 1e18); } - assertEq(lpAccumulator, mintAmount_); + assertEq(lpAccumulator, lpAfterFee); _assertBucket({ index: indexes[i], - lpBalance: mintAmount_, + lpBalance: lpAfterFee, collateral: 0, deposit: deposit, exchangeRate: exchangeRate @@ -1137,11 +1204,11 @@ contract ERC721PoolBorrowFuzzyTest is ERC721FuzzyHelperContract { } // check borrower state after repayment - (debt, , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); + (debt, , , ) = _poolUtils.borrowerInfo(address(_pool), address(_borrower)); assertEq(debt, 0); // check pool state - assertEq(_htp(), 0); + assertEq(_getHtp(), 0); assertEq(_poolUtils.lup(address(_pool)), MAX_PRICE); } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol index d4f1015fd..9276af3fd 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol @@ -13,7 +13,6 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { address internal _borrower; address internal _borrower2; address internal _lender; - address internal _lender2; function setUp() virtual external { _startTest(); @@ -21,7 +20,6 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _borrower = makeAddr("borrower"); _borrower2 = makeAddr("borrower2"); _lender = makeAddr("lender"); - _lender2 = makeAddr("lender2"); // deploy collection pool _pool = _deployCollectionPool(); @@ -31,6 +29,34 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _mintAndApproveCollateralTokens(_borrower, 52); _mintAndApproveCollateralTokens(_borrower2, 53); + + // check initial NFT balances + assertEq(_pool.pledgedCollateral(), 0); + + assertEq(_collateral.balanceOf(_borrower), 52); + assertEq(_collateral.balanceOf(_borrower2), 53); + assertEq(_collateral.balanceOf(address(_pool)), 0); + + // borrower is owner of NFTs + assertEq(_collateral.ownerOf(1), _borrower); + assertEq(_collateral.ownerOf(3), _borrower); + assertEq(_collateral.ownerOf(5), _borrower); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 0, + borrowerCollateral: 0, + borrowert0Np: 0, + borrowerCollateralization: 1 * 1e18 + }); + + _assertBorrower({ + borrower: _borrower2, + borrowerDebt: 0, + borrowerCollateral: 0, + borrowert0Np: 0, + borrowerCollateralization: 1 * 1e18 + }); } /************************************/ @@ -38,12 +64,6 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { /************************************/ function testPledgeCollateral() external tearDown { - // check initial token balances - assertEq(_pool.pledgedCollateral(), 0); - - assertEq(_collateral.balanceOf(_borrower), 52); - assertEq(_collateral.balanceOf(address(_pool)), 0); - uint256[] memory tokenIdsToAdd = new uint256[](3); tokenIdsToAdd[0] = 1; tokenIdsToAdd[1] = 3; @@ -60,46 +80,24 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); - // check token balances after add + // check NFT balances after add assertEq(_pool.pledgedCollateral(), Maths.wad(3)); - assertEq(_collateral.balanceOf(_borrower), 49); + assertEq(_collateral.balanceOf(_borrower), 49); assertEq(_collateral.balanceOf(address(_pool)), 3); } function testPledgeCollateralFromDifferentActor() external tearDown { - // check initial token balances - assertEq(_pool.pledgedCollateral(), 0); - - assertEq(_collateral.balanceOf(_borrower), 52); - assertEq(_collateral.balanceOf(_borrower2), 53); - assertEq(_collateral.balanceOf(address(_pool)), 0); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 0, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 - }); - _assertBorrower({ - borrower: _borrower2, - borrowerDebt: 0, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 - }); - uint256[] memory tokenIdsToAdd = new uint256[](1); tokenIdsToAdd[0] = 53; - // borrower deposits three NFTs into the pool + // borrower2 deposits one NFT into the pool _pledgeCollateral({ from: _borrower2, borrower: _borrower, tokenIds: tokenIdsToAdd }); - // check token balances after add + // check NFT balances after add assertEq(_pool.pledgedCollateral(), Maths.wad(1)); assertEq(_collateral.balanceOf(_borrower), 52); @@ -123,18 +121,6 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { } function testPullCollateral() external tearDown { - // check initial token balances - assertEq(_pool.pledgedCollateral(), 0); - - assertEq(_collateral.balanceOf(_borrower), 52); - assertEq(_collateral.balanceOf(_borrower2), 53); - assertEq(_collateral.balanceOf(address(_pool)), 0); - - // borrower is owner of NFTs - assertEq(_collateral.ownerOf(1), _borrower); - assertEq(_collateral.ownerOf(3), _borrower); - assertEq(_collateral.ownerOf(5), _borrower); - uint256[] memory tokenIdsToAdd = new uint256[](3); tokenIdsToAdd[0] = 1; tokenIdsToAdd[1] = 3; @@ -147,7 +133,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); - // check token balances after add + // check NFT balances after add assertEq(_pool.pledgedCollateral(), Maths.wad(3)); assertEq(_collateral.balanceOf(_borrower), 49); @@ -159,7 +145,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { assertEq(_collateral.ownerOf(3), address(_pool)); assertEq(_collateral.ownerOf(5), address(_pool)); - // should fail if trying to pull collateral by an address without pledged collateral + // reverts if trying to pull collateral by an address without pledged collateral _assertPullInsufficientCollateralRevert({ from: _lender, amount: 3 @@ -168,6 +154,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { // borrower2 is owner of NFT assertEq(_collateral.ownerOf(53), _borrower2); + // borrower2 pledges one NFT tokenIdsToAdd = new uint256[](1); tokenIdsToAdd[0] = 53; _pledgeCollateral({ @@ -176,7 +163,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); - // check token balances after add + // check NFT balances after add assertEq(_pool.pledgedCollateral(), Maths.wad(4)); assertEq(_collateral.balanceOf(_borrower), 49); @@ -195,7 +182,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { collateralToPull: 2 }); - // check token balances after remove + // check NFT balances after remove assertEq(_pool.pledgedCollateral(), Maths.wad(2)); assertEq(_collateral.balanceOf(_borrower), 51); @@ -203,6 +190,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { // pool is owner of remaining pledged NFT assertEq(_collateral.ownerOf(1), address(_pool)); + // borrower is owner of 2 pulled NFTs assertEq(_collateral.ownerOf(3), _borrower); assertEq(_collateral.ownerOf(5), _borrower); @@ -217,18 +205,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { function testPullCollateralToDifferentRecipient() external tearDown { address tokensReceiver = makeAddr("tokensReceiver"); - // check initial token balances - assertEq(_pool.pledgedCollateral(), 0); - - assertEq(_collateral.balanceOf(_borrower), 52); - assertEq(_collateral.balanceOf(_borrower2), 53); assertEq(_collateral.balanceOf(tokensReceiver), 0); - assertEq(_collateral.balanceOf(address(_pool)), 0); - - // borrower is owner of NFTs - assertEq(_collateral.ownerOf(1), _borrower); - assertEq(_collateral.ownerOf(3), _borrower); - assertEq(_collateral.ownerOf(5), _borrower); uint256[] memory tokenIdsToAdd = new uint256[](3); tokenIdsToAdd[0] = 1; @@ -242,7 +219,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); - // borrower2 deposits three NFTs into the pool + // borrower2 deposits one NFT into the pool tokenIdsToAdd = new uint256[](1); tokenIdsToAdd[0] = 53; _pledgeCollateral({ @@ -251,7 +228,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); - // check token balances after add + // check NFT balances after add assertEq(_pool.pledgedCollateral(), Maths.wad(4)); assertEq(_collateral.balanceOf(address(_pool)), 4); @@ -265,7 +242,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { changePrank(_borrower); ERC721Pool(address(_pool)).repayDebt(_borrower, 0, 2, tokensReceiver, MAX_FENWICK_INDEX); - // check token balances after remove + // check NFT balances after remove assertEq(_pool.pledgedCollateral(), Maths.wad(2)); assertEq(_collateral.balanceOf(_borrower), 49); @@ -283,7 +260,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { changePrank(_borrower2); ERC721Pool(address(_pool)).repayDebt(_borrower2, 0, 1, tokensReceiver, MAX_FENWICK_INDEX); - // check token balances after remove + // check NFT balances after remove assertEq(_pool.pledgedCollateral(), Maths.wad(1)); assertEq(_collateral.balanceOf(_borrower), 49); @@ -300,11 +277,6 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { } function testPullCollateralNotInPool() external tearDown { - // borrower is owner of NFTs - assertEq(_collateral.ownerOf(1), _borrower); - assertEq(_collateral.ownerOf(3), _borrower); - assertEq(_collateral.ownerOf(5), _borrower); - uint256[] memory tokenIdsToAdd = new uint256[](3); tokenIdsToAdd[0] = 1; tokenIdsToAdd[1] = 3; @@ -358,7 +330,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { index: 2550 }); - // check initial token balances + // check initial NFT and token balances assertEq(_collateral.balanceOf(_borrower), 52); assertEq(_collateral.balanceOf(address(_pool)), 0); @@ -370,7 +342,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, @@ -402,7 +374,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { newLup: _priceAt(2550) }); - // check token balances after borrow + // check NFT and token balances after borrow assertEq(_collateral.balanceOf(_borrower), 49); assertEq(_collateral.balanceOf(address(_pool)), 3); @@ -412,11 +384,11 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { // check pool state _assertPool( PoolParams({ - htp: 1_000.961538461538462 * 1e18, + htp: 1_041.000000000000000480 * 1e18, lup: _priceAt(2550), - poolSize: 30_000 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, pledgedCollateral: Maths.wad(3), - encumberedCollateral: 0.997340520100278804 * 1e18, + encumberedCollateral: 1.037234140904289956 * 1e18, poolDebt: 3_002.884615384615386 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1 * 1e18, @@ -434,12 +406,12 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, amountToRepay: 0, amountRepaid: 0, - collateralToPull: 2 + collateralToPull: 1 }); - // check token balances after remove - assertEq(_collateral.balanceOf(_borrower), 51); - assertEq(_collateral.balanceOf(address(_pool)), 1); + // check NFT and token balances after remove + assertEq(_collateral.balanceOf(_borrower), 50); + assertEq(_collateral.balanceOf(address(_pool)), 2); assertEq(_quote.balanceOf(address(_pool)), 27_000 * 1e18); assertEq(_quote.balanceOf(_borrower), 3_100 * 1e18); @@ -447,12 +419,12 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { // check pool state _assertPool( PoolParams({ - htp: 3_002.884615384615386000 * 1e18, + htp: 1_561.500000000000000720 * 1e18, lup: _priceAt(2550), - poolSize: 30_000 * 1e18, - pledgedCollateral: Maths.wad(1), - encumberedCollateral: 0.997340520100278804 * 1e18, - poolDebt: 3_002.884615384615386 * 1e18, + poolSize: 29_998.630136986301370000 * 1e18, + pledgedCollateral: Maths.wad(2), + encumberedCollateral: 1.037234140904289956 * 1e18, + poolDebt: 3_002.884615384615386000 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1 * 1e18, minDebtAmount: 300.288461538461538600 * 1e18, @@ -466,7 +438,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { } function testPullCollateralOverlyEncumbered() external tearDown { - // lender deposits 10000 Quote into 3 buckets + // lender deposits 10_000 Quote into 3 buckets _addInitialLiquidity({ from: _lender, amount: 10_000 * 1e18, @@ -502,14 +474,14 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { // borrower borrows some quote _borrow({ from: _borrower, - amount: 9_000 * 1e18, + amount: 8_600 * 1e18, indexLimit: 2_551, newLup: _priceAt(2550) }); // check collateralization after borrow (poolDebt,,,) = _pool.debtInfo(); - assertEq(_encumberance(poolDebt, _lup()), 2.992021560300836411 * 1e18); + assertEq(_encumberance(poolDebt, _lup()), 2.973404537258964540 * 1e18); // should revert if borrower attempts to pull more collateral than is unencumbered _assertPullInsufficientCollateralRevert({ @@ -535,7 +507,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { tokenIds[0] = 1; tokenIds[1] = 5; - // add three tokens to a single bucket + // borrower adds two NFTs to a single bucket _addCollateral({ from: _borrower, tokenIds: tokenIds, @@ -543,21 +515,21 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { lpAward: 975_232.505322350083963682 * 1e18 }); - // should revert if the actor does not have any LP to remove a token + // reverts when borrower2 does not have any LP to remove a NFT _assertRemoveCollateralInsufficientLPRevert({ from: _borrower2, amount: 1, index: 1530 }); - // should revert if we try to remove a token from a bucket with no collateral + // reverts when borrower tries to remove a NFT from a bucket with no collateral _assertRemoveInsufficientCollateralRevert({ from: _borrower, amount: 1, index: 1692 }); - // remove one token + // borrower removes one NFT _removeCollateral({ from: _borrower, amount: 1, @@ -567,9 +539,9 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 1530, - lpBalance: 497_616.252661175041981841 * 1e18, + lpBalance: 497_615.796040170475771841 * 1e18, collateral: Maths.wad(1), - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ @@ -579,7 +551,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { depositTime: _startTime }); - // remove another token + // borrower removes second NFT _removeCollateral({ from: _borrower, amount: 1, @@ -589,9 +561,9 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 1530, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ @@ -606,10 +578,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _removeAllLiquidity({ from: _lender, - amount: 10_000 * 1e18, + amount: 9_999.543378995433790000 * 1e18, index: 1530, newLup: MAX_PRICE, - lpRedeem: 10_000 * 1e18 + lpRedeem: 9_999.543378995433790000 * 1e18 }); _assertBucket({ @@ -623,16 +595,14 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { function testMergeOrRemoveERC721Collateral() external tearDown { for (uint256 i = 3060; i < (3060 + 10); i++) { - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 20 * 1e18, - index: i, - newLup: MAX_PRICE, - lpAward: 20 * 1e18 + index: i }); } - // borrower pledge collateral and draws debt + // borrower pledges two NFTs and draws debt uint256[] memory tokenIdsToAdd = new uint256[](2); tokenIdsToAdd[0] = 1; tokenIdsToAdd[1] = 3; @@ -648,7 +618,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { newLup: 228.476350374240318479 * 1e18 }); - // Borrower starts with possession of tokens 1 and 3 + // Borrower starts with possession of NFTs 1 and 3 uint256[] memory borrowerTokenIds = new uint256[](2); borrowerTokenIds[0] = 1; borrowerTokenIds[1] = 3; @@ -657,8 +627,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 150.144230769230769300 * 1e18, borrowerCollateral: 2.0 * 1e18, - borrowert0Np: 86.468317660735388466 * 1e18, - borrowerCollateralization: 3.043424968161510485 * 1e18, + borrowert0Np: 86.804050367164804003 * 1e18, + borrowerCollateralization: 2.926370161693760082 * 1e18, tokenIds: borrowerTokenIds }); @@ -666,11 +636,11 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { skip(10_000 days); _assertPool( PoolParams({ - htp: 75.072115384615384650 * 1e18, + htp: 307.210419047238320914 * 1e18, lup: 0.000000099836282890 * 1e18, - poolSize: 200.0 * 1e18, + poolSize: 199.990867579908675800 * 1e18, pledgedCollateral: 2 * 1e18, - encumberedCollateral: 5_917_580_766.197687035371154332 * 1e18, + encumberedCollateral: 6_154_283_996.845594516785199193 * 1e18, poolDebt: 590.789267398535232527 * 1e18, actualUtilization: 0, targetUtilization: 1.0 * 1e18, @@ -684,9 +654,9 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3061, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 20.0 * 1e18, + deposit: 19.999086757990867580 * 1e18, exchangeRate: 1.000000000000000000 * 1e18 }); @@ -695,8 +665,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, debt: 590.789267398535232526 * 1e18, collateral: 2.0 * 1e18, - bond: 8.968381880996266239 * 1e18, - transferAmount: 8.968381880996266239 * 1e18 + bond: 6.605224811402125309 * 1e18, + transferAmount: 6.605224811402125309 * 1e18 }); skip(32 hours); @@ -706,15 +676,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 8.968381880996266239 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 6.605224811402125309 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 32 hours, - referencePrice: 340.236543104248948639 * 1e18, - totalBondEscrowed: 8.968381880996266239 * 1e18, - auctionPrice: 0.000081118713165342 * 1e18, + referencePrice: 341.557588066529373749 * 1e18, + totalBondEscrowed: 6.605224811402125309 * 1e18, + auctionPrice: 0.000081433674828178 * 1e18, debtInAuction: 590.789267398535232527 * 1e18, - thresholdPrice: 295.453988355164748340 * 1e18, - neutralPrice: 340.236543104248948639 * 1e18 + debtToCollateral: 295.394633699267616263 * 1e18, + neutralPrice: 341.557588066529373749 * 1e18 }) ); @@ -722,11 +692,11 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 99836282890, - poolSize: 574.548281134908793200 * 1e18, + poolSize: 574.539148714817468952 * 1e18, pledgedCollateral: 2 * 1e18, - encumberedCollateral: 5_918_769_805.977193435161155568 * 1e18, + encumberedCollateral: 6_155_520_598.216281172565197855 * 1e18, poolDebt: 590.907976710329496681 * 1e18, - actualUtilization: 0.750721153846153847 * 1e18, + actualUtilization: 0.750755434916241346 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, loans: 0, @@ -740,82 +710,82 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _updateInterest(); _assertBucket({ index: 3060, - lpBalance: 20 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0000000000000000000 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3061, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3062, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3063, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3064, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3065, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3066, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3067, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3068, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ index: 3069, - lpBalance: 20.0 * 1e18, + lpBalance: 19.999086757990867580 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465578391592604940 * 1e18, - exchangeRate: 2.873278919579630247 * 1e18 + deposit: 57.464665200956929022 * 1e18, + exchangeRate: 2.873364463904645750 * 1e18 }); _assertBucket({ @@ -831,7 +801,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { assertEq(_collateral.ownerOf(3), address(_pool)); // exchange collateral for lpb 3060 - 3070, going down in price - for (uint256 i = _i236_59; i < (3060 + 3); i++) { + for (uint256 i = _i236_59; i < (_i236_59 + 3); i++) { _depositTake({ from: _lender, borrower: _borrower, @@ -841,18 +811,18 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3060, - lpBalance: 20.308286694556134654 * 1e18, - collateral: 0.246630842904997686 * 1e18, - deposit: 0.000000000000000144 * 1e18, - exchangeRate: 2.873278919579630248 * 1e18 + lpBalance: 20.225211496821887632 * 1e18, + collateral: 0.245629261778504471 * 1e18, + deposit: 0.000000000000000149 * 1e18, + exchangeRate: 2.873364463904645751 * 1e18 }); _assertBucket({ index: 3061, - lpBalance: 20.308286694556134655 * 1e18, - collateral: 0.247863997119522673 * 1e18, - deposit: 0.000000000000000006 * 1e18, - exchangeRate: 2.873278919579630248 * 1e18 + lpBalance: 20.225211496821887631 * 1e18, + collateral: 0.246857408087396991 * 1e18, + deposit: 0.000000000000000227 * 1e18, + exchangeRate: 2.873364463904645751 * 1e18 }); _assertBucket({ @@ -868,15 +838,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 8.968381880996266239 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 6.605224811402125309 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 32 hours, - referencePrice: 340.236543104248948639 * 1e18, - totalBondEscrowed: 8.968381880996266239 * 1e18, - auctionPrice: 0.000081118713165342 * 1e18, - debtInAuction: 418.511241535551682100 * 1e18, - thresholdPrice: 333.103014700636165105 * 1e18, - neutralPrice: 340.236543104248948639 * 1e18 + referencePrice: 341.557588066529373749 * 1e18, + totalBondEscrowed: 6.605224811402125309 * 1e18, + auctionPrice: 0.000081433674828178 * 1e18, + debtInAuction: 418.513981107458710209 * 1e18, + debtToCollateral: 295.394633699267616263 * 1e18, + neutralPrice: 341.557588066529373749 * 1e18 }) ); @@ -884,11 +854,11 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 99836282890, - poolSize: 402.259048741148234756 * 1e18, - pledgedCollateral: 1.256401842870359357 * 1e18, - encumberedCollateral: 4_191_975_396.326293274519167147 * 1e18, - poolDebt: 418.511241535551682100 * 1e18, - actualUtilization: 0.750721153846153847 * 1e18, + poolSize: 402.252656406698503718 * 1e18, + pledgedCollateral: 1.259421635006264564 * 1e18, + encumberedCollateral: 4_359_682_950.449208762774280808 * 1e18, + poolDebt: 418.513981107458710209 * 1e18, + actualUtilization: 0.750755434916241346 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, loans: 0, @@ -904,10 +874,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 418.511241535551682100 * 1e18, - borrowerCollateral: 1.256401842870359357 * 1e18, - borrowert0Np: 97.486777718699640528 * 1e18, - borrowerCollateralization: 0.000000000299715939 * 1e18, + borrowerDebt: 418.513981107458710209 * 1e18, + borrowerCollateral: 1.259421635006264564 * 1e18, + borrowert0Np: 97.631273580933683519 * 1e18, + borrowerCollateralization: 0, tokenIds: borrowerTokenIds }); @@ -919,8 +889,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2 * 1e18, - bondChange: 0.000001231409637086 * 1e18, - givenAmount: 0.000081118713165342 * 1e18, + bondChange: 0.000000910456162867 * 1e18, + givenAmount: 0.000081433674828178 * 1e18, collateralTaken: 1 * 1e18, isReward: true }); @@ -930,10 +900,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 418.511161648248153847 * 1e18, - borrowerCollateral: 0.256401842870359357 * 1e18, - borrowert0Np: 477.697595423190347016 * 1e18, - borrowerCollateralization: 0.000000000061164932 * 1e18, + borrowerDebt: 418.513900584240044901 * 1e18, + borrowerCollateral: 0.259421635006264564 * 1e18, + borrowert0Np: 473.973246450485386102 * 1e18, + borrowerCollateralization: 0, tokenIds: borrowerTokenIds }); @@ -956,15 +926,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 8.968383112405903325 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 6.605225721858288176 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - (32 hours + 4210 minutes), - referencePrice: 340.236543104248948639 * 1e18, - totalBondEscrowed: 8.968383112405903325 * 1e18, + referencePrice: 341.557588066529373749 * 1e18, + totalBondEscrowed: 6.605225721858288176 * 1e18, auctionPrice: 0, - debtInAuction: 418.511161648248153847 * 1e18, - thresholdPrice: 1_633.038265299714540882 * 1e18, - neutralPrice: 340.236543104248948639 * 1e18 + debtInAuction: 418.513900584240044901 * 1e18, + debtToCollateral: 295.394633699267616263 * 1e18, + neutralPrice: 341.557588066529373749 * 1e18 }) ); @@ -972,7 +942,14 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 11, - settledDebt: 106.339800629932799697 * 1e18 + settledDebt: 402.720595086055444608 * 1e18 + }); + + _settle({ + from: _lender, + borrower: _borrower, + maxDepth: 11, + settledDebt: 15.996165878204144616 * 1e18 }); _assertBorrower({ @@ -997,20 +974,20 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 8.968383112405903325 * 1e18, + totalBondEscrowed: 6.605225721858288176 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBucket({ index: 3060, - lpBalance: 20.308286694556134654 * 1e18, - collateral: 0.246630842904997687 * 1e18, + lpBalance: 20.225211496821887632 * 1e18, + collateral: 0.245629261778504472 * 1e18, deposit: 0, - exchangeRate: 2.873278919579630252 * 1e18 + exchangeRate: 2.873364463904645755 * 1e18 }); _assertLenderLpBalance({ lender: _borrower, @@ -1088,18 +1065,16 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { assertEq(_collateral.balanceOf(address(_pool)), 0); // lender deposit quote tokens in bucket 7388 in order to claim and merge settled collateral and to be able to remove entire NFT - _addLiquidity({ + _addInitialLiquidity({ from: _lender, amount: 10 * 1e18, - index: 7388, - lpAward: 10 * 1e18, // LP awarded to lender for depositing quote tokens in bucket 7388 - newLup: MAX_PRICE + index: 7388 }); _assertLenderLpBalance({ lender: _lender, index: 7388, - lpBalance: 10 * 1e18, // lender now owns LP in bucket 7388 which can be used to merge bucket collateral + lpBalance: 9.999392237442922370 * 1e18, // lender now owns LP in bucket 7388 which can be used to merge bucket collateral depositTime: _startTime + 10000 days + (32 hours + 4210 minutes) }); @@ -1131,15 +1106,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { }); _assertBucket({ index: 7388, - lpBalance: 10 * 1e18, // LP in bucket 7388 diminished when NFT merged and removed + lpBalance: 9.999392237442922370 * 1e18, // LP in bucket 7388 diminished when NFT merged and removed collateral: 0, // no collateral remaining as it was merged and removed - deposit: 10 * 1e18, + deposit: 9.999392237442922370 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: 7388, - lpBalance: 10 * 1e18, // lender LP decreased with the amount used to merge NFT + lpBalance: 9.999392237442922370 * 1e18, // lender LP decreased with the amount used to merge NFT depositTime: _startTime + 10000 days + (32 hours + 4210 minutes) }); _assertLenderLpBalance({ @@ -1151,10 +1126,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _removeAllLiquidity({ from: _lender, - amount: 10 * 1e18, + amount: 9.999392237442922370 * 1e18, index: 7388, newLup: MAX_PRICE, - lpRedeem: 10 * 1e18 + lpRedeem: 9.999392237442922370 * 1e18 }); _assertBucket({ @@ -1169,16 +1144,16 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50.000079544611684526 * 1e18, + poolSize: 0, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.750721153846153847 * 1e18, + actualUtilization: 0.750755434916241347 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, loans: 0, maxBorrower: address(0), - interestRate: 0.05445 * 1e18, + interestRate: 0.066550000000000000 * 1e18, interestRateUpdate: block.timestamp }) ); @@ -1197,7 +1172,6 @@ contract ERC721SubsetPoolCollateralTest is ERC721PoolCollateralTest { _borrower = makeAddr("borrower"); _borrower2 = makeAddr("borrower2"); _lender = makeAddr("lender"); - _lender2 = makeAddr("lender2"); // deploy subset pool uint256[] memory subsetTokenIds = new uint256[](5); @@ -1232,7 +1206,7 @@ contract ERC721SubsetPoolCollateralTest is ERC721PoolCollateralTest { tokenIdsToAdd[1] = 4; tokenIdsToAdd[2] = 6; - // should revert if borrower attempts to add tokens not in the pool subset + // should revert if borrower attempts to add NFTs not in the pool subset _assertPledgeCollateralNotInSubsetRevert({ from: _borrower, tokenIds: tokenIdsToAdd diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolEMAs.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolEMAs.t.sol index 80337f4d5..e351528c6 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolEMAs.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolEMAs.t.sol @@ -36,7 +36,7 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 10_000 * 1e18 + depositEma: 9_999.543378995433790000 * 1e18 }); // add unmeaningful liquidity in same block; EMA should not update @@ -50,7 +50,7 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { debtColEma: 0, lupt0DebtEma: 0, debtEma: 0, - depositEma: 10_000 * 1e18 + depositEma: 9_999.543378995433790000 * 1e18 }); skip(8 hours); @@ -73,15 +73,15 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 1_159.007377482809680884 * 1e18, // 7000 / 6 = 1166.66 + htp: 1_205.367672582122068119 * 1e18, // 7000 / 6 = 1166.66 lup: _p1505_26, - poolSize: 15_000 * 1e18, + poolSize: 14_999.315068493150685000 * 1e18, pledgedCollateral: 6 * 1e18, - encumberedCollateral: 4.620028820788372636 * 1e18, // 6 / 1.3 = 4.62 - poolDebt: 6_954.361808414458420695 * 1e18, + encumberedCollateral: 4.804610580000000002 * 1e18, // 6 / 1.3 = 4.62 + poolDebt: 6_954.044264896858085302 * 1e18, actualUtilization: 0.000000000000000000 * 1e18, // moving -> 6_947 / 10_000 (meaningful) = 0.7 targetUtilization: 1.000000000000000000 * 1e18, - minDebtAmount: 695.436180841445842070 * 1e18, // debt / 10; only one loan, so not enforced + minDebtAmount: 695.404426489685808530 * 1e18, // debt / 10; only one loan, so not enforced loans: 1, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -89,11 +89,11 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { }) ); _assertEMAs({ - debtColEma: 0.000000000000000000 * 1e18, // 6_954^2 / 6 ~= 8_059_686 + debtColEma: 0.000000000000000000 * 1e18, // 6_954^2 / 6 ~= 8_059_686 lupt0DebtEma: 0.000000000000000000 * 1e18, // 1_505.26 * 6_954.04 ~= 10_467_638.25 - debtEma: 0.000000000000000000 * 1e18, // current debt with origination fee + debtEma: 0.000000000000000000 * 1e18, // current debt with origination fee // previous accumulator had updated to 15_000 before debt was drawn, but now 5_000 is no longer meaningful... - depositEma: 11_850.197375262816985000 * 1e18 // ...so it is moving down toward 10_000 + depositEma: 11_849.656270359836947749 * 1e18 // ...so it is moving down toward 10_000 }); } @@ -104,15 +104,15 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { // debtColEma / lupt0DebtEma ~= 8_059_788.6 / 10_467_670.6 ~= 0.77 expected target utilization _assertPool( PoolParams({ - htp: 1_159.007377482809680884 * 1e18, + htp: 1_205.388312616241411607 * 1e18, lup: _p1505_26, - poolSize: 15_000 * 1e18, + poolSize: 14_999.315068493150685000 * 1e18, pledgedCollateral: 6 * 1e18, - encumberedCollateral: 4.620107931548236591 * 1e18, // small increase due to pending interest - poolDebt: 6_954.480890971813258160 * 1e18, // small increase due to pending interest + encumberedCollateral: 4.804692851433486288 * 1e18, // small increase due to pending interest + poolDebt: 6_954.163342016777374652 * 1e18, // small increase due to pending interest actualUtilization: 0.000000000000000000 * 1e18, targetUtilization: 1.000000000000000000 * 1e18, // debtColEma / lupt0DebtEma - minDebtAmount: 695.448089097181325816 * 1e18, // small increase due to pending interest + minDebtAmount: 695.416334201677737465 * 1e18, // small increase due to pending interest loans: 1, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -123,22 +123,22 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { debtColEma: 0.000000000000000000 * 1e18, // unchanged from setup lupt0DebtEma: 0.000000000000000000 * 1e18, // unchanged from setup debtEma: 0.000000000000000000 * 1e18, // unchanged from setup - depositEma: 11_850.197375262816985000 * 1e18 // unchanged from setup + depositEma: 11_849.656270359836947749 * 1e18 // unchanged from setup }); // touch the pool, triggering an interest accrual - EMAs should update _pool.updateInterest(); _assertPool( PoolParams({ - htp: 1_159.080148495302209694 * 1e18, + htp: 1_205.388312616241411607 * 1e18, lup: _p1505_26, - poolSize: 15_000.371132163711890000 * 1e18, // first interest accrual + poolSize: 14_999.416284045082078099 * 1e18, // first interest accrual pledgedCollateral: 6 * 1e18, - encumberedCollateral: 4.620107931548236591 * 1e18, - poolDebt: 6_954.480890971813258160 * 1e18, // pending interest now equals current interest - actualUtilization: 0.095745083902338016 * 1e18, + encumberedCollateral: 4.804692851433486288 * 1e18, + poolDebt: 6_954.163342016777374652 * 1e18, // pending interest now equals current interest + actualUtilization: 0.095749456023617633 * 1e18, targetUtilization: 0.769969644230769231 * 1e18, - minDebtAmount: 695.448089097181325816 * 1e18, + minDebtAmount: 695.416334201677737465 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -149,7 +149,7 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { debtColEma: 197_072.776194638866068935 * 1e18, // accumulator updated, EMA initialized lupt0DebtEma: 255_948.760670328150445660 * 1e18, // accumulator updated, EMA initialized debtEma: 1_106.413371029437537443 * 1e18, // accumulator updated, EMA initialized - depositEma: 11_555.824340370334487364 * 1e18 // still moving toward 10_000 + depositEma: 11_555.296677158445431048 * 1e18 // still moving toward 10_000 }); (uint256 interestRate, ) = _pool.interestRateInfo(); assertEq(interestRate, 0.05 * 1e18); @@ -157,10 +157,10 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { skip(9 hours); // 12 hours since debt was drawn _pool.updateInterest(); _assertEMAs({ - debtColEma: 759_883.557390504783896613 * 1e18, // updated for interest accrual + debtColEma: 759_857.214782711948426497 * 1e18, // updated for interest accrual lupt0DebtEma: 986_853.627682966275217023 * 1e18, // updated for interest accrual - debtEma: 3_477.199139105917836267 * 1e18, // updated for interest accrual - depositEma: 10_925.249143290274162648 * 1e18 // still moving toward 10_000 + debtEma: 3_477.070405889227128676 * 1e18, // updated for interest accrual + depositEma: 10_924.640857102313939222 * 1e18 // still moving toward 10_000 }); (interestRate, ) = _pool.interestRateInfo(); assertEq(interestRate, 0.045 * 1e18); @@ -176,44 +176,44 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { _skipAndAccrue({ time: 4 hours, - mau: 0.397622119994472546 * 1e18, // dropping from 60% to 35% - tu: 0.770035415811601449 * 1e18, // still at 77% + mau: 0.397628845831341404 * 1e18, // dropping from 60% to 35% + tu: 0.770004681960247602 * 1e18, // still at 77% rate: 0.045 * 1e18 }); (, , , uint256 depositEma) = _pool.emasInfo(); - assertEq(depositEma, 12_582.608507963702724933 * 1e18); // now moving toward 20_000 + assertEq(depositEma, 12_581.863548293381640088 * 1e18); // now moving toward 20_000 _skipAndAccrue({ time: 20 hours, // 24 hours since liquidity was added - mau: 0.358933852890687729 * 1e18, // still dropping toward 35% - tu: 0.770067458236015074 * 1e18, // still at 77% + mau: 0.358938366072679811 * 1e18, // still dropping toward 35% + tu: 0.770034423541948909 * 1e18, // still at 77% rate: 0.0405 * 1e18 // dropping at 4.05% }); (, , , depositEma) = _pool.emasInfo(); - assertEq(depositEma, 17_664.344669688571758688 * 1e18); // still moving toward 20_000 + assertEq(depositEma, 17_663.330795414242803827 * 1e18); // still moving toward 20_000 _skipAndAccrue({ time: 2 days, // 3 days since liquidity was added - mau: 0.348388356770742011 * 1e18, // reached 35% - tu: 0.770135325994564531 * 1e18, // still at 77% + mau: 0.348392289978865214 * 1e18, // reached 35% + tu: 0.770100960789580357 * 1e18, // still at 77% rate: 0.03645 * 1e18 // second interest rate drop }); (, , , depositEma) = _pool.emasInfo(); - assertEq(depositEma, 19_855.532581473734007628 * 1e18); // reached (sort of) 20_000 + assertEq(depositEma, 19_854.402758785373904546 * 1e18); // reached (sort of) 20_000 _assertPool( PoolParams({ - htp: 1_159.575642053959188547 * 1e18, + htp: 1_205.903602387494165119 * 1e18, lup: _p1505_26, - poolSize: 25_002.955913967460376246 * 1e18, // reflects additional 10_000 deposit + poolSize: 25_001.589989976322339749 * 1e18, // reflects additional 10_000 deposit pledgedCollateral: 6 * 1e18, - encumberedCollateral: 4.622082975054377226 * 1e18, - poolDebt: 6_957.453852323755131281 * 1e18, - actualUtilization: 0.348388356770742011 * 1e18, // dropped to 35% as expected - targetUtilization: 0.770135325994564531 * 1e18, - minDebtAmount: 695.745385232375513128* 1e18, + encumberedCollateral: 4.806746802889993501 * 1e18, + poolDebt: 6_957.136167620158644917 * 1e18, + actualUtilization: 0.348392289978865214 * 1e18, // dropped to 35% as expected + targetUtilization: 0.770100960789580357 * 1e18, + minDebtAmount: 695.713616762015864492 * 1e18, loans: 1, maxBorrower: address(_borrower), - interestRate: 0.03645 * 1e18, // dropped twice + interestRate: 0.03645 * 1e18, // dropped twice interestRateUpdate: _startTime + 98 hours }) ); @@ -227,7 +227,7 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { _drawDebt({ from: _borrower, borrower: _borrower, - amountToBorrow: 11_000 * 1e18, // total ~18_000 principal / 20_0000 meaningful liquidity + amountToBorrow: 10_000 * 1e18, // total ~17_000 principal / 20_0000 meaningful liquidity limitIndex: _i1505_26, tokenIds: tokenIdsToAdd, newLup: _p1505_26 @@ -235,45 +235,45 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { _skipAndAccrue({ time: 3 hours, - mau: 0.436398947261022405 * 1e18, // rising from 35% to 90% - tu: 0.794802131238362891 * 1e18, // increases as collateralization decreases + mau: 0.428398216388973547 * 1e18, // rising from 35% to 90% + tu: 0.787754460637874784 * 1e18, // increases as collateralization decreases rate: 0.03645 * 1e18 }); (, , uint256 debtEma, ) = _pool.emasInfo(); - assertEq(debtEma, 8_675.169506576032073392 * 1e18); // increasing from 7_000 to 18_000 + assertEq(debtEma, 8_515.638527238944097371 * 1e18); // increasing from 7_000 to 17_000 _skipAndAccrue({ time: 9 hours, - mau: 0.624275651572709578 * 1e18, // still rising to 90% - tu: 0.846215553223533151 * 1e18, + mau: 0.599187484109433390 * 1e18, // still rising to 90% + tu: 0.825258290067261584 * 1e18, rate: 0.03645 * 1e18 }); (, , debtEma, ) = _pool.emasInfo(); - assertEq(debtEma, 12_441.391312587344397940 * 1e18); // increasing from 7_000 to 18_000 + assertEq(debtEma, 11_940.719160980199574337 * 1e18); // increasing from 7_000 to 17_000 _skipAndAccrue({ time: 4 days, - mau: 0.897069303670436098 * 1e18, // reached 90% - tu: 0.966852816219664605 * 1e18, - rate: 0.032805 * 1e18 + mau: 0.847172260351887090 * 1e18, // reached 90% + tu: 0.917210771098065732 * 1e18, + rate: 0.036450 * 1e18 }); (, , debtEma, ) = _pool.emasInfo(); - assertEq(debtEma, 17_944.480736533919717209 * 1e18); // reached 18_000 + assertEq(debtEma, 16_945.366780417774837920 * 1e18); // reached 17_000 _assertPool( PoolParams({ - htp: 1_497.769957757345433425 * 1e18, + htp: 1_470.886811717333959369 * 1e18, lup: _p1505_26, - poolSize: 25_010.141517477798670592 * 1e18, + poolSize: 25_008.358862466871008035 * 1e18, pledgedCollateral: 12 * 1e18, // 6 additional NFTs deposited - encumberedCollateral: 11.940259472915000621 * 1e18, // all 12 NFTs are encumbered - poolDebt: 17_973.239493088145201105 * 1e18, // includes new debt - actualUtilization: 0.897069303670436098 * 1e18, - targetUtilization: 0.966852816219664605 * 1e18, - minDebtAmount: 1_797.323949308814520111 * 1e18, + encumberedCollateral: 11.725946361943917541 * 1e18, // all 12 NFTs are encumbered + poolDebt: 16_971.770904430776454251 * 1e18, // includes new debt + actualUtilization: 0.847172260351887090 * 1e18, + targetUtilization: 0.917210771098065732 * 1e18, + minDebtAmount: 1_697.177090443077645425 * 1e18, loans: 1, maxBorrower: address(_borrower), - interestRate: 0.032805 * 1e18, - interestRateUpdate: _startTime + 110 hours + 4 days + interestRate: 0.036450 * 1e18, + interestRateUpdate: _startTime + 2 hours + 4 days }) ); } @@ -290,15 +290,15 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { }); _skipAndAccrue({ time: 40 hours, // 2 days after liquidity was added - mau: 0.677110233556701963 * 1e18, // 7_647 / 10_000 ~= 76% - tu: 0.847585126397651853 * 1e18, // starting at 77% + mau: 0.677129230433596332 * 1e18, // 7_647 / 10_000 ~= 76% + tu: 0.847549967163692311 * 1e18, // starting at 77% rate: 0.05 * 1e18 }); _assertEMAs({ - debtColEma: 2_745_524.266553065584517923 * 1e18, // reflects newly drawn debt - lupt0DebtEma: 3_239_231.294940137090747973 * 1e18, // unchanged from setup - debtEma: 6_895.559233472655919795 * 1e18, // increasing toward 7_647 - depositEma: 10_183.805962068972523753 * 1e18 // decreasing toward 10_000 + debtColEma: 2_745_421.852361791542203581 * 1e18, // reflects newly drawn debt + lupt0DebtEma: 3_239_244.833610561710979058 * 1e18, // unchanged from setup + debtEma: 6_895.273194262173362837 * 1e18, // increasing toward 7_647 + depositEma: 10_183.097825871170114674 * 1e18 // decreasing toward 10_000 }); // bad actor comes along and deposits large amount for 5 minutes, and then withdraws @@ -311,49 +311,49 @@ contract ERC721PoolEMAsTest is ERC721HelperContract { _pool.updateInterest(); // not really needed, since removing liquidity will trigger rate update _removeAllLiquidity({ from: _attacker, - amount: 150_000.003062917635863984 * 1e18, + amount: 149_993.153747734144698972 * 1e18, index: _i1505_26, newLup: _p1505_26, - lpRedeem: 149_973.669906855426845472 * 1e18 + lpRedeem: 149_970.868883961819887409 * 1e18 }); uint256 rateChangeTs = block.timestamp; _skipAndAccrue({ time: 12, // skip a single block - mau: 0.632791692026653958 * 1e18, // impacted, enough to cause rate change - tu: 0.847585617691556722 * 1e18, + mau: 0.632808456612359556 * 1e18, // impacted, enough to cause rate change + tu: 0.847550458437217496 * 1e18, rate: 0.045 * 1e18 // rate changed }); _assertEMAs({ - debtColEma: 2_750_544.877504425497154098 * 1e18, - lupt0DebtEma: 3_245_152.843668674754668559 * 1e18, - debtEma: 6_899.360444842923621304 * 1e18, - depositEma: 10_903.051559899926973925 * 1e18 // still noticably impacted + debtColEma: 2_750_442.276033142114157597 * 1e18, + lupt0DebtEma: 3_245_166.407088766607440379 * 1e18, + debtEma: 6_899.074247951901688984 * 1e18, + depositEma: 10_902.310447753826633283 * 1e18 // still noticably impacted }); _skipAndAccrue({ time: 12 hours, - mau: 0.696306196911713144 * 1e18, // moving back toward 75% - tu: 0.847637823306888876 * 1e18, + mau: 0.696326201382970553 * 1e18, // moving back toward 75% + tu: 0.847602661886974316 * 1e18, rate: 0.045 * 1e18 }); _assertEMAs({ - debtColEma: 3_412_160.847313164565839074 * 1e18, - lupt0DebtEma: 4_025_493.853024754985190842 * 1e18, - debtEma: 7_278.073513801178223507 * 1e18, - depositEma: 10_452.403764437541109496 * 1e18 // moving down back to 10_000 + debtColEma: 3_412_033.566087523366578909 * 1e18, + lupt0DebtEma: 4_025_510.677953143880612044 * 1e18, + debtEma: 7_277.771607265212861084 * 1e18, + depositEma: 10_451.669911042929514005 * 1e18 // moving down back to 10_000 }); _assertPool( PoolParams({ - htp: 1_276.209765166823398404 * 1e18, + htp: 1_327.203098908327068572 * 1e18, lup: _p1505_26, - poolSize: 15_002.177276783057210001 * 1e18, + poolSize: 15_001.222354932647619025 * 1e18, pledgedCollateral: 6 * 1e18, - encumberedCollateral: 5.086988044805126619 * 1e18, - poolDebt: 7_657.258591000940390423 * 1e18, // 7_647 principal plus some interest - actualUtilization: 0.696306196911713144 * 1e18, - targetUtilization: 0.847637823306888876 * 1e18, - minDebtAmount: 765.725859100094039042 * 1e18, + encumberedCollateral: 5.290248109245926845 * 1e18, + poolDebt: 7_656.940955240348472526 * 1e18, // 7_647 principal plus some interest + actualUtilization: 0.696326201382970553 * 1e18, + targetUtilization: 0.847602661886974316 * 1e18, + minDebtAmount: 765.694095524034847253 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolFactory.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolFactory.t.sol index 6e50c224c..8cb249e14 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolFactory.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolFactory.t.sol @@ -33,6 +33,8 @@ contract ERC721PoolFactoryTest is ERC721HelperContract { _factory = new ERC721PoolFactory(_ajna); // deploy NFT collection pool + vm.expectEmit(true, true, false, true); + emit PoolCreated(0x8a2be84c82956B6DdA0c4D647Ae9357d845a086B, _factory.getNFTSubsetHash(tokenIds)); _NFTCollectionPoolAddress = _factory.deployPool(address(_collateral), address(_quote), tokenIds, 0.05 * 10**18); _NFTCollectionPool = ERC721Pool(_NFTCollectionPoolAddress); @@ -43,6 +45,8 @@ contract ERC721PoolFactoryTest is ERC721HelperContract { _tokenIdsSubsetOne[2] = 50; _tokenIdsSubsetOne[3] = 61; + vm.expectEmit(true, true, false, true); + emit PoolCreated(0x18D11C8Cf8dc292E647F0b324d10637a3A63F678, _factory.getNFTSubsetHash(_tokenIdsSubsetOne)); _NFTSubsetOnePoolAddress = _factory.deployPool(address(_collateral), address(_quote), _tokenIdsSubsetOne, 0.05 * 10**18); _NFTSubsetOnePool = ERC721Pool(_NFTSubsetOnePoolAddress); @@ -56,6 +60,8 @@ contract ERC721PoolFactoryTest is ERC721HelperContract { _tokenIdsSubsetTwo[5] = 61; _tokenIdsSubsetTwo[6] = 180; + vm.expectEmit(true, true, false, true); + emit PoolCreated(0xf80F47F84F20d8aF58cC8e93634348491357323c, _factory.getNFTSubsetHash(_tokenIdsSubsetTwo)); _NFTSubsetTwoPoolAddress = _factory.deployPool(address(_collateral), address(_quote), _tokenIdsSubsetTwo, 0.05 * 10**18); _NFTSubsetTwoPool = ERC721Pool(_NFTSubsetTwoPoolAddress); @@ -304,6 +310,8 @@ contract ERC721PoolFactoryTest is ERC721HelperContract { tokenIdsTestSubset[1] = 2; tokenIdsTestSubset[2] = 3; + vm.expectEmit(true, true, false, true); + emit PoolCreated(0xA8FBA534d7ebefEBB270cDC4814A1A25916A94d3, _factory.getNFTSubsetHash(tokenIdsTestSubset)); address poolAddress = _factory.deployPool(address(_collateral), address(_quote), tokenIdsTestSubset, 0.05 * 10**18); // check tracking of deployed pools diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol index c19b18895..83646baa5 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol @@ -18,28 +18,28 @@ contract ERC721PoolBorrowTest is ERC721HelperContract { function testValidateAddQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.addQuoteToken(0, 1000, block.timestamp + 1, false); + _pool.addQuoteToken(0, 1000, block.timestamp + 1); // revert on zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, 0, block.timestamp + 1, false); + _pool.addQuoteToken(1000, 0, block.timestamp + 1); // revert on index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); + _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1); } function testValidateMoveQuoteTokenInput() external tearDown { - // revert on zero amount - vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1, false); + // revert on dust amount if amount is below quote token scale + vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); + _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1); // revert on move to same index vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1); // revert on to zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1); // revert on to index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); + _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1); } function testValidateRemoveQuoteTokenInput() external tearDown { @@ -57,7 +57,7 @@ contract ERC721PoolBorrowTest is ERC721HelperContract { function testValidateTakeReservesInput() external tearDown { // revert on zero amount - vm.expectRevert(IPoolErrors.InvalidAmount.selector); + vm.expectRevert(IPoolErrors.NoReservesAuction.selector); _pool.takeReserves(0); } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol index c46c23e4c..aab4809ce 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol @@ -103,8 +103,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_911.763008462438456052 * 1e18, - borrowerCollateralization: 1.804973217265326249 * 1e18 + borrowert0Np: 1_918.840195467602660987 * 1e18, + borrowerCollateralization: 1.735551170447429086 * 1e18 }); _assertLenderInterest(liquidityAdded, 0); @@ -127,11 +127,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 4 * 1e18, - borrowert0Np: 1_433.822256346828842039 * 1e18, - borrowerCollateralization: 2.403665705362551645 * 1e18 + borrowert0Np: 1_439.130146600701995740 * 1e18, + borrowerCollateralization: 2.311217024387068890 * 1e18 }); - _assertLenderInterest(liquidityAdded, 5.247494497896400000 * 1e18); + _assertLenderInterest(liquidityAdded, 5.247494497896371966 * 1e18); // borrower pulls some of their collateral after some time has passed skip(10 days); @@ -152,11 +152,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_902.683561057818747541 * 1e18, - borrowerCollateralization: 1.800750077529217167 * 1e18 + borrowert0Np: 1_909.397570166798164136 * 1e18, + borrowerCollateralization: 1.731490459162708814 * 1e18 }); - _assertLenderInterest(liquidityAdded, 10.004595693661100000 * 1e18); + _assertLenderInterest(liquidityAdded, 10.004597057423574190 * 1e18); // borrower borrows some additional quote after some time has passed skip(10 days); @@ -176,11 +176,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_271.558482861789242177 * 1e18, - borrowerCollateralization: 1.500002057800446964 * 1e18 + borrowert0Np: 2_279.197387150401832726 * 1e18, + borrowerCollateralization: 1.442309670961968235 * 1e18 }); - _assertLenderInterest(liquidityAdded, 14.290532556069200000 * 1e18); + _assertLenderInterest(liquidityAdded, 14.290535149874139349 * 1e18); // mint additional quote to borrower to enable repayment deal(address(_quote), _borrower, 20_000 * 1e18); @@ -259,8 +259,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 3_074.429072381702701017 * 1e18, - borrowerCollateralization: 1.127999893042434013 * 1e18 + borrowert0Np: 3_086.366235276970809007 * 1e18, + borrowerCollateralization: 1.084615281771571166 * 1e18 }); skip(4 hours); @@ -292,18 +292,18 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 3_074.429072381702701017 * 1e18, - borrowerCollateralization: 1.122362328272840838 * 1e18 + borrowert0Np: 3_086.366235276970809007 * 1e18, + borrowerCollateralization: 1.079194546416193113 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 3_170.432595761480458330 * 1e18, - borrowerCollateralization: 1.088376197116173336 * 1e18 + borrowert0Np: 3_182.742513945656986337 * 1e18, + borrowerCollateralization: 1.046515574150166669 * 1e18 }); - _assertLenderInterest(liquidityAdded, 0.155402195487210000 * 1e18); + _assertLenderInterest(liquidityAdded, 0.155402195487205849 * 1e18); skip(4 hours); @@ -336,25 +336,25 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 3_074.429072381702701017 * 1e18, - borrowerCollateralization: 1.122336703854666979 * 1e18 + borrowert0Np: 3_086.366235276970809007 * 1e18, + borrowerCollateralization: 1.079169907552564403 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 3_170.432595761480458330 * 1e18, - borrowerCollateralization: 1.088351348628209297 * 1e18 + borrowert0Np: 3_182.742513945656986337 * 1e18, + borrowerCollateralization: 1.046491681373278170 * 1e18 }); _assertBorrower({ borrower: _borrower3, borrowerDebt: expectedBorrower3Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_882.145647529036115605 * 1e18, - borrowerCollateralization: 1.197213816827790670 * 1e18 + borrowert0Np: 2_893.336226746331069131 * 1e18, + borrowerCollateralization: 1.151167131565183336 * 1e18 }); - _assertLenderInterest(liquidityAdded, 0.365554305676230000 * 1e18); + _assertLenderInterest(liquidityAdded, 0.365554368557644878 * 1e18); skip(4 hours); @@ -363,7 +363,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { from: _lender, amount: 1 * 1e18, index: 2550, - lpAward: 0.999979133938993539 * 1e18, + lpAward: 0.999933471831480917 * 1e18, newLup: 2995.912459898389633881 * 1e18 }); liquidityAdded += 1e18; @@ -374,7 +374,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { (poolDebt,,,) = _pool.debtInfo(); assertEq(poolDebt, expectedPoolDebt); - _assertLenderInterest(liquidityAdded, 0.625994892241440000 * 1e18); + _assertLenderInterest(liquidityAdded, 0.625949442426308567 * 1e18); expectedBorrower1Debt = 8_008.240798551896146547 * 1e18; @@ -382,8 +382,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 3_074.429072381702701017 * 1e18, - borrowerCollateralization: 1.122311080021518821 * 1e18 + borrowert0Np: 3_086.366235276970809007 * 1e18, + borrowerCollateralization: 1.079145269251460405 * 1e18 }); expectedBorrower2Debt = 2_752.769925156330518053 * 1e18; @@ -392,8 +392,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 3_170.432595761480458330 * 1e18, - borrowerCollateralization: 1.088326500707555859 * 1e18 + borrowert0Np: 3_182.742513945656986337 * 1e18, + borrowerCollateralization: 1.046467789141880633 * 1e18 }); expectedBorrower3Debt = 2_502.460979313951751742 * 1e18; @@ -402,8 +402,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower3, borrowerDebt: expectedBorrower3Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_882.145647529036115605 * 1e18, - borrowerCollateralization: 1.197186483491030227 * 1e18 + borrowert0Np: 2_893.336226746331069131 * 1e18, + borrowerCollateralization: 1.151140849510605988 * 1e18 }); // ensure debt from the three borrowers adds up to the pool debt @@ -466,8 +466,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_911.763008462438456052 * 1e18, - borrowerCollateralization: 1.804973217265326249 * 1e18 + borrowert0Np: 1_918.840195467602660987 * 1e18, + borrowerCollateralization: 1.735551170447429086 * 1e18 }); // time passes and interest accrues @@ -481,8 +481,8 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_911.763008462438456052 * 1e18, - borrowerCollateralization: 1.798309619615464420 * 1e18 + borrowert0Np: 1_918.840195467602660987 * 1e18, + borrowerCollateralization: 1.729143865014869634 * 1e18 }); // mint additional quote to borrower to enable repayment @@ -511,7 +511,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrowerCollateralization: 1 * 1e18 }); - _assertLenderInterest(liquidityAdded, 21.028850966013750000 * 1e18); + _assertLenderInterest(liquidityAdded, 21.028850966013719555 * 1e18); // borrower borrows again once repayed all debt _borrow({ @@ -529,12 +529,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_893.159858820699522954 * 1e18, - borrowerCollateralization: 1.805129295309881815 * 1e18 + borrowert0Np: 1_899.840261593407406983 * 1e18, + borrowerCollateralization: 1.735701245490270976 * 1e18 }); - _assertLenderInterest(liquidityAdded, 21.028850966013750000 * 1e18); - + _assertLenderInterest(liquidityAdded, 21.028850966013719555 * 1e18); // borrower pledge additional collateral after some time has passed skip(10 days); @@ -554,11 +553,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 4 * 1e18, - borrowert0Np: 1_419.869894115524642215 * 1e18, - borrowerCollateralization: 2.404169939255701731 * 1e18 + borrowert0Np: 1_424.880196195055555237 * 1e18, + borrowerCollateralization: 2.311701864668943973 * 1e18 }); - _assertLenderInterest(liquidityAdded, 25.779680075333500000 * 1e18); + _assertLenderInterest(liquidityAdded, 25.779681437299323212 * 1e18); // borrower pulls some of their collateral after some time has passed skip(10 days); @@ -579,11 +578,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_884.589452870960229897 * 1e18, - borrowerCollateralization: 1.801327695821111558 * 1e18 + borrowert0Np: 1_890.927039405678542204 * 1e18, + borrowerCollateralization: 1.732045861366453421 * 1e18 }); - _assertLenderInterest(liquidityAdded, 30.059922094508300000 * 1e18); + _assertLenderInterest(liquidityAdded, 30.059924682352556770 * 1e18); // borrower borrows some additional quote after some time has passed skip(10 days); @@ -603,11 +602,11 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_250.568493913377606760 * 1e18, - borrowerCollateralization: 1.500545633513497515 * 1e18 + borrowert0Np: 2_257.779541250011702731 * 1e18, + borrowerCollateralization: 1.442832339916824534 * 1e18 }); - _assertLenderInterest(liquidityAdded, 33.915820770203100000 * 1e18); + _assertLenderInterest(liquidityAdded, 33.915824463483626210 * 1e18); // mint additional quote to borrower to enable repayment deal(address(_quote), _borrower, 20_000 * 1e18); @@ -635,6 +634,6 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrowerCollateralization: 1 * 1e18 }); - _assertLenderInterest(liquidityAdded, 38.081584308182850000 * 1e18); + _assertLenderInterest(liquidityAdded, 38.081589196796064735 * 1e18); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol index 94c574fa8..ad511031e 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol @@ -81,7 +81,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { }); _borrow({ from: _borrower, - amount: 19.8 * 1e18, + amount: 19.0 * 1e18, indexLimit: _i9_91, newLup: expectedNewLup }); @@ -109,15 +109,15 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 9.909519230769230774 * 1e18, + htp: 9.889500000000000005 * 1e18, lup: expectedNewLup, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 3.512434434608473285 * 1e18, - poolDebt: 34.833461538461538478 * 1e18, + encumberedCollateral: 3.568956368038954464 * 1e18, + poolDebt: 34.032692307692307708 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, - minDebtAmount: 1.741673076923076924 * 1e18, + minDebtAmount: 1.701634615384615385 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -126,17 +126,17 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.819038461538461548 * 1e18, + borrowerDebt: 19.018269230769230778 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 1.000773560501591181 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 1.002799417911513430 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.981531649793150539 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.905318894031875518 * 1e18 }); assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); @@ -147,10 +147,10 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); /******************************/ @@ -159,15 +159,15 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 5.739575714606494647 * 1e18, + htp: 5.969158743190754433 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.346887619919714000 * 1e18, + poolSize: 73_000.913625835553743442 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.028103499563389533 * 1e18, - poolDebt: 39.947446973661202747 * 1e18, - actualUtilization: 0.000477170706006322 * 1e18, - targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 3.994744697366120275 * 1e18, + encumberedCollateral: 4.092923555878202698 * 1e18, + poolDebt: 39.029114859324163603 * 1e18, + actualUtilization: 0.000466222553189995 * 1e18, + targetUtilization: 0.758474474342854060 * 1e18, + minDebtAmount: 3.902911485932416360 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -176,21 +176,29 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.727860269914713433 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.661404105687224454 * 1e18 }); } 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( @@ -198,32 +206,24 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 13.089508376044532180 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364710191686173217 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 12.609408860297298412 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); - _addLiquidity({ - from: _lender, - amount: 15.0 * 1e18, - index: _i1505_26, - lpAward: 15.0 * 1e18, - newLup: 9.917184843435912074 * 1e18 - }); - _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.729420383372346434 * 1e18, + borrowerDebt: 21.811059963842150618 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872629805438488447 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874396262534517775 * 1e18 }); // before deposit take: NFTs pledged by auctioned borrower are owned by the pool @@ -235,10 +235,10 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.009965031187761219 * 1e18, - quoteTokenAmount: 14.999999999999999995 * 1e18, - bondChange: 0, - isReward: true, + collateralArbed: 0.009964621805481374 * 1e18, + quoteTokenAmount: 14.999383771703071343 * 1e18, + bondChange: 0.167698208670676263 * 1e18, + isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 }); @@ -248,15 +248,15 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.076149339066797765 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 6 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 13.089508376044532180 * 1e18, - debtInAuction: 8.014051756262951713 * 1e18, - thresholdPrice: 4.027090921445553358 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.076149339066797765 * 1e18, + auctionPrice: 12.609408860297298412 * 1e18, + debtInAuction: 7.063223505145093670 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); // borrower is compensated LP for fractional collateral @@ -268,17 +268,17 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { }); _assertBucket({ index: _i1505_26, - lpBalance: 15 * 1e18, - collateral: 0.009965031187761219 * 1e18, - deposit: 0.000000000000000005 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 14.999383561643835615 * 1e18, + collateral: 0.009964621805481374 * 1e18, + deposit: 0.000000000000000301 * 1e18, + exchangeRate: 1.000000014004524598 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 8.014051756262951713 * 1e18, - borrowerCollateral: 1.990034968812238781 * 1e18, - borrowert0Np: 4.044492274291511923 * 1e18, - borrowerCollateralization: 2.462617566100560496 * 1e18 + borrowerDebt: 7.063223505145093670 * 1e18, + borrowerCollateral: 1.990035378194518626 * 1e18, + borrowert0Np: 3.578472696722346497 * 1e18, + borrowerCollateralization: 2.686661283150441203 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -289,8 +289,8 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i1505_26, - lpBalance: 15.0 * 1e18, - depositTime: block.timestamp + lpBalance: 14.999383561643835615 * 1e18, + 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.987894865384582852 * 1e18 + settledDebt: 7.065836413456418044 * 1e18 }); _assertBorrower({ borrower: _borrower, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol index 6b7e1d1bb..f9dea2aab 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol @@ -74,7 +74,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { }); _borrow({ from: _borrower, - amount: 19.8 * 1e18, + amount: 19.0 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -102,15 +102,15 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 9.909519230769230774 * 1e18, + htp: 9.889500000000000005 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 3.512434434608473285 * 1e18, - poolDebt: 34.833461538461538478 * 1e18, + encumberedCollateral: 3.568956368038954464 * 1e18, + poolDebt: 34.032692307692307708 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, - minDebtAmount: 1.741673076923076924 * 1e18, + minDebtAmount: 1.701634615384615385 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -119,17 +119,17 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.819038461538461548 * 1e18, + borrowerDebt: 19.018269230769230778 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 1.000773560501591181 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 1.002799417911513430 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.981531649793150539 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.905318894031875518 * 1e18 }); assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); @@ -152,25 +152,25 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 11.364359914920859402 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); /******************************/ @@ -179,15 +179,15 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 5.739575714606494647 * 1e18, + htp: 5.969158743190754433 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.346887619919714000 * 1e18, + poolSize: 73_000.913625835553743442 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.028103499563389533 * 1e18, - poolDebt: 39.947446973661202747 * 1e18, - actualUtilization: 0.000477170706006322 * 1e18, - targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 3.994744697366120275 * 1e18, + encumberedCollateral: 4.092923555878202698 * 1e18, + poolDebt: 39.029114859324163603 * 1e18, + actualUtilization: 0.000466222553189995 * 1e18, + targetUtilization: 0.758474474342854060 * 1e18, + minDebtAmount: 3.902911485932416360 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -199,38 +199,38 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3_350.914144267400237568 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364359914920859402 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3_228.008668236108393472 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.727860269914713433 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.661404105687224454 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.345029692224734546 * 1e18 + locked: 0.243847547737474028 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.756152452262525972 * 1e18); // kick should fail if borrower in liquidation _assertKickAuctionActiveRevert({ @@ -275,25 +275,25 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 11.364359914920859402 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); _assertAuction( @@ -301,24 +301,24 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3_350.914144267400237568 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364359914920859402 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3_228.008668236108393472 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); uint256[] memory tokenIdsToAdd = new uint256[](1); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol index c57f03711..657f4f1f6 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol @@ -80,11 +80,11 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 2_502.403846153846155000 * 1e18, + htp: 2_602.500000000000001200 * 1e18, lup: 3_863.654368867279344664 * 1e18, - poolSize: 16_000 * 1e18, + poolSize: 15_999.269406392694064000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 2.590711908723330630 * 1e18, + encumberedCollateral: 2.694340385072263856 * 1e18, poolDebt: 10_009.615384615384620000 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, @@ -99,15 +99,15 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 5_004.807692307692310000 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 1.543977154129479546 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + borrowerCollateralization: 1.484593417432191870 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 5_004.807692307692310000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_921.518170238564188136 * 1e18, - borrowerCollateralization: 2.315965731194219318 * 1e18 + borrowert0Np: 1_928.978897048106755629 * 1e18, + borrowerCollateralization: 2.226890126148287806 * 1e18 }); assertEq(_quote.balanceOf(address(_pool)), 6_000 * 1e18); @@ -126,7 +126,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower, debt: 5_004.80769230769231 * 1e18, collateral: 2 * 1e18, - bond: 75.974681840800023439 * 1e18 + bond: 55.955451071569254199 * 1e18 }); _lenderKick({ @@ -135,7 +135,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower2, debt: 5_004.80769230769231 * 1e18, collateral: 3 * 1e18, - bond: 75.974681840800023439 * 1e18 + bond: 55.955451071569254199 * 1e18 }); // skip to make loans clearable @@ -144,9 +144,9 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 3_863.654368867279344664 * 1e18, - poolSize: 16_000 * 1e18, + poolSize: 15_999.269406392694064000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 2.591895152324015187 * 1e18, + encumberedCollateral: 2.695570958416975794 * 1e18, poolDebt: 10_014.187028922603757647 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -161,39 +161,39 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 5_007.093514461301878824 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 1.543272302667571924 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + borrowerCollateralization: 1.483915675641896080 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 5_007.093514461301878824 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_921.518170238564188136 * 1e18, - borrowerCollateralization: 2.314908454001357886 * 1e18 + borrowert0Np: 1_928.978897048106755629 * 1e18, + borrowerCollateralization: 2.225873513462844121 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 6_151.949363681600046878 * 1e18); // increased by bonds size - assertEq(_quote.balanceOf(_lender), 103_848.050636318399953122 * 1e18); // decreased by bonds size + assertEq(_quote.balanceOf(address(_pool)), 6_111.910902143138508398 * 1e18); // increased by bonds size + assertEq(_quote.balanceOf(_lender), 103_888.089097856861491602 * 1e18); // decreased by bonds size assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); } function testKickAndSettleSubsetPoolFractionalCollateral() external tearDown { - // settle borrower 2 + // settle borrower 2, whose neutral price has been carried from borrower 1 _assertAuction( AuctionParams({ borrower: _borrower2, active: true, kicker: _lender, - bondSize: 75.974681840800023439 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 55.955451071569254199 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: _startTime, - referencePrice: 1_921.518170238564188136 * 1e18, - totalBondEscrowed: 151.949363681600046878 * 1e18, + referencePrice: 2_893.468345572160133444 * 1e18, + totalBondEscrowed: 111.910902143138508398 * 1e18, auctionPrice: 0, debtInAuction: 10_009.615384615384620000 * 1e18, - thresholdPrice: 1_669.031171487100626274 * 1e18, - neutralPrice: 1_921.518170238564188136 * 1e18 + debtToCollateral: 1_668.269230769230770000 * 1e18, + neutralPrice: 1_928.978897048106755629 * 1e18 }) ); @@ -209,7 +209,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 5_004.807692307692310000 * 1e18 + settledDebt: 5_007.093514461301878823 * 1e18 }); _assertAuction( @@ -221,10 +221,10 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 151.949363681600046878 * 1e18, + totalBondEscrowed: 111.910902143138508398 * 1e18, auctionPrice: 0, debtInAuction: 5_007.093514461301878824 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -242,14 +242,14 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 5_004.807692307692310000 * 1e18 + settledDebt: 5_007.093514461301878823 * 1e18 }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 5_989.698868738532498354 * 1e18, + poolSize: 5_988.968275131226558255 * 1e18, pledgedCollateral: 1 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -271,10 +271,10 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 151.949363681600046878 * 1e18, + totalBondEscrowed: 111.910902143138508398 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -301,8 +301,8 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { exchangeRate: 0.999999999995447280 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 6_151.949363681600046878 * 1e18); - assertEq(_quote.balanceOf(_lender), 103_848.050636318399953122 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 6_111.910902143138508398 * 1e18); + assertEq(_quote.balanceOf(_lender), 103_888.089097856861491602 * 1e18); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); @@ -311,7 +311,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, amount: 100 * 1e18, index: MAX_FENWICK_INDEX, - lpAward: 100.000000000455272058 * 1e18, + lpAward: 99.995890411414157448 * 1e18, newLup: MAX_PRICE }); @@ -365,10 +365,10 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 4_988.244512154526666083 * 1e18, + lpBalance: 4_987.559691655058899286 * 1e18, collateral: 0, - deposit: 4_989.456000134711482354 * 1e18, - exchangeRate: 1.000242868603821017 * 1e18 + deposit: 4_988.771068627862163511 * 1e18, + exchangeRate: 1.000242879694218013 * 1e18 }); } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index f03a1350a..da6021631 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -99,7 +99,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, debt: 10_064.648403565736152554 * 1e18, collateral: 2 * 1e18, - bond: 152.784783614301553735 * 1e18 + bond: 112.526190000038609125 * 1e18 }); _lenderKick({ from: _lender, @@ -107,17 +107,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower2, debt: 10_064.648403565736152554 * 1e18, collateral: 3 * 1e18, - bond: 152.784783614301553735 * 1e18 + bond: 112.526190000038609125 * 1e18 }); } function testSettlePartialDebtSubsetPool() external tearDown { _assertBucket({ index: 2500, - lpBalance: 8_000 * 1e18, + lpBalance: 7999.634703196347032000 * 1e18, collateral: 0, - deposit: 13_293.371821008415088000 * 1e18, - exchangeRate: 1.661671477626051886 * 1e18 + deposit: 13293.006524204762122216 * 1e18, + exchangeRate: 1.661701692315198699 * 1e18 }); // the 2 token ids are owned by borrower before settle @@ -151,8 +151,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 10_069.704976226041001321 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 0.767381840478769050 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + borrowerCollateralization: 0.737867154306508702 * 1e18 }); // first settle call settles partial borrower debt @@ -160,33 +160,33 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_485.570270210405357279 * 1e18 + settledDebt: 5_000.732078876477988054 * 1e18 }); // collateral in bucket used to settle auction increased with the amount used to settle debt _assertBucket({ index: 2499, - lpBalance: 5_000 * 1e18, - collateral: 1.287926464788484107 * 1e18, + lpBalance: 4999.748858447488585000 * 1e18, + collateral: 1.287861785696232799 * 1e18, deposit: 0, - exchangeRate: 1.000196645204423177 * 1e18 + exchangeRate: 1.000196653963394216 * 1e18 }); // partial borrower debt is settled, borrower collateral decreased with the amount used to settle debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_068.721750203925124024 * 1e18, - borrowerCollateral: 0.712073535211515893 * 1e18, - borrowert0Np: 4_074.953051699645482676 * 1e18, - borrowerCollateralization: 0.542781032548108438 * 1e18 + borrowerDebt: 5068.972897349563013267 * 1e18, + borrowerCollateral: 0.712138214303767201 * 1e18, + borrowert0Np: 4_090.606107481772639379 * 1e18, + borrowerCollateralization: 0.521926384043273437 * 1e18 }); _assertCollateralInvariants(); // 1 token id (token id 3, the most recent pledged token) was moved from borrower token ids array to pool claimable token ids array after partial bad debt settle - assertEq(ERC721Pool(address(_pool)).totalBorrowerTokens(_borrower), 1); - assertEq(ERC721Pool(address(_pool)).totalBucketTokens(), 1); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); + assertEq(ERC721Pool(address(_pool)).getBorrowerTokenIds(_borrower).length, 1); + assertEq(ERC721Pool(address(_pool)).getBorrowerTokenIds(_borrower)[0], 1); + assertEq(ERC721Pool(address(_pool)).getBucketTokenIds().length, 1); + assertEq(ERC721Pool(address(_pool)).getBucketTokenIds()[0], 3); // all NFTs are owned by the pool assertEq(_collateral.ownerOf(1), address(_pool)); @@ -199,26 +199,26 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_127.089747762669017517 * 1e18 + settledDebt: 2_756.297127247586280076 * 1e18 }); // no token id left in borrower token ids array - assertEq(ERC721Pool(address(_pool)).totalBorrowerTokens(_borrower), 0); - assertEq(ERC721Pool(address(_pool)).totalBucketTokens(), 2); + assertEq(ERC721Pool(address(_pool)).getBorrowerTokenIds(_borrower).length, 0); + assertEq(ERC721Pool(address(_pool)).getBucketTokenIds().length, 2); // tokens used to settle entire bad debt (settle auction) are moved to pool claimable array - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); + assertEq(ERC721Pool(address(_pool)).getBucketTokenIds()[0], 3); + assertEq(ERC721Pool(address(_pool)).getBucketTokenIds()[1], 1); _assertBucket({ index: 2500, - lpBalance: 20_036.073477395793018984 * 1e18, - collateral: 0.712073535211515893 * 1e18, - deposit: 30_548.712777641352242710 * 1e18, - exchangeRate: 1.661998237353453822 * 1e18 + lpBalance: 20034.884788261831319325 * 1e18, + collateral: 0.712138214303767201 * 1e18, + deposit: 30547.093039196991134852 * 1e18, + exchangeRate: 1.662028472538971359 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 789.003620205433623214 * 1e18, + borrowerDebt: 2_312.675770101976733191 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -228,7 +228,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 392.147674334617935204 * 1e18 + settledDebt: 2_312.675770101976733191 * 1e18 }); _assertBorrower({ @@ -245,29 +245,29 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 5_004.807692307692310000 * 1e18 + settledDebt: 10_069.704976226041001321 * 1e18 }); _assertBucket({ index: 2500, - lpBalance: 20_036.073477395793018984 * 1e18, - collateral: 3.318337971638889847 * 1e18, - deposit: 19_690.004181209877611641 * 1e18, - exchangeRate: 1.622619083494012841 * 1e18 + lpBalance: 20_034.884788261831319325 * 1e18, + collateral: 3.318402650731141155 * 1e18, + deposit: 18_164.712292868973392890 * 1e18, + exchangeRate: 1.546596025856924939 * 1e18 }); _assertBucket({ index: 2499, - lpBalance: 5_000 * 1e18, - collateral: 1.287926464788484107 * 1e18, + lpBalance: 4999.748858447488585000 * 1e18, + collateral: 1.287861785696232799 * 1e18, deposit: 0, - exchangeRate: 1.000196645204423177 * 1e18 + exchangeRate: 1.000196653963394216 * 1e18 }); _assertBucket({ index: 7388, - lpBalance: 99.984931546150681783 * 1e18, + lpBalance: 99.994977208251138039 * 1e18, collateral: 0.393735563572626046 * 1e18, - deposit: 100.004593064144716734 * 1e18, - exchangeRate: 1.000196645204423177 * 1e18 + deposit: 100.014641577529559813 * 1e18, + exchangeRate: 1.000196653963394217 * 1e18 }); _assertBorrower({ @@ -314,10 +314,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 15_959.417125063160793398 * 1e18, + lpBalance: 15_757.678471160293718635 * 1e18, collateral: 1.606264436427373954 * 1e18, - deposit: 19_690.004181209877611641 * 1e18, - exchangeRate: 1.622619083494012841 * 1e18 + deposit: 18_164.712292868973392890 * 1e18, + exchangeRate: 1.546596025856924939 * 1e18 }); _assertBucket({ index: 2499, @@ -328,10 +328,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBucket({ index: MAX_FENWICK_INDEX, - lpBalance: 99.984931546150681783 * 1e18, + lpBalance: 99.994977208251138039 * 1e18, collateral: 0.393735563572626046 * 1e18, - deposit: 100.004593064144716734 * 1e18, - exchangeRate: 1.000196645204423177 * 1e18 + deposit: 100.014641577529559813 * 1e18, + exchangeRate: 1.000196653963394217 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -371,25 +371,25 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 3_323.342955252103772000 * 1e18, - exchangeRate: 1.661671477626051886 * 1e18 + deposit: 3_323.251631051190530554 * 1e18, + exchangeRate: 1.661701692315198699 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 0.756365082071426765 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + 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_863.757250427550337858 * 1e18, - collateral: 1.678659796633077181 * 1e18, - deposit: 0.000000000000002754 * 1e18, - exchangeRate: 1.661954009450878778 * 1e18 + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001434 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 3_742.762708953482933471 * 1e18, - borrowerCollateral: 0.321340203366922819 * 1e18, - borrowert0Np: 6_669.712537943716399889 * 1e18, - borrowerCollateralization: 0.330069182462081655 * 1e18 + borrowerDebt: 3_742.625741320959738707 * 1e18, + borrowerCollateral: 0.328094552805976837 * 1e18, + borrowert0Np: 6_557.529424508974043853 * 1e18, + borrowerCollateralization: 0.324057059956572295 * 1e18 }); _assertCollateralInvariants(); @@ -421,21 +421,21 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 2, - settledDebt: 1_860.774838340588348583 * 1e18 + settledDebt: 3_744.317995698454162123 * 1e18 }); _assertBucket({ index: 2500, - lpBalance: 8_000 * 1e18, - collateral: 0.321340203366922819 * 1e18, - deposit: 11_084.202409928441579151 * 1e18, - exchangeRate: 1.540718736319969120 * 1e18 + lpBalance: 7_999.634703196347032000 * 1e18, + collateral: 0.328094552805976837 * 1e18, + deposit: 9_559.443166179627977772 * 1e18, + exchangeRate: 1.353447691080682492 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 3_863.757250427550337858 * 1e18, - collateral: 1.678659796633077181 * 1e18, - deposit: 0.000000000000002755 * 1e18, - exchangeRate: 1.661954009450878778 * 1e18 + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001435 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -456,14 +456,45 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 2, - settledDebt: 5_004.80769230769231 * 1e18 + settledDebt: 10_071.222443357521878028 * 1e18 + }); + + _assertBucket({ + index: 2500, + lpBalance: 7_999.634703196347032000 * 1e18, + collateral: 2.802291842089438895 * 1e18, + deposit: 0, + exchangeRate: 1.353447691080682492 * 1e18 + }); + _assertBucket({ + index: 2501, + lpBalance: 1_999.908675799086758000 * 1e18, + collateral: 0.133122201019904801 * 1e18, + deposit: 2_812.950529824876926491 * 1e18, + exchangeRate: 1.662440814040839338 * 1e18 + }); + _assertBucket({ + index: 2502, + lpBalance: 3_848.220602860971165296 * 1e18, + collateral: 1.671905447194023163 * 1e18, + deposit: 0.000000000000001435 * 1e18, + exchangeRate: 1.661949784757169370 * 1e18 + }); + _assertBucket({ + index: 7388, + lpBalance: 0.000000039203762451 * 1e18, + collateral: 0.392680509696633141 * 1e18, + deposit: 0, + exchangeRate: 1.000000000011796173 * 1e18 }); + _assertCollateralInvariants(); // collateral in buckets: - // 2500 - 2.928128325437681102 - // 2502 - 1.678659796633077182 - // 7388 - 0.393211877929241716 + // 2500 - 2.802290638246429771 + // 2501 - 0.133123410882128970 + // 2502 - 1.671905447194023163 + // 7388 - 0.392680503677418096 // lender deposits quote token into 7388 to merge from that bucket _addLiquidityNoEventCheck({ @@ -473,10 +504,11 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); // lender merge / removes available NFTs - uint256[] memory removalIndexes = new uint256[](3); + uint256[] memory removalIndexes = new uint256[](4); removalIndexes[0] = 2500; - removalIndexes[1] = 2502; - removalIndexes[2] = 7388; + removalIndexes[1] = 2501; + removalIndexes[2] = 2502; + removalIndexes[3] = 7388; _mergeOrRemoveCollateral({ from: _lender, toIndex: 7388, @@ -502,34 +534,35 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 3_323.342955252103772000 * 1e18, - exchangeRate: 1.661671477626051886 * 1e18 + deposit: 3_323.251631051190530554 * 1e18, + exchangeRate: 1.661701692315198699 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 0.756365082071426765 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + 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.021378186081598093 * 1e18, - quoteTokenAmount: 999.999999999999990800 * 1e18, - bondChange: 15.180339887498947860 * 1e18, + collateralArbed: 0.021377546506154720 * 1e18, + quoteTokenAmount: 999.970082801181914578 * 1e18, + bondChange: 11.180005403047679924 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -537,37 +570,37 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, - lpBalance: 1_000 * 1e18, - collateral: 0.021378186081598093 * 1e18, - deposit: 0.000000000000009201 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 999.949771689497717000 * 1e18, + collateral: 0.021377546506154720 * 1e18, + deposit: 0.000000000000024123 * 1e18, + exchangeRate: 1.000020312131928292 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9_087.671681713557968897 * 1e18, - borrowerCollateral: 1.978621813918401907 * 1e18, - borrowert0Np: 2_630.547032872719470290 * 1e18, - borrowerCollateralization: 0.832868255733566506 * 1e18 + borrowerDebt: 9_081.701097185699143214 * 1e18, + borrowerCollateral: 1.978622453493845280 * 1e18, + borrowert0Np: 2_639.024895576489054434 * 1e18, + borrowerCollateralization: 0.801361613336061264 * 1e18 }); - _assertCollateralInvariants(); + _assertCollateralInvariants(); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 4_305.569567228603107470 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 4_225.052380000077218250 * 1e18); // borrower exits from auction by regular take _take({ from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 137.604443726802605875 * 1e18, - givenAmount: 9_299.424314491640485936 * 1e18, - collateralTaken: 0.802193429456335794 * 1e18, + bondChange: 101.346184596990929201 * 1e18, + givenAmount: 9_236.603649496932514865 * 1e18, + collateralTaken: 1.000000000000000000 * 1e18, isReward: false }); - assertEq(_quote.balanceOf(_borrower), 7_393.071925217111242444 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 13_604.993881720243593406 * 1e18); + assertEq(_quote.balanceOf(_borrower), 7_500.903066211834660554 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 13_461.656029497009733115 * 1e18); _assertBorrower({ borrower: _borrower, @@ -586,99 +619,49 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 152.784783614301553735 * 1e18, + totalBondEscrowed: 112.526190000038609125 * 1e18, auctionPrice: 0, - debtInAuction: 10064.901171882309537906 * 1e18, - thresholdPrice: 0, + debtInAuction: 10_064.901171882309537906 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); - _assertCollateralInvariants(); + _assertCollateralInvariants(); // remaining token is moved to pool claimable array assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 1); // buckets with collateral - // 2000 - 0.021876321065491412 - // 2279 - 0.978123678934508588 _assertBucket({ index: 2000, - lpBalance: 1_000 * 1e18, - collateral: 0.021378186081598093 * 1e18, - deposit: 0.000000000000009201 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 999.949771689497717000 * 1e18, + collateral: 0.021377546506154720 * 1e18, + deposit: 0.000000000000024123 * 1e18, + exchangeRate: 1.000020312131928292 * 1e18 }); _assertBucket({ - index: 2279, - lpBalance: 11_384.469793445698921143 * 1e18, - collateral: 0.978621813918401907 * 1e18, + index: 2278, + lpBalance: 11_441.399619901522216594 * 1e18, + collateral: 0.978622453493845280 * 1e18, deposit: 0, - exchangeRate: 1 * 1e18 - }); - - // lender adds liquidity in bucket 2159 and merge / removes remaining NFTs - _addLiquidityNoEventCheck({ - from: _lender, - amount: 40_000 * 1e18, - index: 2279 - }); - _addLiquidityNoEventCheck({ - from: _lender, - amount: 40_000 * 1e18, - index: 2000 - }); - uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2000; - removalIndexes[1] = 2279; - _mergeOrRemoveCollateral({ - from: _lender, - toIndex: 2279, - 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: 40_000.000000000000009178 * 1e18, - collateral: 0, - deposit: 40_000.000000000000009201 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 - }); - _assertBucket({ - index: 2279, - lpBalance: 40_000.000000000000000001 * 1e18, - collateral: 0, - deposit: 40_000.000000000000000000 * 1e18, - exchangeRate: 1 * 1e18 - }); - - _assertCollateralInvariants(); + assertEq(_collateral.ownerOf(1),address(_pool)); - // borrower removes tokens from auction price bucket for compensated collateral fraction - _removeAllLiquidity({ - from: _borrower, - amount: 11_384.469793445698921142 * 1e18, - index: 2279, - newLup: _priceAt(2000), - lpRedeem: 11_384.469793445698921143 * 1e18 - }); + _assertCollateralInvariants(); // borrower2 exits from auction by deposit take - skip(3 hours); + skip(3.2 hours); _assertBucket({ index: 2500, - lpBalance: 8_000.000000000000000000 * 1e18, + lpBalance: 7_999.634703196347032000 * 1e18, collateral: 0 * 1e18, - deposit: 13_293.654327999447280000 * 1e18, - exchangeRate: 1.661706790999930910 * 1e18 + deposit: 13_293.276533507005404455 * 1e18, + exchangeRate: 1.661735445019198470 * 1e18 }); _depositTake({ @@ -686,12 +669,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower2, kicker: _lender, index: 2500, - collateralArbed: 2.645225595891871889 * 1e18, - quoteTokenAmount: 10_220.237430207183199580 * 1e18, - bondChange: 155.146677921483848824 * 1e18, + collateralArbed: 2.641774864645406157 * 1e18, + quoteTokenAmount: 10_206.904997350989042985 * 1e18, + bondChange: 3.376910369914579034 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 93.365678971373374698 * 1e18 + lpAwardKicker: 2.032141649575679124 * 1e18 }); _assertCollateralInvariants(); _assertBorrower({ @@ -711,66 +694,132 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 152.784783614301553735 * 1e18, + totalBondEscrowed: 112.526190000038609125 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); + // lender adds liquidity in bucket 2286 and merge / removes remaining NFTs + _addLiquidityNoEventCheck({ + from: _lender, + amount: 40_000 * 1e18, + index: 2278 + }); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 40_000 * 1e18, + index: 2000 + }); + + // pool owns borrower2's collateral pre-merge and remove + assertEq(_collateral.ownerOf(51), address(_pool)); + assertEq(_collateral.ownerOf(53), address(_pool)); + assertEq(_collateral.ownerOf(73), address(_pool)); + + uint256[] memory removalIndexes = new uint256[](3); + removalIndexes[0] = 2000; + removalIndexes[1] = 2278; + removalIndexes[2] = 2501; + _mergeOrRemoveCollateral({ + from: _lender, + toIndex: 2286, + noOfNFTsToRemove: 1, + collateralMerged: 1 * 1e18, + removeCollateralAtIndex: removalIndexes, + toIndexLps: 0 + }); + // lender removes collateral _assertBucket({ index: 2500, - lpBalance: 8_093.365678971373374698 * 1e18, - collateral: 2.645225595891871889 * 1e18, - deposit: 3_228.588863672794087920 * 1e18, - exchangeRate: 1.661709951994811681 * 1e18 + lpBalance: 8_001.666844845922711124 * 1e18, + collateral: 2.641774864645406157 * 1e18, + deposit: 3_089.860880462677483506 * 1e18, + exchangeRate: 1.661749499903067308 * 1e18 }); _addLiquidityNoEventCheck({ from: _lender, amount: 10_000 * 1e18, - index: 2569 + index: 2576 }); _assertBucket({ - index: 2569, - lpBalance: 10_971.610695426638179656 * 1e18, - collateral: 0.354774404108128111 * 1e18, - deposit: 10_000.000000000000000000 * 1e18, - exchangeRate: 1 * 1e18 + index: 2576, + lpBalance: 9_999.497716894977170000 * 1e18, + collateral: 0.0 * 1e18, + deposit: 9_999.497716894977169999 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 + }); + _assertBucket({ + index: 2502, + lpBalance: 1_999.908675799086758000 * 1e18, + collateral: 0.0 * 1e18, + deposit: 3_323.347241860937986864 * 1e18, + exchangeRate: 1.661749499903067308 * 1e18 + }); + _assertBucket({ + index: 2501, + lpBalance: 2_828.657081073845584103 * 1e18, + collateral: 0.358225135354593843 * 1e18, + deposit: 3_323.347241860937986864 * 1e18, + exchangeRate: 1.661749499903067308 * 1e18 }); removalIndexes[0] = 2500; - removalIndexes[1] = 2569; + removalIndexes[1] = 2501; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 2569, + toIndex: 2502, noOfNFTsToRemove: 3, collateralMerged: 3 * 1e18, removeCollateralAtIndex: removalIndexes, - toIndexLps: 0 + toIndexLps: 0 * 1e18 + }); + + // lender owns collateral post-merge and remove + assertEq(_collateral.ownerOf(51), _lender); + assertEq(_collateral.ownerOf(53), _lender); + assertEq(_collateral.ownerOf(73), _lender); + + _removeAllLiquidity({ + from: _lender, + amount: 3_323.347241860937986864 * 1e18, + index: 2502, + newLup: MAX_PRICE, + lpRedeem: 1_999.908675799086758000 * 1e18 + }); + + _removeAllLiquidity({ + from: _borrower2, + amount: 1_377.172248010795027155 * 1e18, + index: 2501, + newLup: MAX_PRICE, + lpRedeem: 828.748405274758826103 * 1e18 + }); + + _removeAllLiquidity({ + from: _borrower, + amount: 11_441.399619901522216594 * 1e18, + index: 2278, + newLup: MAX_PRICE, + lpRedeem: 11_441.399619901522216594 * 1e18 }); + _assertBucket({ index: 2500, - lpBalance: 1_942.931652901886597757 * 1e18, + lpBalance: 1_859.402323059470972038 * 1e18, collateral: 0, - deposit: 3_228.588863672794087920 * 1e18, - exchangeRate: 1.661709951994811681 * 1e18 + deposit: 3_089.860880462677483506 * 1e18, + exchangeRate: 1.661749499903067308 * 1e18 }); _assertBucket({ - index: 2569, - lpBalance: 10_000.000000000000000004 * 1e18, + index: 2576, + lpBalance: 9_999.497716894977170000 * 1e18, collateral: 0, - deposit: 10_000.000000000000000000 * 1e18, - exchangeRate: 1 * 1e18 - }); - // borrower 2 redeems LP for quote token - _removeAllLiquidity({ - from: _borrower2, - amount: 971.610695426638179651 * 1e18, - index: 2569, - newLup: MAX_PRICE, - lpRedeem: 971.610695426638179652 * 1e18 - }); + deposit: 9_999.497716894977169999 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 + }); } function testDepositTakeAndSettleByBucketTakeSubsetPool() external tearDown { @@ -783,18 +832,25 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, collateral: 0, - deposit: 3_323.342955252103772000 * 1e18, - exchangeRate: 1.661671477626051886 * 1e18 + deposit: 3_323.251631051190530554 * 1e18, + exchangeRate: 1.661701692315198699 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_882.277255357846282204 * 1e18, - borrowerCollateralization: 0.756365082071426765 * 1e18 + borrowert0Np: 2_893.468345572160133444 * 1e18, + 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); @@ -804,50 +860,43 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.882320037286956004 * 1e18, - quoteTokenAmount: 3_375.143849709550192592 * 1e18, - bondChange: 51.235830807792639427 * 1e18, + collateralArbed: 0.878616868279129171 * 1e18, + quoteTokenAmount: 3_360.978096272017407037 * 1e18, + bondChange: 37.576877470760315517 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 30.828669455613465562 * 1e18 + lpAwardKicker: 22.612473883102005275 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_030.828669455613465562 * 1e18, - collateral: 0.882320037286956004 * 1e18, - deposit: 0.000000000000000834 * 1e18, - exchangeRate: 1.661954009450878778 * 1e18 - }); + lpBalance: 2_022.521149682188763275 * 1e18, + collateral: 0.878616868279129171 * 1e18, + deposit: 0.000000000000001612 * 1e18, + exchangeRate: 1.661776489605633371 * 1e18 + }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6_742.762708953482931550 * 1e18, - borrowerCollateral: 1.117679962713043996 * 1e18, - borrowert0Np: 3_454.620119359940588354 * 1e18, - borrowerCollateralization: 0.630927812552385529 * 1e18 + borrowerDebt: 6_743.269509053983393196 * 1e18, + borrowerCollateral: 1.121383131720870829 * 1e18, + borrowert0Np: 3_456.840697666413087238 * 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.146369981971725896 * 1e18, - quoteTokenAmount: 6_846.697910339464805069 * 1e18, - bondChange: 103.935201385981873520 * 1e18, - isReward: true, + collateralArbed: 0.146617724350579337 * 1e18, + quoteTokenAmount: 6_858.286469719939684040 * 1e18, + bondChange: 76.677973777304187687 * 1e18, + isReward: false, lpAwardTaker: 0, - lpAwardKicker: 103.935201385981873519 * 1e18 + lpAwardKicker: 0 }); _assertBorrower({ @@ -866,19 +915,19 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 305.569567228603107470 * 1e18, + totalBondEscrowed: 148.374406222773030563 * 1e18, auctionPrice: 0, debtInAuction: 10_066.670727855240484714 * 1e18, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBucket({ - index: 5476, - lpBalance: 0.001343248402621047 * 1e18, - collateral: 0.971309980741318100 * 1e18, + index: 5475, + lpBalance: 0.001354767131866582 * 1e18, + collateral: 0.974765407370291492 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000249 * 1e18 + exchangeRate: 1.000000000000000024 * 1e18 }); // bucket take on borrower 2 @@ -887,12 +936,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower2, kicker: _lender, index: 2000, - collateralArbed: 0.218524435242978009 * 1e18, - quoteTokenAmount: 10_221.841760049014997661 * 1e18, - bondChange: 155.171032193774512947 * 1e18, - isReward: true, + collateralArbed: 0.218877853231731145 * 1e18, + quoteTokenAmount: 10_238.373470803340954507 * 1e18, + bondChange: 112.526190000038609125 * 1e18, + isReward: false, lpAwardTaker: 0, - lpAwardKicker: 155.171032193774512946 * 1e18 + lpAwardKicker: 0 }); _assertBorrower({ @@ -911,19 +960,19 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 305.569567228603107470 * 1e18, + totalBondEscrowed: 35.848216222734421438 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBucket({ - index: 5557, - lpBalance: 0.000721544103807183 * 1e18, - collateral: 0.781475564757021991 * 1e18, + index: 5565, + lpBalance: 0.0 * 1e18, + collateral: 0.0 * 1e18, deposit: 0, - exchangeRate: 0.999999999999999669 * 1e18 + exchangeRate: 1.0000000000000000000 * 1e18 }); _assertCollateralInvariants(); @@ -935,28 +984,28 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, - lpBalance: 60_259.106233579756386465 * 1e18, - collateral: 0.364894417214703905 * 1e18, - deposit: 43_190.566563191276548531 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + lpBalance: 59_996.986301369863020000 * 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 _addLiquidityNoEventCheck({ from: _lender, - amount: 1_000 * 1e18, - index: 5476 + amount: 2_000 * 1e18, + index: 5475 }); _addLiquidityNoEventCheck({ from: _lender, - amount: 1_000 * 1e18, - index: 5557 + amount: 2_000 * 1e18, + index: 5565 }); uint256[] memory removalIndexes = new uint256[](4); removalIndexes[0] = 2000; removalIndexes[1] = 2502; - removalIndexes[2] = 5476; - removalIndexes[3] = 5557; + removalIndexes[2] = 5475; + removalIndexes[3] = 5565; _mergeOrRemoveCollateral({ from: _lender, @@ -977,18 +1026,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // remove lps for both borrower and borrower 2 _removeAllLiquidity({ from: _borrower, - amount: 0.001343248402621047 * 1e18, - index: 5476, + amount: 0.001354767131866582 * 1e18, + index: 5475, newLup: MAX_PRICE, - lpRedeem: 0.001343248402621047 * 1e18 + lpRedeem: 0.001354767131866582 * 1e18 }); _removeAllLiquidity({ from: _borrower2, - amount: 0.000721544103807182 * 1e18, - index: 5557, + amount: 0.001085634145829627 * 1e18, + index: 5475, + newLup: MAX_PRICE, + lpRedeem: 0.001085634145829627 * 1e18 + }); + + // remove lps for both borrower and borrower 2 + _removeAllLiquidity({ + from: _lender, + amount: 1_999.909589041095890000 * 1e18, + index: 5565, newLup: MAX_PRICE, - lpRedeem: 0.000721544103807183 * 1e18 + lpRedeem: 1_999.909589041095890000 * 1e18 }); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol index 3bdd8b0f1..812ffae50 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol @@ -66,7 +66,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { index: _i9_52 }); - // first borrower adds collateral token and borrows + // first borrower adds collateral token and borrows uint256[] memory tokenIdsToAdd = new uint256[](2); tokenIdsToAdd[0] = 1; tokenIdsToAdd[1] = 3; @@ -79,7 +79,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { }); _borrow({ from: _borrower, - amount: 19.8 * 1e18, + amount: 19.0 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -107,15 +107,15 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 9.909519230769230774 * 1e18, + htp: 9.889500000000000005 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_000 * 1e18, + poolSize: 72_996.666666666666667000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 3.512434434608473285 * 1e18, - poolDebt: 34.833461538461538478 * 1e18, + encumberedCollateral: 3.568956368038954464 * 1e18, + poolDebt: 34.032692307692307708 * 1e18, actualUtilization: 0, targetUtilization: 1 * 1e18, - minDebtAmount: 1.741673076923076924 * 1e18, + minDebtAmount: 1.701634615384615385 * 1e18, loans: 2, maxBorrower: address(_borrower), interestRate: 0.05 * 1e18, @@ -124,17 +124,17 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.819038461538461548 * 1e18, + borrowerDebt: 19.018269230769230778 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 1.000773560501591181 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 1.002799417911513430 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.981531649793150539 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.905318894031875518 * 1e18 }); assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); @@ -156,26 +156,26 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 11.364359914920859402 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); /******************************/ @@ -184,15 +184,15 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 5.739575714606494647 * 1e18, + htp: 5.969158743190754433 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.346887619919714000 * 1e18, + poolSize: 73_000.913625835553743442 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.028103499563389533 * 1e18, - poolDebt: 39.947446973661202747 * 1e18, - actualUtilization: 0.000477170706006322 * 1e18, - targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 3.994744697366120275 * 1e18, + encumberedCollateral: 4.092923555878202698 * 1e18, + poolDebt: 39.029114859324163603 * 1e18, + actualUtilization: 0.000466222553189995 * 1e18, + targetUtilization: 0.758474474342854060 * 1e18, + minDebtAmount: 3.902911485932416360 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -201,41 +201,41 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.727860269914713433 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.661404105687224454 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.756152452262525972 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3350.914144267400237568 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364359914920859402 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3_228.008668236108393472 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.345029692224734546 * 1e18 + locked: 0.243847547737474028 * 1e18 }); skip(5.5 hours); @@ -245,33 +245,33 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // before take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); - assertEq(_quote.balanceOf(_borrower), 119.8 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.756152452262525972 * 1e18); + assertEq(_quote.balanceOf(_borrower), 119 * 1e18); - // threshold price increases slightly due to interest + // debt to collateral increases slightly due to interest _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5.5 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 15.566136492679870612 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364681001543373706 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 14.995198732643899296 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.729362003086747412 * 1e18, + borrowerDebt: 21.811003942355969738 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872632046785045240 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874398508418213347 * 1e18 }); uint256 snapshot = vm.snapshot(); @@ -284,8 +284,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 1, - bondChange: 0.236299242694081216 * 1e18, - givenAmount: 15.566136492679870612 * 1e18, + bondChange: 0.167651418511552261 * 1e18, + givenAmount: 14.995198732643899296 * 1e18, collateralTaken: 1.0 * 1e18, isReward: false }); @@ -293,15 +293,15 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // borrower still under liquidation _assertPool( PoolParams({ - htp: 5.739737879567360457 * 1e18, + htp: 5.969327394750054875 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.347847014760830891 * 1e18, + poolSize: 73_000.914563174737216441 * 1e18, pledgedCollateral: 4 * 1e18, - encumberedCollateral: 2.494345764818852289 * 1e18, - poolDebt: 24.736888013150079997 * 1e18, - actualUtilization: 0.000411524083711660 * 1e18, - targetUtilization: 0.781984313351887130 * 1e18, - minDebtAmount: 2.473688801315008000 * 1e18, + encumberedCollateral: 2.546887671650764282 * 1e18, + poolDebt: 24.286495976181480207 * 1e18, + actualUtilization: 0.000403556882317336 * 1e18, + targetUtilization: 0.754866915220293599 * 1e18, + minDebtAmount: 2.428649597618148021 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -311,10 +311,10 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 7.517674374447998626 * 1e18, + borrowerDebt: 7.067282337479398835 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 7.550178184893434284 * 1e18, - borrowerCollateralization: 1.319182548946741612 * 1e18 + borrowert0Np: 7.125397766163924279 * 1e18, + borrowerCollateralization: 1.349281690159688237 * 1e18 }); _assertAuction( @@ -322,15 +322,15 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.108730449530653330 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.076196129225921767 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 5.5 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.108730449530653330 * 1e18, - auctionPrice: 15.566136492679870612 * 1e18, - debtInAuction: 7.517674374447998626 * 1e18, - thresholdPrice: 7.517674374447998626 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.076196129225921767 * 1e18, + auctionPrice: 14.995198732643899296 * 1e18, + debtInAuction: 7.067282337479398835 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertKicker({ @@ -344,8 +344,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // after take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_984.088833815095394842 * 1e18); - assertEq(_quote.balanceOf(_borrower), 119.8 * 1e18); // no additional tokens as there is no rounding of collateral taken (1) + assertEq(_quote.balanceOf(_lender), 46_984.760953719618626676 * 1e18); + assertEq(_quote.balanceOf(_borrower), 119 * 1e18); // no additional tokens as there is no rounding of collateral taken (1) vm.revertTo(snapshot); @@ -357,22 +357,22 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 0.345029692224734546 * 1e18, - givenAmount: 23.258980855317575086 * 1e18, - collateralTaken: 1.494203835759460320 * 1e18, // not a rounded collateral, difference of 2 - 1.49 collateral should go to borrower in quote tokens at auction price + bondChange: 0.243847547737474028 * 1e18, + givenAmount: 22.183024574062103590 * 1e18, + collateralTaken: 2.0 * 1e18, isReward: false }); _assertPool( PoolParams({ - htp: 5.739737879567360457 * 1e18, + htp: 5.969327394750054875 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.347847014760830891 * 1e18, + poolSize: 73_000.914563174737216441 * 1e18, pledgedCollateral: 3.0 * 1e18, - encumberedCollateral: 1.736300564176668638 * 1e18, + encumberedCollateral: 1.805752586743735384 * 1e18, poolDebt: 17.219213638702081372 * 1e18, - actualUtilization: 0.000411524083711660 * 1e18, - targetUtilization: 0.781984313351887130 * 1e18, + actualUtilization: 0.000403556882317336 * 1e18, + targetUtilization: 0.754866915220293599 * 1e18, minDebtAmount: 1.721921363870208137 * 1e18, loans: 1, maxBorrower: address(_borrower2), @@ -401,7 +401,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); @@ -416,8 +416,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), _lender); // after take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_968.522697322415524242 * 1e18); - assertEq(_quote.balanceOf(_borrower), 127.673292130042166126 * 1e18); // borrower gets quote tokens from the difference of rounded collateral (2) and needed collateral (1.49) at auction price (15.5) = 7.9 additional tokens + assertEq(_quote.balanceOf(_lender), 46_969.765754986974727382 * 1e18); + assertEq(_quote.balanceOf(_borrower), 126.807372891225695000 * 1e18); // borrower gets quote tokens from the difference of rounded collateral (2) and needed collateral (1.49) at auction price (15.5) = 7.9 additional tokens } function testTakeCollateralAndSettleSubsetPool() external tearDown { @@ -436,25 +436,25 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 11.364359914920859402 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); /******************************/ @@ -463,15 +463,15 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 5.739575714606494647 * 1e18, + htp: 5.969158743190754433 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.346887619919714000 * 1e18, + poolSize: 73_000.913625835553743442 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.028103499563389533 * 1e18, - poolDebt: 39.947446973661202747 * 1e18, - actualUtilization: 0.000477170706006322 * 1e18, - targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 3.994744697366120275 * 1e18, + encumberedCollateral: 4.092923555878202698 * 1e18, + poolDebt: 39.029114859324163603 * 1e18, + actualUtilization: 0.000466222553189995 * 1e18, + targetUtilization: 0.758474474342854060 * 1e18, + minDebtAmount: 3.902911485932416360 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -480,41 +480,41 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.764554510715692564 * 1e18, - borrowerCollateralization: 1.727860269914713433 * 1e18 + borrowert0Np: 5.786936691144320266 * 1e18, + borrowerCollateralization: 1.661404105687224454 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.756152452262525972 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3_350.914144267400237568 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364359914920859402 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3_228.008668236108393472 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.345029692224734546 * 1e18 + locked: 0.243847547737474028 * 1e18 }); skip(10 hours); @@ -524,30 +524,30 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // before take: check quote token balances of taker - assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.756152452262525972 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3.272377094011133044 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364943715527677468 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3.152352215074324604 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.729887431055354936 * 1e18, + borrowerDebt: 21.811508140911704231 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872611874873280395 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874378295672619020 * 1e18 }); /**************************************/ @@ -558,8 +558,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 0.099351593054310196 * 1e18, - givenAmount: 6.544754188022266088 * 1e18, + bondChange: 0.070488738419282267 * 1e18, + givenAmount: 6.304704430148649208 * 1e18, collateralTaken: 2 * 1e18, isReward: true }); @@ -569,19 +569,19 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), _lender); // after take: Taker quote token used for buying collateral - assertEq(_quote.balanceOf(_lender), 46_993.110216119752999366 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_993.451448022113876764 * 1e18); _assertPool( PoolParams({ - htp: 5.739870563397816903 * 1e18, + htp: 5.969465385933729579 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.348631994338166115 * 1e18, + poolSize: 73_000.915330108312950970 * 1e18, pledgedCollateral: 3 * 1e18, - encumberedCollateral: 3.378387824288349781 * 1e18, - poolDebt: 33.504096526280849753 * 1e18, - actualUtilization: 0.000371337774626592 * 1e18, - targetUtilization: 0.778640404875432888 * 1e18, - minDebtAmount: 3.350409652628084975 * 1e18, + encumberedCollateral: 3.439361153737805799 * 1e18, + poolDebt: 32.796904139375787999 * 1e18, + actualUtilization: 0.000365195584296466 * 1e18, + targetUtilization: 0.751903493883837161 * 1e18, + minDebtAmount: 3.279690413937578800 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -592,7 +592,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // Borrower collateral is 0 and some debt is still to be paid _assertBorrower({ borrower: _borrower, - borrowerDebt: 16.284484836087399045 * 1e18, + borrowerDebt: 15.577292449182337291 * 1e18, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 0 @@ -602,22 +602,22 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.444381285279044742 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.314336286156756295 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.444381285279044742 * 1e18, - auctionPrice: 3.272377094011133044 * 1e18, - debtInAuction: 16.284484836087399045 * 1e18, - thresholdPrice: 0, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.314336286156756295 * 1e18, + auctionPrice: 3.152352215074324604 * 1e18, + debtInAuction: 15.577292449182337291 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); // kicker bond is locked as auction is not cleared _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.444381285279044742 * 1e18 + locked: 0.314336286156756295 * 1e18 }); // settle auction @@ -625,7 +625,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 14.199051019135248430 * 1e18 + settledDebt: 15.577292449182337290 * 1e18 }); _assertAuction( @@ -637,16 +637,16 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, referencePrice: 0, - totalBondEscrowed: 0.444381285279044742 * 1e18, + totalBondEscrowed: 0.314336286156756295 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 0, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertKicker({ kicker: _lender, - claimable: 0.444381285279044742 * 1e18, + claimable: 0.314336286156756295 * 1e18, locked: 0 }); @@ -658,7 +658,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // Kicker claims remaining bond + reward to his own address _pool.withdrawBonds(_lender, type(uint256).max); - assertEq(_quote.balanceOf(_lender), 46_993.454597405032044108 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_993.665784308270633059 * 1e18); } function testTakeCollateralSubsetPoolAndSettleWithDebt() external tearDown { @@ -677,48 +677,48 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 11.364359914920859402 * 1e18, + debtToCollateral: 0, neutralPrice: 0 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.728719829841718805 * 1e18, + borrowerDebt: 21.810387715504679661 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 11.413817931217071277 * 1e18, - borrowerCollateralization: 0.872656701977127996 * 1e18 + borrowert0Np: 10.995179713174208507 * 1e18, + borrowerCollateralization: 0.874423213519591818 * 1e18 }); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224734546 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737474028 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224734546 * 1e18, - auctionPrice: 3_350.914144267400237568 * 1e18, - debtInAuction: 22.728719829841718805 * 1e18, - thresholdPrice: 11.364359914920859402 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737474028 * 1e18, + auctionPrice: 3_228.008668236108393472 * 1e18, + debtInAuction: 21.810387715504679661 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); @@ -729,8 +729,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 1, - bondChange: 0.000000000000180719 * 1e18, - givenAmount: 0.000000000011904838 * 1e18, + bondChange: 0.000000000000128218 * 1e18, + givenAmount: 0.000000000011468190 * 1e18, collateralTaken: 1 * 1e18, isReward: true }); @@ -740,23 +740,23 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224915265 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737602246 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 50 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224915265 * 1e18, - auctionPrice: 0.000000000011904838 * 1e18, - debtInAuction: 22.734558435739539104 * 1e18, - thresholdPrice: 22.734558435739539104 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737602246 * 1e18, + auctionPrice: 0.000000000011468190 * 1e18, + debtInAuction: 21.815990418133811604 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.734558435739539104 * 1e18, + borrowerDebt: 21.815990418133811604 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 22.827635862422370438 * 1e18, - borrowerCollateralization: 0.436216294742093726 * 1e18 + borrowert0Np: 21.990359426336986406 * 1e18, + borrowerCollateralization: 0.437099323678820406 * 1e18 }); // confirm borrower cannot repay while in liquidation @@ -773,23 +773,23 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.345029692224915265 * 1e18, - bondFactor: 0.015180339887498948 * 1e18, + bondSize: 0.243847547737602246 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, kickTime: block.timestamp - 50 hours, - referencePrice: 13.089508376044532178 * 1e18, - totalBondEscrowed: 0.345029692224915265 * 1e18, - auctionPrice: 0.000000000011904838 * 1e18, - debtInAuction: 22.734558435739539104 * 1e18, - thresholdPrice: 22.734558435739539104 * 1e18, - neutralPrice: 13.089508376044532178 * 1e18 + referencePrice: 12.609408860297298412 * 1e18, + totalBondEscrowed: 0.243847547737602246 * 1e18, + auctionPrice: 0.000000000011468190 * 1e18, + debtInAuction: 21.815990418133811604 * 1e18, + debtToCollateral: 10.905193857752339830 * 1e18, + neutralPrice: 12.609408860297298412 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 22.734558435739539104 * 1e18, + borrowerDebt: 21.815990418133811604 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 22.827635862422370438 * 1e18, - borrowerCollateralization: 0.436216294742093726 * 1e18 + borrowert0Np: 21.990359426336986406 * 1e18, + borrowerCollateralization: 0.437099323678820406 * 1e18 }); // settle the auction with debt @@ -798,7 +798,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 19.819038461528240952 * 1e18 + settledDebt: 21.818209514194938031 * 1e18 }); } @@ -809,10 +809,10 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 22.728719829841718804 * 1e18, + debt: 21.810387715504679660 * 1e18, collateral: 2 * 1e18, - bond: 0.345029692224734546 * 1e18, - transferAmount: 0.345029692224734546 * 1e18 + bond: 0.243847547737474028 * 1e18, + transferAmount: 0.243847547737474028 * 1e18 }); skip(5.5 hours); @@ -839,4 +839,478 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // check address received is the address of current ajna pool assertEq(taker.poolAddressReceived(), address(_pool)); } +} + +contract ERC721PoolLiquidationsHighTakeTest is ERC721HelperContract { + + address internal _borrower; + address internal _lender; + + function setUp() external { + _startTest(); + + _borrower = makeAddr("borrower"); + _lender = makeAddr("lender"); + + // deploy subset pool + uint256[] memory subsetTokenIds = new uint256[](2); + subsetTokenIds[0] = 1; + subsetTokenIds[1] = 2; + + _pool = _deploySubsetPool(subsetTokenIds); + + _mintAndApproveQuoteTokens(_lender, 300_000_000_000 * 1e18); + _mintAndApproveQuoteTokens(_borrower, 100 * 1e18); + + _mintAndApproveCollateralTokens(_borrower, 6); + + // Lender adds Quote token accross 5 prices + _addInitialLiquidity({ + from: _lender, + amount: 1_000_000_000.0 * 1e18, + index: 1 + }); + + // first borrower adds collateral token and borrows + uint256[] memory tokenIdsToAdd = new uint256[](1); + tokenIdsToAdd[0] = 1; + + // borrower deposits one NFTs into the subset pool and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + tokenIds: tokenIdsToAdd + }); + _borrow({ + from: _borrower, + amount: 960_550_000.0 * 1e18, + indexLimit: _i9_91, + newLup: 999_969_141.897027226245329498 * 1e18 + }); + + + skip(100 days); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 974_735_101.867470788027259956 * 1e18, + borrowerCollateral: 1 * 1e18, + borrowert0Np: 1_111_728_407.735735366471916722 * 1e18, + borrowerCollateralization: 0.986430865620282143 * 1e18 + }); + } + + + function testTakeHighPrice() external tearDown { + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + _kick({ + from: _lender, + borrower: _borrower, + debt: 974_735_101.867470788027259955 * 1e18, + collateral: 1 * 1e18, + bond: 10_897_869.739154233968795067 * 1e18, + transferAmount: 10_897_869.739154233968795067 * 1e18 + }); + + skip(1 minutes); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: address(_lender), + bondSize: 10_897_869.739154233968795067 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp - 1 minutes, + referencePrice: 1_127_062_351.229373656878717077 * 1e18, + totalBondEscrowed: 10_897_869.739154233968795067 * 1e18, + auctionPrice: 278_699_640_324.071955737458053632 * 1e18, // auction price exceeds top bucket + debtInAuction: 974_735_101.867470788027259956 * 1e18, + debtToCollateral: 974_735_101.867470788027259955 * 1e18, + neutralPrice: 1_127_062_351.229373656878717077 * 1e18 + }) + ); + + // top bucket price + assertEq(1_004_968_987.606512354182109771 * 1e18, _priceAt(0)); + + _take({ + from: _lender, + borrower: _borrower, + maxCollateral: 2 * 1e18, + bondChange: 10_897_869.739154233968795067 * 1e18, + givenAmount: 991_360_820.988112939930817798 * 1e18, + collateralTaken: 1.0 * 1e18, + isReward: false + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 0, + borrowerCollateral: 0, + borrowert0Np: 0, + borrowerCollateralization: 1.0 * 1e18 + }); + + assertEq(_collateral.ownerOf(1), address(_lender)); + } + + function testTakeMultipleNFTHighPrice() external tearDown { + + _addLiquidity({ + from: _lender, + amount: 1_000_000_000.0 * 1e18, + index: 1, + lpAward: 988_807_719.662757027238723574 * 1e18, + newLup: 999_969_141.897027226245329498 * 1e18 + }); + + // first borrower adds another collateral token and borrows + uint256[] memory tokenIdsToAdd = new uint256[](1); + tokenIdsToAdd[0] = 2; + + // borrower deposits and additional NFT into the subset pool and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + tokenIds: tokenIdsToAdd + }); + + _borrow({ + from: _borrower, + amount: 947_300_000.0 * 1e18, + indexLimit: _i9_91, + newLup: 999_969_141.897027226245329498 * 1e18 + }); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 1_922_945_967.252086173079859956 * 1e18, + borrowerCollateral: 2.000000000000000000 * 1e18, + borrowert0Np: 1_096_602_376.501712863397587463 * 1e18, + borrowerCollateralization: 1.000037241461975329 * 1e18 + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + skip(1 days); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_180_947.482590772745713575 * 1e18, + exchangeRate: 1.011272786422610071 * 1e18 + }); + + _kick({ + from: _lender, + borrower: _borrower, + debt: 1_923_209_402.550975799525343720 * 1e18, + collateral: 2 * 1e18, + bond: 21_502_134.795353695767188920 * 1e18, + transferAmount: 21_502_134.795353695767188920 * 1e18 + }); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_431_041.846142986663199620 * 1e18, + exchangeRate: 1.011398540211305519 * 1e18 + }); + + skip(1 minutes); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: address(_lender), + bondSize: 21_502_134.795353695767188920 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp - 1 minutes, + referencePrice: 1_111_879_990.262346637742836677 * 1e18, + totalBondEscrowed: 21_502_134.795353695767188920 * 1e18, + auctionPrice: 274_945_350_655.745057322116218624 * 1e18, // auction price exceeds top bucket + debtInAuction: 1_923_209_402.550975799525343721 * 1e18, + debtToCollateral: 961_604_701.275487899762671860 * 1e18, + neutralPrice: 1_111_879_990.262346637742836677 * 1e18 + }) + ); + + // top bucket price + assertEq(1_004_968_987.606512354182109771 * 1e18, _priceAt(0)); + + _take({ + from: _lender, + borrower: _borrower, + maxCollateral: 1 * 1e18, + bondChange: 21_502_134.795353695767188920 * 1e18, + givenAmount: 1_956_012_919.399533852112525653 * 1e18, + collateralTaken: 1.0 * 1e18, + isReward: false + }); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_431_215.177575407462265845 * 1e18, + exchangeRate: 1.011398627366745639 * 1e18 + }); + + assertEq(_collateral.ownerOf(1), address(_pool)); + assertEq(_collateral.ownerOf(2), address(_lender)); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 0, + borrowerCollateral: 1 * 1e18, + borrowert0Np: 0, + borrowerCollateralization: 1.0 * 1e18 + }); + + } + + function testLenderKickTakeHighPrice() external tearDown { + + _addLiquidity({ + from: _lender, + amount: 1_000_000_000.0 * 1e18, + index: 1, + lpAward: 988_807_719.662757027238723574 * 1e18, + newLup: 999_969_141.897027226245329498 * 1e18 + }); + + // first borrower adds another collateral token and borrows + uint256[] memory tokenIdsToAdd = new uint256[](1); + tokenIdsToAdd[0] = 2; + + // borrower deposits two NFTs into the subset pool and borrows + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + tokenIds: tokenIdsToAdd + }); + _borrow({ + from: _borrower, + amount: 947_300_000.0 * 1e18, + indexLimit: _i9_91, + newLup: 999_969_141.897027226245329498 * 1e18 + }); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 1_922_945_967.252086173079859956 * 1e18, + borrowerCollateral: 2.000000000000000000 * 1e18, + borrowert0Np: 1_096_602_376.501712863397587463 * 1e18, + borrowerCollateralization: 1.000037241461975329 * 1e18 + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + skip(1 days); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_180_947.482590772745713575 * 1e18, + exchangeRate: 1.011272786422610071 * 1e18 + }); + + _assertLenderLpBalance({ + lender: _lender, + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + depositTime: block.timestamp - 1 days + }); + + _lenderKick({ + from: _lender, + index: 1, + borrower: _borrower, + debt: 1_923_209_402.550975799525343720 * 1e18, + collateral: 2.00000000000000000 * 1e18, + bond: 21_502_134.795353695767188920 * 1e18 + }); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_431_041.846142986663199620 * 1e18, + exchangeRate: 1.011398540211305519 * 1e18 + }); + + _assertLenderLpBalance({ + lender: _lender, + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + depositTime: block.timestamp - 1 days + }); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 1_923_209_402.550975799525343721 * 1e18, + borrowerCollateral: 2.0 * 1e18, + borrowert0Np: 1_096_602_376.501712863397587463 * 1e18, + borrowerCollateralization: 0.999900259441579706 * 1e18 + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: _lender, + bondSize: 21_502_134.795353695767188920 * 1e18, + bondFactor: 0.011180339887498948 * 1e18, + kickTime: block.timestamp, + referencePrice: 1111879990.262346637742836677 * 1e18, + totalBondEscrowed: 21_502_134.795353695767188920 * 1e18, + auctionPrice: 284_641_277_507.160739262166189312 * 1e18, // auction price exceeds top bucket + debtInAuction: 1_923_209_402.550975799525343721 * 1e18, + debtToCollateral: 961_604_701.275487899762671860 * 1e18, + neutralPrice: 1111879990.262346637742836677 * 1e18 + }) + ); + + // top bucket price + assertEq(1_004_968_987.606512354182109771 * 1e18, _priceAt(0)); + + skip(1 minutes); + + _take({ + from: _lender, + borrower: _borrower, + maxCollateral: 2 * 1e18, + bondChange: 21_502_134.795353695767188920 * 1e18, + givenAmount: 1_956_012_919.399533852112525653 * 1e18, + collateralTaken: 1.0 * 1e18, + isReward: false + }); + + assertEq(_collateral.ownerOf(1), address(_pool)); + assertEq(_collateral.ownerOf(2), address(_lender)); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 0, + auctionPrice: 0, + debtInAuction: 0, + debtToCollateral: 0, + neutralPrice: 0 + }) + ); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 0, + borrowerCollateral: 1.0 * 1e18, + borrowert0Np: 0, + borrowerCollateralization: 1.0 * 1e18 + }); + + _assertBucket({ + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + collateral: 0, + deposit: 2_011_431_215.177575407462265845 * 1e18, + exchangeRate: 1.011398627366745639 * 1e18 + }); + + _assertLenderLpBalance({ + lender: _lender, + index: 1, + lpBalance: 1_988_762_057.562300406238723574 * 1e18, + depositTime: block.timestamp - 1 days - 1 minutes + }); + } } \ No newline at end of file diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolPurchaseQuote.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolPurchaseQuote.t.sol index 5091d3965..e43ab9663 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolPurchaseQuote.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolPurchaseQuote.t.sol @@ -43,7 +43,7 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { _mintAndApproveCollateralTokens(_bidder, 13); } - function testSubsetPurchaseQuote() external tearDown { + function testSubsetPurchaseQuoteWithoutDebt() external tearDown { // test setup uint256 testIndex = 2550; uint256 _priceAtTestIndex = _priceAt(testIndex); @@ -75,9 +75,9 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { // check bucket state _assertBucket({ index: testIndex, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: 0, - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -99,9 +99,9 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { // check bucket state _assertBucket({ index: testIndex, - lpBalance: 19_032.676066593644673535 * 1e18, + lpBalance: 19_032.219445589078463535 * 1e18, collateral: Maths.wad(3), - deposit: 10_000 * 1e18, + deposit: 9_999.543378995433790000 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ @@ -119,10 +119,7 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { assertEq(_quote.balanceOf(_bidder), 0); // bidder removes quote token from bucket - skip(1 days); // skip to avoid penalty - uint256 qtToRemove = Maths.wmul(_priceAtTestIndex, 3 * 1e18); - _removeAllLiquidity({ from: _bidder, amount: qtToRemove, @@ -135,9 +132,9 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { _assertBucket({ index: testIndex, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, collateral: Maths.wad(3), - deposit: 967.323933406355326465 * 1e18, + deposit: 966.867312401789116465 * 1e18, exchangeRate: 1 * 1e18 }); _assertLenderLpBalance({ @@ -157,19 +154,19 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { _assertBucket({ index: testIndex, - lpBalance: 967.323933406355326465 * 1e18, + lpBalance: 966.867312401789116465 * 1e18, collateral: 0, - deposit: 967.323933406355326465 * 1e18, + deposit: 966.867312401789116465 * 1e18, exchangeRate: 1 * 1e18 }); // lender removes remaining quote token to empty the bucket _removeAllLiquidity({ from: _lender, - amount: 967.323933406355326465 * 1e18, + amount: 966.867312401789116465 * 1e18, index: testIndex, newLup: _lup(), - lpRedeem: 967.323933406355326465 * 1e18 + lpRedeem: 966.867312401789116465 * 1e18 }); _assertBucket({ @@ -239,14 +236,14 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { assertEq(_lup(), _priceAt(2351)); - skip(86400); + skip(1 days); // check bucket state _assertBucket({ index: 2350, - lpBalance: 24_000 * 1e18, + lpBalance: 23_998.904109589041096000 * 1e18, collateral: 0, - deposit: 24_000 * 1e18, + deposit: 23_998.904109589041096000 * 1e18, exchangeRate: 1 * 1e18 }); @@ -259,23 +256,21 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { uint256 amountToPurchase = 10_100 * 1e18; assertGt(_quote.balanceOf(address(_pool)), amountToPurchase); - uint256 amountWithInterest = 24_002.693295339317544000 * 1e18; + uint256 amountWithInterest = 24_000.274264292017267014 * 1e18; _addCollateral({ from: _bidder, tokenIds: tokenIdsToAdd, index: 2350, - lpAward: 32_654.476857047354370624 * 1e18 + lpAward: 32_654.476771923355611910 * 1e18 }); - skip(25 hours); // remove liquidity after one day to avoid early withdraw penalty - _removeAllLiquidity({ from: _bidder, amount: amountWithInterest, index: 2350, newLup: _priceAt(2352), - lpRedeem: 24_000.762569742914919828 * 1e18 + lpRedeem: 23_998.904109589041096000 * 1e18 }); assertEq(_quote.balanceOf(_bidder), amountWithInterest); @@ -283,10 +278,10 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { // check bucket state _assertBucket({ index: 2350, - lpBalance: 32_653.714287304439450796 * 1e18, + lpBalance: 32_654.476771923355611910 * 1e18, collateral: Maths.wad(4), deposit: 0, - exchangeRate: 1.000080444343832502 * 1e18 + exchangeRate: 1.000057092386248951 * 1e18 }); // bidder withdraws unused collateral @@ -294,17 +289,17 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { from: _bidder, amount: 1, index: 2350, - lpRedeem: 8_163.428571826109862699 * 1e18 + lpRedeem: 8_163.619192980838902978 * 1e18 }); _assertLenderLpBalance({ lender: _bidder, index: 2350, - lpBalance: 490.285715478329588097 * 1e18, + lpBalance: 491.953469353475612932 * 1e18, depositTime: _startTime + 25 hours }); - skip(7200); + skip(2 hours); changePrank(_lender); // lender exchanges their lp for collateral @@ -312,25 +307,25 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { from: _lender, amount: 1, index: 2350, - lpRedeem: 8_163.428571826109862699 * 1e18 + lpRedeem: 8_163.619192980838902978 * 1e18 }); _assertLenderLpBalance({ lender: _bidder, index: 2350, - lpBalance: 490.285715478329588097 * 1e18, + lpBalance: 491.953469353475612932 * 1e18, depositTime: _startTime + 25 hours }); - skip(3600); + skip(1 hours); // check bucket state _assertBucket({ index: 2350, - lpBalance: 16_326.857143652219725398 * 1e18, + lpBalance: 16_327.238385961677805954 * 1e18, collateral: Maths.wad(2), deposit: 0, - exchangeRate: 1.000080444343832502 * 1e18 + exchangeRate: 1.000057092386248951 * 1e18 }); // should revert if lender2 attempts to remove more collateral than lp is available for @@ -340,6 +335,6 @@ contract ERC721PoolPurchaseQuoteTest is ERC721HelperContract { index: 2350 }); - skip(3600); + skip(1 hours); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol index 9e579ef35..ecce34a81 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol @@ -60,11 +60,11 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { assertEq(poolDebt - 175_000 * 1e18, 4_590.373946590638353626 * 1e18); // debt matches develop } - function testClaimableReserveNoAuction() external { + function testClaimableReserveNoAuction() external tearDown { // ensure empty state is returned _assertReserveAuction({ - reserves: 168.26923076923085 * 1e18, - claimableReserves : 0, + reserves: 177.401650860555050000 * 1e18, + claimableReserves : 177.401450869687470091 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -76,31 +76,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); } - function testUnclaimableReserves() external { - // borrower repays partial debt, ensure cannot kick when there are no claimable reserves - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 5_000 * 1e18, - amountRepaid: 5_000 * 1e18, - collateralToPull: 0, - newLup: 251_183.992399245533703810 * 1e18 - }); - - _assertReserveAuction({ - reserves: 831.584938142442153626 * 1e18, - claimableReserves : 0, - claimableReservesRemaining: 0, - auctionPrice: 0, - timeRemaining: 0 - }); - - changePrank(_bidder); - - _assertTakeReservesNoReservesRevert(); - } - - function testReserveAuctionPricing() external { + function testReserveAuctionPricing() external tearDown { // borrower repays all debt (auction for full reserves) _repayDebt({ from: _borrower, @@ -112,8 +88,8 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); _assertReserveAuction({ - reserves: 831.584938142442153626 * 1e18, - claimableReserves : 831.584734383653145178 * 1e18, + reserves: 840.717358233766377865 * 1e18, + claimableReserves : 840.717154484109789508 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -122,64 +98,43 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 831.584734383653145178 * 1e18, - price: 1_000_000_000 * 1e18, + remainingReserves: 840.717154484109789508 * 1e18, + price: 1_189_460.682069263974570223 * 1e18, epoch: 1 }); - _assertReserveAuctionPrice(1_000_000_000 * 1e18); + _assertReserveAuctionPrice(1_189_460.682069263974570223 * 1e18); // check prices skip(37 minutes); - _assertReserveAuctionPrice(652176034.882782126826643053 * 1e18); + _assertReserveAuctionPrice(775_737.751280902122928059 * 1e18); skip(23 hours); // 23 hours 37 minutes - _assertReserveAuctionPrice(77.745441780421987394 * 1e18); + _assertReserveAuctionPrice(0.092475146207916989 * 1e18); skip(1400); // 24 hours 0 minutes 20 seconds - _assertReserveAuctionPrice(59.604644775390625 * 1e18); + _assertReserveAuctionPrice(0.070897381429032324 * 1e18); skip(100); // 24 hours 2 minutes - _assertReserveAuctionPrice(58.243272807255146201 * 1e18); + _assertReserveAuctionPrice(0.069278082999263921 * 1e18); skip(58 minutes); // 25 hours - _assertReserveAuctionPrice(29.8023223876953125 * 1e18); + _assertReserveAuctionPrice(0.035448690714516162 * 1e18); skip(5 hours); // 30 hours - _assertReserveAuctionPrice(0.931322574615478515 * 1e18); - - skip(121 minutes); // 32 hours 1 minute - _assertReserveAuctionPrice(0.230156355619639189 * 1e18); - - skip(7700 seconds); // 34 hours 9 minutes 20 seconds - _assertReserveAuctionPrice(0.052459681325756842 * 1e18); - - skip(8 hours); // 42 hours 9 minutes 20 seconds - _assertReserveAuctionPrice(0.000204920630178738 * 1e18); + _assertReserveAuctionPrice(0.00110777158482863 * 1e18); - skip(6 hours); // 42 hours 9 minutes 20 seconds - _assertReserveAuctionPrice(0.000003201884846542 * 1e18); + skip(6 hours); // 36 hours + _assertReserveAuctionPrice(0.000017308931012947 * 1e18); - skip(3100 seconds); // 43 hours - _assertReserveAuctionPrice(0.000001755953640897 * 1e18); + skip(12 hours); // 48 hours + _assertReserveAuctionPrice(0.000000004225813235 * 1e18); - skip(5 hours); // 48 hours - _assertReserveAuctionPrice(0.000000054873551278 * 1e18); - - skip(12 hours); // 60 hours - _assertReserveAuctionPrice(0.000000000013396863 * 1e18); - - skip(11 hours); // 71 hours - _assertReserveAuctionPrice(0.000000000000006541 * 1e18); - - skip(3599 seconds); // 71 hours 59 minutes 59 seconds - _assertReserveAuctionPrice(0.000000000000003308 * 1e18); - - skip(1 seconds); // 72 hours - _assertReserveAuctionPrice(0.000000000000003270 * 1e18); + skip(24 hours); // 72 hours + _assertReserveAuctionPrice(0.000000000000000251 * 1e18); } - function testReserveAuctionTiming() external { + function testReserveAuctionTiming() external tearDown { // borrower repays all debt (auction for full reserves) _repayDebt({ from: _borrower, @@ -193,8 +148,8 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 831.584734383653145178 * 1e18, - price: 1_000_000_000 * 1e18, + remainingReserves: 840.717154484109789508 * 1e18, + price: 1_189_460.682069263974570223 * 1e18, epoch: 1 }); @@ -204,9 +159,9 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // check that you can't start a new auction if a previous auction is active _assertReserveAuctionTooSoon(); - (, uint256 unclaimed, , ) = _pool.reservesInfo(); + (, uint256 unclaimed, , ,) = _pool.reservesInfo(); - uint256 expectedPrice = 59.604644775390625 * 1e18; + uint256 expectedPrice = 0.070897381429032324 * 1e18; _takeReserves({ from: _bidder, amount: Maths.wdiv(unclaimed, Maths.wad(2)), @@ -218,11 +173,24 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // pass time to allow auction to complete skip(48 hours); - // check that you can't start a new auction unless two weeks have passed + // check that you can't start a new auction immediately after the last one finished... + _assertReserveAuctionTooSoon(); + + // ...or a day later... + skip(24 hours); _assertReserveAuctionTooSoon(); + + // ...but you can start another auction five days after the last one was kicked + skip(24 hours); + _kickReserveAuction({ + from: _bidder, + remainingReserves: 420.358577242054894754 * 1e18, + price: 2_378_921.364138527949140447 * 1e18, + epoch: 2 + }); } - function testClaimableReserveAuction() external { + function testClaimableReserveAuction() external tearDown { // borrower repays all debt (auction for full reserves) _repayDebt({ from: _borrower, @@ -235,8 +203,8 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { (uint256 debt,,,) = _pool.debtInfo(); assertEq(debt, 0); - uint256 reserves = 831.584938142442153626 * 1e18; - uint256 claimableReserves = 831.584734383653145178 * 1e18; + uint256 reserves = 840.717358233766377865 * 1e18; + uint256 claimableReserves = 840.717154484109789508 * 1e18; uint256 expectedReserves = claimableReserves; _assertReserveAuction({ reserves: reserves, @@ -247,17 +215,17 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); // kick off a new auction - uint256 expectedPrice = 1_000_000_000 * 1e18; + uint256 expectedPrice = 1_189_460.682069263974570223 * 1e18; uint256 expectedQuoteBalance = _quote.balanceOf(_bidder); - _kickReserveAuction({ from: _bidder, remainingReserves: expectedReserves, price: expectedPrice, epoch: 1 }); + reserves = 0.000203749656588357 * 1e18; _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, @@ -266,47 +234,45 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { assertEq(_quote.balanceOf(_bidder), expectedQuoteBalance); // bid once the price becomes attractive - skip(24 hours); - expectedPrice = 59.604644775390625 * 1e18; + skip(16 hours); + expectedPrice = 18.149729645832275002 * 1e18; _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, - claimableReservesRemaining: 831.584734383653145178 * 1e18, + claimableReservesRemaining: 840.717154484109789508 * 1e18, auctionPrice: expectedPrice, - timeRemaining: 2 days + timeRemaining: 72 hours - 16 hours }); - _takeReserves({ from: _bidder, amount: 300 * 1e18, - remainingReserves: 531.584734383653145178 * 1e18, + remainingReserves: 540.717154484109789508 * 1e18, price: expectedPrice, epoch: 1 }); expectedQuoteBalance += 300 * 1e18; assertEq(_quote.balanceOf(_bidder), expectedQuoteBalance); - assertEq(_ajnaToken.balanceOf(_bidder), 62_118.606567382812500000 * 1e18); + assertEq(_ajnaToken.balanceOf(_bidder), 74_555.081106250317499400 * 1e18); expectedReserves -= 300 * 1e18; _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, - timeRemaining: 2 days + timeRemaining: 72 hours - 16 hours }); // bid max amount skip(5 minutes); - expectedPrice = 56.259293120008319416 * 1e18; + expectedPrice = 17.131063594818494900 * 1e18; _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, - timeRemaining: 2875 minutes + timeRemaining: 72 hours - 16 hours - 5 minutes }); - _takeReserves({ from: _bidder, amount: 600 * 1e18, @@ -316,15 +282,15 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); expectedQuoteBalance += expectedReserves; assertEq(_quote.balanceOf(_bidder), expectedQuoteBalance); - assertEq(_ajnaToken.balanceOf(_bidder), 32_212.025177571105194476 * 1e18); + assertEq(_ajnaToken.balanceOf(_bidder), 65_292.021145973736199572 * 1e18); expectedReserves = 0; _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, - timeRemaining: 2875 minutes + timeRemaining: 72 hours - 16 hours - 5 minutes }); // ensure take reverts after auction ends @@ -334,8 +300,12 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { amount: 777 * 1e18 }); + // ensure auction cannot be kicked when no reserves are claimable + skip(5 days); + _assertKickReservesNoReservesRevert(); + _assertReserveAuction({ - reserves: 0.000203758789008448 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, @@ -353,8 +323,8 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { collateralToPull: 0, newLup: 251_183.992399245533703810 * 1e18 }); - uint256 reserves = 831.584938142442153626 * 1e18; - uint256 claimableReserves = 433.632864650699953410 * 1e18; + uint256 reserves = 840.717358233766377865 * 1e18; + uint256 claimableReserves = 840.717154484109789508 * 1e18; _assertReserveAuction({ reserves: reserves, claimableReserves : claimableReserves, @@ -364,16 +334,15 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); // kick off a new auction - uint256 expectedPrice = 1_000_000_000 * 1e18; + uint256 expectedPrice = 1_189_460.682069263974570223 * 1e18; uint256 expectedReserves = claimableReserves; - _kickReserveAuction({ from: _bidder, remainingReserves: expectedReserves, price: expectedPrice, epoch: 1 }); - reserves = 397.952073491742200216 * 1e18; + reserves = 0.000203749656588357 * 1e18; claimableReserves = 0; _assertReserveAuction({ reserves: reserves, @@ -385,8 +354,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // partial take skip(1 days); - - expectedPrice = 59.604644775390625 * 1e18; + expectedPrice = 0.070897381429032324 * 1e18; expectedReserves -= 100 * 1e18; _takeReserves({ from: _bidder, @@ -407,7 +375,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { skip(3 days); expectedPrice = 0; _assertReserveAuction({ - reserves: 397.952073491742200216 * 1e18, + reserves: reserves, claimableReserves : 0, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, @@ -430,8 +398,8 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // start an auction, confirm old claimable reserves are included alongside new claimable reserves skip(1 days); - reserves = 426.740068998777899912 * 1e18; - uint256 newClaimableReserves = 426.739864884071882914 * 1e18; + reserves = 28.785107815609080430 * 1e18; + uint256 newClaimableReserves = 28.784903710032392082 * 1e18; _assertReserveAuction({ reserves: reserves, claimableReserves : newClaimableReserves, @@ -439,7 +407,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { auctionPrice: expectedPrice, timeRemaining: 0 }); - expectedPrice = 1_000_000_000 * 1e18; + expectedPrice = 1_299_541.683289044748128697 * 1e18; expectedReserves += newClaimableReserves; _kickReserveAuction({ from: _bidder, @@ -453,15 +421,17 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { _pool.removeQuoteToken(type(uint256).max, 1663); // ensure entire reserves can still be taken - skip(28 hours); - assertEq(expectedReserves, 760.372729534771836324 * 1e18); - expectedPrice = 3.725290298461914062 * 1e18; + skip(18 hours); + reserves = 0.000204105576599248 * 1e18; + newClaimableReserves = 0.000204105576599248 * 1e18; + assertEq(expectedReserves, 769.502058194142181590 * 1e18); + expectedPrice = 4.957358105808428757 * 1e18; _assertReserveAuction({ - reserves: 0.000204114705960104 * 1e18, - claimableReserves : 0.000204114705960104 * 1e18, + reserves: reserves, + claimableReserves : newClaimableReserves, claimableReservesRemaining: expectedReserves, auctionPrice: expectedPrice, - timeRemaining: 44 hours + timeRemaining: 72 hours - 18 hours }); _takeReserves({ from: _bidder, @@ -472,12 +442,11 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); _assertReserveAuction({ - reserves: 0.000204114705960104 * 1e18, - claimableReserves : 0.000204114705960104 * 1e18, + reserves: reserves, + claimableReserves : newClaimableReserves, claimableReservesRemaining: 0, auctionPrice: expectedPrice, - timeRemaining: 44 hours + timeRemaining: 72 hours - 18 hours }); - } } diff --git a/tests/forge/unit/FenwickTree.t.sol b/tests/forge/unit/FenwickTree.t.sol index 84e50c96d..559fc8f78 100644 --- a/tests/forge/unit/FenwickTree.t.sol +++ b/tests/forge/unit/FenwickTree.t.sol @@ -152,6 +152,24 @@ contract FenwickTreeTest is DSTestPlus { assertEq(_tree.valueAt(3_700), 0); } + function testFenwickOutOfBoundsBehavior() external { + uint depositAmount = 3 * 1e18; + + // set up a tree with 100 deposit in each bucket + for (uint256 i; i < MAX_FENWICK_INDEX; i++) { + _tree.add(i, depositAmount); + } + + // try sum of bottom bucket + assertEq(_tree.prefixSum(0), depositAmount); + assertEq(_tree.prefixSum(1), 2 * depositAmount); + + // try a prefixSum above SIZE + assertEq(_tree.prefixSum(MAX_INDEX + 1), depositAmount * MAX_FENWICK_INDEX); + // CAUTION: this will cause infinite loop + // assertEq(_tree.prefixSum(8192 + 1), depositAmount * MAX_FENWICK_INDEX); + } + /** * @notice Fuzz tests additions and scaling values, testing findSum. */ diff --git a/tests/forge/unit/Heap.t.sol b/tests/forge/unit/Heap.t.sol index d792de2ec..939a3fd93 100644 --- a/tests/forge/unit/Heap.t.sol +++ b/tests/forge/unit/Heap.t.sol @@ -14,7 +14,7 @@ contract HeapTest is DSTestPlus { function testHeapInsertAndRandomlyRemoveTps() public { // assert initial state assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); address b1 = makeAddr("b1"); address b2 = makeAddr("b2"); @@ -22,46 +22,46 @@ contract HeapTest is DSTestPlus { address b4 = makeAddr("b4"); address b5 = makeAddr("b5"); - _loans.upsertTp(b1, 100 * 1e18); - _loans.upsertTp(b5, 500 * 1e18); - _loans.upsertTp(b2, 200 * 1e18); - _loans.upsertTp(b4, 400 * 1e18); - _loans.upsertTp(b3, 300 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 100 * 1e18); + _loans.upsertT0DebtToCollateral(b5, 500 * 1e18); + _loans.upsertT0DebtToCollateral(b2, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b3, 300 * 1e18); - assertEq(_loans.getMaxTp(), 500 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 500 * 1e18); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getTotalTps(), 6); + assertEq(_loans.getTotalT0DebtToCollaterals(), 6); - _loans.removeTp(b2); - assertEq(_loans.getMaxTp(), 500 * 1e18); + _loans.removeT0DebtToCollateral(b2); + assertEq(_loans.getMaxT0DebtToCollateral(), 500 * 1e18); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getTotalTps(), 5); + assertEq(_loans.getTotalT0DebtToCollaterals(), 5); - _loans.removeTp(b5); - assertEq(_loans.getMaxTp(), 400 * 1e18); + _loans.removeT0DebtToCollateral(b5); + assertEq(_loans.getMaxT0DebtToCollateral(), 400 * 1e18); assertEq(_loans.getMaxBorrower(), b4); - assertEq(_loans.getTotalTps(), 4); + assertEq(_loans.getTotalT0DebtToCollaterals(), 4); - _loans.removeTp(b4); + _loans.removeT0DebtToCollateral(b4); assertEq(_loans.getMaxBorrower(), b3); - assertEq(_loans.getMaxTp(), 300 * 1e18); - assertEq(_loans.getTotalTps(), 3); + assertEq(_loans.getMaxT0DebtToCollateral(), 300 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 3); - _loans.removeTp(b1); + _loans.removeT0DebtToCollateral(b1); assertEq(_loans.getMaxBorrower(), b3); - assertEq(_loans.getMaxTp(), 300 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 300 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); - _loans.removeTp(b3); + _loans.removeT0DebtToCollateral(b3); assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); } function testHeapInsertMultipleLoansWithSameTp() public { // assert initial state assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); address b1 = makeAddr("b1"); address b2 = makeAddr("b2"); @@ -70,64 +70,64 @@ contract HeapTest is DSTestPlus { address b5 = makeAddr("b5"); address b6 = makeAddr("b6"); - _loans.upsertTp(b1, 100 * 1e18); - _loans.upsertTp(b2, 200 * 1e18); - _loans.upsertTp(b3, 200 * 1e18); - _loans.upsertTp(b4, 300 * 1e18); - _loans.upsertTp(b5, 400 * 1e18); - _loans.upsertTp(b6, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 100 * 1e18); + _loans.upsertT0DebtToCollateral(b2, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b3, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 300 * 1e18); + _loans.upsertT0DebtToCollateral(b5, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b6, 400 * 1e18); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getMaxTp(), 400 * 1e18); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getMaxT0DebtToCollateral(), 400 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - assertEq(_loans.getTp(b1), 100 * 1e18); - assertEq(_loans.getTp(b2), 200 * 1e18); - assertEq(_loans.getTp(b3), 200 * 1e18); - assertEq(_loans.getTp(b4), 300 * 1e18); - assertEq(_loans.getTp(b5), 400 * 1e18); - assertEq(_loans.getTp(b6), 400 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b1), 100 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b2), 200 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b3), 200 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b4), 300 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b5), 400 * 1e18); + assertEq(_loans.getT0DebtToCollateral(b6), 400 * 1e18); - _loans.removeTp(b5); + _loans.removeT0DebtToCollateral(b5); assertEq(_loans.getMaxBorrower(), b6); - assertEq(_loans.getMaxTp(), 400 * 1e18); - assertEq(_loans.getTotalTps(), 6); + assertEq(_loans.getMaxT0DebtToCollateral(), 400 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 6); - _loans.removeTp(b6); + _loans.removeT0DebtToCollateral(b6); assertEq(_loans.getMaxBorrower(), b4); - assertEq(_loans.getMaxTp(), 300 * 1e18); - assertEq(_loans.getTotalTps(), 5); + assertEq(_loans.getMaxT0DebtToCollateral(), 300 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 5); - _loans.removeTp(b4); + _loans.removeT0DebtToCollateral(b4); assertEq(_loans.getMaxBorrower(), b2); - assertEq(_loans.getMaxTp(), 200 * 1e18); - assertEq(_loans.getTotalTps(), 4); + assertEq(_loans.getMaxT0DebtToCollateral(), 200 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 4); - _loans.upsertTp(b1, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 200 * 1e18); assertEq(_loans.getMaxBorrower(), b2); - assertEq(_loans.getMaxTp(), 200 * 1e18); - assertEq(_loans.getTotalTps(), 4); + assertEq(_loans.getMaxT0DebtToCollateral(), 200 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 4); - _loans.removeTp(b2); + _loans.removeT0DebtToCollateral(b2); assertEq(_loans.getMaxBorrower(), b3); - assertEq(_loans.getMaxTp(), 200 * 1e18); - assertEq(_loans.getTotalTps(), 3); + assertEq(_loans.getMaxT0DebtToCollateral(), 200 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 3); - _loans.removeTp(b3); + _loans.removeT0DebtToCollateral(b3); assertEq(_loans.getMaxBorrower(), b1); - assertEq(_loans.getMaxTp(), 200 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 200 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); - _loans.removeTp(b1); + _loans.removeT0DebtToCollateral(b1); assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); } function testHeapInsertAndRemoveHeadByMaxTp() public { // assert initial state assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); address b1 = makeAddr("b1"); address b2 = makeAddr("b2"); @@ -135,60 +135,60 @@ contract HeapTest is DSTestPlus { address b4 = makeAddr("b4"); address b5 = makeAddr("b5"); - _loans.upsertTp(b1, 100 * 1e18); - _loans.upsertTp(b2, 200 * 1e18); - _loans.upsertTp(b3, 300 * 1e18); - _loans.upsertTp(b4, 400 * 1e18); - _loans.upsertTp(b5, 500 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 100 * 1e18); + _loans.upsertT0DebtToCollateral(b2, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b3, 300 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b5, 500 * 1e18); - assertEq(_loans.getMaxTp(), 500 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 500 * 1e18); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getTotalTps(), 6); + assertEq(_loans.getTotalT0DebtToCollaterals(), 6); - _loans.removeTp(b5); - assertEq(_loans.getMaxTp(), 400 * 1e18); + _loans.removeT0DebtToCollateral(b5); + assertEq(_loans.getMaxT0DebtToCollateral(), 400 * 1e18); assertEq(_loans.getMaxBorrower(), b4); - assertEq(_loans.getTotalTps(), 5); + assertEq(_loans.getTotalT0DebtToCollaterals(), 5); - _loans.removeTp(b4); + _loans.removeT0DebtToCollateral(b4); assertEq(_loans.getMaxBorrower(), b3); - assertEq(_loans.getMaxTp(), 300 * 1e18); - assertEq(_loans.getTotalTps(), 4); + assertEq(_loans.getMaxT0DebtToCollateral(), 300 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 4); - _loans.removeTp(b3); + _loans.removeT0DebtToCollateral(b3); assertEq(_loans.getMaxBorrower(), b2); - assertEq(_loans.getMaxTp(), 200 * 1e18); - assertEq(_loans.getTotalTps(), 3); + assertEq(_loans.getMaxT0DebtToCollateral(), 200 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 3); - _loans.removeTp(b2); + _loans.removeT0DebtToCollateral(b2); assertEq(_loans.getMaxBorrower(), b1); - assertEq(_loans.getMaxTp(), 100 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 100 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); - _loans.removeTp(b1); + _loans.removeT0DebtToCollateral(b1); assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); } function testHeapRemoveLastTp() public { // assert initial state assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); address b1 = makeAddr("b1"); - _loans.upsertTp(b1, 100 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 100 * 1e18); assertEq(_loans.getMaxBorrower(), b1); - assertEq(_loans.getMaxTp(), 100 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 100 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); // remove last TP - _loans.removeTp(b1); + _loans.removeT0DebtToCollateral(b1); assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); } function testHeapUpdateTp() public { @@ -199,36 +199,72 @@ contract HeapTest is DSTestPlus { address b5 = makeAddr("b5"); address b6 = makeAddr("b6"); - _loans.upsertTp(b1, 100 * 1e18); - _loans.upsertTp(b2, 200 * 1e18); - _loans.upsertTp(b3, 300 * 1e18); - _loans.upsertTp(b4, 400 * 1e18); - _loans.upsertTp(b5, 500 * 1e18); - _loans.upsertTp(b6, 600 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 100 * 1e18); + _loans.upsertT0DebtToCollateral(b2, 200 * 1e18); + _loans.upsertT0DebtToCollateral(b3, 300 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b5, 500 * 1e18); + _loans.upsertT0DebtToCollateral(b6, 600 * 1e18); - assertEq(_loans.getMaxTp(), 600 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 600 * 1e18); assertEq(_loans.getMaxBorrower(), b6); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - _loans.upsertTp(b4, 1_000 * 1e18); - assertEq(_loans.getMaxTp(), 1_000 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 1_000 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 1_000 * 1e18); assertEq(_loans.getMaxBorrower(), b4); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - _loans.upsertTp(b4, 10 * 1e18); - assertEq(_loans.getMaxTp(), 600 * 1e18); + _loans.upsertT0DebtToCollateral(b4, 10 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 600 * 1e18); assertEq(_loans.getMaxBorrower(), b6); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - _loans.upsertTp(b6, 100 * 1e18); - assertEq(_loans.getMaxTp(), 500 * 1e18); + _loans.upsertT0DebtToCollateral(b6, 100 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 500 * 1e18); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - _loans.upsertTp(b6, 3_000 * 1e18); - assertEq(_loans.getMaxTp(), 3_000 * 1e18); + _loans.upsertT0DebtToCollateral(b6, 3_000 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 3_000 * 1e18); assertEq(_loans.getMaxBorrower(), b6); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); + } + + function testHeapZeroInsertion() public { + address b1 = makeAddr("b1"); + address b2 = makeAddr("b2"); + address b3 = makeAddr("b3"); + + _loans.upsertT0DebtToCollateral(b1, 0); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getMaxBorrower(), b1); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); + + _loans.upsertT0DebtToCollateral(b2, 153 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 153 * 1e18); + assertEq(_loans.getMaxBorrower(), b2); + assertEq(_loans.getTotalT0DebtToCollaterals(), 3); + + _loans.removeT0DebtToCollateral(b2); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getMaxBorrower(), b1); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); + + _loans.upsertT0DebtToCollateral(b3, 2_007 * 1e18); + assertEq(_loans.getMaxT0DebtToCollateral(), 2_007 * 1e18); + assertEq(_loans.getMaxBorrower(), b3); + assertEq(_loans.getTotalT0DebtToCollaterals(), 3); + + _loans.removeT0DebtToCollateral(b1); + assertEq(_loans.getMaxT0DebtToCollateral(), 2_007 * 1e18); + assertEq(_loans.getMaxBorrower(), b3); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); + + _loans.removeT0DebtToCollateral(b3); + assertEq(_loans.getMaxBorrower(), address(0)); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); } function testLoadHeapFuzzy(uint256 inserts_, uint256 seed_) public { @@ -238,33 +274,33 @@ contract HeapTest is DSTestPlus { // test adding different TPs address removeAddress = _loans.getIdByInsertIndex(randomInRange(1, _loans.numInserts() - 1, true)); - uint256 tp = _loans.getTp(removeAddress); + uint256 tp = _loans.getT0DebtToCollateral(removeAddress); uint256 length = _loans.getCount() - 1; - _loans.removeTp(removeAddress); + _loans.removeT0DebtToCollateral(removeAddress); assertEq(length - 1, _loans.getCount() - 1); - assertEq(_loans.getTp(removeAddress), 0); - assertTrue(_loans.getTp(removeAddress) != tp); + assertEq(_loans.getT0DebtToCollateral(removeAddress), 0); + assertTrue(_loans.getT0DebtToCollateral(removeAddress) != tp); } function testHeapBorrowRepayBorrow() public { address b1 = makeAddr("b1"); - _loans.upsertTp(b1, 300 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 300 * 1e18); assertEq(_loans.getMaxBorrower(), b1); - assertEq(_loans.getMaxTp(), 300 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 300 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); - _loans.removeTp(b1); + _loans.removeT0DebtToCollateral(b1); assertEq(_loans.getMaxBorrower(), address(0)); - assertEq(_loans.getMaxTp(), 0); - assertEq(_loans.getTotalTps(), 1); + assertEq(_loans.getMaxT0DebtToCollateral(), 0); + assertEq(_loans.getTotalT0DebtToCollaterals(), 1); - _loans.upsertTp(b1, 400 * 1e18); + _loans.upsertT0DebtToCollateral(b1, 400 * 1e18); assertEq(_loans.getMaxBorrower(), b1); - assertEq(_loans.getMaxTp(), 400 * 1e18); - assertEq(_loans.getTotalTps(), 2); + assertEq(_loans.getMaxT0DebtToCollateral(), 400 * 1e18); + assertEq(_loans.getTotalT0DebtToCollaterals(), 2); } function testHeapRemoveMiddleAndHead() public { @@ -276,31 +312,31 @@ contract HeapTest is DSTestPlus { address b6 = makeAddr("b6"); address b7 = makeAddr("b7"); - _loans.upsertTp(b7, 7); - _loans.upsertTp(b4, 4); - _loans.upsertTp(b6, 6); - _loans.upsertTp(b2, 2); - _loans.upsertTp(b3, 3); - _loans.upsertTp(b1, 1); - _loans.upsertTp(b5, 5); + _loans.upsertT0DebtToCollateral(b7, 7); + _loans.upsertT0DebtToCollateral(b4, 4); + _loans.upsertT0DebtToCollateral(b6, 6); + _loans.upsertT0DebtToCollateral(b2, 2); + _loans.upsertT0DebtToCollateral(b3, 3); + _loans.upsertT0DebtToCollateral(b1, 1); + _loans.upsertT0DebtToCollateral(b5, 5); assertEq(_loans.getMaxBorrower(), b7); - assertEq(_loans.getMaxTp(), 7); - assertEq(_loans.getTotalTps(), 8); + assertEq(_loans.getMaxT0DebtToCollateral(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 8); - _loans.removeTp(b2); + _loans.removeT0DebtToCollateral(b2); assertEq(_loans.getMaxBorrower(), b7); - assertEq(_loans.getMaxTp(), 7); - assertEq(_loans.getTotalTps(), 7); + assertEq(_loans.getMaxT0DebtToCollateral(), 7); + assertEq(_loans.getTotalT0DebtToCollaterals(), 7); - _loans.removeTp(b7); + _loans.removeT0DebtToCollateral(b7); assertEq(_loans.getMaxBorrower(), b6); - assertEq(_loans.getMaxTp(), 6); - assertEq(_loans.getTotalTps(), 6); + assertEq(_loans.getMaxT0DebtToCollateral(), 6); + assertEq(_loans.getTotalT0DebtToCollaterals(), 6); - _loans.removeTp(b6); + _loans.removeT0DebtToCollateral(b6); assertEq(_loans.getMaxBorrower(), b5); - assertEq(_loans.getMaxTp(), 5); - assertEq(_loans.getTotalTps(), 5); + assertEq(_loans.getMaxT0DebtToCollateral(), 5); + assertEq(_loans.getTotalT0DebtToCollaterals(), 5); } } @@ -313,40 +349,40 @@ contract HeapGasLoadTest is DSTestPlus { _loans = new HeapInstance(); for (uint256 i; i < NODES_COUNT; i++) { address borrower = makeAddr(vm.toString(i)); - _loans.upsertTp(borrower, 1 * 1e18 + i * 1e18); + _loans.upsertT0DebtToCollateral(borrower, 1 * 1e18 + i * 1e18); _borrowers.push(borrower); } } function testLoadHeapGasExerciseDeleteOnAllNodes() public { - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); // account node 0 too + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); // account node 0 too for (uint256 i; i < NODES_COUNT; i++) { uint256 snapshot = vm.snapshot(); - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); - _loans.removeTp(_borrowers[i]); + _loans.removeT0DebtToCollateral(_borrowers[i]); - assertEq(_loans.getTotalTps(), NODES_COUNT); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT); vm.revertTo(snapshot); } - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); } function testLoadHeapGasExerciseUpsertOnAllNodes() public { - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); // account node 0 too + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); // account node 0 too for (uint256 i; i < NODES_COUNT; i++) { uint256 snapshot = vm.snapshot(); - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); - _loans.upsertTp(_borrowers[i], 1_000_000 * 1e18 + i * 1e18); + _loans.upsertT0DebtToCollateral(_borrowers[i], 1_000_000 * 1e18 + i * 1e18); - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); vm.revertTo(snapshot); } - assertEq(_loans.getTotalTps(), NODES_COUNT + 1); + assertEq(_loans.getTotalT0DebtToCollaterals(), NODES_COUNT + 1); } } diff --git a/tests/forge/unit/MathTest.t.sol b/tests/forge/unit/MathTest.t.sol index 4cbb256da..9c676cbd2 100644 --- a/tests/forge/unit/MathTest.t.sol +++ b/tests/forge/unit/MathTest.t.sol @@ -10,19 +10,6 @@ import 'src/libraries/internal/Maths.sol'; contract MathTest is DSTestPlus { - function testRayToWadRounded() external { - uint256 amount = 5_000.00076103507940381999999950 * 1e27; - assertEq(Maths.rayToWad(amount), 5_000.000761035079403820 * 1e18); - - assertEq(Maths.rayToWad(4 * 1e27), 4 * 1e18); - assertEq(Maths.rayToWad(0.0000000000000000006 * 1e27), 1); - assertEq(Maths.rayToWad(0.0000000000000000004 * 1e27), 0); - } - - function testZeroStaysZero() external { - assertEq(Maths.rayToWad(0), 0); - } - function testMultiplication() external { uint256 debt = 10_000.44444444444443999 * 1e18; uint256 inflator = 1.02132007 * 1e27; diff --git a/tests/forge/unit/PoolHelperTest.t.sol b/tests/forge/unit/PoolHelperTest.t.sol index 53c621ac9..cb8151bad 100644 --- a/tests/forge/unit/PoolHelperTest.t.sol +++ b/tests/forge/unit/PoolHelperTest.t.sol @@ -11,62 +11,65 @@ contract PoolHelperTest is DSTestPlus { * @notice Tests fenwick index calculation from varying bucket prices */ function testPriceToIndex() external { - _assertBucketPriceOutOfBoundsRevert(2_000_000_000 * 10**18); - _assertBucketPriceOutOfBoundsRevert(1_004_968_987.606512354182109772 * 10**18); - assertEq(_indexOf(1_004_968_987.606512354182109771 * 10**18), 0); - assertEq(_indexOf(4_669_863.090889329544038534 * 1e18), 1077); - assertEq(_indexOf(49_910.043670274810022205 * 1e18), 1987); - assertEq(_indexOf(21_699.795273870723549803 * 1e18), 2154); - assertEq(_indexOf(2_000.221618840727700609 * 1e18), 2632); - assertEq(_indexOf(146.575625611106531706 * 1e18), 3156); - assertEq(_indexOf(145.846393642892072537 * 1e18), 3157); - assertEq(_indexOf(100.332368143282009890 * 1e18), 3232); - assertEq(_indexOf(5.263790124045347667 * 1e18), 3823); - assertEq(_indexOf(1.646668492116543299 * 1e18), 4056); - assertEq(_indexOf(1.315628874808846999 * 1e18), 4101); - assertEq(_indexOf(1.051140132040790557 * 1e18), 4146); - assertEq(_indexOf(1 * 1e18), 4156); - assertEq(_indexOf(0.951347940696068854 * 1e18), 4166); - assertEq(_indexOf(0.463902261297398000 * 1e18), 4310); - assertEq(_indexOf(0.006856528811048429 * 1e18), 5155); - assertEq(_indexOf(0.006822416727411372 * 1e18), 5156); - assertEq(_indexOf(0.002144924036174487 * 1e18), 5388); - assertEq(_indexOf(0.000046545370002462 * 1e18), 6156); - assertEq(_indexOf(0.000009917388865689 * 1e18), 6466); - assertEq(_indexOf(99_836_282_890), 7388); - _assertBucketPriceOutOfBoundsRevert(99_836_282_889); - _assertBucketPriceOutOfBoundsRevert(1); - _assertBucketPriceOutOfBoundsRevert(0); + assertEq(_indexOf(4_669_863.090889329544038534 * 1e18), 1077); + assertEq(_indexOf(49_910.043670274810022205 * 1e18), 1987); + assertEq(_indexOf(21_699.795273870723549803 * 1e18), 2154); + assertEq(_indexOf(2_000.221618840727700609 * 1e18), 2632); + assertEq(_indexOf(146.575625611106531706 * 1e18), 3156); + assertEq(_indexOf(145.846393642892072537 * 1e18), 3157); + assertEq(_indexOf(100.332368143282009890 * 1e18), 3232); + assertEq(_indexOf(5.263790124045347667 * 1e18), 3823); + assertEq(_indexOf(1.646668492116543299 * 1e18), 4056); + assertEq(_indexOf(1.315628874808846999 * 1e18), 4101); + assertEq(_indexOf(1.051140132040790557 * 1e18), 4146); + assertEq(_indexOf(1 * 1e18), 4156); + assertEq(_indexOf(0.951347940696068854 * 1e18), 4166); + assertEq(_indexOf(0.463902261297398000 * 1e18), 4310); + assertEq(_indexOf(0.006856528811048429 * 1e18), 5155); + assertEq(_indexOf(0.006822416727411372 * 1e18), 5156); + assertEq(_indexOf(0.002144924036174487 * 1e18), 5388); + assertEq(_indexOf(0.000046545370002462 * 1e18), 6156); + assertEq(_indexOf(0.000009917388865689 * 1e18), 6466); + assertEq(_indexOf(99_836_282_890), 7388); + } + + function testPriceToIndexRevertOnPriceGtMaxPrice() external { + _assertBucketPriceOutOfBoundsRevert(MAX_PRICE + 1); + } + + function testPriceToIndexRevertOnPriceLtMinPrice() external { + _assertBucketPriceOutOfBoundsRevert(MIN_PRICE - 1); } /** * @notice Tests bucket price calculation from varying fenwick index */ function testIndexToPrice() external { - assertEq( _priceAt(0), 1_004_968_987.606512354182109771 * 10**18); - assertEq( _priceAt(1077), 4_669_863.090889329544038534 * 1e18); - assertEq( _priceAt(1987), 49_910.043670274810022205 * 1e18); - assertEq( _priceAt(2154), 21_699.795273870723549803 * 1e18); - assertEq( _priceAt(2632), 2_000.221618840727700609 * 1e18); - assertEq( _priceAt(3156), 146.575625611106531706 * 1e18); - assertEq( _priceAt(3157), 145.846393642892072537 * 1e18); - assertEq( _priceAt(3232), 100.332368143282009890 * 1e18); - assertEq( _priceAt(3823), 5.263790124045347667 * 1e18); - assertEq( _priceAt(4056), 1.646668492116543299 * 1e18); - assertEq( _priceAt(4101), 1.315628874808846999 * 1e18); - assertEq( _priceAt(4146), 1.051140132040790557 * 1e18); - assertEq( _priceAt(4156), 1 * 1e18); - assertEq( _priceAt(4166), 0.951347940696068854 * 1e18); - assertEq( _priceAt(4310), 0.463902261297391185 * 1e18); - assertEq( _priceAt(5155), 0.006856528811048429 * 1e18); - assertEq( _priceAt(5156), 0.006822416727411372 * 1e18); - assertEq( _priceAt(5388), 0.002144924036174487 * 1e18); - assertEq( _priceAt(6156), 0.000046545370002462 * 1e18); - assertEq( _priceAt(6466), 0.000009917388865689 * 1e18); - assertEq( _priceAt(7388), 99_836_282_890); - _assertBucketIndexOutOfBoundsRevert(7389); - _assertBucketIndexOutOfBoundsRevert(8191); - _assertBucketIndexOutOfBoundsRevert(9999); + assertEq(_priceAt(0), 1_004_968_987.606512354182109771 * 10**18); + assertEq(_priceAt(1077), 4_669_863.090889329544038534 * 1e18); + assertEq(_priceAt(1987), 49_910.043670274810022205 * 1e18); + assertEq(_priceAt(2154), 21_699.795273870723549803 * 1e18); + assertEq(_priceAt(2632), 2_000.221618840727700609 * 1e18); + assertEq(_priceAt(3156), 146.575625611106531706 * 1e18); + assertEq(_priceAt(3157), 145.846393642892072537 * 1e18); + assertEq(_priceAt(3232), 100.332368143282009890 * 1e18); + assertEq(_priceAt(3823), 5.263790124045347667 * 1e18); + assertEq(_priceAt(4056), 1.646668492116543299 * 1e18); + assertEq(_priceAt(4101), 1.315628874808846999 * 1e18); + assertEq(_priceAt(4146), 1.051140132040790557 * 1e18); + assertEq(_priceAt(4156), 1 * 1e18); + assertEq(_priceAt(4166), 0.951347940696068854 * 1e18); + assertEq(_priceAt(4310), 0.463902261297391185 * 1e18); + assertEq(_priceAt(5155), 0.006856528811048429 * 1e18); + assertEq(_priceAt(5156), 0.006822416727411372 * 1e18); + assertEq(_priceAt(5388), 0.002144924036174487 * 1e18); + assertEq(_priceAt(6156), 0.000046545370002462 * 1e18); + assertEq(_priceAt(6466), 0.000009917388865689 * 1e18); + assertEq(_priceAt(7388), 99_836_282_890); + } + + function testIndexToPriceRevertOnIndexGtMaxIndex() external { + _assertBucketIndexOutOfBoundsRevert(MAX_FENWICK_INDEX + 1); } /** @@ -76,7 +79,7 @@ contract PoolHelperTest is DSTestPlus { uint256 debt = 11_000.143012091382543917 * 1e18; uint256 price = 1_001.6501589292607751220 * 1e18; - assertEq(_encumberance(debt, price), 10.98202093218880245 * 1e18); + assertEq(_encumberance(debt, price), 11.421301769476354548 * 1e18); assertEq(_encumberance(0, price), 0); assertEq(_encumberance(debt, 0), 0); assertEq(_encumberance(0, 0), 0); @@ -86,15 +89,78 @@ contract PoolHelperTest is DSTestPlus { * @notice Tests loan/pool collateralization for varying values of debt, collateral and lup */ function testCollateralization() external { - uint256 debt = 11_000.143012091382543917 * 1e18; - uint256 price = 1_001.6501589292607751220 * 1e18; - uint256 collateral = 10.98202093218880245 * 1e18; - - assertEq(_collateralization(debt, collateral, price), 1 * 1e18); - assertEq(_collateralization(0, collateral, price), Maths.WAD); - assertEq(_collateralization(debt, collateral, 0), Maths.WAD); - assertEq(_collateralization(0, collateral, 0), Maths.WAD); - assertEq(_collateralization(debt, 0, price), 0); + uint8 erc20 = uint8(PoolType.ERC20); + uint8 erc721 = uint8(PoolType.ERC721); + + uint256 debt = 11_000.143012091382543917 * 1e18; + uint256 price = 1_001.6501589292607751220 * 1e18; + uint256 collateral = Maths.wmul(10.98202093218880245 * 1e18, 1.04 * 1e18); + + assertEq(_collateralization(debt, collateral, price), 1 * 1e18); + // due to rounding error, _collateralization and _isCollateralized do not agree at 100% CR + assertEq(_isCollateralized(debt, collateral + 1, price, erc20), true); + assertEq(_isCollateralized(debt, 12 * 1e18, price, erc721), true); + + assertEq(_collateralization(0, collateral, price), Maths.WAD); + assertEq(_isCollateralized(0, collateral, price, erc20), true); + assertEq(_isCollateralized(0, collateral, price, erc721), true); + + // if collateral is not worth anything, no amount of debt can be collateralized + assertEq(_collateralization(debt, collateral, 0), 0); + assertEq(_isCollateralized(debt, collateral, 0, erc20), false); + assertEq(_isCollateralized(debt, collateral, 0, erc721), false); + + assertEq(_collateralization(0, collateral, 0), Maths.WAD); + assertEq(_isCollateralized(0, collateral, 0, erc20), true); + assertEq(_isCollateralized(0, collateral, 0, erc721), true); + + assertEq(_collateralization(debt, 0, price), 0); + assertEq(_isCollateralized(debt, 0, price, erc20), false); + assertEq(_isCollateralized(debt, 0, price, erc721), false); + + // borrower with no debt or collateral is not undercollateralized + assertEq(_collateralization(0, 0, price), Maths.WAD); + assertEq(_isCollateralized(0, 0, price, erc20), true); + assertEq(_isCollateralized(0, 0, price, erc721), true); + + // undercollateralized with single unit of collateral at high price + debt = 5_000_000_000 * 1e18; + price = _priceAt(1); // 999969141.897027226245329498 + collateral = 1 * 1e18; + assertEq(_collateralization(debt, collateral, price), 0.192301758057120620 * 1e18); + assertEq(_isCollateralized(debt, collateral, price, erc20), false); + assertEq(_isCollateralized(debt, collateral, price, erc721), false); + + // undercollateralized with tiny amount of high-priced collateral + debt = 33_000_000_000 * 1e18; + collateral = 6; + assertEq(_collateralization(debt, collateral, price), 0 * 1e18); + assertEq(_isCollateralized(debt, collateral, price, erc20), false); + assertEq(_isCollateralized(debt, collateral, price, erc721), false); + + // 130% CR at high price + debt = 900 * 1e18; + collateral = 0.000001170036105095 * 1e18; + assertEq(_collateralization(debt, collateral, price), 1.250000000000413585 * 1e18); + assertEq(_isCollateralized(debt, collateral, price, erc20), true); + assertEq(_isCollateralized(debt, 1e18, price, erc721), true); + + // undercollateralized at low price + price = _priceAt(7388); // 0.000000099836282890 + assertEq(_collateralization(debt, collateral, price), 0); + assertEq(_isCollateralized(debt, collateral, price, erc20), false); + assertEq(_isCollateralized(debt, collateral, price, erc721), false); + + // 0% CR at MIN_PRICE + collateral = 11_719_186_313.147400474096316788 * 1e18; + assertEq(_collateralization(debt, collateral, price), 0); + assertEq(_isCollateralized(debt, collateral, price, erc20), false); + assertEq(_isCollateralized(debt, collateral, price, erc721), false); + + // borrower with no debt or collateral is still not undercollateralized at MIN_PRICE + assertEq(_collateralization(0, 0, price), Maths.WAD); + assertEq(_isCollateralized(0, 0, price, erc20), true); + assertEq(_isCollateralized(0, 0, price, erc721), true); } /** @@ -126,11 +192,9 @@ contract PoolHelperTest is DSTestPlus { */ function testDepositFeeRate() external { uint256 interestRate = 0.07 * 1e18; - assertEq(_depositFeeRate(interestRate), 0.000191780821917808 * 1e18); - assertEq(_depositFeeRate(0.2 * 1e18), 0.000547945205479452 * 1e18); - - // fee rate should be capped at 10% - assertEq(_depositFeeRate(1_000 * 1e18), 0.1 * 1e18); + assertEq(_depositFeeRate(interestRate), 0.000063926940639269 * 1e18); + assertEq(_depositFeeRate(0.2 * 1e18), 0.000182648401826484 * 1e18); + assertEq(_depositFeeRate(4 * 1e18), 0.003652968036529680 * 1e18); } /** diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/PositionManager/CodearenaReports.t.sol similarity index 90% rename from tests/forge/unit/Positions/CodearenaReports.t.sol rename to tests/forge/unit/PositionManager/CodearenaReports.t.sol index d582c4ff5..4d43d1b1e 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/PositionManager/CodearenaReports.t.sol @@ -71,7 +71,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract }); _borrow({ from: testBorrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -91,7 +91,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _borrow({ from: testBorrowerTwo, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -139,10 +139,10 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); // skip ahead so take can be called on the loan @@ -153,8 +153,8 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 60.911699561320164197 * 1e18, - givenAmount: 4_012.538586931187076 * 1e18, + bondChange: 43.041357036021185676 * 1e18, + givenAmount: 3_849.736007055289588000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -163,7 +163,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 5_821.65265251164695163 * 1e18 + settledDebt: 5_610.784873601483468048 * 1e18 }); // bucket is insolvent, balances are reset @@ -184,19 +184,19 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract // testMinter2 moves liquidity from healthy deposit _i9_52 to bankrupt _i9_91 deposit assertEq(_positionManager.getLP(tokenId2, _i9_91), 0); - assertEq(_positionManager.getLP(tokenId2, _i9_52), 10_000 * 1e18); + assertEq(_positionManager.getLP(tokenId2, _i9_52), 9_999.543378995433790000 * 1e18); changePrank(testMinter2); vm.expectRevert(IPoolErrors.BucketBankruptcyBlock.selector); - _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours); // skip time to avoid move in same block as bucket bankruptcy skip(1 hours); - _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours); // report 494: testMinter2 position at _i9_91 should not be bankrupt assertFalse(_positionManager.isPositionBucketBankrupt(tokenId2, _i9_91)); - assertEq(_positionManager.getLP(tokenId2, _i9_91), 10_000 * 1e18); + assertEq(_positionManager.getLP(tokenId2, _i9_91), 9_999.543378995433790000 * 1e18); /******************/ /*** Report 179 ***/ @@ -207,23 +207,23 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_52)); assertEq(_positionManager.getLP(tokenId, _i9_91), 0); - assertEq(_positionManager.getLP(tokenId, _i9_52), 30_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, _i9_52), 29_998.630136986301370000 * 1e18); changePrank(testMinter); // testMinter1 moves liquidity from bankrupt _i9_91 deposit to healthy deposit _i9_52 // call reverts as cannot move from bankrupt bucket vm.expectRevert(IPositionManagerErrors.BucketBankrupt.selector); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_52, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_52, block.timestamp + 5 hours); // testMinter1 moves liquidity from healthy deposit _i9_52 to bankrupt _i9_91 - // _i9_52 should remain with 0 LP, _i9_91 should have 30_000 - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_52, _i9_91, block.timestamp + 5 hours, false); + // _i9_52 should remain with 0 LP, _i9_91 should have 29_998.630136986301370000 + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_52, _i9_91, block.timestamp + 5 hours); assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_91)); assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_52)); // report 179: testMinter1 position at _i9_91 should contain only moved LP (without LP before bankruptcy) - assertEq(_positionManager.getLP(tokenId, _i9_91), 30_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, _i9_91), 29_998.630136986301370000 * 1e18); assertEq(_positionManager.getLP(tokenId, _i9_52), 0); } @@ -257,23 +257,23 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract // check from and to positions before move (uint256 fromLp, uint256 fromDepositTime) = _positionManager.getPositionInfo(tokenId1, mintIndex); (uint256 toLp, uint256 toDepositTime) = _positionManager.getPositionInfo(tokenId1, moveIndex); - assertEq(fromLp, 2_500 * 1e18); + assertEq(fromLp, 2_499.885844748858447500 * 1e18); assertEq(toLp, 0); assertEq(fromDepositTime, block.timestamp); assertEq(toDepositTime, 0); // move liquidity called by testAddress1 owner vm.expectEmit(true, true, true, true); - emit MoveLiquidity(testAddress1, tokenId1, mintIndex, moveIndex, 2_500 * 1e18, 2_500 * 1e18); + emit MoveLiquidity(testAddress1, tokenId1, mintIndex, moveIndex, 2_499.885844748858447500 * 1e18, 2_499.771694710285440276 * 1e18); changePrank(address(testAddress1)); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); // check from and to positions after move // from position should have 0 LP and 0 deposit time (FROM Position struct is deleted) (fromLp, fromDepositTime) = _positionManager.getPositionInfo(tokenId1, mintIndex); (toLp, toDepositTime) = _positionManager.getPositionInfo(tokenId1, moveIndex); assertEq(fromLp, 0); - assertEq(toLp, 2_500 * 1e18); + assertEq(toLp, 2_499.771694710285440276 * 1e18); assertEq(fromDepositTime, 0); assertEq(toDepositTime, block.timestamp); } @@ -321,25 +321,25 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _removeAllCollateral({ from: testAddress2, - amount: 66425.497336169705758544 * 1e18, + amount: 66_422.464208437460566804 * 1e18, index: 2550, - lpRedeem: 200000000 * 1e18 + lpRedeem: 199_990_867.579908675800000000 * 1e18 }); // check from and to positions before move (uint256 fromLp, uint256 fromDepositTime) = _positionManager.getPositionInfo(tokenId1, mintIndex); (uint256 toLp, uint256 toDepositTime) = _positionManager.getPositionInfo(tokenId1, moveIndex); - assertEq(fromLp, 2661558999339261847178.534720637400665211 * 1e18); + assertEq(fromLp, 2661558999339261847178.420565386259112711 * 1e18); assertEq(toLp, 0); assertEq(fromDepositTime, block.timestamp); assertEq(toDepositTime, 0); // move liquidity called by testAddress1 owner - // This protects LP owner of losing LP because position manager tried to move 2661558999339261847178.534720637400665211 memorialized LP + // This protects LP owner of losing LP because position manager tried to move 2661558999339261847178.420565386259112711 memorialized LP // but the amount of LP that can be moved (constrained by available max quote token) is only 200002500 changePrank(address(testAddress1)); vm.expectRevert(IPositionManagerErrors.RemovePositionFailed.selector); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); } /** @@ -542,7 +542,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _positionManager.memorializePositions(address(_pool), tokenIdAlice, indexes); // check memorialization success for Alice - assertEq(_positionManager.getLP(tokenIdAlice, indexes[0]), 3000 * 1e18); + assertEq(_positionManager.getLP(tokenIdAlice, indexes[0]), 2_999.863013698630137000 * 1e18); // Bob @@ -584,8 +584,8 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract console.log("Balance of Alice: ", lpBalanceAliceAfter); // Bob and Alice LP balances are the same as initial - assertEq(lpBalanceBobAfter, 3_000 * 1e18); - assertEq(lpBalanceAliceAfter, 3_000 * 1e18); + assertEq(lpBalanceBobAfter, 2_999.863013698630137000 * 1e18); + assertEq(lpBalanceAliceAfter, 2_999.863013698630137000 * 1e18); } @@ -646,7 +646,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract }); _borrow({ from: testBorrower, - amount: 19.25 * 1e18, + amount: 15 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -666,7 +666,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _borrow({ from: testBorrowerTwo, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -707,15 +707,15 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _assertPool( PoolParams({ - htp: 9.719336538461538466 * 1e18, + htp: 9.660480000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 83_000.0* 1e18, + poolSize: 82_996.210045662100457000 * 1e18, pledgedCollateral: 1_002.0 * 1e18, - encumberedCollateral: 1_001.780542767698891702 * 1e18, - poolDebt: 9_738.605048076923081414 * 1e18, + encumberedCollateral: 995.350325135729028065 * 1e18, + poolDebt: 9_303.937500000000004290 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 486.930252403846154071 * 1e18, + minDebtAmount: 465.196875000000000215 * 1e18, loans: 2, maxBorrower: address(testBorrowerTwo), interestRate: 0.05 * 1e18, @@ -725,9 +725,9 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _assertBucketAssets({ index: _i9_81, - lpBalance: 5_000.0 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 5_000.0 * 1e18, + deposit: 4_999.771689497716895000 * 1e18, exchangeRate: 1e18 }); @@ -735,14 +735,14 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract // Move positiion upwards from _i9_81 to _i9_91 changePrank(testMinter); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_91, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_91, block.timestamp + 5 hours); vm.revertTo(preMoveUpState); uint256 preMoveDownState = vm.snapshot(); // Move positiion downwards from _i9_91 to _i9_81 - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_81, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_81, block.timestamp + 5 hours); vm.revertTo(preMoveDownState); @@ -750,21 +750,21 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _assertBucketAssets({ index: _i9_81, - lpBalance: 5_000.0 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 5_000.0 * 1e18, + deposit: 4_999.771689497716895000 * 1e18, exchangeRate: 1e18 }); _assertBucketAssets({ index: _i9_52, - lpBalance: 40_000.0 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, collateral: 0, - deposit: 40_000.0 * 1e18, + deposit: 39_998.173515981735160000 * 1e18, exchangeRate: 1e18 }); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_52, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_52, block.timestamp + 5 hours); _assertBucketAssets({ index: _i9_81, @@ -776,23 +776,23 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _assertBucketAssets({ index: _i9_52, - lpBalance: 44_999.315068493150685000 * 1e18, + lpBalance: 44_997.716905402306040553 * 1e18, collateral: 0, - deposit: 44_999.315068493150685000 * 1e18, + deposit: 44_997.716905402306040553 * 1e18, exchangeRate: 1e18 }); _assertPool( PoolParams({ - htp: 9.719336538461538466 * 1e18, + htp: 9.660480000000000004 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 82_999.315068493150685000 * 1e18, - pledgedCollateral: 1_002.0 * 1e18, - encumberedCollateral: 1_001.780542767698891702 * 1e18, - poolDebt: 9_738.605048076923081414 * 1e18, + poolSize: 82_995.981745584954442553 * 1e18, + pledgedCollateral: 1_002 * 1e18, + encumberedCollateral: 995.350325135729028065 * 1e18, + poolDebt: 9_303.937500000000004290 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 486.930252403846154071 * 1e18, + minDebtAmount: 465.196875000000000215 * 1e18, loans: 2, maxBorrower: address(testBorrowerTwo), interestRate: 0.05 * 1e18, @@ -873,7 +873,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: alice, index: 2551, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); } diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/PositionManager/PositionManager.t.sol similarity index 89% rename from tests/forge/unit/Positions/PositionManager.t.sol rename to tests/forge/unit/PositionManager/PositionManager.t.sol index 926f69913..55f3880db 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/PositionManager/PositionManager.t.sol @@ -181,7 +181,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // memorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testAddress, address(_positionManager), indexes, 9_000 * 1e18); + emit TransferLP(testAddress, address(_positionManager), indexes, 8_999.589041095890411000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testAddress, tokenId, indexes); _positionManager.memorializePositions(address(_pool), tokenId, indexes); @@ -234,7 +234,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress, index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -246,7 +246,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress, index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -258,7 +258,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress, index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -285,7 +285,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // memorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testAddress, address(_positionManager), indexes, 9_000 * 1e18); + emit TransferLP(testAddress, address(_positionManager), indexes, 8_999.589041095890411000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testAddress, tokenId, indexes); _positionManager.memorializePositions(address(_pool), tokenId, indexes); @@ -299,7 +299,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -311,7 +311,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -323,14 +323,14 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 2_999.863013698630137000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -339,13 +339,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, indexes[2])); (uint256 lps, uint256 depositTime) = _positionManager.getPositionInfo(tokenId, indexes[0]); - assertEq(lps, 3_000 * 1e18); + assertEq(lps, 2_999.863013698630137000 * 1e18); assertEq(depositTime, _startTime); (lps, depositTime) = _positionManager.getPositionInfo(tokenId, indexes[1]); - assertEq(lps, 3_000 * 1e18); + assertEq(lps, 2_999.863013698630137000 * 1e18); assertEq(depositTime, _startTime); (lps, depositTime) = _positionManager.getPositionInfo(tokenId, indexes[2]); - assertEq(lps, 3_000 * 1e18); + assertEq(lps, 2_999.863013698630137000 * 1e18); assertEq(depositTime, _startTime); // add more liquidity @@ -369,44 +369,44 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress, index: indexes[0], - lpBalance: 1_000 * 1e18, + lpBalance: 999.954337899543379000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: testAddress, index: indexes[1], - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: testAddress, index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 2_999.863013698630137000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -419,7 +419,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // rememorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testAddress, address(_positionManager), indexes, 6_000 * 1e18); + emit TransferLP(testAddress, address(_positionManager), indexes, 5_999.726027397260274000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testAddress, tokenId, indexes); _positionManager.memorializePositions(address(_pool), tokenId, indexes); @@ -434,7 +434,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 4_000 * 1e18, + lpBalance: 3_999.817351598173516000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -446,7 +446,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -458,14 +458,14 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 6_000 * 1e18, + lpBalance: 5_999.726027397260274000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 4_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 5_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 6_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_999.817351598173516000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 4_999.771689497716895000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 5_999.726027397260274000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -479,6 +479,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract address testLender1 = makeAddr("testLender1"); address testLender2 = makeAddr("testLender2"); uint256 mintAmount = 10000 * 1e18; + uint256 lpbAfterDepositFee = 2_999.863013698630137000 * 1e18; // for adding initial liquidity of 3000 * 1e18 _mintQuoteAndApproveManagerTokens(testLender1, mintAmount); _mintQuoteAndApproveManagerTokens(testLender2, mintAmount); @@ -525,13 +526,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testLender1, index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ lender: testLender2, index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -543,7 +544,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testLender1, index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -561,7 +562,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testLender1, index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -585,7 +586,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testLender2, index: indexes[3], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -603,7 +604,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.getLP(tokenId2, indexes[3]), 0); (uint256 poolSize, , , , ) = _poolUtils.poolLoansInfo(address(_pool)); - assertEq(poolSize, 15_000 * 1e18); + assertEq(poolSize, 14_999.315068493150685000 * 1e18); // construct memorialize lender 1 params struct uint256[] memory lender1Indexes = new uint256[](3); @@ -625,12 +626,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // memorialize lender 1 quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testLender1, address(_positionManager), lender1Indexes, 9_000 * 1e18); + emit TransferLP(testLender1, address(_positionManager), lender1Indexes, 8_999.589041095890411000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testLender1, tokenId1, lender1Indexes); _positionManager.memorializePositions(address(_pool), tokenId1, lender1Indexes); - // check lender, position manager, and pool state + // check lender, position manager, and pool state _assertLenderLpBalance({ lender: testLender1, index: indexes[0], @@ -640,7 +641,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -652,7 +653,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -664,7 +665,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -680,12 +681,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract depositTime: 0 }); - assertEq(_positionManager.getLP(tokenId1, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId1, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId1, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId1, indexes[0]), lpbAfterDepositFee); + assertEq(_positionManager.getLP(tokenId1, indexes[1]), lpbAfterDepositFee); + assertEq(_positionManager.getLP(tokenId1, indexes[2]), lpbAfterDepositFee); (poolSize, , , , ) = _poolUtils.poolLoansInfo(address(_pool)); - assertEq(poolSize, 15_000 * 1e18); + assertEq(poolSize, 14_999.315068493150685000 * 1e18); // allow position manager to take ownership of lender 2's position changePrank(testLender2); @@ -693,8 +694,8 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract transferIndexes[0] = indexes[0]; transferIndexes[1] = indexes[3]; amounts = new uint256[](2); - amounts[0] = 3_000 * 1e18; - amounts[1] = 3_000 * 1e18; + amounts[0] = lpbAfterDepositFee; + amounts[1] = lpbAfterDepositFee; _pool.increaseLPAllowance(address(_positionManager), transferIndexes, amounts); // memorialize lender 2 quote tokens into minted NFT @@ -703,12 +704,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract newIndexes[1] = 2553; vm.expectEmit(true, true, true, true); - emit TransferLP(testLender2, address(_positionManager), newIndexes, 6_000 * 1e18); + emit TransferLP(testLender2, address(_positionManager), newIndexes, 5_999.726027397260274000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testLender2, tokenId2, newIndexes); _positionManager.memorializePositions(address(_pool), tokenId2, newIndexes); - // // check lender, position manager, and pool state + // check lender, position manager, and pool state _assertLenderLpBalance({ lender: testLender2, index: indexes[0], @@ -718,7 +719,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 6_000 * 1e18, + lpBalance: 5_999.726027397260274000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -730,7 +731,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -742,7 +743,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); _assertLenderLpBalance({ @@ -754,19 +755,19 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[3], - lpBalance: 3_000 * 1e18, + lpBalance: lpbAfterDepositFee, depositTime: _startTime }); - assertEq(_positionManager.getLP(tokenId1, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId1, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId1, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId1, indexes[0]), lpbAfterDepositFee); + assertEq(_positionManager.getLP(tokenId1, indexes[1]), lpbAfterDepositFee); + assertEq(_positionManager.getLP(tokenId1, indexes[2]), lpbAfterDepositFee); - assertEq(_positionManager.getLP(tokenId2, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId2, indexes[3]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId2, indexes[0]), lpbAfterDepositFee); + assertEq(_positionManager.getLP(tokenId2, indexes[3]), lpbAfterDepositFee); (poolSize, , , , ) = _poolUtils.poolLoansInfo(address(_pool)); - assertEq(poolSize, 15_000 * 1e18); + assertEq(poolSize, 14_999.315068493150685000 * 1e18); } function testMemorializeAndRedeemBucketBankruptcy() external { @@ -820,7 +821,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); _borrow({ from: testBorrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -840,7 +841,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _borrow({ from: testBorrowerTwo, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); @@ -857,7 +858,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndex, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -895,13 +896,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: testIndex, - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, depositTime: _startTime }); // check position state (uint256 lps, uint256 depositTime) = _positionManager.getPositionInfo(tokenId, testIndex); - assertEq(lps, 2_000 * 1e18); + assertEq(lps, 1_999.908675799086758000 * 1e18); assertEq(depositTime, _startTime); // check position is not bankrupt @@ -918,22 +919,22 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 }); // skip ahead so take can be called on the loan - skip(9 hours); + skip(10 hours); // take entire collateral _take({ from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 60.911699561320164197 * 1e18, - givenAmount: 4012.538586931187076000 * 1e18, + bondChange: 30.434835431641900439 * 1e18, + givenAmount: 2_722.174436366817848000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -942,7 +943,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 5_821.652652511646951630 * 1e18 + settledDebt: 6_725.788300273139601003 * 1e18 }); // bucket is insolvent, balances are reset @@ -962,7 +963,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // move liquidity should fail as the bucket has bankrupted vm.expectRevert(IPositionManagerErrors.BucketBankrupt.selector); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_72, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_72, block.timestamp + 30); // check lender state after bankruptcy before rememorializing _assertLenderLpBalance({ @@ -985,7 +986,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract amounts[0] = 30_000 * 1e18; changePrank(testMinter); - _pool.addQuoteToken(amounts[0], _i9_91, type(uint256).max, false); + _pool.addQuoteToken(amounts[0], _i9_91, type(uint256).max); _pool.increaseLPAllowance(address(_positionManager), indexes, amounts); _pool.approveLPTransferors(transferors); @@ -1002,7 +1003,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: testIndex, - lpBalance: 30_000 * 1e18, + lpBalance: 29_998.767123287671230000 * 1e18, depositTime: block.timestamp }); @@ -1063,7 +1064,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1114,12 +1115,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, testIndexPrice), 15_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, testIndexPrice), 14_999.315068493150685000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, testIndexPrice)); // approve and transfer NFT to different address @@ -1151,7 +1152,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1195,7 +1196,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1219,7 +1220,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract uint256[] memory indexes = new uint256[](1); indexes[0] = testIndexPrice; uint256[] memory amounts = new uint256[](1); - amounts[0] = 15_000 * 1e18; + amounts[0] = 14_999.315068493150685000 * 1e18; // allow position manager to take ownership of the position of testMinter _pool.increaseLPAllowance(address(_positionManager), indexes, amounts); // memorialize positions of testMinter @@ -1241,12 +1242,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, testIndexPrice), 15_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, testIndexPrice), 14_999.315068493150685000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, testIndexPrice)); // deploy spender contract @@ -1286,7 +1287,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1337,7 +1338,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _positionManager.nonces(5); // check domain separator matches expectations for the test chain - assertEq(_positionManager.DOMAIN_SEPARATOR(), 0x3d157903719b756bd03176f9e889ef6b5c39980675541c11c005ea6c4e1b6c07); + assertEq(_positionManager.DOMAIN_SEPARATOR(), 0x255893ac72554d931c70a8c246ff1216c7122c81a4d4f7f2a2eb5377f2481f12); } function testPermitReverts() external { @@ -1445,6 +1446,11 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.nonces(tokenId), 2); } + function testPermitSupportsInterface() external { + assertTrue(_positionManager.supportsInterface(0x5604e225)); + assertFalse(_positionManager.supportsInterface(0xffffffff)); + } + /** * @notice Tests NFT position can & can't be burned based on liquidity attached to it. * Checks that old owner cannot move positions. @@ -1543,7 +1549,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // move liquidity should fail because is not performed by owner changePrank(notOwner); vm.expectRevert(IPositionManagerErrors.NoAuth.selector); - _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30); } function testMoveLiquidity() external tearDown { @@ -1577,13 +1583,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress1, index: mintIndex, - lpBalance: 2_500 * 1e18, + lpBalance: 2_499.885844748858447500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: testAddress2, index: mintIndex, - lpBalance: 5_500 * 1e18, + lpBalance: 5_499.748858447488584500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1643,13 +1649,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress2, index: mintIndex, - lpBalance: 5_500 * 1e18, + lpBalance: 5_499.748858447488584500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: mintIndex, - lpBalance: 2_500 * 1e18, + lpBalance: 2_499.885844748858447500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1672,7 +1678,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); // check position manager state - assertEq(_positionManager.getLP(tokenId1, mintIndex), 2_500 * 1e18); + assertEq(_positionManager.getLP(tokenId1, mintIndex), 2_499.885844748858447500 * 1e18); assertEq(_positionManager.getLP(tokenId1, moveIndex), 0); assertEq(_positionManager.getLP(tokenId2, mintIndex), 0); assertEq(_positionManager.getLP(tokenId2, moveIndex), 0); @@ -1682,12 +1688,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertFalse(_positionManager.isIndexInPosition(tokenId2, moveIndex)); // move liquidity called by testAddress1 owner - uint256 lpRedeemed = 2_500 * 1e18; - uint256 lpAwarded = 2_500 * 1e18; + uint256 lpRedeemed = 2_499.885844748858447500 * 1e18; + uint256 lpAwarded = 2_499.771694710285440276 * 1e18; vm.expectEmit(true, true, true, true); emit MoveLiquidity(testAddress1, tokenId1, mintIndex, moveIndex, lpRedeemed, lpAwarded); changePrank(address(testAddress1)); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); // check pool state _assertLenderLpBalance({ @@ -1699,7 +1705,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testAddress2, index: mintIndex, - lpBalance: 5_500 * 1e18, + lpBalance: 5_499.748858447488584500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1723,13 +1729,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: moveIndex, - lpBalance: 2_500 * 1e18, + lpBalance: 2_499.771694710285440276 * 1e18, depositTime: _startTime }); // check position manager state assertEq(_positionManager.getLP(tokenId1, mintIndex), 0); - assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_500 * 1e18); + assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_499.771694710285440276 * 1e18); assertEq(_positionManager.getLP(tokenId2, mintIndex), 0); assertEq(_positionManager.getLP(tokenId2, moveIndex), 0); assertFalse(_positionManager.isIndexInPosition(tokenId1, mintIndex)); @@ -1762,7 +1768,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: mintIndex, - lpBalance: 5_500 * 1e18, + lpBalance: 5_499.748858447488584500 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -1780,14 +1786,14 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: moveIndex, - lpBalance: 2_500 * 1e18, + lpBalance: 2_499.771694710285440276 * 1e18, depositTime: _startTime }); // check position manager state assertEq(_positionManager.getLP(tokenId1, mintIndex), 0); - assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_500 * 1e18); - assertEq(_positionManager.getLP(tokenId2, mintIndex), 5_500 * 1e18); + assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_499.771694710285440276 * 1e18); + assertEq(_positionManager.getLP(tokenId2, mintIndex), 5_499.748858447488584500 * 1e18); assertEq(_positionManager.getLP(tokenId2, moveIndex), 0); assertFalse(_positionManager.isIndexInPosition(tokenId1, mintIndex)); assertTrue(_positionManager.isIndexInPosition(tokenId1, moveIndex)); @@ -1802,12 +1808,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); // move liquidity called by testAddress2 owner - lpRedeemed = 5_500 * 1e18; - lpAwarded = 5_500 * 1e18; + lpRedeemed = 5_499.748858447488584500 * 1e18; + lpAwarded = 5_499.497728362627968608 * 1e18; vm.expectEmit(true, true, true, true); emit MoveLiquidity(testAddress2, tokenId2, mintIndex, moveIndex, lpRedeemed, lpAwarded); changePrank(address(testAddress2)); - _positionManager.moveLiquidity(address(_pool), tokenId2, mintIndex, moveIndex, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId2, mintIndex, moveIndex, block.timestamp + 30); // check pool state _assertLenderLpBalance({ @@ -1843,15 +1849,15 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: moveIndex, - lpBalance: 8_000 * 1e18, + lpBalance: 7_999.269423072913408884 * 1e18, depositTime: _startTime }); // check position manager state assertEq(_positionManager.getLP(tokenId1, mintIndex), 0); - assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_500 * 1e18); + assertEq(_positionManager.getLP(tokenId1, moveIndex), 2_499.771694710285440276 * 1e18); assertEq(_positionManager.getLP(tokenId2, mintIndex), 0); - assertEq(_positionManager.getLP(tokenId2, moveIndex), 5_500 * 1e18); + assertEq(_positionManager.getLP(tokenId2, moveIndex), 5_499.497728362627968608 * 1e18); assertFalse(_positionManager.isIndexInPosition(tokenId1, mintIndex)); assertTrue(_positionManager.isIndexInPosition(tokenId1, moveIndex)); assertFalse(_positionManager.isIndexInPosition(tokenId2, mintIndex)); @@ -1859,7 +1865,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract changePrank(address(testAddress2)); vm.expectRevert(IPositionManagerErrors.RemovePositionFailed.selector); - _positionManager.moveLiquidity(address(_pool), tokenId2, 1000, 2000, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId2, 1000, 2000, block.timestamp + 30); } function testMoveLiquidityWithInterest() external tearDown { @@ -1932,25 +1938,25 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: mintIndex, - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: _startTime }); // lender 1 moves liquidity changePrank(lender1); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); // check pool state _assertLenderLpBalance({ lender: address(_positionManager), index: mintIndex, - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: moveIndex, - lpBalance: 1_999.865897356084855977 * 1e18, + lpBalance: 1_999.953352094523396188 * 1e18, depositTime: _startTime }); skip(1 weeks); @@ -1969,7 +1975,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: borrower, borrower: borrower, amountToRepay: type(uint256).max, - amountRepaid: 1_002.608307827389905518 * 1e18, + amountRepaid: 1_002.596862592399049586 * 1e18, collateralToPull: 250 * 1e18, newLup: MAX_PRICE }); @@ -2007,7 +2013,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2046,12 +2052,12 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, testIndexPrice), 15_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, testIndexPrice), 14_999.315068493150685000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, testIndexPrice)); // redeem positions of testMinter @@ -2070,7 +2076,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2140,13 +2146,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testMinter, index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: testReceiver, index: testIndexPrice, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2164,7 +2170,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: 2551, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2202,13 +2208,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: testIndexPrice, - lpBalance: 25_000 * 1e18, + lpBalance: 24_998.858447488584475000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: testIndexPrice, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2220,7 +2226,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: 2551, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2231,7 +2237,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); // check position manager state - assertEq(_positionManager.getLP(tokenId, testIndexPrice), 15_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, testIndexPrice), 14_999.315068493150685000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, testIndexPrice)); // approve and transfer NFT to different address @@ -2255,7 +2261,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _pool.approveLPTransferors(transferors); vm.expectEmit(true, true, true, true); - emit TransferLP(address(_positionManager), testReceiver, indexes, 15_000 * 1e18); + emit TransferLP(address(_positionManager), testReceiver, indexes, 14_999.315068493150685000 * 1e18); vm.expectEmit(true, true, true, true); emit RedeemPosition(testReceiver, tokenId, indexes); _positionManager.redeemPositions(address(_pool), tokenId, indexes); @@ -2270,7 +2276,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: testIndexPrice, - lpBalance: 40_000 * 1e18, + lpBalance: 39_998.173515981735160000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2288,7 +2294,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: testReceiver, index: 2551, - lpBalance: 15_000 * 1e18, + lpBalance: 14_999.315068493150685000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2322,7 +2328,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2376,7 +2382,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); @@ -2389,7 +2395,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // minter cannot move liquidity on behalf of lender (is not approved) vm.expectRevert(IPositionManagerErrors.NoAuth.selector); - _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30); // minter cannot redeem positions on behalf of lender (is not approved) vm.expectRevert(IPositionManagerErrors.NoAuth.selector); @@ -2404,7 +2410,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract changePrank(minter); // minter can move liquidity on behalf of lender - _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30); _assertLenderLpBalance({ lender: lender, @@ -2421,7 +2427,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: 2551, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.086778841141761105 * 1e18, depositTime: _startTime }); @@ -2432,7 +2438,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: lender, index: 2551, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.086778841141761105 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2473,7 +2479,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: lender, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -2521,7 +2527,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertLenderLpBalance({ lender: minter, index: 2550, - lpBalance: 10_000 * 1e18, + lpBalance: 9_999.543378995433790000 * 1e18, depositTime: _startTime }); } @@ -2595,7 +2601,8 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract address alice = makeAddr("alice"); address bob = makeAddr("bob"); - uint256 mintAmount = 10_000 * 1e18; + uint256 mintAmount = 10_000 * 1e18; + uint256 lpAfterDepositFee = 2_999.863013698630137000 * 1e18; uint256 lpBalance; uint256 depositTime; @@ -2619,7 +2626,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], alice); uint256 aliceDepositTime = block.timestamp; - assertEq(lpBalance, amounts[0]); + assertEq(lpBalance, lpAfterDepositFee); assertEq(depositTime, aliceDepositTime); // bob adds liquidity later @@ -2630,7 +2637,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract index: indexes[0] }); (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], bob); - assertEq(lpBalance, amounts[0]); + assertEq(lpBalance, lpAfterDepositFee); assertEq(depositTime, aliceDepositTime + 1 hours); @@ -2655,7 +2662,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // memorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(addresses[i], address(_positionManager), indexes, amounts[0]); + emit TransferLP(addresses[i], address(_positionManager), indexes, lpAfterDepositFee); vm.expectEmit(true, true, true, true); emit MemorializePosition(addresses[i], tokenIds[i], indexes); @@ -2670,7 +2677,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(lpBalance, 0); assertEq(depositTime, aliceDepositTime + 1 hours); (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], address(_positionManager)); - assertEq(lpBalance, 6_000 * 1e18); + assertEq(lpBalance, 5_999.726027397260274000 * 1e18); assertEq(depositTime, aliceDepositTime + 1 hours); // both alice and bob redeem @@ -2680,10 +2687,10 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract } (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], alice); - assertEq(lpBalance, 3_000 * 1e18); + assertEq(lpBalance, lpAfterDepositFee); assertEq(depositTime, aliceDepositTime + 1 hours); (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], bob); - assertEq(lpBalance, 3_000 * 1e18); + assertEq(lpBalance, lpAfterDepositFee); assertEq(depositTime, aliceDepositTime + 1 hours); (lpBalance, depositTime) = _pool.lenderInfo(indexes[0], address(_positionManager)); assertEq(lpBalance, 0); @@ -2751,7 +2758,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract }); _borrow({ from: testBorrower, - amount: 19.25 * 1e18, + amount: 18.65 * 1e18, indexLimit: _i9_91, newLup: 9.917184843435912074 * 1e18 }); @@ -2771,11 +2778,36 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _borrow({ from: testBorrowerTwo, - amount: 1_730 * 1e18, + amount: 1_300 * 1e18, indexLimit: _i9_72, newLup: 9.721295865031779605 * 1e18 }); + // check bucket status after setup + _assertBucket({ + index: _i9_91, + lpBalance: 1_999.908675799086758000 * 1e18, + collateral: 0, + deposit: 1_999.908675799086758000 * 1e18, + exchangeRate: 1 * 1e18 + }); + + _assertBucket({ + index: _i9_81, + lpBalance: 4_999.771689497716895000 * 1e18, + collateral: 0, + deposit: 4_999.771689497716895000 * 1e18, + exchangeRate: 1 * 1e18 + }); + + _assertBucketAssets({ + index: _i9_72, + lpBalance: 10_999.497716894977169000 * 1e18, + collateral: 0, + deposit: 10_999.497716894977169000 * 1e18, + exchangeRate: 1 * 1e18 + }); + /****************************/ /*** Memorialize Position ***/ /****************************/ @@ -2807,31 +2839,55 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_853.394241979221645666 * 1e18, + debt: 9_417.044136515672180410 * 1e18, collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 + bond: 105.285754181824258217 * 1e18, + transferAmount: 105.285754181824258217 * 1e18 + }); + + _assertBucketAssets({ + index: _i9_72, + lpBalance: 10_999.497716894977169000 * 1e18, + collateral: 0, + deposit: 11_066.183238499379780461 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 }); // skip ahead so take can be called on the loan - skip(14 hours); + skip(10 hours); + + _assertBucketAssets({ + index: _i9_72, + lpBalance: 10_999.497716894977169000 * 1e18, + collateral: 0, + deposit: 11_066.183238499379780461 * 1e18, + exchangeRate: 1.006062596976766964 * 1e18 + }); // take entire collateral _take({ from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 10.767768953351785113 * 1e18, - givenAmount: 709.323311147932380000 * 1e18, + bondChange: 30.434835431641900439 * 1e18, + givenAmount: 2_722.174436366817848000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); + _assertBucketAssets({ + index: _i9_72, + lpBalance: 10_999.497716894977169000 * 1e18, + collateral: 0, + deposit: 11_066.444606162187637588 * 1e18, + exchangeRate: 1.006086358758398720 * 1e18 + }); + _settle({ from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_030.334558988288428680 * 1e18 + settledDebt: 6_725.788300273139601003 * 1e18 }); // bucket is insolvent, balances are reset @@ -2845,22 +2901,22 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertBucket({ index: _i9_81, - lpBalance: 0, // bucket is bankrupt + lpBalance: 4_999.771689497716895000 * 1e18, collateral: 0, - deposit: 0, - exchangeRate: 1 * 1e18 + deposit: 321.022288565791497075 * 1e18, + exchangeRate: 0.064207389557430329 * 1e18 }); _assertBucketAssets({ index: _i9_72, - lpBalance: 11_000 * 1e18, + lpBalance: 10_999.497716894977169000 * 1e18, collateral: 0, - deposit: 8_988.841151969900795435 * 1e18, - exchangeRate: 0.817167377451809164 * 1e18 + deposit: 11_066.444606162187637588 * 1e18, + exchangeRate: 1.006086358758398720 * 1e18 }); assertTrue(_positionManager.isPositionBucketBankrupt(tokenId, testIndex)); - assertTrue(_positionManager.isPositionBucketBankrupt(tokenId, _i9_81)); + assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_81)); assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_72)); // check buckets that are not bankrupt in NFT @@ -2877,15 +2933,15 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter2, amount: 10_000 * 1e18, index: _i9_91, - lpAward: 10000.0 * 1e18, + lpAward: 9_999.589041095890410000 * 1e18, newLup: 9.917184843435912074 * 1e18 }); _assertBucketAssets({ index: _i9_91, - lpBalance: 10_000.000000000000000000 * 1e18, + lpBalance: 9_999.589041095890410000 * 1e18, collateral: 0, - deposit: 10_000.000000000000000000 * 1e18, + deposit: 9_999.589041095890410000 * 1e18, exchangeRate: 1.0 * 1e18 }); @@ -2902,13 +2958,13 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // testMinter moves 8_936 QT _i9_72 to bankrupt _i9_91 deposit, should not have any pre bankruptcy LP changePrank(testMinter); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_72, testIndex, block.timestamp + 5 hours, false); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_72, testIndex, block.timestamp + 5 hours); _assertBucketAssets({ index: _i9_91, - lpBalance: 18_988.843069038537201221 * 1e18, + lpBalance: 21_066.033647258078047588 * 1e18, collateral: 0, - deposit: 18_988.843069038537201221 * 1e18, + deposit: 21_066.033647258078047588 * 1e18, exchangeRate: 1.0 * 1e18 }); @@ -2931,19 +2987,19 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // minter one should only be able to withdraw what they moved _removeAllLiquidity({ from: testMinter, - amount: 8_988.843069038537201221 * 1e18, + amount: 11_066.444606162187637588 * 1e18, index: _i9_91, newLup: _p9_91, - lpRedeem: 8_988.843069038537201221 * 1e18 + lpRedeem: 11_066.444606162187637588 * 1e18 }); // minter2 has remaining liquidity in _i9_91 _assertBucketAssets({ index: _i9_91, - lpBalance: 10_000.000000000000000000 * 1e18, + lpBalance: 9_999.589041095890410000 * 1e18, collateral: 0, - deposit: 10_000.000000000000000000 * 1e18, - exchangeRate: 1.0 * 1e18 + deposit: 9_999.589041095890410000 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); } } @@ -3009,7 +3065,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress1, index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3021,7 +3077,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress1, index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3033,7 +3089,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress1, index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3065,7 +3121,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract // memorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testAddress1, address(_positionManager), indexes, 9_000 * 1e18); + emit TransferLP(testAddress1, address(_positionManager), indexes, 8_999.589041095890411000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testAddress1, tokenId, indexes); _positionManager.memorializePositions(address(_pool), tokenId, indexes); @@ -3079,7 +3135,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3091,7 +3147,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3103,14 +3159,14 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 2_999.863013698630137000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -3136,44 +3192,44 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress1, index: indexes[0], - lpBalance: 1_000 * 1e18, + lpBalance: 999.954337899543379000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ lender: testAddress1, index: indexes[1], - lpBalance: 2_000 * 1e18, + lpBalance: 1_999.908675799086758000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ lender: testAddress1, index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 3_000 * 1e18, + lpBalance: 2_999.863013698630137000 * 1e18, depositTime: currentTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 3_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 3_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 2_999.863013698630137000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 2_999.863013698630137000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -3190,7 +3246,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract // rememorialize quote tokens into minted NFT vm.expectEmit(true, true, true, true); - emit TransferLP(testAddress1, address(_positionManager), indexes, 6_000 * 1e18); + emit TransferLP(testAddress1, address(_positionManager), indexes, 5_999.726027397260274000 * 1e18); vm.expectEmit(true, true, true, true); emit MemorializePosition(testAddress1, tokenId, indexes); _positionManager.memorializePositions(address(_pool), tokenId, indexes); @@ -3205,7 +3261,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[0], - lpBalance: 4_000 * 1e18, + lpBalance: 3_999.817351598173516000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3217,7 +3273,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 5_000 * 1e18, + lpBalance: 4_999.771689497716895000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3229,25 +3285,25 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 6_000 * 1e18, + lpBalance: 5_999.726027397260274000 * 1e18, depositTime: currentTime }); // check position manager state - assertEq(_positionManager.getLP(tokenId, indexes[0]), 4_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 5_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 6_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[0]), 3_999.817351598173516000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 4_999.771689497716895000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 5_999.726027397260274000 * 1e18); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); // move liquidity called by testAddress1 - uint256 lpRedeemed = 4_000 * 1e18; - uint256 lpAwarded = 4_000 * 1e18; + uint256 lpRedeemed = 3_999.817351598173516000 * 1e18; + uint256 lpAwarded = 3_999.634711536456704442 * 1e18; vm.expectEmit(true, true, true, true); emit MoveLiquidity(testAddress1, tokenId, indexes[0], indexes[1], lpRedeemed, lpAwarded); changePrank(testAddress1); - _positionManager.moveLiquidity(address(_pool), tokenId, indexes[0], indexes[1], block.timestamp + 30, false); + _positionManager.moveLiquidity(address(_pool), tokenId, indexes[0], indexes[1], block.timestamp + 30); // check LP balance _assertLenderLpBalance({ @@ -3271,7 +3327,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[1], - lpBalance: 9_000 * 1e18, + lpBalance: 8_999.406401034173599442 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3283,14 +3339,14 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: address(_positionManager), index: indexes[2], - lpBalance: 6_000 * 1e18, + lpBalance: 5_999.726027397260274000 * 1e18, depositTime: currentTime }); // check position manager state assertEq(_positionManager.getLP(tokenId, indexes[0]), 0); - assertEq(_positionManager.getLP(tokenId, indexes[1]), 9_000 * 1e18); - assertEq(_positionManager.getLP(tokenId, indexes[2]), 6_000 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[1]), 8_999.406401034173599442 * 1e18); + assertEq(_positionManager.getLP(tokenId, indexes[2]), 5_999.726027397260274000 * 1e18); assertFalse(_positionManager.isIndexInPosition(tokenId, indexes[0])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); @@ -3355,7 +3411,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress2, index: indexes[1], - lpBalance: 9_000 * 1e18, + lpBalance: 8_999.406401034173599442 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3373,7 +3429,7 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract _assertLenderLpBalance({ lender: testAddress2, index: indexes[2], - lpBalance: 6_000 * 1e18, + lpBalance: 5_999.726027397260274000 * 1e18, depositTime: currentTime }); _assertLenderLpBalance({ @@ -3396,7 +3452,6 @@ abstract contract PositionManagerERC721PoolTest is PositionManagerHelperContract vm.expectRevert("ERC721: invalid token ID"); _positionManager.ownerOf(tokenId); - } } @@ -3430,4 +3485,4 @@ contract PositionManagerERC721SubsetPoolTest is PositionManagerERC721PoolTest { function setUp() external { _startTest(); } -} \ No newline at end of file +} diff --git a/tests/forge/unit/Rewards/ClaimRewards.t.sol b/tests/forge/unit/Rewards/ClaimRewards.t.sol deleted file mode 100644 index b9d629a83..000000000 --- a/tests/forge/unit/Rewards/ClaimRewards.t.sol +++ /dev/null @@ -1,366 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.18; - -import { IERC20Token } from 'src/interfaces/pool/IPool.sol'; - -import { RewardsHelperContract } from './RewardsDSTestPlus.sol'; - -/** - Stake should be possible regardless pool balance: - 1. stake nft with enough balance - staker should receive rewards for bucket update - 2. stake nft without enough balance - staker should receive portion of reward for bucket update - 3. stake nft with no balance - staker should not receive any token but should be able to stake - */ -contract ClaimRewardsOnStakeTest is RewardsHelperContract { - address internal _borrower; - address internal _borrower2; - address internal _borrower3; - address internal _lender; - address internal _lender1; - - uint256 tokenIdOne; - uint256 tokenIdTwo; - uint256[] depositIndexes; - - function setUp() public { - _startTest(); - - // borrowers - _borrower = makeAddr("borrower"); - _borrower2 = makeAddr("borrower2"); - _borrower3 = makeAddr("borrower3"); - - _lender = makeAddr("lender"); - _lender1 = makeAddr("lender1"); - - // instantiate test minters - _minterOne = makeAddr("minterOne"); - _minterTwo = makeAddr("minterTwo"); - - // instantiate test bidder - _bidder = makeAddr("bidder"); - deal(address(_ajna), _bidder, 900_000_000 * 10**18); - - changePrank(_bidder); - _ajnaToken.approve(address(_pool), type(uint256).max); - _quoteOne.approve(address(_pool), type(uint256).max); - _quoteTwo.approve(address(_pool), type(uint256).max); - - // instantiate test updater - _updater = makeAddr("updater"); - _updater2 = makeAddr("updater2"); - - _mintCollateralAndApproveTokens(_borrower, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower, 200_000 * 1e18); - - _mintCollateralAndApproveTokens(_borrower2, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower2, 200_000 * 1e18); - - _mintCollateralAndApproveTokens(_borrower3, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower3, 200_000 * 1e18); - - _mintQuoteAndApproveTokens(_lender, 200_000 * 1e18); - _mintQuoteAndApproveTokens(_lender1, 200_000 * 1e18); - - _mintQuoteAndApproveTokens(_minterOne, 500_000_000 * 1e18); - _mintQuoteAndApproveTokens(_minterTwo, 500_000_000 * 1e18); - - skip(10); - - // configure NFT position - depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterTwo, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625038077222056449 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - } - - function testClaimOnStakeWithInsufficientFunds() external { - - uint256 stakeSnapshot = vm.snapshot(); - - // 1. stake nft with enough balance - staker should receive rewards for bucket update - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 4.131251903861097650 * 1e18); - - vm.revertTo(stakeSnapshot); - - // 2. stake nft without enough balance - staker should receive portion of reward for bucket update - // burn rewards manager tokens and leave less tokens than rewards available - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_999 * 1e18); - - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 1 * 1e18); - } - - function testClaimOnStakeWithNoBalance() external { - // 3. stake nft with no balance - staker should not receive any token but should be able to stake - // burn all rewards manager tokens - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(100_000_000 * 1e18); - - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 0); - } -} - -/** - Exchange rate update should be possible regardless pool balance - 1. update with enough balance - staker should receive rewards for bucket update - 2. update without enough balance - staker should receive portion of reward for bucket update (available balance) - 3. update with no balance - staker should not receive any token but should be able to update - */ -contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { - - function testClaimOnUpdateRateWithInsufficientFunds() external { - uint256 updateSnapshot = vm.snapshot(); - - // 1. update with enough balance - staker should receive rewards for bucket update - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131251903861097650 * 1e18 - }); - - uint256 updaterBalance = _ajnaToken.balanceOf(_updater); - assertEq(updaterBalance, 4.131251903861097650 * 1e18); - - vm.revertTo(updateSnapshot); - - // 2. update without enough balance - staker should receive portion of reward for bucket update - // burn rewards manager tokens and leave less tokens than rewards available - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_999 * 1e18); - - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131251903861097650 * 1e18 - }); - updaterBalance = _ajnaToken.balanceOf(_updater); - assertEq(updaterBalance, 1 * 1e18); - } - - function testClaimOnUpdateRateWithNoBalance() external { - // 3. update with no balance - staker should not receive any token but should be able to update rate - // burn all rewards manager tokens - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(_ajnaToken.balanceOf(address(_rewardsManager))); - - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131251903861097650 * 1e18 - }); - uint256 updaterBalance = _ajnaToken.balanceOf(_updater); - assertEq(updaterBalance, 0); - } -} - -/** - Claim Rewards should be constrained by pool balance and user provided limit: - 1. claim rewards with balance > rewards and rewards > limit - staker should receive rewards - 2. claim rewards with balance > rewards and rewards < limit - tx should revert - 3. claim rewards with balance < rewards and balance > limit - staker should receive balance - 4. claim rewards with balance < rewards and balance < limit - tx should revert - 5. claim rewards with balance = 0 and limit != 0 - tx should revert - 6. claim rewards with balance = 0 and limit = 0 - staker should receive no token - */ -contract ClaimRewardsTest is ClaimRewardsOnStakeTest { - - function testClaimOnClaimRewardsWithBalance() external { - uint256 claimSnapshot = vm.snapshot(); - - // 1. claim rewards with balance > rewards and rewards > limit - staker should receive rewards - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 19 * 1e18, - reward: 24.787511423166585895 * 1e18, - epochsClaimed: _epochsClaimedArray(1,0) - }); - uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.787511423166585895 * 1e18); - - vm.revertTo(claimSnapshot); - - // 2. claim rewards with balance > rewards and rewards < limit - tx should revert - _assertClaimRewardsInsufficientLiquidityRevert( - _minterOne, - tokenIdOne, - 25 * 1e18 - ); - } - - function testClaimOnClaimRewardsWithInsufficientFunds() external { - // burn rewards manager tokens to drive balance < reward - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_990 * 1e18); - - uint256 claimSnapshot = vm.snapshot(); - - // 3. claim rewards with balance < rewards and balance > limit - staker should receive balance - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 5 * 1e18, - reward: 24.787511423166585895 * 1e18, - epochsClaimed: _epochsClaimedArray(1,0) - }); - uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 10 * 1e18); - - vm.revertTo(claimSnapshot); - - // 4. claim rewards with balance < rewards and balance < limit - tx should revert - _assertClaimRewardsInsufficientLiquidityRevert( - _minterOne, - tokenIdOne, - 11 * 1e18 - ); - _assertClaimRewardsInsufficientLiquidityRevert( - _minterOne, - tokenIdOne, - 25 * 1e18 - ); - } - - function testClaimOnClaimRewardsWithNoBalance() external { - // burn all rewards manager tokens - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(_ajnaToken.balanceOf(address(_rewardsManager))); - - // 5. claim rewards with balance = 0 and limit != 0 - tx should revert - _assertClaimRewardsInsufficientLiquidityRevert( - _minterOne, - tokenIdOne, - 11 * 1e18 - ); - _assertClaimRewardsInsufficientLiquidityRevert( - _minterOne, - tokenIdOne, - 25 * 1e18 - ); - - // 6. claim rewards with balance = 0 and limit = 0 - staker should receive no token - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - reward: 24.787511423166585895 * 1e18, - epochsClaimed: _epochsClaimedArray(1,0) - }); - uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 0); - } -} - -/** - Unstake should be constrained by pool balance: - 1. unstake with balance > rewards - staker should receive rewards - 2. unstake with balance < rewards - tx should revert - */ -contract ClaimRewardsOnUnstakeTest is ClaimRewardsOnStakeTest { - - function testClaimOnUnstakeWithBalance() external { - // 1. unstake with balance > rewards - staker should receive rewards - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 24.787511423166585895 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 4.131251903861097650 * 1e18 - }); - uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.787511423166585895 * 1e18); - } - - function testClaimOnUnstakeWithInsufficientFunds() external { - // burn rewards manager tokens to drive balance < reward - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_990 * 1e18); - - uint256 unstakeSnapshot = vm.snapshot(); - - // 2. unstake with balance < rewards - tx should revert - _assertUnstakeInsufficientLiquidityRevert(_minterOne, tokenIdOne); - - // emergency unstake should unstake without any reward - _emergencyUnstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne - }); - uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 0); - - vm.revertTo(unstakeSnapshot); - - // burn all rewards manager tokens - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(_ajnaToken.balanceOf(address(_rewardsManager))); - - _assertUnstakeInsufficientLiquidityRevert(_minterOne, tokenIdOne); - - // emergency unstake should unstake without any reward - _emergencyUnstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne - }); - minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 0); - } -} diff --git a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol b/tests/forge/unit/Rewards/RewardsDSTestPlus.sol deleted file mode 100644 index b424608ca..000000000 --- a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol +++ /dev/null @@ -1,557 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.18; - -import 'src/RewardsManager.sol'; -import 'src/PoolInfoUtils.sol'; -import 'src/PositionManager.sol'; - -import 'src/interfaces/rewards/IRewardsManager.sol'; -import 'src/interfaces/position/IPositionManager.sol'; -import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; -import '@openzeppelin/contracts/token/ERC721/ERC721.sol'; - -import { Token } from '../../utils/Tokens.sol'; -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { IPoolErrors } from 'src/interfaces/pool/commons/IPoolErrors.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { PositionManager } from 'src/PositionManager.sol'; - -import { ERC20HelperContract } from '../ERC20Pool/ERC20DSTestPlus.sol'; -import { IRewardsManagerEvents } from 'src/interfaces/rewards/IRewardsManagerEvents.sol'; - -abstract contract RewardsDSTestPlus is IRewardsManagerEvents, ERC20HelperContract { - - address internal _minterOne; - address internal _minterTwo; - address internal _minterThree; - address internal _minterFour; - address internal _minterFive; - - ERC20 internal _ajnaToken; - - IPool internal _poolTwo; - IRewardsManager internal _rewardsManager; - IPositionManager internal _positionManager; - - uint256 internal REWARDS_CAP = 0.8 * 1e18; - - struct TriggerReserveAuctionParams { - address borrower; - uint256 borrowAmount; - uint256 limitIndex; - IPool pool; - } - - function _stakeToken(address pool, address owner, uint256 tokenId) internal { - changePrank(owner); - - // approve and deposit NFT into rewards contract - PositionManager(address(_positionManager)).approve(address(_rewardsManager), tokenId); - vm.expectEmit(true, true, true, true); - emit Stake(owner, address(pool), tokenId); - _rewardsManager.stake(tokenId); - - // check token was transferred to rewards contract - (address ownerInf, address poolInf, ) = _rewardsManager.getStakeInfo(tokenId); - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId), address(_rewardsManager)); - assertEq(ownerInf, owner); - assertEq(poolInf, pool); - } - - function _unstakeToken( - address owner, - address pool, - uint256[] memory claimedArray, - uint256 tokenId, - uint256 reward, - uint256[] memory indexes, - uint256 updateExchangeRatesReward - ) internal { - changePrank(owner); - - // unstake using emergency (without claiming rewards) - uint256 preEmergency = vm.snapshot(); - _emergencyUnstakeToken(owner, pool, tokenId); - _assertUnstakeInvariants(owner, tokenId); - vm.revertTo(preEmergency); - - // unstake gracefully (with claimed rewards) - _unstakeTokenGracefully( - owner, - pool, - claimedArray, - tokenId, - reward, - indexes, - updateExchangeRatesReward - ); - _assertUnstakeInvariants(owner, tokenId); - } - - function _unstakeTokenGracefully( - address owner, - address pool, - uint256[] memory claimedArray, - uint256 tokenId, - uint256 reward, - uint256[] memory indexes, - uint256 updateExchangeRatesReward - ) internal { - // token owner is Rewards manager - assertEq(ERC721(address(_positionManager)).ownerOf(tokenId), address(_rewardsManager)); - - if (updateExchangeRatesReward != 0) { - // when the token is unstaked updateExchangeRates emits - vm.expectEmit(true, true, true, true); - emit UpdateExchangeRates(owner, pool, indexes, updateExchangeRatesReward); - } - - if (claimedArray.length != 0) { - // when the token is unstaked claimRewards emits - vm.expectEmit(true, true, true, true); - emit ClaimRewards(owner, pool, tokenId, claimedArray, reward); - } - - // when the token is unstaked unstake emits - vm.expectEmit(true, true, true, true); - emit Unstake(owner, address(pool), tokenId); - _rewardsManager.unstake(tokenId); - - // token owner is staker - assertEq(ERC721(address(_positionManager)).ownerOf(tokenId), owner); - - // check exchange rates were updated - uint256 updateEpoch = IPool(pool).currentBurnEpoch(); - _assertBucketsUpdated(pool, indexes, updateEpoch); - } - - function _emergencyUnstakeToken( - address owner, - address pool, - uint256 tokenId - ) internal { - // token owner is Rewards manager - assertEq(ERC721(address(_positionManager)).ownerOf(tokenId), address(_rewardsManager)); - - // when the token is unstaked in emergency mode then no claim event is emitted - vm.expectEmit(true, true, true, true); - emit Unstake(owner, address(pool), tokenId); - _rewardsManager.emergencyUnstake(tokenId); - - // token owner is staker - assertEq(ERC721(address(_positionManager)).ownerOf(tokenId), owner); - } - - function _updateExchangeRates( - address updater, - address pool, - uint256[] memory indexes, - uint256 reward - ) internal { - changePrank(updater); - vm.expectEmit(true, true, true, true); - emit UpdateExchangeRates(updater, pool, indexes, reward); - _rewardsManager.updateBucketExchangeRatesAndClaim(pool, keccak256("ERC20_NON_SUBSET_HASH"), indexes); - - // check exchange rates were updated - uint256 updateEpoch = IPool(pool).currentBurnEpoch(); - _assertBucketsUpdated(pool, indexes, updateEpoch); - } - - function _epochsClaimedArray(uint256 numberOfAuctions_, uint256 lastClaimed_) internal pure returns (uint256[] memory epochsClaimed_) { - epochsClaimed_ = new uint256[](numberOfAuctions_); - uint256 claimEpoch = lastClaimed_; // starting index, not inclusive - - for (uint256 i = 0; i < numberOfAuctions_; i++) { - epochsClaimed_[i] = claimEpoch + 1; - claimEpoch += 1; - } - } - - function _claimRewards( - address from, - address pool, - uint256 tokenId, - uint256 minAmountToReceive, - uint256 reward, - uint256[] memory epochsClaimed - ) internal { - changePrank(from); - uint256 fromAjnaBal = _ajnaToken.balanceOf(from); - - uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - uint256 rewardTransferred = Maths.min(reward, managerBalance); - - uint256 currentBurnEpoch = IPool(pool).currentBurnEpoch(); - vm.expectEmit(true, true, true, true); - emit ClaimRewards(from, pool, tokenId, epochsClaimed, reward); - _rewardsManager.claimRewards(tokenId, currentBurnEpoch, minAmountToReceive); - - assertEq(_ajnaToken.balanceOf(from), fromAjnaBal + rewardTransferred); - } - - /***************/ - /*** Asserts ***/ - /***************/ - - function _assertUnstakeInvariants(address owner_, uint256 tokenId_) internal { - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId_), owner_); - - // check token was transferred from rewards contract to minter - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId_), owner_); - - // invariant: all bucket snapshots are removed for the token id that was unstaked - for (uint256 bucketIndex = 0; bucketIndex <= 7388; bucketIndex++) { - (uint256 lps, uint256 rate) = _rewardsManager.getBucketStateStakeInfo(tokenId_, bucketIndex); - assertEq(lps, 0); - assertEq(rate, 0); - } - - (address ownerInf, address poolInf, uint256 interactionBlockInf) = _rewardsManager.getStakeInfo(tokenId_); - assertEq(ownerInf, address(0)); - assertEq(poolInf, address(0)); - assertEq(interactionBlockInf, 0); - } - - function _assertBurn( - address pool, - uint256 epoch, - uint256 timestamp, - uint256 interest, - uint256 burned, - uint256 tokensToBurn - ) internal { - (uint256 bETimestamp, uint256 bEInterest, uint256 bEBurned) = IPool(pool).burnInfo(epoch); - - assertEq(bETimestamp, timestamp); - assertEq(bEInterest, interest); - assertEq(bEBurned, burned); - assertEq(burned, tokensToBurn); - } - - // check that an array of bucket indexes had their exchange rates updated - function _assertBucketsUpdated( - address pool_, - uint256[] memory indexes_, - uint256 epoch_ - ) internal { - for (uint256 i = 0; i < indexes_.length; ++i) { - assertTrue(_rewardsManager.isBucketUpdated(pool_, indexes_[i], epoch_)); - } - } - - function _assertNotOwnerOfDepositRevert(address from , uint256 tokenId) internal { - // check only deposit owner can claim rewards - changePrank(from); - uint256 currentBurnEpoch = _pool.currentBurnEpoch(); - vm.expectRevert(IRewardsManagerErrors.NotOwnerOfDeposit.selector); - _rewardsManager.claimRewards(tokenId, currentBurnEpoch, 0); - } - - function _assertNotOwnerOfDepositUnstakeRevert(address from , uint256 tokenId) internal { - // check only deposit owner can unstake - changePrank(from); - vm.expectRevert(IRewardsManagerErrors.NotOwnerOfDeposit.selector); - _rewardsManager.unstake(tokenId); - } - - function _assertAlreadyClaimedRevert(address from , uint256 tokenId) internal { - // check if rewards can only be claimed once - changePrank(from); - uint256 currentBurnEpoch = _pool.currentBurnEpoch(); - vm.expectRevert(IRewardsManagerErrors.AlreadyClaimed.selector); - _rewardsManager.claimRewards(tokenId, currentBurnEpoch, 0); - } - - function _assertUnstakeInsufficientLiquidityRevert(address from, uint256 tokenId) internal { - // should revert if token balance is less than rewards to claim - changePrank(from); - vm.expectRevert(IRewardsManagerErrors.InsufficientLiquidity.selector); - _rewardsManager.unstake(tokenId); - } - - function _assertClaimRewardsInsufficientLiquidityRevert(address from, uint256 tokenId, uint256 minRewardToClaim) internal { - // should revert if token balance is less than rewards to claim - changePrank(from); - uint256 currentBurnEpoch = _pool.currentBurnEpoch(); - vm.expectRevert(IRewardsManagerErrors.InsufficientLiquidity.selector); - _rewardsManager.claimRewards(tokenId, currentBurnEpoch, minRewardToClaim); - } - - function _assertStake( - address owner, - address pool, - uint256 tokenId, - uint256 burnEvent, - uint256 rewardsEarned - ) internal { - uint256 currentBurnEpoch = _pool.currentBurnEpoch(); - (address ownerInf, address poolInf, uint256 interactionBurnEvent) = _rewardsManager.getStakeInfo(tokenId); - uint256 rewardsEarnedInf = _rewardsManager.calculateRewards(tokenId, currentBurnEpoch); - - assertEq(ownerInf, owner); - assertEq(poolInf, pool); - assertEq(interactionBurnEvent, burnEvent); - assertEq(rewardsEarnedInf, rewardsEarned); - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId), address(_rewardsManager)); - } -} - -abstract contract RewardsHelperContract is RewardsDSTestPlus { - - address internal _bidder; - address internal _updater; - address internal _updater2; - - Token internal _collateralOne; - Token internal _quoteOne; - Token internal _collateralTwo; - Token internal _quoteTwo; - - constructor() { - vm.makePersistent(_ajna); - - _ajnaToken = ERC20(_ajna); - _positionManager = new PositionManager(_poolFactory, new ERC721PoolFactory(_ajna)); - _rewardsManager = new RewardsManager(_ajna, _positionManager); - - _collateralOne = new Token("Collateral 1", "C1"); - _quoteOne = new Token("Quote 1", "Q1"); - _collateralTwo = new Token("Collateral 2", "C2"); - _quoteTwo = new Token("Quote 2", "Q2"); - - _poolTwo = ERC20Pool(_poolFactory.deployPool(address(_collateralTwo), address(_quoteTwo), 0.05 * 10**18)); - - // provide initial ajna tokens to staking rewards contract - deal(_ajna, address(_rewardsManager), 100_000_000 * 1e18); - assertEq(_ajnaToken.balanceOf(address(_rewardsManager)), 100_000_000 * 1e18); - } - - // create a new test borrower with quote and collateral sufficient to draw a specified amount of debt - function _createTestBorrower(address pool, address borrower, uint256 borrowAmount, uint256 limitIndex) internal returns (uint256 collateralToPledge_) { - - changePrank(borrower); - Token collateral = Token(ERC20Pool(address(pool)).collateralAddress()); - Token quote = Token(ERC20Pool(address(pool)).quoteTokenAddress()); - // deal twice as much quote so the borrower has sufficient quote to repay the loan - deal(address(quote), borrower, Maths.wmul(borrowAmount, Maths.wad(2))); - - // approve tokens - collateral.approve(address(pool), type(uint256).max); - quote.approve(address(pool), type(uint256).max); - - collateralToPledge_ = _requiredCollateral(borrowAmount, limitIndex); - deal(address(collateral), borrower, collateralToPledge_); - } - - function _triggerReserveAuctionsNoTake( - address borrower, - address pool, - uint256 borrowAmount, - uint256 limitIndex - ) internal { - // create a new borrower to write state required for reserve auctions - uint256 collateralToPledge = _createTestBorrower(address(pool), borrower, borrowAmount, limitIndex); - - // borrower drawsDebt from the pool - ERC20Pool(address(pool)).drawDebt(borrower, borrowAmount, limitIndex, collateralToPledge); - - // allow time to pass for interest to accumulate - skip(26 weeks); - - // borrower repays some of their debt, providing reserves to be claimed - // don't pull any collateral, as such functionality is unrelated to reserve auctions - ERC20Pool(address(pool)).repayDebt(borrower, Maths.wdiv(borrowAmount, Maths.wad(2)), 0, borrower, MAX_FENWICK_INDEX); - - // start reserve auction - _kickReserveAuction(address(pool), _bidder); - } - - function _kickReserveAuction( - address pool, - address bidder - ) internal { - changePrank(bidder); - _ajnaToken.approve(address(pool), type(uint256).max); - ERC20Pool(address(pool)).kickReserveAuction(); - } - - function _mintAndMemorializePositionNFT( - address minter, - uint256 mintAmount, - address pool, - uint256[] memory indexes - ) internal returns (uint256 tokenId_) { - changePrank(minter); - - Token collateral = Token(ERC20Pool(address(pool)).collateralAddress()); - Token quote = Token(ERC20Pool(address(pool)).quoteTokenAddress()); - - // deal tokens to the minter - deal(address(quote), minter, mintAmount * indexes.length); - - // approve tokens - collateral.approve(address(pool), type(uint256).max); - quote.approve(address(pool), type(uint256).max); - - tokenId_ = _positionManager.mint(address(pool), minter, keccak256("ERC20_NON_SUBSET_HASH")); - - uint256[] memory lpBalances = new uint256[](indexes.length); - - for (uint256 i = 0; i < indexes.length; i++) { - ERC20Pool(address(pool)).addQuoteToken(mintAmount, indexes[i], type(uint256).max, false); - (lpBalances[i], ) = ERC20Pool(address(pool)).lenderInfo(indexes[i], minter); - } - - ERC20Pool(address(pool)).increaseLPAllowance(address(_positionManager), indexes, lpBalances); - - _positionManager.memorializePositions(pool, tokenId_, indexes); - - // register position manager as lender at memorialized indexes (for LP test assertions) - _registerLender(address(_positionManager), indexes); - } - - function _triggerReserveAuctions( - address borrower, - address pool, - uint256 borrowAmount, - uint256 limitIndex, - uint256 tokensToBurn - ) internal returns (uint256 tokensBurned_) { - - // fund borrower to write state required for reserve auctions - changePrank(borrower); - Token collateral = Token(ERC20Pool(address(pool)).collateralAddress()); - Token quote = Token(ERC20Pool(address(pool)).quoteTokenAddress()); - deal(address(quote), borrower, borrowAmount); - - // approve tokens - collateral.approve(address(pool), type(uint256).max); - quote.approve(address(pool), type(uint256).max); - - uint256 collateralToPledge = _requiredCollateral(borrowAmount, limitIndex); - deal(address(_collateral), borrower, collateralToPledge); - - // borrower drawsDebt from the pool - ERC20Pool(address(pool)).drawDebt(borrower, borrowAmount, limitIndex, collateralToPledge); - - // allow time to pass for interest to accumulate - skip(26 weeks); - - // borrower repays some of their debt, providing reserves to be claimed - // don't pull any collateral, as such functionality is unrelated to reserve auctions - ERC20Pool(address(pool)).repayDebt(borrower, borrowAmount, 0, borrower, MAX_FENWICK_INDEX); - - // start reserve auction - changePrank(_bidder); - _ajnaToken.approve(address(pool), type(uint256).max); - ERC20Pool(address(pool)).kickReserveAuction(); - - // Can't trigger reserve auction if less than two weeks have passed since last auction - vm.expectRevert(IPoolErrors.ReserveAuctionTooSoon.selector); - ERC20Pool(address(pool)).kickReserveAuction(); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves(pool, _bidder); - - (,, tokensBurned_) = IPool(pool).burnInfo(IPool(pool).currentBurnEpoch()); - assertEq(tokensBurned_, tokensToBurn); - - return tokensBurned_; - } - - function _triggerReserveAuctionsBurnUnknown( - address borrower, - address pool, - uint256 borrowAmount, - uint256 limitIndex - ) internal returns (uint256 tokensBurned_) { - - // fund borrower to write state required for reserve auctions - changePrank(borrower); - Token collateral = Token(ERC20Pool(address(pool)).collateralAddress()); - Token quote = Token(ERC20Pool(address(pool)).quoteTokenAddress()); - deal(address(quote), borrower, borrowAmount); - - // approve tokens - collateral.approve(address(pool), type(uint256).max); - quote.approve(address(pool), type(uint256).max); - - uint256 collateralToPledge = _requiredCollateral(borrowAmount, limitIndex); - deal(address(_collateral), borrower, collateralToPledge); - - // borrower drawsDebt from the pool - ERC20Pool(address(pool)).drawDebt(borrower, borrowAmount, limitIndex, collateralToPledge); - - // allow time to pass for interest to accumulate - skip(26 weeks); - - // borrower repays some of their debt, providing reserves to be claimed - // don't pull any collateral, as such functionality is unrelated to reserve auctions - ERC20Pool(address(pool)).repayDebt(borrower, borrowAmount, 0, borrower, MAX_FENWICK_INDEX); - - // start reserve auction - changePrank(_bidder); - _ajnaToken.approve(address(pool), type(uint256).max); - ERC20Pool(address(pool)).kickReserveAuction(); - - // Can't trigger reserve auction if less than two weeks have passed since last auction - vm.expectRevert(IPoolErrors.ReserveAuctionTooSoon.selector); - ERC20Pool(address(pool)).kickReserveAuction(); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves(pool, _bidder); - - (,, tokensBurned_) = IPool(pool).burnInfo(IPool(pool).currentBurnEpoch()); - - return tokensBurned_; - } - - function _takeReserves(address pool, address from) internal { - changePrank(from); - ( - , - , - uint256 curClaimableReservesRemaining, - , - ) = _poolUtils.poolReservesInfo(pool); - - ERC20Pool(pool).takeReserves(curClaimableReservesRemaining); - } - - function _requiredCollateral(ERC20Pool pool_, uint256 borrowAmount, uint256 indexPrice) internal view returns (uint256 requiredCollateral_) { - // calculate the required collateral based upon the borrow amount and index price - (uint256 interestRate, ) = pool_.interestRateInfo(); - uint256 newInterestRate = Maths.wmul(interestRate, 1.1 * 10**18); // interest rate multipled by increase coefficient - uint256 expectedDebt = Maths.wmul(borrowAmount, _borrowFeeRate(newInterestRate) + Maths.WAD); - requiredCollateral_ = Maths.wdiv(expectedDebt, _poolUtils.indexToPrice(indexPrice)) + Maths.WAD; - } - - // Helper function that returns a random subset from array - function _getRandomSubsetFromArray(uint256[] memory array) internal returns (uint256[] memory subsetArray) { - uint256[] memory copyOfArray = new uint256[](array.length); - for (uint j = 0; j < copyOfArray.length; j++){ - copyOfArray[j] = array[j]; - } - uint256 randomNoOfNfts = randomInRange(1, copyOfArray.length); - subsetArray = new uint256[](randomNoOfNfts); - for (uint256 i = 0; i < randomNoOfNfts; i++) { - uint256 randomIndex = randomInRange(0, copyOfArray.length - i - 1); - subsetArray[i] = copyOfArray[randomIndex]; - copyOfArray[randomIndex] = copyOfArray[copyOfArray.length - i - 1]; - } - } - - // Returns N addresses array - function _getAddresses(uint256 noOfAddress) internal returns(address[] memory addresses_) { - addresses_ = new address[](noOfAddress); - for (uint i = 0; i < noOfAddress; i++) { - addresses_[i] = makeAddr(string(abi.encodePacked("Minter", Strings.toString(i)))); - } - } -} diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol deleted file mode 100644 index cbefbb353..000000000 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ /dev/null @@ -1,2985 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED -pragma solidity 0.8.18; - -import 'src/PoolInfoUtils.sol'; -import 'src/RewardsManager.sol'; -import 'src/PositionManager.sol'; -import 'src/interfaces/rewards/IRewardsManager.sol'; - -import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { RewardsHelperContract } from './RewardsDSTestPlus.sol'; -import { IPoolErrors } from 'src/interfaces/pool/commons/IPoolErrors.sol'; -import { IPositionManagerErrors } from 'src/interfaces/position/IPositionManagerErrors.sol'; -import { Token } from '../../utils/Tokens.sol'; -import { RoguePool } from './RoguePool.sol'; - -contract RewardsManagerTest is RewardsHelperContract { - - address internal _borrower; - address internal _borrower2; - address internal _borrower3; - address internal _lender; - address internal _lender1; - - uint256 constant BLOCKS_IN_DAY = 7200; - mapping (uint256 => address) internal tokenIdToMinter; - mapping (address => uint256) internal minterToBalance; - - function setUp() external { - _startTest(); - - // borrowers - _borrower = makeAddr("borrower"); - _borrower2 = makeAddr("borrower2"); - _borrower3 = makeAddr("borrower3"); - - _lender = makeAddr("lender"); - _lender1 = makeAddr("lender1"); - - // instantiate test minters - _minterOne = makeAddr("minterOne"); - _minterTwo = makeAddr("minterTwo"); - _minterThree = makeAddr("minterThree"); - _minterFour = makeAddr("minterFour"); - _minterFive = makeAddr("minterFive"); - - // instantiate test bidder - _bidder = makeAddr("bidder"); - deal(address(_ajna), _bidder, 900_000_000 * 10**18); - - changePrank(_bidder); - _ajnaToken.approve(address(_pool), type(uint256).max); - ERC20(address(_quoteOne)).approve(address(_pool), type(uint256).max); - ERC20(address(_quoteTwo)).approve(address(_pool), type(uint256).max); - - // instantiate test updater - _updater = makeAddr("updater"); - _updater2 = makeAddr("updater2"); - - _mintCollateralAndApproveTokens(_borrower, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower, 200_000 * 1e18); - - _mintCollateralAndApproveTokens(_borrower2, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower2, 200_000 * 1e18); - - _mintCollateralAndApproveTokens(_borrower3, 1_000 * 1e18); - _mintQuoteAndApproveTokens(_borrower3, 200_000 * 1e18); - - _mintQuoteAndApproveTokens(_lender, 200_000 * 1e18); - _mintQuoteAndApproveTokens(_lender1, 200_000 * 1e18); - - _mintQuoteAndApproveTokens(_minterOne, 500_000_000 * 1e18); - _mintQuoteAndApproveTokens(_minterTwo, 500_000_000 * 1e18); - } - - function testDeployWith0xAddressRevert() external { - PositionManager positionManager = new PositionManager(_poolFactory, new ERC721PoolFactory(_ajna)); - - vm.expectRevert(IRewardsManagerErrors.DeployWithZeroAddress.selector); - new RewardsManager(address(0), positionManager); - - PositionManager zeroPositionManager; - - vm.expectRevert(IRewardsManagerErrors.DeployWithZeroAddress.selector); - new RewardsManager(address(_ajnaToken), zeroPositionManager); - } - - function testStakeToken() external { - skip(10); - - // configure NFT position one - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 9; - depositIndexes[1] = 1; - depositIndexes[2] = 2; - depositIndexes[3] = 3; - depositIndexes[4] = 4; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // configure NFT position two - depositIndexes = new uint256[](4); - depositIndexes[0] = 5; - depositIndexes[1] = 1; - depositIndexes[2] = 3; - depositIndexes[3] = 12; - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterTwo, - mintAmount: 1_000 * 1e18, - pool: address(_poolTwo) - }); - - // check only owner of an NFT can deposit it into the rewards contract - _assertNotOwnerOfDepositRevert({ - from: _minterTwo, - tokenId: tokenIdOne - }); - - // minterOne deposits their NFT into the rewards contract - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - // minterTwo deposits their NFT into the rewards contract - _stakeToken({ - pool: address(_poolTwo), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - } - - function testUnstakeToken() external { - skip(10); - - // configure NFT position one - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 9; - depositIndexes[1] = 1; - depositIndexes[2] = 2; - depositIndexes[3] = 3; - depositIndexes[4] = 4; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // check only owner of an NFT can deposit it into the rewards contract - _assertNotOwnerOfDepositRevert({ - from: _minterTwo, - tokenId: tokenIdOne - }); - - // minterOne deposits their NFT into the rewards contract - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - // only owner should be able to withdraw the NFT - _assertNotOwnerOfDepositUnstakeRevert({ - from: _minterTwo, - tokenId: tokenIdOne - }); - - uint256[] memory claimedArray = new uint256[](0); - - _unstakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne, - claimedArray: claimedArray, // no rewards as no reserve auctions have occured - reward: 0, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - } - - function testUnstakeTokenAfterBurnNoInterest() external { - skip(10); - ERC20Pool pool = ERC20Pool(address(_pool)); - - // deposit into a high and low bucket - deal(address(_quoteOne), _minterOne, 400 * 1e18); - changePrank(_minterOne); - _quoteOne.approve(address(_pool), type(uint256).max); - _pool.addQuoteToken(200 * 1e18, 2_000, type(uint256).max, false); - _pool.addQuoteToken(200 * 1e18, 4_000, type(uint256).max, false); - skip(1 hours); - - // draw debt between the buckets - uint256 borrowAmount = 100 * 1e18; - uint256 limitIndex = 3_000; - assertGt(_pool.depositSize(), borrowAmount); - ( - uint256 collateralToPledge - ) = _createTestBorrower(address(_pool), _borrower, borrowAmount, limitIndex); - pool.drawDebt(_borrower, borrowAmount, limitIndex, collateralToPledge); - skip(3 days); - (,,, uint256 htpIndex,,) = _poolUtils.poolPricesInfo(address(_pool)); - assertLt(htpIndex, 4_000); - - // mint LP NFT and memorialize position for only the bucket which did not earn interest - (uint256 lpBalance, ) = _pool.lenderInfo(4000, _minterOne); - assertGt(lpBalance, 0); - uint256[] memory indexes = new uint256[](1); - indexes[0] = 4_000; - uint256[] memory lpBalances = new uint256[](1); - lpBalances[0] = lpBalance; - changePrank(_minterOne); - _pool.increaseLPAllowance(address(_positionManager), indexes, lpBalances); - uint256 tokenId = _positionManager.mint(address(_pool), _minterOne, keccak256("ERC20_NON_SUBSET_HASH")); - _positionManager.memorializePositions(address(_pool), tokenId, indexes); - _registerLender(address(_positionManager), indexes); - skip(4 days); - - // stake rewards - _stakeToken(address(_pool), _minterOne, tokenId); - skip(7 days); - - // repay debt to accumulate some reserves - changePrank(_borrower); - pool.repayDebt(_borrower, type(uint256).max, collateralToPledge, _borrower, MAX_FENWICK_INDEX); - skip(2 hours); - - // burn - changePrank(_bidder); - pool.kickReserveAuction(); - skip(11 hours); - _ajnaToken.approve(address(_pool), type(uint256).max); - (,, uint256 curClaimableReservesRemaining,,) = _poolUtils.poolReservesInfo(address(_pool)); - _pool.takeReserves(curClaimableReservesRemaining); - - // unstake with no interest earned - changePrank(_minterOne); - vm.expectEmit(true, true, true, true); - emit Unstake(_minterOne, address(_pool), tokenId); - _rewardsManager.unstake(tokenId); - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId), _minterOne); - } - - function testUnstakeNoBurn() external { - skip(10); - ERC20Pool pool = ERC20Pool(address(_pool)); - - // deposit into some buckets and mint an NFT - uint256[] memory indexes = new uint256[](3); - indexes[0] = 2000; - indexes[1] = 2500; - indexes[2] = 3000; - uint256 tokenId = _mintAndMemorializePositionNFT({ - indexes: indexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // draw debt - uint256 borrowAmount = 1_500 * 1e18; - uint256 limitIndex = 2_500; - assertEq(_pool.depositIndex(borrowAmount), limitIndex); - assertGt(_pool.depositSize(), borrowAmount); - ( - uint256 collateralToPledge - ) = _createTestBorrower(address(_pool), _borrower, borrowAmount, limitIndex); - pool.drawDebt(_borrower, borrowAmount, limitIndex, collateralToPledge); - skip(3 days); - - // stake rewards - _stakeToken(address(_pool), _minterOne, tokenId); - skip(7 days); - - // repay debt to accumulate some reserves - changePrank(_borrower); - pool.repayDebt(_borrower, type(uint256).max, collateralToPledge, _borrower, MAX_FENWICK_INDEX); - skip(2 hours); - - // start auction, but no burn - changePrank(_bidder); - pool.kickReserveAuction(); - skip(11 hours); - - // unstake - changePrank(_minterOne); - vm.expectEmit(true, true, true, true); - emit Unstake(_minterOne, address(_pool), tokenId); - _rewardsManager.unstake(tokenId); - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenId), _minterOne); - } - - function testUpdateExchangeRatesAndClaimRewards() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 9; - depositIndexes[1] = 1; - depositIndexes[2] = 2; - depositIndexes[3] = 3; - depositIndexes[4] = 4; - - // mint memorialize and deposit NFT - uint256 tokenId = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // should revert if not an Ajna pool - address fakePool = makeAddr("fakePool"); - vm.expectRevert(); - _rewardsManager.updateBucketExchangeRatesAndClaim( - fakePool, keccak256("ERC20_NON_SUBSET_HASH"), depositIndexes - ); - // should revert if Ajna pool but wrong subset - vm.expectRevert(IRewardsManagerErrors.NotAjnaPool.selector); - _rewardsManager.updateBucketExchangeRatesAndClaim( - address(_pool), keccak256("ERC721_NON_SUBSET_HASH"), depositIndexes - ); - // no rewards earned if legit Ajna pool - uint256 rewards = _rewardsManager.updateBucketExchangeRatesAndClaim( - address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), depositIndexes - ); - assertEq(rewards, 0); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenId - }); - - // borrower takes actions providing reserves enabling reserve auctions - // bidder takes reserve auctions by providing ajna tokens to be burned - uint256 tokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - borrowAmount: 300 * 1e18, - limitIndex: 3, - pool: address(_pool), - tokensToBurn: 82.625336100445516170 * 1e18 - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022275123 * 1e18 - }); - - // check only deposit owner can claim rewards - _assertNotOwnerOfDepositRevert({ - from: _updater, - tokenId: tokenId - }); - - // claim rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenId, - minAmountToReceive: 0, - reward: 41.312668050222751231 * 1e18, - epochsClaimed: _epochsClaimedArray(1, 0) - }); - - // check can't claim rewards twice - _assertAlreadyClaimedRevert({ - from: _minterOne, - tokenId: tokenId - }); - - _assertStake({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenId, - burnEvent: 1, - rewardsEarned: 0 - }); - assertEq(_ajnaToken.balanceOf(_minterOne), 41.312668050222751231 * 1e18); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 82.625336100445516170 * 1e18, - tokensToBurn: tokensToBurn, - interest: 6.443638300196908069 * 1e18 - }); - - skip(2 weeks); - - // check can't call update exchange rate after the update period has elapsed - uint256 updateRewards = _rewardsManager.updateBucketExchangeRatesAndClaim( - address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), depositIndexes - ); - assertEq(updateRewards, 0); - - // check unstake will only emit Unstake event since block.timestamp > curBurnTime + UPDATE_PERIOD - vm.expectEmit(true, true, true, true); - emit Unstake(_minterOne, address(_pool), tokenId); - _rewardsManager.unstake(tokenId); - } - - function testWithdrawAndClaimRewardsNoExchangeRateUpdate() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // epoch 0 - 1 is checked for rewards - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - // first reserve auction happens successfully -> epoch 1 - uint256 tokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2_555, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming for epoch 0 - 1 - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022279800 * 1e18 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 82.625336100445635379 * 1e18, - tokensToBurn: tokensToBurn, - interest: 6.443638300196908069 * 1e18 - }); - - // second reserve auction happens successfully -> epoch 2 - tokensToBurn += _triggerReserveAuctions({ - borrower: _borrower, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool), - tokensToBurn: 152.051743197066838325 * 1e18 - }); - - // check owner can withdraw the NFT and rewards will be automatically claimed - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(2, 0), - reward: 79.497191953364437697 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 3.471320354831058155 * 1e18 - }); - } - - function testWithdrawAndClaimRewardsNoReserveTake() external { - - // healthy epoch, bad epoch - - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1000 * 1e18, - pool: address(_pool) - }); - - // epoch 0 - 1 is checked for rewards - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - // first reserve auction happens successfully Staker should receive rewards epoch 0 - 1 - uint256 tokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - //call update exchange rate to enable claiming rewards for epoch 0 - 1 - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022279800 * 1e18 - }); - - skip(2 weeks); - - // second reserve auction is kicked, no take - _triggerReserveAuctionsNoTake({ - borrower: _borrower, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - (2 weeks + 26 weeks + 24 hours), - burned: 82.625336100445635379 * 1e18, - tokensToBurn: tokensToBurn, - interest: 6.443638300196908069 * 1e18 - }); - - // no take has been called on reserveAuction therefore totalBurned is zero. No rewards to distribute - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 0 - }); - } - - // two lenders stake their positions in the pool - // staker one bucket bankrupt, staker two bucket active - // interest accrued to both buckets, but staker one receives no rewards - function testClaimRewardsBankruptBucket() external { - - address[] memory transferors = new address[](1); - transferors[0] = address(_positionManager); - - changePrank(_minterOne); - _quote.approve(address(_positionManager), type(uint256).max); - _pool.approveLPTransferors(transferors); - - changePrank(_minterTwo); - _quote.approve(address(_positionManager), type(uint256).max); - _pool.approveLPTransferors(transferors); - - /*****************************/ - /*** Initialize Pool State ***/ - /*****************************/ - - // MinterOne adds Quote token accross 5 prices - _addInitialLiquidity({ - from: _minterOne, - amount: 2_000 * 1e18, - index: _i9_91 - }); - _addInitialLiquidity({ - from: _minterOne, - amount: 5_000 * 1e18, - index: _i9_81 - }); - _addInitialLiquidity({ - from: _minterOne, - amount: 11_000 * 1e18, - index: _i9_72 - }); - _addInitialLiquidity({ - from: _minterOne, - amount: 25_000 * 1e18, - index: _i9_62 - }); - _addInitialLiquidity({ - from: _minterOne, - amount: 30_000 * 1e18, - index: _i9_52 - }); - - // first borrower adds collateral token and borrows - _pledgeCollateral({ - from: _borrower, - borrower: _borrower, - amount: 2 * 1e18 - }); - _borrow({ - from: _borrower, - amount: 19.25 * 1e18, - indexLimit: _i9_91, - newLup: 9.917184843435912074 * 1e18 - }); - - // second borrower adds collateral token and borrows - _pledgeCollateral({ - from: _borrower2, - borrower: _borrower2, - amount: 1_000 * 1e18 - }); - _borrow({ - from: _borrower2, - amount: 9_710 * 1e18, - indexLimit: _i9_72, - newLup: 9.721295865031779605 * 1e18 - }); - - /*****************************/ - /*** Lenders Deposits NFTs ***/ - /*****************************/ - - // set deposit indexes - uint256[] memory depositIndexes = new uint256[](1); - uint256[] memory depositIndexes2 = new uint256[](1); - depositIndexes[0] = _i9_91; - depositIndexes2[0] = _i9_81; - - // ERC20Pool pool = ERC20Pool(address(_pool)); - - // stake NFT position one - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 2_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - - // stake NFT position two - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes2, - minter: _minterTwo, - mintAmount: 5_000 * 1e18, - pool: address(_pool) - }); - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - - /***********************************/ - /*** Borrower Bankrupts A Bucket ***/ - /***********************************/ - - // Skip to make borrower two undercollateralized - skip(100 days); - - // all QT was inserted when minting NFT, provide more to kick - deal(address(_quote), _minterTwo, 10_000 * 1e18); - - _kick({ - from: _minterTwo, - borrower: _borrower2, - debt: 9_853.394241979221645666 * 1e18, - collateral: 1_000 * 1e18, - bond: 149.577873638769639523 * 1e18, - transferAmount: 149.577873638769639523 * 1e18 - }); - - // skip ahead so take can be called on the loan - skip(9 hours); - - // take entire collateral - _take({ - from: _minterTwo, - borrower: _borrower2, - maxCollateral: 1_000 * 1e18, - bondChange: 60.911699561320164197 * 1e18, - givenAmount: 4012.538586931187076000 * 1e18, - collateralTaken: 1_000 * 1e18, - isReward: true - }); - - _settle({ - from: _minterTwo, - borrower: _borrower2, - maxDepth: 10, - settledDebt: 5_821.652652511646951630 * 1e18 - }); - - // bucket is insolvent, balances are reset - _assertBucket({ - index: _i9_91, - lpBalance: 0, // bucket is bankrupt - collateral: 0, - deposit: 0, - exchangeRate: 1 * 1e18 - }); - - // lower priced bucket isn't bankrupt, but exchange rate has decreased - _assertBucket({ - index: _i9_81, - lpBalance: 10_000 * 1e18, - collateral: 0, - deposit: 8_191.675009896270870814 * 1e18, - exchangeRate: 0.819167500989627088 * 1e18 - }); - - /***********************/ - /*** Reserve Auction ***/ - /***********************/ - - // skip some time to accumulate reserves - skip(1000 days); - - // update pool reserves - _pool.updateInterest(); - - // start reserve auction - _kickReserveAuction({ - pool: address(_pool), - bidder: _bidder - }); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - ( - , - , - uint256 curClaimableReservesRemaining, - , - ) = _poolUtils.poolReservesInfo(address(_pool)); - - // take claimable reserves - changePrank(_bidder); - _pool.takeReserves(curClaimableReservesRemaining); - - /*********************/ - /*** Claim Rewards ***/ - /*********************/ - // _minterOne withdraws and claims rewards, rewards should be 0 - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 0, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - // _minterTwo withdraws and claims rewards, rewards should be 0 as their bucket exchange rate decreased - _unstakeToken({ - owner: _minterTwo, - pool: address(_pool), - tokenId: tokenIdTwo, - claimedArray: _epochsClaimedArray(1, 0), - reward: 0, - indexes: depositIndexes2, - updateExchangeRatesReward: 0 - }); - } - - function testNoRewardsToClaimPostBankrupt() external { - skip(10); - - /***************************/ - /*** Lender Deposits NFT ***/ - /***************************/ - - // set deposit indexes - uint256[] memory depositIndexes = new uint256[](2); - uint256[] memory depositIndex1 = new uint256[](1); - uint256[] memory depositIndex2 = new uint256[](1); - depositIndexes[0] = 2770; - depositIndexes[1] = 2771; - depositIndex1[0] = 2771; - depositIndex2[0] = 2770; - - // configure NFT position one - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 10_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /************************************/ - /*** Borrower One Accrue Interest ***/ - /************************************/ - - // borrower borrows - (uint256 collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 10_000 * 1e18, 2770); - - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 5 * 1e18, - limitIndex: 2770, - collateralToPledge: collateralToPledge, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // pass time to allow interest to accrue - skip(2 hours); - - // borrower repays their loan - (uint256 debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 5.004807692307692310 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - // start reserve auction - _kickReserveAuction({ - pool: address(_pool), - bidder: _bidder - }); - - // _borrower now takes out more debt to accumulate more interest - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 2_000 * 1e18, - limitIndex: 2770, - collateralToPledge: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves({ - pool: address(_pool), - from: _bidder - }); - - (,, uint256 tokensBurned) = IPool(address(_pool)).burnInfo(IPool(address(_pool)).currentBurnEpoch()); - - // recorder updates the change in exchange rates in the first index - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndex1, - reward: 0.007146561992635801 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 0.007146561992635801 * 1e18); - - _assertBurn({ - pool: address(_pool), - epoch: 0, - timestamp: 0, - burned: 0, - interest: 0, - tokensToBurn: 0 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 0.285862479721117855 * 1e18, - interest: 0.000048562908902619 * 1e18, - tokensToBurn: tokensBurned - }); - - // skip more time to allow more interest to accrue - skip(10 days); - - // borrower repays their loan again - (debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 2_001.900281182536528587 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // recorder updates the change in exchange rates in the second index - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndex2, - reward: 0.021439685979475985 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 0.021439685979475985 * 1e18); - - // assert minterOne has rewards to be claimed - uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 0.228689983776894284 * 1e18); - - _assertBucket({ - index: 2770, - lpBalance: 10000000000000000000000, - collateral: 0, - deposit: 10_001.283047927145090000 * 1e18, - exchangeRate: 1000128304792714509 - }); - - _assertBucket({ - index: 2771, - lpBalance: 10000000000000000000000, - collateral: 0, - deposit: 10_001.283047927145090000 * 1e18, - exchangeRate: 1000128304792714509 - }); - - /***************************************************************/ - /*** Borrower One Accrue Interest for second reserve auction ***/ - /***************************************************************/ - - // borrower borrows - (collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 10_000 * 1e18, 2770); - - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 5 * 1e18, - limitIndex: 2770, - collateralToPledge: collateralToPledge, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // pass time to allow interest to accrue - skip(2 hours); - - // borrower repays their loan - (debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 8.034323493614017007 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - /******************************/ - /*** Second Reserve Auction ***/ - /******************************/ - skip(2 weeks); - - // start reserve auction - _kickReserveAuction({ - pool: address(_pool), - bidder: _bidder - }); - - // _borrower now takes out more debt to accumulate more interest - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 2_000 * 1e18, - limitIndex: 2770, - collateralToPledge: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves({ - pool: address(_pool), - from: _bidder - }); - - (,,tokensBurned) = IPool(address(_pool)).burnInfo(IPool(address(_pool)).currentBurnEpoch()); - - // recorder updates the change in exchange rates in the first index - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndex1, - reward: 3.547459596875587275 * 1e18 - }); - - assertEq(_ajnaToken.balanceOf(_updater), 3.554606158868223076 * 1e18); - - _assertBurn({ - pool: address(_pool), - epoch: 2, - timestamp: block.timestamp - 24 hours, - burned: 142.184246354747130336 * 1e18, - interest: 2.566194585267388219 * 1e18, - tokensToBurn: tokensBurned - }); - - // skip more time to allow more interest to accrue - skip(10 days); - - // borrower repays their loan again - (debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 1_995.045633466463004690 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // recorder updates the change in exchange rates in the second index - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndex2, - reward: 3.192497129782555259 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 3.213936815762031244 * 1e18); - - // assert minterOne has more rewards to be claimed - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 67.628257250358319615 * 1e18); - - // QT is adeed to a bucket - deal(address(_quote), _minterOne, 100 * 1e18 * depositIndexes.length + 6_000.0 * 1e18); - changePrank(_minterOne); - uint256[] memory lpBalances = new uint256[](depositIndexes.length); - for (uint256 i = 0; i < depositIndexes.length; i++) { - ERC20Pool(address(_pool)).addQuoteToken(100 * 1e18, depositIndexes[i], type(uint256).max, false); - (lpBalances[i], ) = ERC20Pool(address(_pool)).lenderInfo(depositIndexes[i], _minterOne); - } - - // add more QT so borrower can draw enough debt to bankrupt bucket - ERC20Pool(address(_pool)).addQuoteToken(6_000.0 * 1e18, 2775, type(uint256).max, false); - - // borrower borrows - (collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 25_000 * 1e18, 2775); - - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 25_000 * 1e18, - limitIndex: MAX_FENWICK_INDEX, - collateralToPledge: 6 * 1e18, - newLup: 980.237438737934313685 * 1e18 - }); - - // pass time to allow interest to accrue - skip(2 hours); - - // Skip to make borrower undercollateralized - skip(200 days); - - - // all QT was inserted when minting NFT, provide more to kick - deal(address(_quote), _minterTwo, 10_000 * 1e18); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 25656.385808102176964640 * 1e18, - borrowerCollateral: 25.921751033498703620 * 1e18, - borrowert0Np: 1_101.390902162019364514 * 1e18, - borrowerCollateralization: 0.990376081445383032 * 1e18 - }); - - _kick({ - from: _minterTwo, - borrower: _borrower, - debt: 25_656.385808102176964640 * 1e18, - collateral: 25.921751033498703620 * 1e18, - bond: 374.752609017118925592 * 1e18, - transferAmount: 374.752609017118925592 * 1e18 - }); - - // skip ahead so take can be called on the loan - skip(72 hours); - - // take entire collateral - _take({ - from: _minterTwo, - borrower: _borrower, - maxCollateral: 100.0 * 1e18, - bondChange: 80, - givenAmount: 5495, - collateralTaken: 25.921751033498703620 * 1e18, - isReward: true - }); - - _settle({ - from: _minterTwo, - borrower: _borrower, - maxDepth: 10, - settledDebt: 24_911.288118205001229802 * 1e18 - }); - - // bucket is insolvent, balances are reset - _assertBucket({ - index: 2770, - lpBalance: 0, // bucket is bankrupt - collateral: 0, - deposit: 0, - exchangeRate: 1.0 * 1e18 - }); - - _assertBucket({ - index: 2771, - lpBalance: 0, // bucket is bankrupt - collateral: 0, - deposit: 0, - exchangeRate: 1.0 * 1e18 - }); - - ERC20Pool(address(_pool)).increaseLPAllowance(address(_positionManager), depositIndexes, lpBalances); - - // actor cannot re-memorialize using same tokenID because they are not the owner, rewardsManager is - vm.expectRevert(IPositionManagerErrors.NoAuth.selector); - _positionManager.memorializePositions(address(_pool), tokenIdOne, depositIndexes); - - // Staker doesn't receive rewards, proof that once a bucket is bankrupted all previous rewards are nullified for if the positionManager's deposit time - // is before the bucket's bankruptcy. Due to filtering in `getFilteredPositions()` - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(2, 0), - reward: 0 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 // updateExchangeRates is not emitted - }); - } - - function testClaimRewardsCap() external { - skip(10); - - /***************************/ - /*** Lender Deposits NFT ***/ - /***************************/ - - // set deposit indexes - uint256[] memory depositIndexes = new uint256[](2); - uint256[] memory depositIndex1 = new uint256[](1); - uint256[] memory depositIndex2 = new uint256[](1); - depositIndexes[0] = 2770; - depositIndexes[1] = 2771; - depositIndex1[0] = 2771; - depositIndex2[0] = 2770; - - // configure NFT position one - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 10_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /************************************/ - /*** Borrower One Accrue Interest ***/ - /************************************/ - - // borrower borrows - (uint256 collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 10_000 * 1e18, 2770); - - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 5 * 1e18, - limitIndex: 2770, - collateralToPledge: collateralToPledge, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // pass time to allow interest to accrue - skip(2 hours); - - // borrower repays their loan - (uint256 debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 5.004807692307692310 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - // start reserve auction - _kickReserveAuction({ - pool: address(_pool), - bidder: _bidder - }); - - // _borrower now takes out more debt to accumulate more interest - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 2_000 * 1e18, - limitIndex: 2770, - collateralToPledge: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves({ - pool: address(_pool), - from: _bidder - }); - - (,, uint256 tokensBurned) = IPool(address(_pool)).burnInfo(IPool(address(_pool)).currentBurnEpoch()); - - // recorder updates the change in exchange rates in the first index - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndex1, - reward: 0.007146561992635801 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 0.007146561992635801 * 1e18); - - _assertBurn({ - pool: address(_pool), - epoch: 0, - timestamp: 0, - burned: 0, - interest: 0, - tokensToBurn: 0 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 0.285862479721117855 * 1e18, - interest: 0.000048562908902619 * 1e18, - tokensToBurn: tokensBurned - }); - - // skip more time to allow more interest to accrue - skip(10 days); - - // borrower repays their loan again - (debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 2001.900281182536528587 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - // recorder updates the change in exchange rates in the second index - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndex2, - reward: 0.021439685979475985 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 0.021439685979475985 * 1e18); - - /*******************************************/ - /*** Lender Withdraws And Claims Rewards ***/ - /*******************************************/ - - // _minterOne withdraws and claims rewards, rewards should be set to the difference between total claimed and cap - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 0.228689983776894284 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - } - - function testClaimRewardsCapMultiplePools() external { - skip(10); - - /***************************/ - /*** Lender Deposits NFT ***/ - /***************************/ - - // set deposit indexes - uint256[] memory depositIndexes = new uint256[](2); - uint256[] memory depositIndex1 = new uint256[](1); - uint256[] memory depositIndex2 = new uint256[](1); - depositIndexes[0] = 2770; - depositIndexes[1] = 2771; - depositIndex1[0] = 2771; - depositIndex2[0] = 2770; - - // configure NFT position one - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 10_000 * 1e18, - pool: address(_pool) - }); - - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 10_000 * 1e18, - pool: address(_poolTwo) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - _stakeToken({ - pool: address(_poolTwo), - owner: _minterOne, - tokenId: tokenIdTwo - }); - - /************************************/ - /*** Borrower One Accrue Interest ***/ - /************************************/ - - // borrower borrows - (uint256 collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 10_000 * 1e18, 2770); - - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 5 * 1e18, - limitIndex: 2770, - collateralToPledge: collateralToPledge, - newLup: 1_004.989662429170775094 * 1e18 - }); - - (collateralToPledge) = _createTestBorrower(address(_poolTwo), _borrower, 10_000 * 1e18, 2770); - - ERC20Pool(address(_poolTwo)).drawDebt(_borrower, 5 * 1e18, 2770, collateralToPledge); - - // pass time to allow interest to accrue - skip(2 hours); - - // borrower repays their loan - (uint256 debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 5.004807692307692310 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - (debt, , ) = _poolTwo.borrowerInfo(_borrower); - - ERC20Pool(address(_poolTwo)).repayDebt(_borrower, debt, 0, _borrower, 7388); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - // start reserve auction - _kickReserveAuction({ - pool: address(_pool), - bidder: _bidder - }); - - _kickReserveAuction({ - pool: address(_poolTwo), - bidder: _bidder - }); - - // _borrower now takes out more debt to accumulate more interest - _drawDebt({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 2_000 * 1e18, - limitIndex: 2770, - collateralToPledge: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - ERC20Pool(address(_poolTwo)).drawDebt(_borrower, 2_000 * 1e18, 2770, 0); - - // allow time to pass for the reserve price to decrease - skip(24 hours); - - _takeReserves({ - pool: address(_pool), - from: _bidder - }); - - _takeReserves({ - pool: address(_poolTwo), - from: _bidder - }); - - (,, uint256 tokensBurned) = IPool(address(_pool)).burnInfo(IPool(address(_pool)).currentBurnEpoch()); - - // recorder updates the change in exchange rates in the first index - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndex1, - reward: 0.007146561992635801 * 1e18 - }); - - _updateExchangeRates({ - updater: _updater, - pool: address(_poolTwo), - indexes: depositIndex1, - reward: 0.007146561992635801 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 2 * 0.007146561992635801 * 1e18); - - _assertBurn({ - pool: address(_pool), - epoch: 0, - timestamp: 0, - burned: 0, - interest: 0, - tokensToBurn: 0 - }); - - _assertBurn({ - pool: address(_poolTwo), - epoch: 0, - timestamp: 0, - burned: 0, - interest: 0, - tokensToBurn: 0 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 0.285862479721117855 * 1e18, - interest: 0.000048562908902619 * 1e18, - tokensToBurn: tokensBurned - }); - - _assertBurn({ - pool: address(_poolTwo), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 0.285862479721117855 * 1e18, - interest: 0.000048562908902619 * 1e18, - tokensToBurn: tokensBurned - }); - - // skip more time to allow more interest to accrue - skip(10 days); - - // borrower repays their loan again - (debt, , ) = _pool.borrowerInfo(_borrower); - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: debt, - amountRepaid: 2001.900281182536528587 * 1e18, - collateralToPull: 0, - newLup: 1_004.989662429170775094 * 1e18 - }); - - (debt, , ) = _pool.borrowerInfo(_borrower); - - ERC20Pool(address(_poolTwo)).repayDebt(_borrower, debt, 0, _borrower, 7388); - - // recorder updates the change in exchange rates in the second index - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndex2, - reward: 0.021439685979475985 * 1e18 - }); - - _updateExchangeRates({ - updater: _updater2, - pool: address(_poolTwo), - indexes: depositIndex2, - reward: 0.021439685979475985 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 2 * 0.021439685979475985 * 1e18); - - - /*******************************************/ - /*** Lender Withdraws And Claims Rewards ***/ - /*******************************************/ - - // _minterOne withdraws and claims rewards, rewards should be set to the difference between total claimed and cap - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 0.228689983776894284 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - _unstakeToken({ - owner: _minterOne, - pool: address(_poolTwo), - tokenId: tokenIdTwo, - claimedArray: _epochsClaimedArray(1, 0), - reward: 0.228689983776894284 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - } - - function testClaimRewardsInsufficientFunds() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake nft - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022279800 * 1e18 - }); - - // burn rewards manager tokens and leave only 5 tokens available - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); - - uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 4.958687331949770257 * 1e18); - - // check reward generated are more than manager token balance - uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertGt(rewards, managerBalance); - - // claimRewards should revert when user tries to claim more rewards than available in manager - _assertClaimRewardsInsufficientLiquidityRevert(_minterOne, tokenIdOne, managerBalance + 1); - - // claimRewards should claim all available ajna token in manager - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - reward: 41.312668050222798013 * 1e18, - epochsClaimed: _epochsClaimedArray(1,0) - }); - - // manager balance should be zero after all ajna tokens are claimed - managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 0); - } - - function testMultiPeriodRewardsSingleClaim() external { - skip(10); - - uint256 totalTokensBurned; - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](10); - depositIndexes[0] = 5995; - depositIndexes[1] = 5996; - depositIndexes[2] = 5997; - depositIndexes[3] = 5998; - depositIndexes[4] = 5999; - depositIndexes[5] = 6000; - depositIndexes[6] = 6001; - depositIndexes[7] = 6002; - depositIndexes[8] = 6003; - depositIndexes[9] = 6004; - - // mint memorialize and deposit NFT - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - - // borrower takes actions providing reserves enabling reserve auctions - // bidder takes reserve auctions by providing ajna tokens to be burned - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 413.127574571899032653 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6000, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 20.656378728594950130 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 20.656378728594950130 * 1e18); - - uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 206.563787285949501291 * 1e18); - assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); - - /******************************/ - /*** Second Reserve Auction ***/ - /******************************/ - // trigger second reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 757.513427352933392466 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 17.219292639051716786 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 37.875671367646666916 * 1e18); - - // check available rewards - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 378.756713676466669152 * 1e18); - assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); - - /*****************************/ - /*** Third Reserve Auction ***/ - /*****************************/ - - // trigger third reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 1_040.728884278226145090 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // skip updating exchange rates and check available rewards - uint256 rewardsEarnedNoUpdate = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedNoUpdate, 378.756713676466669152* 1e18); - assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); - - // snapshot calling update exchange rate - uint256 snapshot = vm.snapshot(); - - // call update exchange rate - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndexes, - reward: 14.160772846264633918 * 1e18 - }); - - assertEq(_ajnaToken.balanceOf(_updater2), 14.160772846264633918 * 1e18); - - // check available rewards - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertGt(rewardsEarned, rewardsEarnedNoUpdate); - assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); - - // revert to no update state - vm.revertTo(snapshot); - - /******************************/ - /*** Fourth Reserve Auction ***/ - /******************************/ - - // triger fourth reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 1_298.676796181373516144 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // check rewards earned - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 378.756713676466669152 * 1e18); - - // call update exchange rate - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndexes, - reward: 0 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 0); - - // check rewards earned won't increase since previous update was missed - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 378.756713676466669152 * 1e18); - - /*****************************/ - /*** Fifth Reserve Auction ***/ - /*****************************/ - - // triger fifth reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 1_533.340435326746598961 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // call update exchange rate - _updateExchangeRates({ - updater: _updater2, - pool: address(_pool), - indexes: depositIndexes, - reward: 11.733181957268654420 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater2), 11.733181957268654420 * 1e18); - - rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 496.088533249153213379 * 1e18); - - // claim all rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(5,0), - reward: 496.088533249153213379 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_minterOne), rewardsEarned); - assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); - } - - function testEarlyAndLateStakerRewards() external { - skip(10); - - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - // configure NFT position two - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterTwo, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // bucket exchange rates are not changed at the time minter two stakes - assertEq(_pool.bucketExchangeRate(2550), 1e18); - assertEq(_pool.bucketExchangeRate(2551), 1e18); - assertEq(_pool.bucketExchangeRate(2552), 1e18); - assertEq(_pool.bucketExchangeRate(2553), 1e18); - assertEq(_pool.bucketExchangeRate(2555), 1e18); - - // stake NFT - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - - (uint256 collateralToPledge) = _createTestBorrower(address(_pool), _borrower2, 10_000 * 1e18, 2770); - - // borrower borrows and change the exchange rates of buckets - _drawDebt({ - from: _borrower2, - borrower: _borrower2, - amountToBorrow: 5 * 1e18, - limitIndex: 2770, - collateralToPledge: collateralToPledge, - newLup: 3_010.892022197881557845 * 1e18 - }); - - skip(1 days); - - // configure NFT position three one day after early minter - uint256 tokenIdThree = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterThree, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // bucket exchange rates are higher at the time minter three stakes - assertEq(_pool.bucketExchangeRate(2550), 1.000000116558299386 * 1e18); - assertEq(_pool.bucketExchangeRate(2551), 1.000000116558299386 * 1e18); - assertEq(_pool.bucketExchangeRate(2552), 1.000000116558299386 * 1e18); - assertEq(_pool.bucketExchangeRate(2553), 1.000000116558299386 * 1e18); - assertEq(_pool.bucketExchangeRate(2555), 1.000000116558299386 * 1e18); - - // stake NFT - _stakeToken({ - pool: address(_pool), - owner: _minterThree, - tokenId: tokenIdThree - }); - - skip(1 days); - - _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 134.354263094095890105 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - // unstake and compare rewards and balances of minter two and minter three - _unstakeToken({ - owner: _minterTwo, - pool: address(_pool), - tokenId: tokenIdTwo, - claimedArray: _epochsClaimedArray(1, 0), - reward: 40.311260092505644727 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 6.718205558019761798 * 1e18 - }); - - uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 40.311260092505644727 * 1e18); - _unstakeToken({ - owner: _minterThree, - pool: address(_pool), - tokenId: tokenIdThree, - claimedArray: _epochsClaimedArray(1, 0), - reward: 33.584077012562068097 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - uint256 minterThreeBalance = _ajnaToken.balanceOf(_minterThree); - assertEq(minterThreeBalance, 33.584077012562068097 * 1e18); - - assertGt(minterTwoBalance, minterThreeBalance); - } - - // Calling updateExchangeRates not needed since deposits will update the exchange rate themselves - function testClaimRewardsMultipleDepositsSameBucketsMultipleAuctions() external { - skip(10); - - /*****************************/ - /*** First Lender Deposits ***/ - /*****************************/ - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 9; - depositIndexes[1] = 1; - depositIndexes[2] = 2; - depositIndexes[3] = 3; - depositIndexes[4] = 4; - - // mint memorialize and deposit NFT - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake NFT - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - - // borrower takes actions providing reserves enabling reserve auctions - uint256 firstTokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445516170 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 3, - pool: address(_pool) - }); - - /******************************/ - /*** Second Lender Deposits ***/ - /******************************/ - - // second depositor deposits an NFT representing the same positions into the rewards contract - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterTwo, - mintAmount: 1000 * 1e18, - pool: address(_pool) - }); - - // second depositor stakes NFT, generating an update reward - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 8.254436745949651197 * 1e18); - - // calculate rewards earned since exchange rates have been updated - uint256 idOneRewardsAtOne = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertLt(idOneRewardsAtOne, firstTokensToBurn); - assertGt(idOneRewardsAtOne, 1); - - // minter one claims rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(1,0), - reward: idOneRewardsAtOne - }); - - /******************************/ - /*** Second Reserve Auction ***/ - /******************************/ - // // borrower takes actions providing reserves enabling additional reserve auctions - // conduct second reserve auction - uint256 secondTokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 177.662570358430069210 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 3, - pool: address(_pool) - }); - - /*****************************/ - /*** Third Lender Deposits ***/ - /*****************************/ - - // third depositor deposits an NFT representing the same positions into the rewards contract - uint256 tokenIdThree = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterThree, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterThree, - tokenId: tokenIdThree - }); - - /***********************/ - /*** Rewards Claimed ***/ - /***********************/ - - // calculate rewards earned since exchange rates have been updated - uint256 idOneRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertLt(idOneRewardsAtTwo, secondTokensToBurn); - assertGt(idOneRewardsAtTwo, 0); - assertEq(idOneRewardsAtTwo, 23.777445314991285190 * 1e18); - - uint256 idTwoRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdTwo, _pool.currentBurnEpoch()); - assertLt(idOneRewardsAtTwo + idTwoRewardsAtTwo, secondTokensToBurn); - assertEq(idTwoRewardsAtTwo, 23.744671674761352175 * 1e18); - assertGt(idTwoRewardsAtTwo, 0); - - // minter one claims rewards accrued after second auction - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(1,1), - reward: 23.777445314991285190 * 1e18 - }); - - assertEq(_ajnaToken.balanceOf(_minterOne), idOneRewardsAtOne + idOneRewardsAtTwo); - - // minter two claims rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterTwo, - tokenId: tokenIdTwo, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(1,1), - reward: idTwoRewardsAtTwo - }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 31.999108420711003372 * 1e18); - - // check there are no remaining rewards available after claiming - uint256 remainingRewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(remainingRewards, 0); - - remainingRewards = _rewardsManager.calculateRewards(tokenIdTwo, _pool.currentBurnEpoch()); - assertEq(remainingRewards, 0); - - remainingRewards = _rewardsManager.calculateRewards(tokenIdThree, _pool.currentBurnEpoch()); - assertEq(remainingRewards, 0); - } - - function testClaimRewardsMultipleDepositsDifferentBucketsMultipleAuctions() external { - // configure _minterOne's NFT position - uint256[] memory firstIndexes = new uint256[](5); - firstIndexes[0] = 2550; - firstIndexes[1] = 2551; - firstIndexes[2] = 2552; - firstIndexes[3] = 2553; - firstIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: firstIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // configure _minterTwo's NFT position - uint256[] memory secondIndexes = new uint256[](5); - secondIndexes[0] = 2550; - secondIndexes[1] = 2551; - secondIndexes[2] = 2200; - secondIndexes[3] = 2221; - secondIndexes[4] = 2222; - - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: secondIndexes, - minter: _minterTwo, - mintAmount: 5_000 * 1e18, - pool: address(_pool) - }); - - // lenders stake their NFTs - _stakeToken(address(_pool), _minterOne, tokenIdOne); - _stakeToken(address(_pool), _minterTwo, tokenIdTwo); - - uint256[] memory depositIndexes = new uint256[](8); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - depositIndexes[5] = 2200; - depositIndexes[6] = 2221; - depositIndexes[7] = 2222; - - // borrower takes actions providing reserves enabling three reserve auctions - // proof of burn events (burn epoch 0) - _assertBurn({ - pool: address(_pool), - epoch: 0, - timestamp: 0, - burned: 0, - interest: 0, - tokensToBurn: 0 - }); - - // auction one - uint256 tokensToBurnE1 = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.623845984327740729 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131192299216369040 * 1e18 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 1, - timestamp: block.timestamp - 24 hours, - burned: 82.623845984327740729 * 1e18, - tokensToBurn: tokensToBurnE1, - interest: 6.443638300196908069 * 1e18 - }); - - // auction two - uint256 tokensToBurnE2 = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 311.638636889018838585 * 1e18, - borrowAmount: 1_000 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 11.450739545234514130 * 1e18 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 2, - timestamp: block.timestamp - 24 hours, - burned: 311.638636889018838585 * 1e18, - tokensToBurn: tokensToBurnE2, - interest: 23.938554041534910348 * 1e18 - }); - - // auction three - uint256 tokensToBurnE3 = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 683.342383405688644410 * 1e18, - borrowAmount: 2_000 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 18.585187325833511425 * 1e18 - }); - - _assertBurn({ - pool: address(_pool), - epoch: 3, - timestamp: block.timestamp - 24 hours, - burned: 683.342383405688644410 * 1e18, - tokensToBurn: tokensToBurnE3, - interest: 52.423541260157607958 * 1e18 - }); - - // both stakers claim rewards - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(3, 0), - reward: 56.945198617140657657 * 1e18, - indexes: firstIndexes, - updateExchangeRatesReward: 0 - }); - - _unstakeToken({ - owner: _minterTwo, - pool: address(_pool), - tokenId: tokenIdTwo, - claimedArray: _epochsClaimedArray(3, 0), - reward: 284.725993085703288290 * 1e18, - indexes: secondIndexes, - updateExchangeRatesReward: 0 - }); - } - - function testWithdrawClaimAndRestake() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake nft - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022279800 * 1e18 - }); - - // _minterOne unstakes staked position - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 41.312668050222798013 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - // borrower drawsDebt from the pool - Token collateral = Token(ERC20Pool(address(_pool)).collateralAddress()); - Token quote = Token(ERC20Pool(address(_pool)).quoteTokenAddress()); - deal(address(quote), _borrower, 300 * 1e18); - - // approve tokens - collateral.approve(address(_pool), type(uint256).max); - quote.approve(address(_pool), type(uint256).max); - - changePrank(_borrower); - uint256 collateralToPledge = _requiredCollateral(300 * 1e18, 2555); - deal(address(collateral), _borrower, collateralToPledge); - ERC20Pool(address(_pool)).drawDebt(_borrower, 300 * 1e18, 2555, collateralToPledge); - - // allow time to pass for interest to accumulate - skip(26 weeks); - - // borrower repays some of their debt, providing reserves to be claimed - // don't pull any collateral, as such functionality is unrelated to reserve auctions - ERC20Pool(address(_pool)).repayDebt(_borrower, 300 * 1e18, 0, _borrower, MAX_FENWICK_INDEX); - - // start reserve auction - changePrank(_bidder); - _ajnaToken.approve(address(_pool), type(uint256).max); - (,, uint256 tokensBurned_) = IPool(_pool).burnInfo(IPool(_pool).currentBurnEpoch()); - - ERC20Pool(address(_pool)).kickReserveAuction(); - - // exchange rate is updated even though no ajna tokens are burned in epoch - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 0 - }); - - // allow time to pass for the reserve price to decrease - skip(72 hours); - - // take reserves is called with 1 ajna being burned due to very low price and low take amount - _ajnaToken.approve(address(_pool), type(uint256).max); - ERC20Pool(address(_pool)).takeReserves(612); - - (,, tokensBurned_) = IPool(_pool).burnInfo(IPool(_pool).currentBurnEpoch()); - - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterTwo, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake nft - // reverts here because totalBurned = 0 for Epoch 2 (takes haven't burned any ajna) - // causes the update cap to be zero which then causes overflow - _stakeToken({ - pool: address(_pool), - owner: _minterTwo, - tokenId: tokenIdTwo - }); - } - - function testWithdrawAndClaimRewards() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake nft - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - uint256 tokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 4.131266805022279800 * 1e18 - }); - - // check owner can withdraw the NFT and rewards will be automatically claimed - - uint256 snapshot = vm.snapshot(); - - // claimed rewards amount is greater than available tokens in rewards manager contract - - // burn rewards manager tokens and leave only 5 tokens available - changePrank(address(_rewardsManager)); - IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); - - uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 4.958687331949770257 * 1e18); - - // check reward generated are more than manager token balance - uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertGt(rewards, managerBalance); - - // should revert when rewards are more than token balance - _assertUnstakeInsufficientLiquidityRevert(_minterOne, tokenIdOne); - - vm.revertTo(snapshot); - - // test when enough tokens in rewards manager contracts - // _minterOne unstakes staked position - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: 41.312668050222798013 * 1e18, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - assertEq(PositionManager(address(_positionManager)).ownerOf(tokenIdOne), _minterOne); - assertEq(_ajnaToken.balanceOf(_minterOne), 41.312668050222798013 * 1e18); - assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); - - // check can't claim rewards twice - _assertNotOwnerOfDepositRevert({ - from: _minterOne, - tokenId: tokenIdOne - }); - } - - function testClaimAndWithdraw() external { - skip(10); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 2550; - depositIndexes[1] = 2551; - depositIndexes[2] = 2552; - depositIndexes[3] = 2553; - depositIndexes[4] = 2555; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // stake nft - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - // trigger ajna burns - _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445635379 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 2555, - pool: address(_pool) - }); - - // claim rewards - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - reward: 45.443934855245077813 * 1e18, - epochsClaimed: _epochsClaimedArray(1, 0) - }); - - // unstake token and check no rewards are received as user already claimed - uint256[] memory claimedArray = new uint256[](0); - _unstakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne, - claimedArray: claimedArray, // no rewards as no reserve auctions have occured since the last claim - reward: 0, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - } - - function testMultiplePools() external { - skip(10); - - // configure NFT position one - uint256[] memory firstIndexes = new uint256[](5); - firstIndexes[0] = 9; - firstIndexes[1] = 1; - firstIndexes[2] = 2; - firstIndexes[3] = 3; - firstIndexes[4] = 4; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: firstIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - // configure NFT position two - uint256[] memory secondIndexes = new uint256[](4); - secondIndexes[0] = 5; - secondIndexes[1] = 1; - secondIndexes[2] = 3; - secondIndexes[3] = 12; - - uint256 tokenIdTwo = _mintAndMemorializePositionNFT({ - indexes: secondIndexes, - minter: _minterTwo, - mintAmount: 1_000 * 1e18, - pool: address(_poolTwo) - }); - - // minterOne deposits their NFT into the rewards contract - _stakeToken(address(_pool), _minterOne, tokenIdOne); - - // minterTwo deposits their NFT into the rewards contract - _stakeToken(address(_poolTwo), _minterTwo, tokenIdTwo); - - // borrower takes actions providing reserves enabling reserve auctions - // bidder takes reserve auctions by providing ajna tokens to be burned - uint256 tokensToBurn = _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 82.625336100445516170 * 1e18, - borrowAmount: 300 * 1e18, - limitIndex: 3, - pool: address(_pool) - }); - - // check only deposit owner can claim rewards - _assertNotOwnerOfDepositRevert({ - from: _minterTwo, - tokenId: tokenIdOne - }); - - // check rewards earned in one pool shouldn't be claimable by depositors from another pool - assertEq(_ajnaToken.balanceOf(_minterTwo), 0); - _claimRewards({ - pool: address(_poolTwo), - from: _minterTwo, - tokenId: tokenIdTwo, - minAmountToReceive: 0, - reward: 0, - epochsClaimed: _epochsClaimedArray(0, 0) - }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 0); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _minterOne, - pool: address(_pool), - indexes: firstIndexes, - reward: 4.131266805022275123 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_minterOne), 4.131266805022275123 * 1e18); - - // check owner in pool with accrued interest can properly claim rewards - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - reward: 41.312668050222751231 * 1e18, - epochsClaimed: _epochsClaimedArray(1, 0) - }); - assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); - } - - function testMultipleUnstakeInSameEpoch() external { - - skip(10); - - uint256 totalTokensBurned; - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](10); - depositIndexes[0] = 5995; - depositIndexes[1] = 5996; - depositIndexes[2] = 5997; - depositIndexes[3] = 5998; - depositIndexes[4] = 5999; - depositIndexes[5] = 6000; - depositIndexes[6] = 6001; - depositIndexes[7] = 6002; - depositIndexes[8] = 6003; - depositIndexes[9] = 6004; - - // mint memorialize and deposit NFT - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /*****************************/ - /*** First Reserve Auction ***/ - /*****************************/ - - // borrower takes actions providing reserves enabling reserve auctions - // bidder takes reserve auctions by providing ajna tokens to be burned - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 413.127574571899032653 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6000, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 20.656378728594950130 * 1e18 - }); - assertEq(_ajnaToken.balanceOf(_updater), 20.656378728594950130 * 1e18); - - uint256 rewardsEarnedFirstEpoch = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedFirstEpoch, 206.563787285949501291 * 1e18); - - uint256 snapshot = vm.snapshot(); - - // unstake and stake multiple times to check it has no effect on staking rewards - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(1, 0), - reward: rewardsEarnedFirstEpoch, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - _unstakeToken({ - owner: _minterOne, - pool: address(_pool), - tokenId: tokenIdOne, - claimedArray: _epochsClaimedArray(0, 0), - reward: 0, - indexes: depositIndexes, - updateExchangeRatesReward: 0 - }); - - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - - /******************************/ - /*** Second Reserve Auction ***/ - /******************************/ - // trigger second reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 757.513427352933392466 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 17.219292639051716786 * 1e18 - }); - - uint256 totalRewardEarned = 378.756713676466669152 * 1e18; - uint256 newRewardsEarned = totalRewardEarned - rewardsEarnedFirstEpoch; // 172.192926390517167861 - - // claim rewards for second epoch - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(1, 1), - reward: newRewardsEarned - }); - - // ensure total rewards earned are same with and without unstake between epochs - assertEq(_ajnaToken.balanceOf(_minterOne), totalRewardEarned); - - // Check rewards total rewards generated without any unstake between epochs - vm.revertTo(snapshot); - - /******************************/ - /*** Second Reserve Auction ***/ - /******************************/ - - // trigger second reserve auction - totalTokensBurned += _triggerReserveAuctions({ - borrower: _borrower, - tokensToBurn: 757.513427352933392466 * 1e18, - borrowAmount: 1_500 * 1e18, - limitIndex: 6_000, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - _updateExchangeRates({ - updater: _updater, - pool: address(_pool), - indexes: depositIndexes, - reward: 17.219292639051716786 * 1e18 - }); - - // check available rewards - uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, totalRewardEarned); - - // claim all rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - epochsClaimed: _epochsClaimedArray(2,0), - reward: totalRewardEarned - }); - - // ensure total rewards earned are same with and without unstake between epochs - assertEq(_ajnaToken.balanceOf(_minterOne), totalRewardEarned); - } - - /********************/ - /*** FUZZ TESTING ***/ - /********************/ - - function testClaimRewardsFuzzy(uint256 indexes, uint256 mintAmount) external { - indexes = bound(indexes, 3, 10); // number of indexes to add liquidity to - mintAmount = bound(mintAmount, 1 * 1e18, 100_000 * 1e18); // bound mint amount and dynamically determine borrow amount and collateral based upon provided index and mintAmount - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](indexes); - for (uint256 i = 0; i < indexes; ++i) { - depositIndexes[i] = _randomIndex(); - } - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: mintAmount, - pool: address(_pool) - }); - - // stake NFT - _stakeToken(address(_pool), _minterOne, tokenIdOne); - - // calculates a limit index leaving one index above the htp to accrue interest - uint256 limitIndex = _findSecondLowestIndexPrice(depositIndexes); - - // start and end new reserve auction - uint256 tokensToBurn= _triggerReserveAuctionsBurnUnknown({ - borrower: _borrower, - borrowAmount: Maths.wdiv(mintAmount, Maths.wad(3)), - limitIndex: limitIndex, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - changePrank(_updater); - assertEq(_ajnaToken.balanceOf(_updater), 0); - _rewardsManager.updateBucketExchangeRatesAndClaim( - address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), depositIndexes - ); - assertGt(_ajnaToken.balanceOf(_updater), 0); - - // calculate rewards earned and compare to percentages for updating and claiming - uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertGt(rewardsEarned, 0); - - // claim rewards accrued since deposit - _claimRewards({ - pool: address(_pool), - from: _minterOne, - tokenId: tokenIdOne, - minAmountToReceive: 0, - reward: rewardsEarned, - epochsClaimed: _epochsClaimedArray(1, 0) - }); - - // assert rewards claimed is less than ajna tokens burned cap - assertLt(_ajnaToken.balanceOf(_minterOne), Maths.wmul(tokensToBurn, 0.800000000000000000 * 1e18)); - } - - function testStakingRewardsFuzzy(uint256 deposits, uint256 reserveAuctions) external { - deposits = bound(deposits, 1, 25); // number of deposits to make - reserveAuctions = bound(reserveAuctions, 1, 25); // number of reserve Auctions to complete - - uint256[] memory tokenIds = new uint256[](deposits); - - // configure NFT position - uint256[] memory depositIndexes = new uint256[](3); - for (uint256 j = 0; j < 3; ++j) { - depositIndexes[j] = _randomIndex(); - vm.roll(block.number + 1); // advance block to ensure that the index price is different - } - - address[] memory minters = _getAddresses(deposits); - - // stake variable no of deposits - for (uint256 i = 0; i < deposits; ++i) { - - tokenIds[i] = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: minters[i], - mintAmount: 1_000_000_000 * 1e18, - pool: address(_pool) - }); - tokenIdToMinter[tokenIds[i]] = minters[i]; - _stakeToken(address(_pool), minters[i], tokenIds[i]); - } - - uint256 updaterBalance = _ajnaToken.balanceOf(_updater); - - for (uint i = 0; i < deposits; i++) { - minterToBalance[minters[i]] = _ajnaToken.balanceOf(minters[i]); - } - - // start variable no of reserve Auctions and claim rewards for random tokenIds in each epoch - for (uint i = 0; i < reserveAuctions; ++i) { - uint256 limitIndex = _findSecondLowestIndexPrice(depositIndexes); - - // start and end new reserve auction - uint256 tokensBurned = _triggerReserveAuctionsBurnUnknown({ - borrower: _borrower, - borrowAmount: 20_000 * 1e18, - limitIndex: limitIndex, - pool: address(_pool) - }); - - // call update exchange rate to enable claiming rewards - assertEq(_ajnaToken.balanceOf(_updater), updaterBalance); - - changePrank(_updater); - assertEq(_ajnaToken.balanceOf(_updater), updaterBalance); - _rewardsManager.updateBucketExchangeRatesAndClaim( - address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), depositIndexes - ); - - // ensure updater gets reward for updating exchange rate - assertGt(_ajnaToken.balanceOf(_updater), updaterBalance); - - // ensure update rewards in each epoch is less than or equals to 10% of tokensBurned - assertLe(_ajnaToken.balanceOf(_updater) - updaterBalance, tokensBurned / 10); - - updaterBalance = _ajnaToken.balanceOf(_updater); - - // pick random NFTs from all NFTs to claim rewards - uint256[] memory randomNfts = _getRandomSubsetFromArray(tokenIds); - - for (uint j = 0; j < randomNfts.length; j++) { - address minterAddress = tokenIdToMinter[randomNfts[j]]; - changePrank(minterAddress); - - (, , uint256 lastInteractionEpoch) = _rewardsManager.getStakeInfo(randomNfts[j]); - - // select random epoch to claim reward - uint256 epochToClaim = lastInteractionEpoch < _pool.currentBurnEpoch() ? randomInRange(lastInteractionEpoch + 1, _pool.currentBurnEpoch()) : lastInteractionEpoch; - - uint256 rewardsEarned = _rewardsManager.calculateRewards(randomNfts[j], epochToClaim); - assertGt(rewardsEarned, 0); - - _rewardsManager.claimRewards(randomNfts[j], _pool.currentBurnEpoch(), 0); - - // ensure user gets reward - assertGt(_ajnaToken.balanceOf(minterAddress), minterToBalance[minterAddress]); - minterToBalance[minterAddress] = _ajnaToken.balanceOf(minterAddress); - } - } - } - - function testClaimRewardsFreezeUnclaimedYield() external { - skip(10); - - uint256[] memory depositIndexes = new uint256[](5); - depositIndexes[0] = 9; - depositIndexes[1] = 1; - depositIndexes[2] = 2; - depositIndexes[3] = 3; - depositIndexes[4] = 4; - - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: 1_000 * 1e18, - pool: address(_pool) - }); - - _stakeToken(address(_pool), _minterOne, tokenIdOne); - - uint256 currentBurnEpoch = _pool.currentBurnEpoch(); - - changePrank(_minterOne); - // should revert if the epoch to claim is not available yet - vm.expectRevert(IRewardsManagerErrors.EpochNotAvailable.selector); - _rewardsManager.claimRewards(tokenIdOne, currentBurnEpoch + 10, 0); - - // user should be able to claim rewards for current epoch - _rewardsManager.claimRewards(tokenIdOne, currentBurnEpoch, 0); - } - - function testRoguePoolAttack_report_151() external { - address mal = makeAddr("mal"); - changePrank(mal); - - uint256 rewardsManagerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - uint256 malBalance = _ajnaToken.balanceOf(mal); - assertEq(malBalance, 0); - // set prev exchange rate to bypass - // https://github.com/code-423n4/2023-05-ajna/blob/main/ajna-core/src/RewardsManager.sol#L789 - RoguePool roguePool = new RoguePool(_rewardsManager, _ajnaToken); - roguePool.setBurnEpoch(1); - uint256[] memory indexes = new uint256[](1); - indexes[0] = 777; - - vm.expectRevert(); - _rewardsManager.updateBucketExchangeRatesAndClaim( - address(roguePool), keccak256("ERC20_NON_SUBSET_HASH"), indexes - ); - // finalize the attack - roguePool.setBurnEpoch(2); - vm.expectRevert(); - _rewardsManager.updateBucketExchangeRatesAndClaim( - address(roguePool), keccak256("ERC20_NON_SUBSET_HASH"), indexes - ); - // post attack checks - malBalance = _ajnaToken.balanceOf(mal); - assertEq(malBalance, 0); - - rewardsManagerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(rewardsManagerBalance, 100000000 * 1e18); - } - - function testUnsafeCasting_report_227() external { - // configure NFT position one - uint256[] memory depositIndexes = new uint256[](1); - depositIndexes[0] = 9; - uint256 mintAmount = uint256(type(uint128).max) + 1; - uint256 tokenIdOne = _mintAndMemorializePositionNFT({ - indexes: depositIndexes, - minter: _minterOne, - mintAmount: mintAmount, - pool: address(_pool) - }); - uint256 lpBalance; - (lpBalance, ) =_pool.lenderInfo(depositIndexes[0], address(_positionManager)); - - // minterOne deposits their NFT into the rewards contract - _stakeToken({ - pool: address(_pool), - owner: _minterOne, - tokenId: tokenIdOne - }); - uint256 lpsAtStakeTime; - uint256 rateAtStakeTime; - (lpsAtStakeTime, rateAtStakeTime) = _rewardsManager.getBucketStateStakeInfo(tokenIdOne, depositIndexes[0]); - - // make sure LP balance before staking is the same as staked LP amount - assertEq(lpBalance, lpsAtStakeTime); - } - -} diff --git a/tests/forge/unit/Rewards/RoguePool.sol b/tests/forge/unit/Rewards/RoguePool.sol deleted file mode 100644 index 72c9e6443..000000000 --- a/tests/forge/unit/Rewards/RoguePool.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import 'src/interfaces/rewards/IRewardsManager.sol'; -import '@openzeppelin/contracts/token/ERC20/ERC20.sol'; - -contract RoguePool { - IRewardsManager immutable rewardsManager; - ERC20 immutable ajnaToken; - - uint256 public burnEpoch; - uint256 public prevBurnEpoch; - - constructor(IRewardsManager _rewardsManager, ERC20 _ajnaToken) { - rewardsManager = _rewardsManager; - ajnaToken = _ajnaToken; - } - - function reset() external { - prevBurnEpoch = 0; - burnEpoch = 0; - } - - function setBurnEpoch(uint256 newEpoch) external { - prevBurnEpoch = burnEpoch; - burnEpoch = newEpoch; - } - - function currentBurnEpoch() external view returns(uint256) { - return burnEpoch; - } - - function burnInfo(uint256 epoch) external view returns (uint256 burnBlock_, uint256 totalInterest_, uint256 totalBurned_) { - uint256 targetBalance = ajnaToken.balanceOf(address(rewardsManager)); - burnBlock_ = block.timestamp; - if (epoch == burnEpoch - 1) { - // overwhelm the reward cap check - totalInterest_ = 1 * 1e18; - totalBurned_ = targetBalance * 10; - } - } - - function bucketInfo(uint256) external pure returns(uint256, uint256, uint256, uint256, uint256) { - return (0, 0, 0, 100000 * 1e18, 0); - } - - function bucketExchangeRate(uint256) external view returns(uint256) { - if (prevBurnEpoch == 0) - return 1; - else - return 300000; - } -} \ No newline at end of file diff --git a/tests/forge/utils/AuctionQueueInstance.sol b/tests/forge/utils/AuctionQueueInstance.sol new file mode 100644 index 000000000..cddf28f63 --- /dev/null +++ b/tests/forge/utils/AuctionQueueInstance.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.18; + +import './DSTestPlus.sol'; + +import { + AuctionsState, + Borrower, + Bucket, + DepositsState, + LoansState, + PoolState, + ReserveAuctionState +} from 'src/interfaces/pool/commons/IPoolState.sol'; +import { SettleParams } from 'src/interfaces/pool/commons/IPoolInternals.sol'; +import { PoolType } from 'src/interfaces/pool/IPool.sol'; + +import { Buckets } from 'src/libraries/internal/Buckets.sol'; +import { Deposits } from 'src/libraries/internal/Deposits.sol'; +import { Loans } from 'src/libraries/internal/Loans.sol'; +import { Maths } from 'src/libraries/internal/Maths.sol'; + +import { KickerActions } from 'src/libraries/external/KickerActions.sol'; +import { SettlerActions } from 'src/libraries/external/SettlerActions.sol'; + +import { _indexOf } from 'src/libraries/helpers/PoolHelper.sol'; + +contract AuctionQueueInstance is DSTestPlus { + AuctionsState private _auctions; + mapping(uint256 => Bucket) private _buckets; + DepositsState private _deposits; + LoansState private _loans; + PoolState private _poolState; + ReserveAuctionState private _reserveAuction; + + uint256 private constant LOAN_SIZE = 100 * 1e18; + uint256 private constant TP = 5 * 1e18; + uint256 private constant LUP = 4 * 1e18; + uint256 private constant LUP_INDEX = 3_878; + address private _lender; + + constructor() { + Loans.init(_loans); + _poolState.inflator = 1 * 1e18; + // _poolState.rate = 0.05 * 1e18; + _poolState.poolType = uint8(PoolType.ERC20); + _poolState.quoteTokenScale = 18; + _lender = makeAddr("lender"); + skip(1); + } + + function add(address loan) external { + _mockDraw(loan); + KickerActions.kick( + _auctions, + _deposits, + _loans, + _poolState, + loan, + 7_388 + ); + } + + function remove(address loan) external { + _mockSettle(loan); + SettlerActions.settlePoolDebt( + _auctions, + _buckets, + _deposits, + _loans, + _reserveAuction, + _poolState, + SettleParams({ + borrower: loan, + poolBalance: type(uint256).max, + bucketDepth: 1 + }) + ); + } + + function count() external view returns (uint256 count_) { + return _auctions.noOfAuctions; + } + + function _mockDraw(address loan) internal { + // add debt and collateral to PoolState + uint256 pledge = Maths.wdiv(LOAN_SIZE, TP); + _poolState.debt += LOAN_SIZE; + _poolState.collateral += pledge; + + // create Deposits with single Bucket at LUP + Deposits.unscaledAdd(_deposits, LUP_INDEX, LOAN_SIZE); + Bucket storage bucket = _buckets[LUP_INDEX]; + bucket.lps += LOAN_SIZE; + Buckets.addLenderLP(bucket, 0, _lender, LOAN_SIZE); + + // add Borrower to Loans + Borrower memory borrower; + borrower.t0Debt = LOAN_SIZE; + borrower.collateral = pledge; + borrower.npTpRatio = 1 * 1e18; + Loans.update(_loans, borrower, loan, _poolState.rate, false, false); + } + + function _mockSettle(address loan) internal { + // remove debt and collateral from PoolState + uint256 pull = Maths.wdiv(LOAN_SIZE, TP); + _poolState.debt -= LOAN_SIZE; + _poolState.collateral -= pull; + + // remove Borrower from Loans + Borrower memory borrower; + borrower.t0Debt = 0; + borrower.collateral = 0; + Loans.update(_loans, borrower, loan, _poolState.rate, false, false); + + // remove liquidity from LUP + Deposits.unscaledRemove(_deposits, LUP_INDEX, LOAN_SIZE); + Bucket storage bucket = _buckets[LUP_INDEX]; + bucket.lps -= LOAN_SIZE; + } +} diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index d5b945159..4df3f8785 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -12,7 +12,7 @@ import 'src/interfaces/pool/commons/IPoolEvents.sol'; import 'src/interfaces/pool/IERC3156FlashBorrower.sol'; import 'src/PoolInfoUtils.sol'; -import { _auctionPrice, _bpf, MAX_PRICE } from 'src/libraries/helpers/PoolHelper.sol'; +import { _auctionPrice, _bpf, _depositFeeRate, MAX_PRICE } from 'src/libraries/helpers/PoolHelper.sol'; abstract contract DSTestPlus is Test, IPoolEvents { @@ -82,7 +82,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 totalBondEscrowed; uint256 auctionPrice; uint256 debtInAuction; - uint256 thresholdPrice; + uint256 debtToCollateral; uint256 neutralPrice; } @@ -118,19 +118,19 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 amount, uint256 index ) internal { - uint256 quoteTokenScale = IPool(address(_pool)).quoteTokenScale(); - uint256 lpAmount = (amount / quoteTokenScale) * quoteTokenScale; - _addLiquidity(from, amount, index, lpAmount, MAX_PRICE); + uint256 amountAdded = Maths.wmul(amount, _depositFee()); + uint256 lpAmount = amountAdded; + _addLiquidityWithPenalty(from, amount, amountAdded, index, lpAmount, MAX_PRICE); } - // Adds liquidity with interest rate update + // Adds liquidity without checking LP awarded or LUP function _addLiquidityNoEventCheck( address from, uint256 amount, uint256 index ) internal { changePrank(from); - _pool.addQuoteToken(amount, index, type(uint256).max, false); + _pool.addQuoteToken(amount, index, type(uint256).max); // Add for tearDown lenders.add(from); @@ -145,24 +145,27 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 lpAward, uint256 newLup ) internal { - _addLiquidityWithPenalty(from, amount, amount, index, lpAward, newLup); + uint256 amountAdded = Maths.wmul(amount, _depositFee()); + _addLiquidityWithPenalty(from, amount, amountAdded, index, lpAward, newLup); } + // Adds liquidity validating the lender deposit fee function _addLiquidityWithPenalty( address from, uint256 amount, - uint256 amountAdded, // amount less penalty, where applicable + uint256 amountAdded, // amount less fee uint256 index, uint256 lpAward, uint256 newLup ) internal { - uint256 quoteTokenScale = IPool(address(_pool)).quoteTokenScale(); changePrank(from); vm.expectEmit(true, true, false, true); - emit AddQuoteToken(from, index, (amountAdded / quoteTokenScale) * quoteTokenScale, lpAward, newLup); + emit AddQuoteToken(from, index, amountAdded, lpAward, newLup); _assertQuoteTokenTransferEvent(from, address(_pool), amount); - _pool.addQuoteToken(amount, index, type(uint256).max, false); + (uint256 returnLpAward, uint256 returnedAmountAdded) = _pool.addQuoteToken(amount, index, type(uint256).max); + assertEq(returnLpAward, lpAward); + assertEq(returnedAmountAdded, amountAdded); // Add for tearDown lenders.add(from); @@ -281,7 +284,8 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 lpAwardTo, uint256 newLup ) internal { - _moveLiquidityWithPenalty(from, amount, amount, fromIndex, toIndex, lpRedeemFrom, lpAwardTo, newLup); + uint256 amountMoved = fromIndex > toIndex ? amount : Maths.wmul(amount, _depositFee()); + _moveLiquidityWithPenalty(from, amount, amountMoved, fromIndex, toIndex, lpRedeemFrom, lpAwardTo, newLup); } function _moveLiquidityWithPenalty( @@ -297,7 +301,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { changePrank(from); vm.expectEmit(true, true, true, true); emit MoveQuoteToken(from, fromIndex, toIndex, amountMoved, lpRedeemFrom, lpAwardTo, newLup); - (uint256 lpbFrom, uint256 lpbTo, ) = _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + (uint256 lpbFrom, uint256 lpbTo, ) = _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); assertEq(lpbFrom, lpRedeemFrom); assertEq(lpbTo, lpAwardTo); @@ -357,7 +361,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { changePrank(from); vm.expectEmit(true, true, false, true); emit RemoveQuoteToken(from, index, amount, lpRedeem, newLup); - _assertQuoteTokenTransferEvent(address(_pool), from, amount); + _assertQuoteTokenTransferEventRoundingDown(address(_pool), from, amount); (uint256 removedAmount, uint256 lpRedeemed) = _pool.removeQuoteToken(amount, index); assertEq(removedAmount, amount); assertEq(lpRedeemed, lpRedeem); @@ -413,7 +417,15 @@ abstract contract DSTestPlus is Test, IPoolEvents { address to, uint256 amount ) internal virtual { - // to be overidden by ERC20 helper + // to be overidden by ERC20 helper + } + + function _assertQuoteTokenTransferEventRoundingDown( + address from, + address to, + uint256 amount + ) internal virtual { + // to be overidden by ERC20 helper } function _assertCollateralTokenTransferEvent( @@ -421,7 +433,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { address to, uint256 amount ) internal virtual { - // to be overidden by ERC20 helper + // to be overidden by ERC20 helper } /*********************/ @@ -437,7 +449,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 auctionNeutralPrice; uint256 auctionTotalBondEscrowed; uint256 auctionDebtInAuction; - uint256 borrowerThresholdPrice; + uint256 borrowerDebtToCollateral; } function _assertAuction(AuctionParams memory state_) internal { @@ -449,15 +461,15 @@ abstract contract DSTestPlus is Test, IPoolEvents { vars.auctionKickTime, vars.auctionReferencePrice, vars.auctionNeutralPrice, + vars.borrowerDebtToCollateral, , , ) = _pool.auctionInfo(state_.borrower); - (uint256 borrowerDebt, uint256 borrowerCollateral , ) = _poolUtils.borrowerInfo(address(_pool), state_.borrower); + (uint256 borrowerDebt, uint256 borrowerCollateral , , ) = _poolUtils.borrowerInfo(address(_pool), state_.borrower); (, uint256 lockedBonds) = _pool.kickerInfo(state_.kicker); - (vars.auctionTotalBondEscrowed,,,) = _pool.reservesInfo(); - (,, vars.auctionDebtInAuction,) = _pool.debtInfo(); - vars.borrowerThresholdPrice = borrowerCollateral > 0 ? borrowerDebt * Maths.WAD / borrowerCollateral : 0; + (vars.auctionTotalBondEscrowed,,,,) = _pool.reservesInfo(); + (,, vars.auctionDebtInAuction,) = _pool.debtInfo(); assertEq(vars.auctionKickTime != 0, state_.active); assertEq(vars.auctionKicker, state_.kicker); @@ -472,15 +484,17 @@ abstract contract DSTestPlus is Test, IPoolEvents { vars.auctionKickTime), state_.auctionPrice); assertEq(vars.auctionDebtInAuction, state_.debtInAuction); assertEq(vars.auctionNeutralPrice, state_.neutralPrice); - assertEq(vars.borrowerThresholdPrice, state_.thresholdPrice); + assertEq(vars.borrowerDebtToCollateral, state_.debtToCollateral); ( - uint256 kickTime, - uint256 collateral, - uint256 debtToCover, - bool isCollateralized, - uint256 price, - uint256 neutralPrice + uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 neutralPrice, + , + , ) = _poolUtils.auctionStatus(address(_pool), state_.borrower); assertEq(kickTime, state_.kickTime); assertEq(neutralPrice, state_.neutralPrice); @@ -492,9 +506,9 @@ abstract contract DSTestPlus is Test, IPoolEvents { assertEq(collateral, borrowerCollateral); assertEq(debtToCover, borrowerDebt); assertEq(isCollateralized, _isCollateralized( - borrowerDebt, - borrowerCollateral, - _lup(), + borrowerDebt, + borrowerCollateral, + _lup(), _pool.poolType()) ); assertEq(price, state_.auctionPrice); @@ -502,12 +516,12 @@ abstract contract DSTestPlus is Test, IPoolEvents { } function _assertPool(PoolParams memory state_) internal { - ( - , - , - uint256 htp, - , - uint256 lup, + ( + , + , + uint256 htp, + , + uint256 lup, ) = _poolUtils.poolPricesInfo(address(_pool)); ( uint256 poolSize, @@ -516,9 +530,9 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 pendingInflator, ) = _poolUtils.poolLoansInfo(address(_pool)); ( - uint256 poolMinDebtAmount, - , - uint256 poolActualUtilization, + uint256 poolMinDebtAmount, + , + uint256 poolActualUtilization, uint256 poolTargetUtilization ) = _poolUtils.poolUtilizationInfo(address(_pool)); @@ -572,7 +586,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { _assertBucketAssets(index, lpBalance, collateral, deposit, exchangeRate); - // validate bucket is healthy / LP consistent with assets + // validate bucket is healthy / LP consistent with assets _validateBucketLp(index, lpBalance); _validateBucketQuantities(index); } @@ -650,7 +664,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ( uint256 debt, uint256 col, - uint256 t0Np + uint256 t0Np, ) = _poolUtils.borrowerInfo(address(_pool), borrower); uint256 lup = _poolUtils.lup(address(_pool)); @@ -713,12 +727,12 @@ abstract contract DSTestPlus is Test, IPoolEvents { function _assertLoans( uint256 noOfLoans, address maxBorrower, - uint256 maxThresholdPrice + uint256 maxT0DebtToCollateral ) internal { (address curMaxBorrower, uint256 curTpPrice, uint256 curNoOfLoans) = _pool.loansInfo(); assertEq(curNoOfLoans, noOfLoans); assertEq(curMaxBorrower, maxBorrower); - assertEq(curTpPrice, maxThresholdPrice); + assertEq(curTpPrice, maxT0DebtToCollateral); } function _assertPoolPrices( @@ -778,6 +792,11 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.kickReserveAuction(); } + function _assertReserveAuctionUnsettledLiquidation() internal { + vm.expectRevert(IPoolErrors.AuctionActive.selector); + _pool.kickReserveAuction(); + } + /**********************/ /*** Revert asserts ***/ /**********************/ @@ -789,7 +808,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('BucketBankruptcyBlock()')); - _pool.addQuoteToken(amount, index, type(uint256).max, false); + _pool.addQuoteToken(amount, index, type(uint256).max); } function _assertAddLiquidityAtIndex0Revert( @@ -798,7 +817,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(amount, 0, type(uint256).max, false); + _pool.addQuoteToken(amount, 0, type(uint256).max); } function _assertAddLiquidityDustRevert( @@ -808,7 +827,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); - _pool.addQuoteToken(amount, index, type(uint256).max, false); + _pool.addQuoteToken(amount, index, type(uint256).max); } function _assertAddLiquidityExpiredRevert( @@ -819,17 +838,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.TransactionExpired.selector); - _pool.addQuoteToken(amount, index, expiry, false); - } - - function _assertAddLiquidityPriceBelowLUPRevert( - address from, - uint256 amount, - uint256 index - ) internal { - changePrank(from); - vm.expectRevert(abi.encodeWithSignature('PriceBelowLUP()')); - _pool.addQuoteToken(amount, index, type(uint256).max, true); + _pool.addQuoteToken(amount, index, expiry); } function _assertArbTakeNoAuction( @@ -1003,7 +1012,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256, uint256 ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertBorrowBorrowerNotSenderRevert( @@ -1012,7 +1021,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256, uint256 ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertBorrowLimitIndexRevert( @@ -1020,7 +1029,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256, uint256 ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertBorrowBorrowerUnderCollateralizedRevert( @@ -1028,7 +1037,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256, uint256 ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertBorrowMinDebtRevert( @@ -1036,7 +1045,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256, uint256 ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertFlashloanFeeRevertsForToken( @@ -1253,7 +1262,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('BucketBankruptcyBlock()')); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertMoveLiquidityLupBelowHtpRevert( @@ -1264,7 +1273,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.LUPBelowHTP.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertMoveLiquidityExpiredRevert( @@ -1276,7 +1285,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.TransactionExpired.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, expiry, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, expiry); } function _assertMoveLiquidityDustRevert( @@ -1287,7 +1296,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertMoveLiquidityToSameIndexRevert( @@ -1298,7 +1307,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertMoveLiquidityToIndex0Revert( @@ -1308,7 +1317,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(amount, fromIndex, 0, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, 0, type(uint256).max); } function _assertMoveDepositLockedByAuctionDebtRevert( @@ -1319,7 +1328,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.RemoveDepositLockedByAuctionDebt.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertMoveDepositAuctionNotClearedRevert( @@ -1330,25 +1339,14 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.AuctionNotCleared.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); - } - - function _assertMoveDepositBelowLUPRevert( - address from, - uint256 amount, - uint256 fromIndex, - uint256 toIndex - ) internal { - changePrank(from); - vm.expectRevert(IPoolErrors.PriceBelowLUP.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, true); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); } function _assertRepayAuctionActiveRevert( address from, uint256 maxAmount ) internal virtual { - // to be overidden by ERC20/ERC721DSTestPlus + // to be overidden by ERC20/ERC721DSTestPlus } function _assertTakeDebtUnderMinPoolDebtRevert( @@ -1388,7 +1386,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.takeReserves(amount); } - function _assertTakeReservesNoReservesRevert() internal { + function _assertKickReservesNoReservesRevert() internal { vm.expectRevert(IPoolErrors.NoReserves.selector); _pool.kickReserveAuction(); } @@ -1411,7 +1409,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ( , , , , , lupIndex_ ) = _poolUtils.poolPricesInfo(address(_pool)); } - function _htp() internal view returns (uint256 htp_) { + function _getHtp() internal view returns (uint256 htp_) { ( , , htp_, , , ) = _poolUtils.poolPricesInfo(address(_pool)); } @@ -1428,7 +1426,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { /********************/ // Pool deployer events - event PoolCreated(address pool_); + event PoolCreated(address pool_, bytes32 subsetHash_); /************************/ @@ -1451,7 +1449,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { IPool pool = IPool(pool_); uint256 lupIndex = pool.depositIndex(debtAmount_); - lup_ = _priceAt(lupIndex); + lup_ = _priceAt(lupIndex); } function setRandomSeed(uint256 seed) public { @@ -1530,7 +1528,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { (uint256 interestRate, ) = _pool.interestRateInfo(); uint256 newInterestRate = Maths.wmul(interestRate, 1.1 * 10**18); // interest rate multipled by increase coefficient uint256 expectedDebt = Maths.wmul(borrowAmount, _borrowFeeRate(newInterestRate) + Maths.WAD); - requiredCollateral_ = Maths.wdiv(expectedDebt, _poolUtils.indexToPrice(indexPrice)); + requiredCollateral_ = Maths.wdiv(Maths.wmul(expectedDebt, COLLATERALIZATION_FACTOR), _poolUtils.indexToPrice(indexPrice)); } // calculate the fee that will be charged a borrower @@ -1540,6 +1538,12 @@ abstract contract DSTestPlus is Test, IPoolEvents { // calculate the fee rate based upon the interest rate feeRate_ = _borrowFeeRate(newInterestRate) + Maths.WAD; } + + // calculate the fee that will be charged a lender + function _depositFee() internal view returns (uint256 feeRate_) { + (uint256 interestRate, ) = _pool.interestRateInfo(); + feeRate_ = Maths.WAD - _depositFeeRate(interestRate); + } } function getDiff(uint256 x, uint256 y) pure returns (uint256 diff) { @@ -1553,5 +1557,3 @@ abstract contract DSTestPlus is Test, IPoolEvents { function greaterThanWithinDiff(uint256 x, uint256 y, uint256 expectedDiff, string memory err) pure { require(x > y || getDiff(x, y) <= expectedDiff, err); } - - diff --git a/tests/forge/utils/FenwickTreeInstance.sol b/tests/forge/utils/FenwickTreeInstance.sol index 733464b72..eec9d3e6e 100644 --- a/tests/forge/utils/FenwickTreeInstance.sol +++ b/tests/forge/utils/FenwickTreeInstance.sol @@ -95,10 +95,13 @@ contract FenwickTreeInstance is DSTestPlus { amount = insertions_ == 1 ? amount_ : (amount_ % insertions_) * randomInRange(1_000, 1 * 1e10, true); // Update values - add(i, amount); - amount_ -= amount; - insertions_ -= 1; - cumulativeAmount += amount; + if (amount != 0) { + add(i, amount); + amount_ -= amount; + cumulativeAmount += amount; + } + + insertions_ -= 1; // Verify tree sum assertEq(deposits.treeSum(), cumulativeAmount); diff --git a/tests/forge/utils/HeapInstance.sol b/tests/forge/utils/HeapInstance.sol index f1225c830..18031fb4c 100644 --- a/tests/forge/utils/HeapInstance.sol +++ b/tests/forge/utils/HeapInstance.sol @@ -31,27 +31,27 @@ contract HeapInstance is DSTestPlus { return inserts[i_]; } - function upsertTp(address borrower_, uint256 tp_) public { + function upsertT0DebtToCollateral(address borrower_, uint256 tp_) public { _heap._upsert(borrower_, _heap.indices[borrower_], uint96(tp_)); } - function removeTp(address borrower_) external { + function removeT0DebtToCollateral(address borrower_) external { _heap.remove(borrower_, _heap.indices[borrower_]); } - function getTp(address borrower_) public view returns (uint256) { - return _heap.getByIndex(_heap.indices[borrower_]).thresholdPrice; + function getT0DebtToCollateral(address borrower_) public view returns (uint256) { + return _heap.getByIndex(_heap.indices[borrower_]).t0DebtToCollateral; } - function getMaxTp() external view returns (uint256) { - return _heap.getMax().thresholdPrice; + function getMaxT0DebtToCollateral() external view returns (uint256) { + return _heap.getMax().t0DebtToCollateral; } function getMaxBorrower() external view returns (address) { return _heap.getMax().borrower; } - function getTotalTps() external view returns (uint256) { + function getTotalT0DebtToCollaterals() external view returns (uint256) { return _heap.loans.length; } @@ -81,12 +81,12 @@ contract HeapInstance is DSTestPlus { tp = randomInRange(99_836_282_890, 1_004_968_987.606512354182109771 * 10**18, true); // Insert TP - upsertTp(borrower, tp); + upsertT0DebtToCollateral(borrower, tp); insertsDec -= 1; // Verify amount of Heap TPs assertEq(_heap.loans.length - 1, totalInserts - insertsDec); - assertEq(getTp(borrower), tp); + assertEq(getT0DebtToCollateral(borrower), tp); if (trackInserts_) inserts.push(borrower); }