From 089cb9d695ec2ddeb119dcfc94e58f79f0f918b9 Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Wed, 7 Jun 2023 14:40:48 -0400 Subject: [PATCH 01/32] Position invariants (#854) * initial draft * got initial scaffolding running * included Matts invaraints * added PM1 and PM5 * Reward invariants merged (#773) * changes needed for contract verification (#764) * changes needed for contract verification * gotcha * Make NFT tokens claimable after `take`, `bucketTake`, `settle` actions (#763) * Add test failure * When ERC721.bucketTake always rebalance token ids from borrower to pool claimable array * Consistent take with bucketTake, always rebalance tokens * Check invariants in regression test * Always rebalance tokens on settle (settle could enter with 0 collateral but still with bad debt) * Changed epsilon from 1e16 to 1e17 in F1 and F2 invariants (#765) * Add variable token precision for ERC721Pool invariants (#755) * Add multiple precision of quote token in erc721Pool invariants * Add shebang and set -e option * Invariant framework improvements (#769) * Update forge library, set default env vars using envOr instead reading from env file * Remove InvariantsTestHelpers contract and move invariants helper functions to BaseInvariants * env cleanup for invariants * Update invariant testing scripts * Add skipTime in merge collateral handler * Add fuzzed time skip between kick and take/bucketTake --------- Co-authored-by: grandizzy * Removing brownie TODOs as these tests won't be further expanded (#767) * ERC20 R1_R2_R3_R4_R5_R6_R7_R8 invariant failure (#771) * Add failing test * Change cutoff for deminimus check to 1 LP in a bucket for exchange rate diffs --------- Co-authored-by: mwc * Erc721 CT2 invariant failure (#770) * Reproduce CT2 invariant failure * Add collateral that could be compensated in bucket 7388 when auction settled * Make sure MAX bucket not accounted twice. Fix test-regression target * Fix bucketTake invariant logic in place instead in CT2 invariant. Added regression test comments. * Fix CI, lock foundry version until resolution for https://github.com/foundry-rs/foundry/issues/4835 --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: mwc * working through PM3 * wrapped position calls * made getPoolAccumulators a free function & cleaned up logging * included free function * increased logging robustness * working through adding positions without passing positions to baseclass * cleanup * Fix position manager invariant testing setup * Fix EVM reverts * Fix some assertions in moveliquidity handler * Move post action checks in try to run only when transaction is successful * position man initially working * removed redundant invariant check * got rewards structure running * Update Rewards Manager handler structure * Remove redundancy in Rewards Handler * regression PM1 failing * Fix invariant PM1 * Fix invariant RW1 * Add remaining rewards manager handlers * Add drawDebt before kick reserve auction to generate some reserves * Fix drawDebt evm revert in preUnstake * handled broken rewardsCap * Fixed evm revert and PM1 invariant * Add failing regression test * Update make commands for Position and Rewards Manager * added check in moveLiquidity that ensure QT amount for actor doesn't change * cleaned up * revised invariants per Prototech labs suggestion * cleanup invar * added update interest to fix QT diff on moveLiquidity * working through test failure * resolved fee on move liquidity * working through rewards * initial commit * cleanup * low haning fruit feedback * fixed takeReserves in rewards invariant * added NFT position tracking for rewards manager * cleanup * Add comments for failing regression test * responded to Mikes feedback * EOF line addition * cleaned up requires, formally added more PositionManager invar * Quote to lps inc on move (#877) * cleaned up requires, formally added more PositionManager invar * cleaned up requires, formally added more PositionManager invar * added logs * works with diff * cleanup --------- Co-authored-by: Ian Harvey * cleaned up rewards and position naming * responded to class naming * cleaned up spaced --------- Co-authored-by: Ian Harvey Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: mwc Co-authored-by: prateek105 --- .gitignore | 1 + Makefile | 4 + src/RewardsManager.sol | 79 ++--- tests/INVARIANTS.md | 25 +- tests/README.md | 16 + .../PositionsInvariants.t.sol | 124 +++++++ .../RewardsInvariants.t.sol | 82 +++++ .../handlers/BasePositionHandler.sol | 199 +++++++++++ .../handlers/PositionHandler.sol | 26 ++ .../handlers/RewardsHandler.sol | 173 ++++++++++ .../UnboundedBasePositionHandler.sol | 70 ++++ .../unbounded/UnboundedPositionsHandler.sol | 313 ++++++++++++++++++ .../unbounded/UnboundedRewardsHandler.sol | 99 ++++++ .../forge/invariants/base/BaseInvariants.sol | 16 - .../invariants/base/BasicInvariants.t.sol | 62 +++- .../base/LiquidationInvariants.t.sol | 2 +- .../invariants/base/ReserveInvariants.t.sol | 75 ++--- .../base/handlers/ReservePoolHandler.sol | 6 +- .../base/handlers/unbounded/BaseHandler.sol | 4 +- .../UnboundedLiquidationPoolHandler.sol | 1 + .../unbounded/UnboundedReservePoolHandler.sol | 2 +- .../invariants/interfaces/IBaseHandler.sol | 2 +- .../IPositionsAndRewardsHandler.sol | 13 + .../RegressionPositionManager.t.sol | 124 +++++++ .../RegressionRewardsManager.t.sol | 289 ++++++++++++++++ tests/forge/utils/DSTestPlus.sol | 15 +- 26 files changed, 1713 insertions(+), 109 deletions(-) create mode 100644 tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol create mode 100644 tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol create mode 100644 tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol create mode 100644 tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol diff --git a/.gitignore b/.gitignore index a5215a3a7..784a5b2dc 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ report/ keystore/ broadcast/ logFile.txt +*.log # Certora .certora_internal/ diff --git a/Makefile b/Makefile index 71af3eb12..efbd3f870 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,8 @@ test-load :; forge test --match-test testLoad --gas-report test-invariant-all :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} test-invariant-erc20 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC20 test-invariant-erc721 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC721 +test-invariant-position :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Position +test-invariant-rewards :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Rewards 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 @@ -48,6 +50,8 @@ 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 test-regression :; forge t --mt ${MT} diff --git a/src/RewardsManager.sol b/src/RewardsManager.sol index 5cf04b384..9a103d08a 100644 --- a/src/RewardsManager.sol +++ b/src/RewardsManager.sol @@ -570,43 +570,6 @@ contract RewardsManager is IRewardsManager { } } - /** - * @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_ - ) internal 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_); - - // calculate total tokens burned and interest earned in epoch - tokensBurned_ = totalBurnedLatest != 0 ? totalBurnedLatest - totalBurnedPrev : 0; - interestEarned_ = totalInterestLatest != 0 ? totalInterestLatest - totalInterestPrev : 0; - } - } - /** * @notice Update the exchange rate of a list of buckets. * @dev Called as part of `stake`, `unstake`, and `claimRewards`, as well as `updateBucketExchangeRatesAndClaim`. @@ -835,5 +798,45 @@ contract RewardsManager is IRewardsManager { 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/tests/INVARIANTS.md b/tests/INVARIANTS.md index 6c75cc5ef..1832ed1ab 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -77,5 +77,26 @@ - **RE11**: Reserves decrease by claimableReserves by kickReserveAuction - **RE12**: Reserves decrease by amount of reserve used to settle a auction -Rewards: -- Can't claim rewards for an end epoch twice \ No newline at end of file +## 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()`) +- **RW5**: After unstaking or claiming rewards, `isEpochClaimed` should be equal to `true`, `stakeInfo_.lastClaimedEpoch` be equal to the current epoch and `rewardsClaimed` should be incremented by the claimed amount. +- **RW6**: Each time the bucket rate is updated the `updateRewardsClaimed` accumulator should be properly updated +- **RW7**: 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()`. +- **RW8**: After unstaking, stakeInfo's tokenId mapping should be deleted and all corrosponding values should therefore be zero'd out (`StakeInfo.ajnaPool`, `StakeInfo.lastClaimedEpoch`, `StakeInfo.owner`, `StakeInfo.stakingEpoch`, `StakeInfo.snapshots`) +- **RW9**: Can't claim rewards for an end 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 +- **PM3**: Position deposit time (`depositTime`) tracked by tokenId in PositionManager (`positions[tokenId][index]`) should always be of equal or lesser value than the PositionManager's LP at that index in the pool contract. +- **PM4**: mint should populate `poolKey[tokenId]`, `positionIndexes` should be empty and the owner of the NFT should be the caller. +- **PM5**: burn should reset `poolKey[tokenId]`, `positionIndexes` should be empty and the owner of the NFT should be the zero address. +- **PM6**: moveLiquidity should remove all LP from the from index and set deposit time to zero. To index should receive increased LP and deposit time should match positionManager's deposit time. PositionManager should have less then or equal to the same quoteToken after move. +- **PM7**: memorializePosition should transfer all pool contract LP in the provided index to the positionManager. PositionManager should take on the greater of the lender of positionManager's deposit time. PositionManager's LP in the provided index should match what the lender had in the pool contract before memorializePosition was called. +- **PM8**: reedemPositions should maintain the preivous owner of the NFT position and pool associated with position. Remove the passed in indexes from the positionIndexes associated token. LP of redeemer should increase with same amount that LP of PositionManager decrease (by checking the pool). tokenId associated with the indexes redeemed should be zero. + + diff --git a/tests/README.md b/tests/README.md index 61e23661b..2a4072fed 100644 --- a/tests/README.md +++ b/tests/README.md @@ -33,6 +33,14 @@ make test-regression-erc20 ```bash make test-regression-erc721 ``` +- regression tests for Position Manager: +```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 @@ -138,6 +146,14 @@ make test-invariant-erc20 ```bash make test-invariant-erc721 ``` +- run all invariant tests for Position Manager: +```bash +make test-invariant-position +``` +- 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= diff --git a/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol new file mode 100644 index 000000000..80cc47880 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.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 { Maths } from 'src/libraries/internal/Maths.sol'; + +import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; +import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; +import { BaseInvariants } from '../base/BaseInvariants.sol'; +import { ReserveERC20PoolInvariants } from '../ERC20Pool/ReserveERC20PoolInvariants.t.sol'; +import { ReserveERC20PoolHandler } from '../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; +import { TokenWithNDecimals } from '../../utils/Tokens.sol'; + +import { PositionHandler } from './handlers/PositionHandler.sol'; + +contract PositionsInvariants is BaseInvariants { + + uint256 internal constant NUM_ACTORS = 10; + + TokenWithNDecimals internal _collateral; + ERC20Pool internal _erc20pool; + ERC20Pool internal _erc20impl; + ERC20PoolFactory internal _erc20poolFactory; + ERC721PoolFactory internal _erc721poolFactory; + ERC721Pool internal _erc721impl; + PositionManager internal _positionManager; + PositionHandler internal _positionHandler; + + function setUp() public override virtual { + + super.setUp(); + _collateral = new TokenWithNDecimals("Collateral", "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18)))); + _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); + _erc20impl = _erc20poolFactory.implementation(); + _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); + _erc721impl = _erc721poolFactory.implementation(); + _erc20pool = ERC20Pool(_erc20poolFactory.deployPool(address(_collateral), address(_quote), 0.05 * 10**18)); + _pool = Pool(address(_erc20pool)); + _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); + + excludeContract(address(_ajna)); + excludeContract(address(_collateral)); + excludeContract(address(_quote)); + excludeContract(address(_erc20poolFactory)); + excludeContract(address(_erc721poolFactory)); + excludeContract(address(_erc20pool)); + excludeContract(address(_poolInfo)); + excludeContract(address(_erc20impl)); + excludeContract(address(_erc721impl)); + excludeContract(address(_positionManager)); + + _positionHandler = new PositionHandler( + address(_positionManager), + address(_erc20pool), + address(_ajna), + address(_quote), + address(_collateral), + address(_poolInfo), + NUM_ACTORS, + address(this) + ); + + _handler = address(_positionHandler); + } + + function invariant_positions_PM1_PM2_PM3() public useCurrentTimestamp { + uint256[] memory bucketIndexes = IPositionsAndRewardsHandler(_handler).getBucketIndexesWithPosition(); + + // loop over bucket indexes with positions + for (uint256 i = 0; i < bucketIndexes.length; i++) { + uint256 mostRecentDepositTime; + uint256 bucketIndex = bucketIndexes[i]; + uint256 posLpAccum; + uint256 poolLpAccum; + + (uint256 poolLp, uint256 depositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + poolLpAccum += poolLp; + + // loop over tokenIds in bucket indexes + uint256[] memory tokenIds = IPositionsAndRewardsHandler(_handler).getTokenIdsByBucketIndex(bucketIndex); + for (uint256 k = 0; k < tokenIds.length; k++) { + uint256 tokenId = tokenIds[k]; + + (, uint256 posDepositTime) = _positionManager.getPositionInfo(tokenId, bucketIndex); + uint256 posLp = _positionManager.getLP(tokenId, bucketIndex); + posLpAccum += posLp; + mostRecentDepositTime = (posDepositTime > mostRecentDepositTime) ? posDepositTime : mostRecentDepositTime; + } + require(poolLpAccum == posLpAccum, "Positions Invariant PM1 and PM2"); + require(depositTime >= mostRecentDepositTime, "Positions Invariant PM3"); + } + } + + function invariant_call_summary() public virtual useCurrentTimestamp { + console.log("\nCall Summary\n"); + console.log("--Positions--------"); + console.log("UBPositionHandler.mint ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.mint")); + console.log("BPositionHandler.mint ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.mint")); + console.log("UBPositionHandler.burn ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.burn")); + console.log("BPositionHandler.burn ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.burn")); + console.log("UBPositionHandler.memorialize ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.memorialize")); + console.log("BPositionHandler.memorialize ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.memorialize")); + console.log("UBPositionHandler.redeem ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.redeem")); + console.log("BPositionHandler.redeem ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.redeem")); + console.log("UBPositionHandler.moveLiquidity ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.moveLiquidity")); + console.log("BPositionHandler.moveLiquidity ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.moveLiquidity")); + console.log( + "Sum", + IBaseHandler(_handler).numberOfCalls("BPositionHandler.mint") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.burn") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.memorialize") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.redeem") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.moveLiquidity") + ); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol new file mode 100644 index 000000000..2ef8cb822 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.sol"; +import { Maths } from 'src/libraries/internal/Maths.sol'; +import { RewardsManager } from 'src/RewardsManager.sol'; +import { _getEpochInfo } from 'src/RewardsManager.sol'; + +import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; +import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; +import { RewardsHandler } from './handlers/RewardsHandler.sol'; +import { PositionsInvariants } from './PositionsInvariants.t.sol'; + +contract RewardsInvariants is PositionsInvariants { + + RewardsManager internal _rewardsManager; + RewardsHandler internal _rewardsHandler; + + function setUp() public override virtual { + + super.setUp(); + + _rewardsManager = new RewardsManager(address(_ajna), _positionManager); + + // fund the rewards manager with 100M ajna + _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); + + excludeContract(address(_positionHandler)); + excludeContract(address(_rewardsManager)); + + _rewardsHandler = new RewardsHandler( + address(_rewardsManager), + address(_positionManager), + address(_erc20pool), + address(_ajna), + address(_quote), + address(_collateral), + address(_poolInfo), + NUM_ACTORS, + address(this) + ); + + _handler = address(_rewardsHandler); + } + + function invariant_rewards_RW1_RW2() public useCurrentTimestamp { + + // get current epoch (is incremented every kickReserve() call) + uint256 curEpoch = _pool.currentBurnEpoch(); + + // get rewards that have been claimed + uint256 claimedRewards = IPositionsAndRewardsHandler(_handler).totalRewardPerEpoch(curEpoch); + + // total ajna burned by the pool over the epoch + (, uint256 totalBurnedInPeriod,) = _getEpochInfo(address(_pool), curEpoch); + + // stake rewards cap is 80% of total burned + uint256 stakeRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.8 * 1e18); + // check claimed rewards < rewards cap + if (stakeRewardsCap != 0) require(claimedRewards < stakeRewardsCap, "Rewards invariant RW1"); + + // update rewards cap is 10% of total burned + uint256 updateRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.1 * 1e18); + // check claimed rewards < rewards cap + if (updateRewardsCap != 0) require(claimedRewards < updateRewardsCap, "Rewards invariant RW2"); + } + + function invariant_call_summary() public virtual override useCurrentTimestamp { + console.log("\nCall Summary\n"); + console.log("--Positions--------"); + console.log("UBRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.unstake")); + console.log("BRewardsHandler.unstake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake")); + console.log("UBRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("UBRewardsHandler.stake")); + console.log("BRewardsHandler.stake ", IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake")); + console.log( + "Sum", + IBaseHandler(_handler).numberOfCalls("BRewardsHandler.unstake") + + IBaseHandler(_handler).numberOfCalls("BRewardsHandler.stake") + ); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol new file mode 100644 index 000000000..69f25ca51 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import '@std/console.sol'; + +import { Maths } from 'src/libraries/internal/Maths.sol'; + +import { _priceAt } from 'src/libraries/helpers/PoolHelper.sol'; + +import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; +import { PositionManager } from 'src/PositionManager.sol'; +import { ERC20Pool } from 'src/ERC20Pool.sol'; + +import { UnboundedPositionsHandler } from './unbounded/UnboundedPositionsHandler.sol'; +import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; + +abstract contract BasePositionHandler is UnboundedPositionsHandler { + + using EnumerableSet for EnumerableSet.UintSet; + + /********************************/ + /*** Positions Test Functions ***/ + /********************************/ + + function memorializePositions( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.memorialize']++; + // Pre action // + (uint256 tokenId, uint256[] memory indexes) = _preMemorializePositions(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _memorializePositions(tokenId, indexes); + } + + function redeemPositions( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.redeem']++; + // Pre action // + (uint256 tokenId, uint256[] memory indexes) = _preRedeemPositions(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _redeemPositions(tokenId, indexes); + } + + function mint( + uint256 actorIndex_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.mint']++; + + // Action phase // + _mint(); + } + + function burn( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 skippedTime_, + uint256 amountToAdd_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.burn']++; + // Pre action // + (uint256 tokenId_) = _preBurn(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _burn(tokenId_); + } + + function moveLiquidity( + uint256 actorIndex_, + uint256 skippedTime_, + uint256 amountToMove_, + uint256 fromIndex_, + uint256 toIndex_ + ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.moveLiquidity']++; + // Pre action // + ( + uint256 tokenId, + uint256 fromIndex, + uint256 toIndex + ) = _preMoveLiquidity(amountToMove_, fromIndex_, toIndex_); + + // retrieve info of bucket from pool + ( + , + uint256 bucketCollateral, + , + , + ) = _pool.bucketInfo(fromIndex); + + // to avoid LP mismatch revert return if bucket has collateral or exchangeRate < 1e18 + if (bucketCollateral != 0) return; + if (_pool.bucketExchangeRate(fromIndex) < 1e18) return; + + // Action phase // + _moveLiquidity(tokenId, fromIndex, toIndex); + } + + function _preMemorializePositions( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, 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) { + // Prepare test phase + uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); + _ensureQuoteAmount(_actor, boundedAmount); + try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes) { + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + indexes_ = new uint256[](1); + indexes_[0] = bucketIndex_; + + uint256[] memory lpBalances = new uint256[](1); + + // mint position NFT + tokenId_ = _mint(); + + (lpBalances[0], ) = _pool.lenderInfo(bucketIndex_, _actor); + _pool.increaseLPAllowance(address(_positionManager), indexes_, lpBalances); + } + + function _preRedeemPositions( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + (tokenId_, indexes_) = _getNFTPosition(bucketIndex_, amountToAdd_); + + // approve positionManager to transfer LP tokens + address[] memory transferors = new address[](1); + transferors[0] = address(_positionManager); + + _pool.approveLPTransferors(transferors); + } + + function _preBurn( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_) { + uint256[] memory indexes; + + // check and create the position + (tokenId_, indexes) = _preRedeemPositions(bucketIndex_, amountToAdd_); + + _redeemPositions(tokenId_, indexes); + } + + function _preMoveLiquidity( + uint256 amountToMove_, + uint256 fromIndex_, + uint256 toIndex_ + ) internal returns (uint256 tokenId_, uint256 boundedFromIndex_, uint256 boundedToIndex_) { + boundedFromIndex_ = constrictToRange(fromIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + boundedToIndex_ = constrictToRange(toIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + + uint256[] memory indexes; + (tokenId_, indexes) = _getNFTPosition(boundedFromIndex_, amountToMove_); + boundedFromIndex_ = indexes[0]; + + } + + function _getNFTPosition( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + // Check for exisiting nft positions in PositionManager + uint256[] memory tokenIds = getTokenIdsByActor(address(_actor)); + + if (tokenIds.length != 0 ) { + // use existing position NFT + tokenId_ = tokenIds[0]; + indexes_ = getBucketIndexesByTokenId(tokenId_); + } else { + // create a position for the actor + (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); + _memorializePositions(tokenId_, indexes_); + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol new file mode 100644 index 000000000..3e2e48a10 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { PositionManager } from 'src/PositionManager.sol'; + +import { BasePositionHandler } from './BasePositionHandler.sol'; +import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; + +contract PositionHandler is BasePositionHandler { + + constructor( + address positions_, + address pool_, + address ajna_, + address quote_, + address collateral_, + address poolInfo_, + uint256 numOfActors_, + address testContract_ + ) BaseERC20PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { + + // Position manager + _positionManager = PositionManager(positions_); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol new file mode 100644 index 000000000..7de658e2e --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +import { PositionManager } from 'src/PositionManager.sol'; +import { RewardsManager } from 'src/RewardsManager.sol'; + +import { UnboundedRewardsHandler } from './unbounded/UnboundedRewardsHandler.sol'; + +import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; +import { BasePositionHandler } from './BasePositionHandler.sol'; + +contract RewardsHandler is UnboundedRewardsHandler, BasePositionHandler, ReserveERC20PoolHandler { + + constructor( + address rewards_, + address positions_, + address pool_, + address ajna_, + address quote_, + address collateral_, + address poolInfo_, + uint256 numOfActors_, + address testContract_ + ) ReserveERC20PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { + + // Position manager + _positionManager = PositionManager(positions_); + + // Rewards manager + _rewardsManager = RewardsManager(rewards_); + } + + /*******************************/ + /*** Rewards Test Functions ***/ + /*******************************/ + + function stake( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.stake']++; + // Pre action + (uint256 tokenId,) = _preStake(_lenderBucketIndex, amountToAdd_); + + // Action phase + _stake(tokenId); + } + + function unstake( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.unstake']++; + // Pre action + uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); + + // 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 updateExchangeRate( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.updateRate']++; + + // Pre action // + uint256[] memory indexes = _preUpdateExchangeRate(_lenderBucketIndex); + + // Action phase + _updateExchangeRate(indexes); + } + + function claimRewards( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.claimRewards']++; + + // Pre action // + uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); + + uint256 currentEpoch = _pool.currentBurnEpoch(); + + // Action phase + _claimRewards(tokenId, currentEpoch); + } + + /*******************************/ + /*** Rewards Tests Functions ***/ + /*******************************/ + + function _preStake( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); + + _memorializePositions(tokenId_, indexes_); + + // Approve rewards contract to transfer token + _positionManager.approve(address(_rewardsManager), tokenId_); + + } + + function _preUnstake( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_) { + + // TODO: Check if the actor has a NFT position or a staked position is tracking events + + // Create a staked position + uint256[] memory indexes; + (tokenId_, indexes)= _preStake(bucketIndex_, amountToAdd_); + _stake(tokenId_); + + _advanceEpochRewardStakers(amountToAdd_, indexes); + } + + function _advanceEpochRewardStakers( + uint256 amountToAdd_, + uint256[] memory indexes_ + ) internal { + + // 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(20 days); // epochs are spaced a minimum of 14 days apart + + _repayDebt(type(uint256).max); + } + + (, 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 checked + _rewardsManager.updateBucketExchangeRatesAndClaim(address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), indexes_); + + } + + function _preUpdateExchangeRate( + uint256 bucketIndex_ + ) internal pure returns (uint256[] memory indexes_) { + indexes_ = new uint256[](1); + indexes_[0] = bucketIndex_; + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol new file mode 100644 index 000000000..49dc5384b --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -0,0 +1,70 @@ + +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; + +import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; +import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; +import { Maths } from "src/libraries/internal/Maths.sol"; + +import { BaseERC20PoolHandler } from '../../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; + +import { PositionManager } from 'src/PositionManager.sol'; +import { RewardsManager } from 'src/RewardsManager.sol'; +import { ERC20Pool } from 'src/ERC20Pool.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 UnboundedBasePositionHandler is BaseERC20PoolHandler { + + PositionManager internal _positionManager; + RewardsManager internal _rewardsManager; + + uint256 MAX_AJNA_AMOUNT = vm.envOr("MAX_AJNA_AMOUNT_ERC20", uint256(100_000_000 * 1e18)); + + // Position invariant test state // + + // used for PM1_PM2_PM3 tracking + mapping(uint256 => EnumerableSet.UintSet) internal tokenIdsByBucketIndex; + EnumerableSet.UintSet internal bucketIndexesWithPosition; + + // used for removing all CT and QT to reset bucket exchange rate + mapping(uint256 => address) internal actorByTokenId; + mapping(address => EnumerableSet.UintSet) internal tokenIdsByActor; + mapping(uint256 => EnumerableSet.UintSet) internal bucketIndexesByTokenId; + + // used to track LP changes in `_redeemPositions()` and `_memorializePositions()` + mapping(uint256 => uint256) internal bucketIndexToActorPositionManLps; + mapping(uint256 => uint256) internal bucketIndexToPositionManPoolLps; + mapping(uint256 => uint256) internal bucketIndexToActorPoolLps; + mapping(uint256 => uint256) internal bucketIndexToDepositTime; + + // Rewards invariant test state // + mapping(uint256 => uint256) public totalRewardPerEpoch; // total rewards per epoch + uint256 public totalStakerRewPerEpoch; // amount of reserve decrease + uint256 public totalUpdaterRewPerEpoch; // amount of reserve increase + + using EnumerableSet for EnumerableSet.UintSet; + + function getBucketIndexesWithPosition() public view returns(uint256[] memory) { + return bucketIndexesWithPosition.values(); + } + + function getTokenIdsByBucketIndex(uint256 bucketIndex_) public view returns(uint256[] memory) { + return tokenIdsByBucketIndex[bucketIndex_].values(); + } + + function getBucketIndexesByTokenId(uint256 tokenId_) public view returns(uint256[] memory) { + return bucketIndexesByTokenId[tokenId_].values(); + } + + function getTokenIdsByActor(address actor_) public view returns(uint256[] memory) { + return tokenIdsByActor[actor_].values(); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol new file mode 100644 index 000000000..b66dff4a9 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol @@ -0,0 +1,313 @@ +// 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'; + +/** + * @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 UnboundedPositionsHandler is UnboundedBasePositionHandler { + + using EnumerableSet for EnumerableSet.UintSet; + + function _memorializePositions( + uint256 tokenId_, + uint256[] memory indexes_ + ) internal { + numberOfCalls['UBPositionHandler.memorialize']++; + + for(uint256 i=0; i < indexes_.length; i++) { + + // store vals pre action to check after memorializing: + (uint256 actorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); + (uint256 posManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + + bucketIndexToActorPoolLps[indexes_[i]] = actorLps; + bucketIndexToPositionManPoolLps[indexes_[i]] = posManLps; + + // positionManager is assigned the most recent depositTime + bucketIndexToDepositTime[indexes_[i]] = (actorDepositTime >= posManDepositTime) ? actorDepositTime : posManDepositTime; + + // assert that the underlying LP balance in PositionManager is 0 + (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); + require(posPreActionLps == 0, "tokenID already has lps associated on memorialize"); + + } + + try _positionManager.memorializePositions(address(_pool), tokenId_, indexes_) { + + // track created positions + for ( uint256 i = 0; i < indexes_.length; i++) { + // PM1_PM2_PM3 tracking + bucketIndexesWithPosition.add(indexes_[i]); + tokenIdsByBucketIndex[indexes_[i]].add(tokenId_); + + // info used to tearDown buckets + bucketIndexesByTokenId[tokenId_].add(indexes_[i]); + } + + // info used track actors positions + actorByTokenId[tokenId_] = address(_actor); + tokenIdsByActor[address(_actor)].add(tokenId_); + + // Post action Checks // + for(uint256 i=0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + + // assert that the LP that now exists in the pool contract matches the amount added by the actor + (uint256 poolLps, uint256 poolDepositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + require(poolLps == bucketIndexToActorPoolLps[bucketIndex] + bucketIndexToPositionManPoolLps[bucketIndex], + "PM7: pool contract lps do not match amount added by actor"); + + require(poolDepositTime == bucketIndexToDepositTime[bucketIndex], + "PM7: positionManager depositTime does not match most recent depositTime"); + + // assert that the positionManager LP balance of the actor has increased + (uint256 posLps,) = _positionManager.getPositionInfo(tokenId_, bucketIndex); + require(posLps == bucketIndexToActorPoolLps[bucketIndex], + "PM7: positionManager lps do not match amount added by actor"); + + delete bucketIndexToActorPoolLps[bucketIndex]; + delete bucketIndexToPositionManPoolLps[bucketIndex]; + delete bucketIndexToDepositTime[bucketIndex]; + } + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + function _mint() internal returns (uint256 tokenIdResult) { + numberOfCalls['UBPositionHandler.mint']++; + try _positionManager.mint(address(_pool), _actor, keccak256("ERC20_NON_SUBSET_HASH")) 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"); + + // assert that poolKey is returns correct pool address + address poolAddress = _positionManager.poolKey(tokenId); + 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"); + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + function _redeemPositions( + uint256 tokenId_, + uint256[] memory indexes_ + ) internal { + numberOfCalls['UBPositionHandler.redeem']++; + + address preActionOwner = _positionManager.ownerOf(tokenId_); + + for (uint256 i=0; i < indexes_.length; i++) { + + // store vals in mappings to check lps + (uint256 poolPreActionActorLps,) = _pool.lenderInfo(indexes_[i], preActionOwner); + (uint256 poolPreActionPosManLps,) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + + bucketIndexToActorPoolLps[indexes_[i]] = poolPreActionActorLps; + bucketIndexToPositionManPoolLps[indexes_[i]] = poolPreActionPosManLps; + + // assert that the underlying LP balance in PositionManager is greater than 0 + (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); + require(posPreActionLps > 0, "tokenID does not have lps associated on redemption"); + } + + try _positionManager.redeemPositions(address(_pool), tokenId_, indexes_) { + // remove tracked positions + for ( uint256 i = 0; i < indexes_.length; i++) { + bucketIndexesWithPosition.remove(indexes_[i]); + tokenIdsByBucketIndex[indexes_[i]].remove(tokenId_); + } + + // info for tear down + delete actorByTokenId[tokenId_]; + delete bucketIndexesByTokenId[tokenId_]; + tokenIdsByActor[address(_actor)].remove(tokenId_); + + // Post action Checks // + // assert that the minter is still the owner + require(_positionManager.ownerOf(tokenId_) == preActionOwner, + 'PM8: previous owner is no longer owner on redemption'); + + // assert that poolKey is still same + address poolAddress = _positionManager.poolKey(tokenId_); + require(poolAddress == address(_pool), 'PM8: poolKey has changed on redemption'); + + // 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'); + + for(uint256 i=0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + + uint256 actorPoolLps = bucketIndexToActorPoolLps[bucketIndex]; + uint256 positionManPoolLps = bucketIndexToPositionManPoolLps[bucketIndex]; + + (uint256 poolActorLps,) = _pool.lenderInfo(bucketIndex, preActionOwner); + (uint256 poolPosLps,) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + + // assert PositionsMan LP in pool matches the amount redeemed by actor + // positionMan has now == positionMan pre - actor's LP change + require(poolPosLps == positionManPoolLps - (poolActorLps - actorPoolLps), + "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 == actorPoolLps + (positionManPoolLps - 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"); + + // delete mappings for reuse + delete bucketIndexToActorPoolLps[bucketIndex]; + delete bucketIndexToPositionManPoolLps[bucketIndex]; + } + + } catch (bytes memory err) { + _ensurePoolError(err); + } + + } + + function _getQuoteAtIndex( + uint256 lp, + uint256 index + ) internal view returns (uint256 quoteAtIndex_) { + // retrieve info of bucket from pool + ( + uint256 bucketLP, + uint256 bucketCollateral, + , + uint256 bucketDeposit, + ) = _pool.bucketInfo(index); + + // calculate the max amount of quote tokens that can be moved, given the tracked LP + quoteAtIndex_ = _lpToQuoteToken( + bucketLP, + bucketCollateral, + bucketDeposit, + lp, + bucketDeposit, + _priceAt(index) + ); + } + + function _moveLiquidity( + uint256 tokenId_, + uint256 fromIndex_, + uint256 toIndex_ + ) internal { + numberOfCalls['UBPositionHandler.moveLiquidity']++; + + // update interest so pre and post token amounts are equal + _pool.updateInterest(); + + // fromIndex values + (uint256 preActionFromLps,) = _positionManager.getPositionInfo(tokenId_, fromIndex_); + uint256 preActionFromIndexQuote = _getQuoteAtIndex(preActionFromLps, fromIndex_); + + // toIndex values + (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) { + + bucketIndexesByTokenId[tokenId_].add(toIndex_); + bucketIndexesByTokenId[tokenId_].remove(fromIndex_); + + // Post Action Checks // + // remove tracked positios + bucketIndexesWithPosition.remove(fromIndex_); + tokenIdsByBucketIndex[fromIndex_].remove(tokenId_); + + // track created positions + bucketIndexesWithPosition.add(toIndex_); + tokenIdsByBucketIndex[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"); + + // 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"); + + // get post action QT represented in positionManager for tokenID + uint256 postActionFromIndexQuote = _getQuoteAtIndex(fromLps, fromIndex_); + uint256 postActionToIndexQuote = _getQuoteAtIndex(toLps, toIndex_); + + // positionManager's total QT postAction is less than or equal to preAction + // can be less than or equal due to fee on movements above -> below LUP + + greaterThanWithinDiff( + preActionFromIndexQuote + preActionToIndexQuote, + postActionFromIndexQuote + postActionToIndexQuote, + 1, + "PM6: positiionManager QT balance has increased by `1` margin" + ); + + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + + + function _burn( + uint256 tokenId_ + ) internal { + numberOfCalls['UBPositionHandler.burn']++; + 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"); + + // assert that poolKey is returns zero address + address poolAddress = _positionManager.poolKey(tokenId_); + 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"); + } catch (bytes memory err) { + _ensurePoolError(err); + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol new file mode 100644 index 000000000..59788fc5f --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import '@std/console.sol'; +import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; + +import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; +import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; +import { Maths } from "src/libraries/internal/Maths.sol"; + +import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; + +import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.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 UnboundedRewardsHandler is UnboundedBasePositionHandler { + + using EnumerableSet for EnumerableSet.UintSet; + + function _stake( + uint256 tokenId_ + ) internal updateLocalStateAndPoolInterest { + numberOfCalls['UBRewardsHandler.stake']++; + + try _rewardsManager.stake(tokenId_) { + // actor should loses ownership, positionManager gains it + tokenIdsByActor[address(_rewardsManager)].add(tokenId_); + tokenIdsByActor[address(_actor)].remove(tokenId_); + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + function _unstake( + uint256 tokenId_ + ) internal updateLocalStateAndPoolInterest { + numberOfCalls['UBRewardsHandler.unstake']++; + + uint256 actorBalanceBeforeClaim = _quote.balanceOf(_actor); + + try _rewardsManager.unstake(tokenId_) { + + // check token was transferred from rewards contract to actor + require(_positionManager.ownerOf(tokenId_) == _actor, "actor should receive ownership after unstaking"); + + // actor should receive tokenId, positionManager loses ownership + tokenIdsByActor[address(_actor)].add(tokenId_); + tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); + + // add to total rewards if actor received reward + if ((_quote.balanceOf(_actor) - actorBalanceBeforeClaim) != 0) { + (,,uint256 lastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); + totalRewardPerEpoch[lastClaimedEpoch] += _quote.balanceOf(_actor) - actorBalanceBeforeClaim; + } + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + function _updateExchangeRate( + uint256[] memory indexes_ + ) internal { + numberOfCalls['UBRewardsHandler.exchangeRate']++; + + uint256 actorBalanceBeforeClaim = _quote.balanceOf(_actor); + + try _rewardsManager.updateBucketExchangeRatesAndClaim(address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), indexes_) { + + // add to total rewards if actor received reward + if ((_quote.balanceOf(_actor) - actorBalanceBeforeClaim) != 0) { + uint256 curBurnEpoch = _pool.currentBurnEpoch(); + totalRewardPerEpoch[curBurnEpoch] += _quote.balanceOf(_actor) - actorBalanceBeforeClaim; + } + + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + function _claimRewards( + uint256 tokenId_, + uint256 epoch_ + ) internal { + numberOfCalls['UBRewardsHandler.claimRewards']++; + + try _rewardsManager.claimRewards(tokenId_, epoch_, 0) { + } catch (bytes memory err) { + _ensurePoolError(err); + } + } +} diff --git a/tests/forge/invariants/base/BaseInvariants.sol b/tests/forge/invariants/base/BaseInvariants.sol index 598453581..e5c0069df 100644 --- a/tests/forge/invariants/base/BaseInvariants.sol +++ b/tests/forge/invariants/base/BaseInvariants.sol @@ -63,20 +63,4 @@ abstract contract BaseInvariants is Test { function setCurrentTimestamp(uint256 currentTimestamp_) external { currentTimestamp = currentTimestamp_; } - - /************************/ - /*** Helper Functions ***/ - /************************/ - - function getDiff(uint256 x, uint256 y) internal pure returns (uint256 diff) { - diff = x > y ? x - y : y - x; - } - - function requireWithinDiff(uint256 x, uint256 y, uint256 expectedDiff, string memory err) internal pure { - require(getDiff(x, y) <= expectedDiff, err); - } - - function greaterThanWithinDiff(uint256 x, uint256 y, uint256 expectedDiff, string memory err) internal pure { - require(x > y || getDiff(x, y) <= expectedDiff, err); - } } \ 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 3de0694f1..956d679e5 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.18; import "@std/console.sol"; +import '../../utils/DSTestPlus.sol'; import { IERC20Pool } from 'src/interfaces/pool/erc20/IERC20Pool.sol'; import { Maths } from 'src/libraries/internal/Maths.sol'; @@ -445,13 +446,15 @@ abstract contract BasicInvariants is BaseInvariants { console.log("BBasicHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addQuoteToken")); console.log("UBBasicHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addQuoteToken")); console.log("BBasicHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeQuoteToken")); + console.log("UBBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.moveQuoteToken")); + console.log("BBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.moveQuoteToken")); console.log("UBBasicHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeQuoteToken")); console.log("BBasicHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addCollateral")); console.log("UBBasicHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addCollateral")); console.log("BBasicHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeCollateral")); console.log("UBBasicHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeCollateral")); - console.log("BBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.moveQuoteToken")); - console.log("UBBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.moveQuoteToken")); + console.log("BBasicHandler.incLPAllowance ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.incLPAllowance")); + console.log("UBBasicHandler.incLPAllowance ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.incLPAllowance")); console.log("BBasicHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps")); console.log("UBBasicHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.transferLps")); console.log("--Borrower--------"); @@ -463,6 +466,40 @@ abstract contract BasicInvariants is BaseInvariants { console.log("UBBasicHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); console.log("BBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); console.log("UBBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); + console.log("--Liquidation--------"); + console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); + console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); + console.log("BLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); + console.log("UBLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); + console.log("BLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction")); + console.log("UBLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.takeAuction")); + console.log("BLiquidationHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake")); + console.log("UBLiquidationHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.bucketTake")); + console.log("BLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds")); + console.log("UBLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.withdrawBonds")); + console.log("BLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction")); + console.log("UBLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.settleAuction")); + console.log("--Reserves--------"); + console.log("BReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves")); + 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")); + console.log("UBPositionHandler.burn ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.burn")); + console.log("BPositionHandler.burn ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.burn")); + console.log("UBPositionHandler.memorialize ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.memorialize")); + console.log("BPositionHandler.memorialize ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.memorialize")); + console.log("UBPositionHandler.redeem ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.redeem")); + console.log("BPositionHandler.redeem ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.redeem")); + console.log("UBPositionHandler.moveLiquidity ", IBaseHandler(_handler).numberOfCalls("UBPositionHandler.moveLiquidity")); + console.log("BPositionHandler.moveLiquidity ", IBaseHandler(_handler).numberOfCalls("BPositionHandler.moveLiquidity")); console.log("------------------"); console.log( "Sum", @@ -473,10 +510,25 @@ abstract contract BasicInvariants is BaseInvariants { IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeCollateral") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.pledgeCollateral") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral") + + IBaseHandler(_handler).numberOfCalls("BBasicHandler.incLPAllowance") + + IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt") + - IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + - IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps") - + IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds") + + 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") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.redeem") + + IBaseHandler(_handler).numberOfCalls("BPositionHandler.moveLiquidity") ); } diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index 5b8ea61e8..9ce277173 100644 --- a/tests/forge/invariants/base/LiquidationInvariants.t.sol +++ b/tests/forge/invariants/base/LiquidationInvariants.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.18; import "@std/console.sol"; +import '../../utils/DSTestPlus.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; import { BasicInvariants } from './BasicInvariants.t.sol'; @@ -209,5 +210,4 @@ abstract contract LiquidationInvariants is BasicInvariants { console.log("bucket take: ", IBaseHandler(_handler).numberOfActions("bucketTake")); console.log("settle ", IBaseHandler(_handler).numberOfActions("settle")); } - } \ No newline at end of file diff --git a/tests/forge/invariants/base/ReserveInvariants.t.sol b/tests/forge/invariants/base/ReserveInvariants.t.sol index 37c6a5c28..e5c349566 100644 --- a/tests/forge/invariants/base/ReserveInvariants.t.sol +++ b/tests/forge/invariants/base/ReserveInvariants.t.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.18; import "@std/console.sol"; +import '../../utils/DSTestPlus.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; @@ -35,45 +36,45 @@ abstract contract ReserveInvariants is LiquidationInvariants { function invariant_call_summary() public virtual override useCurrentTimestamp { console.log("\nCall Summary\n"); console.log("--Lender----------"); - console.log("BReserveHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addQuoteToken")); - console.log("UBReserveHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addQuoteToken")); - console.log("BReserveHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeQuoteToken")); - console.log("UBReserveHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeQuoteToken")); - console.log("BReserveHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addCollateral")); - console.log("UBReserveHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addCollateral")); - console.log("BReserveHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeCollateral")); - console.log("UBReserveHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeCollateral")); - console.log("BReserveHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.moveQuoteToken")); - console.log("UBReserveHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.moveQuoteToken")); - console.log("BReserveHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps")); - console.log("UBReserveHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.transferLps")); + console.log("BBasicHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addQuoteToken")); + console.log("UBBasicHandler.addQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addQuoteToken")); + console.log("BBasicHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeQuoteToken")); + console.log("UBBasicHandler.removeQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeQuoteToken")); + console.log("BBasicHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addCollateral")); + console.log("UBBasicHandler.addCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.addCollateral")); + console.log("BBasicHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.removeCollateral")); + console.log("UBBasicHandler.removeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.removeCollateral")); + console.log("BBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.moveQuoteToken")); + console.log("UBBasicHandler.moveQuoteToken ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.moveQuoteToken")); + console.log("BBasicHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps")); + console.log("UBBasicHandler.transferLps ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.transferLps")); console.log("--Borrower--------"); - console.log("BReserveHandler.drawDebt ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt")); - console.log("UBReserveHandler.drawDebt ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.drawDebt")); - console.log("BReserveHandler.repayDebt ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt")); - console.log("UBReserveHandler.repayDebt ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.repayDebt")); - console.log("BReserveHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pledgeCollateral")); - console.log("UBReserveHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); - console.log("BReserveHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); - console.log("UBReserveHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); + console.log("BBasicHandler.drawDebt ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt")); + console.log("UBBasicHandler.drawDebt ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.drawDebt")); + console.log("BBasicHandler.repayDebt ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt")); + console.log("UBBasicHandler.repayDebt ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.repayDebt")); + console.log("BBasicHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pledgeCollateral")); + console.log("UBBasicHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); + console.log("BBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); + console.log("UBBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); console.log("--Kicker/Taker----"); - console.log("BReserveHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); - console.log("UBReserveHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); - console.log("BReserveHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction")); - console.log("UBReserveHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.takeAuction")); - console.log("BReserveHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake")); - console.log("UBReserveHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.bucketTake")); - console.log("BReserveHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction")); - console.log("UBReserveHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.settleAuction")); - console.log("BReserveHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds")); - console.log("UBReserveHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.withdrawBonds")); - console.log("BReserveHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); - console.log("UBReserveHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); - console.log("BReserveHandler.kickReserveAuction ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.kickReserveAuction")); - console.log("UBReserveHandler.kickReserveAuction ", IBaseHandler(_handler).numberOfCalls("UBReserveHandler.kickReserveAuction")); - console.log("BReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves")); - console.log("UBReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("UBReserveHandler.takeReserves")); - console.log("------------------"); + console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); + console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); + console.log("BLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction")); + console.log("UBLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.takeAuction")); + console.log("BLiquidationHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake")); + console.log("UBLiquidationHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.bucketTake")); + console.log("BLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction")); + console.log("UBLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.settleAuction")); + console.log("BLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds")); + console.log("UBLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.withdrawBonds")); + console.log("BLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); + console.log("UBLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); + console.log("--Reserves--------"); + console.log("BReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves")); + 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( "Sum", IBaseHandler(_handler).numberOfCalls("BBasicHandler.addQuoteToken") + diff --git a/tests/forge/invariants/base/handlers/ReservePoolHandler.sol b/tests/forge/invariants/base/handlers/ReservePoolHandler.sol index a503ef74b..7535a5cf4 100644 --- a/tests/forge/invariants/base/handlers/ReservePoolHandler.sol +++ b/tests/forge/invariants/base/handlers/ReservePoolHandler.sol @@ -7,8 +7,7 @@ import { Maths } from 'src/libraries/internal/Maths.sol'; import { UnboundedReservePoolHandler } from '../../base/handlers/unbounded/UnboundedReservePoolHandler.sol'; import { LiquidationPoolHandler } from './LiquidationPoolHandler.sol'; -abstract contract ReservePoolHandler is UnboundedReservePoolHandler, LiquidationPoolHandler { - +abstract contract ReservePoolHandler is UnboundedReservePoolHandler, LiquidationPoolHandler { /*******************************/ /*** Reserves Test Functions ***/ /*******************************/ @@ -32,7 +31,7 @@ abstract contract ReservePoolHandler is UnboundedReservePoolHandler, Liquidation uint256 amountToTake_, uint256 skippedTime_ ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BReserveHandler.takeReserves']++; + numberOfCalls['BReserveHandler.takeReserves']++; // kick reserve auction if claimable reserves available (, uint256 claimableReserves, , , ) = _poolInfo.poolReservesInfo(address(_pool)); @@ -47,5 +46,4 @@ abstract contract ReservePoolHandler is UnboundedReservePoolHandler, Liquidation _takeReserves(boundedAmount); } } - } \ No newline at end of file diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 4685e1d73..22cde9594 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.18; import '@std/Test.sol'; -import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import { EnumerableSet } from '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; import { Pool } from 'src/base/Pool.sol'; @@ -216,9 +216,7 @@ abstract contract BaseHandler is Test { } catch { changePrank(_actor); } - _; - } modifier useRandomLenderBucket(uint256 bucketIndex_) { diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index f8cb48638..c0ea71164 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -59,6 +59,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { uint256 bucketIndex_ ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.kickWithDeposit']++; + (address maxBorrower, , ) = _pool.loansInfo(); (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), maxBorrower); (uint256 interestRate, ) = _pool.interestRateInfo(); diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol index fc60dcf98..114160bd8 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol @@ -36,7 +36,7 @@ abstract contract UnboundedReservePoolHandler is BaseHandler { function _takeReserves( uint256 amount_ ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBReserveHandler.takeReserves']++; + numberOfCalls['UBReserveHandler.takeReserves']++; deal(address(_ajna), _actor, type(uint256).max); IERC20(address(_ajna)).approve(address(_pool), type(uint256).max); diff --git a/tests/forge/invariants/interfaces/IBaseHandler.sol b/tests/forge/invariants/interfaces/IBaseHandler.sol index 7f2841762..9f3d4c658 100644 --- a/tests/forge/invariants/interfaces/IBaseHandler.sol +++ b/tests/forge/invariants/interfaces/IBaseHandler.sol @@ -26,7 +26,7 @@ interface IBaseHandler { function previousReserves() external view returns(uint256); function increaseInReserves() external view returns(uint256); - function decreaseInReserves() external view returns(uint256); + function decreaseInReserves() external view returns(uint256); function previousTotalBonds() external view returns(uint256); function increaseInBonds() external view returns(uint256); diff --git a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol new file mode 100644 index 000000000..44980f0ed --- /dev/null +++ b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +interface IPositionsAndRewardsHandler { + + function totalRewardPerEpoch(uint256) external view returns(uint256); + + function getBucketIndexesWithPosition() external view returns(uint256[] memory); + function getTokenIdsByBucketIndex(uint256) external view returns(uint256[] memory); + function getBucketIndexesByTokenId(uint256) external view returns(uint256[] memory); + function getTokenIdsByActor() external view returns(uint256[] memory); +} \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol new file mode 100644 index 000000000..8ed989272 --- /dev/null +++ b/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { PositionsInvariants } from "../../invariants/PositionsAndRewards/PositionsInvariants.t.sol"; + +contract RegressionPositionManager is PositionsInvariants { + + function setUp() public override { + super.setUp(); + } + + // Test was failing because handler was using unbounded bucketIndex + // Fixed by bounding bucketIndex + function test_regression_position_evm_revert_1() external { + _positionHandler.memorializePositions(265065747026302585864021010218, 462486804883131506688620136159543, 43470270713791727776, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + } + + // Test was failing because handler was using unbounded bucketIndex + // Fixed by bounding bucketIndex + function test_regression_position_evm_revert_2() external { + _positionHandler.burn(3492, 4670, 248, 9615); + } + + // Test was failing due to incorrect check in moveLiquidity handler + // Fixed by updating Lps and depositTime checks in moveLiquidity + function test_regression_position_moveLiquidity_assertions() external { + _positionHandler.redeemPositions(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 383, 55401367687647196204681805934009816110); + _positionHandler.memorializePositions(63114273171442586497890388, 154152435409657628166549200091090874517100159073873, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _positionHandler.memorializePositions(5108, 999999999999999999, 18382, 12291); + _positionHandler.burn(138176025109205882910260935173830393, 486526542428702931007164500131103382164, 909564196488498523878255414236, 25516699); + _positionHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3, 2); + } + + // example has a divergence of the positionManager's depositTime from the actor tokenId's depositTime stored in positionManager + function test_regression_position_deposittime_assertions() external { + _positionHandler.burn(2361, 11336, 3859341707, 3646975496); + _positionHandler.mint(68692219213121667537675943993034658256534085966823702, 312562089476538195); + _positionHandler.redeemPositions(14346285029390138384631699352851716037838873523252820863546, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 156099301165664793782770725300034911992745565612292730719535759193816917); + _positionHandler.failed(); + _positionHandler.moveLiquidity(3124, 4851, 22482, 489, 12560); + _positionHandler.failed(); + _positionHandler.failed(); + _positionHandler.redeemPositions(12847, 1716, 21792638192227207103739660380579104546232133259664619746653999669489792464176, 6416); + _positionHandler.failed(); + _positionHandler.mint(1, 1); + _positionHandler.burn(429855229349693967633032639264591, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 16061636408720604028163146864844242179959313271462038759); + _positionHandler.memorializePositions(1000000000000000000000000000, 2339, 9277, 2979); + _positionHandler.failed(); + _positionHandler.moveLiquidity(1126936726725513634974948946146229558794440522269778954941252072750, 28213197928202789385986111147974297715344406983, 0, 1078163238702153671724735140934660154334823619509725521693, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _positionHandler.memorializePositions(218844288525098671251665, 1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _positionHandler.burn(7059, 6750, 15855, 2093); + _positionHandler.redeemPositions(18729, 617, 21015, 14643); + _positionHandler.moveLiquidity(558, 0, 11493693556659833093547598989650493235947229407, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 21934937701560087003712); + _positionHandler.mint(1135715274316739321105, 23206); + _positionHandler.redeemPositions(15334, 3730, 31354931781638678607228669297131712859107492772550336241160036866987736981860, 2012); + + invariant_positions_PM1_PM2_PM3(); + } + + + // assertion check on depositTime -> positionManager takes on larger of the two depositTime's (it's current DT and the incoming pos DT) + function test_regression_position_assertions() external { + + _positionHandler.redeemPositions(14305804179334726329087114711985529806684597589133, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _positionHandler.redeemPositions(15796477295184955704374920720797, 8371624407570958028199016842329852681, 415665569658864472013466984364553963913525434423794529513837676955108, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _positionHandler.burn(1, 0, 21220, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _positionHandler.redeemPositions(23121, 7032, 1209600, 56750200883517406918163409362901600125139979314138135292026435586444244246336); + _positionHandler.mint(17499, 10155); + _positionHandler.moveLiquidity(4204702690764076468, 49830487004238111081, 3, 8687554674969877, 34664948256017662264545053667706057584168120838401342); + _positionHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25655664119351, 378440596); + _positionHandler.burn(9170, 9504, 11036, 7293); + _positionHandler.memorializePositions(51818345872077820903041, 8835932826797125445564909432711163860901660866650218491158279446532175, 0, 43692); + _positionHandler.moveLiquidity(3233, 18341, 1300, 20191, 9673); + + invariant_positions_PM1_PM2_PM3(); + } + + + function test_regression_position_PM2_1() external { + _positionHandler.mint(13840, 6533); + _positionHandler.redeemPositions(20893347623242005284621573233176425472191492931621662294445581855285746938414, 4668, 249, 3313); + _positionHandler.burn(106160155011218672810293641622355669764959155203, 5522, 6204, 13310117884160603562225350139269278401977957428370674638691902160380855891484); + _positionHandler.mint(9971, 18762); + _positionHandler.moveLiquidity(4746, 45809833274545460487123239222682366952882889382523246407515296007456152700521, 14885, 14435506720187687976692190077864919062649980910355626804100643005278456306280, 569); + _positionHandler.burn(5618, 3294, 1912023601, 2562); + _positionHandler.redeemPositions(19238, 9370, 18471734244850835106, 3079); + _positionHandler.memorializePositions(840358, 614555546558083013200530954309972982184, 3, 3); + _positionHandler.mint(1336497562, 1); + _positionHandler.moveLiquidity(2, 17729644, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1780470449382083675, 4500661183205373); + + invariant_positions_PM1_PM2_PM3(); + } + + function test_regression_PM2_2() external { + _positionHandler.redeemPositions(3025, 6080, 5086, 69064799185578049928162507577850320714069641703745944312650055827195794732674); + _positionHandler.memorializePositions(83432655750528826189938123470649849289913398, 47342, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1914359238258985260305115291516); + _positionHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _positionHandler.redeemPositions(0, 251587735425228951994560583717, 0, 814796085823627054357); + _positionHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639934, 94458646023247094980210508097430099597791255713941721593); + _positionHandler.burn(2, 128812301633031168244819496636531096630, 54560285418771898578153, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _positionHandler.moveLiquidity(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1, 16482458); + _positionHandler.burn(2694, 1221913943207264759036595977299, 19113, 24481779477797754811799548851326479703104086113172195246494668587412015886643); + _positionHandler.burn(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _positionHandler.redeemPositions(0, 7413805626748343619920391043, 150386923782054503303407770601037610373899200732399952156206643020965362, 120900543111660751); + _positionHandler.redeemPositions(30227346354289516712800253757043461339716641700294196, 674502096198391694316949722119995662541, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1132758169212807134889911836402520); + _positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _positionHandler.burn(313828860859517646886425614636, 208145610429269588268786717871941251049199228446877892696424877907568733235, 455942413, 2); + _positionHandler.burn(19986504, 2423591226355826423555756030845668, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _positionHandler.burn(1, 465288888898469935211527628026186267178198412320, 3, 482209135685696192055); + _positionHandler.mint(119225955014423, 600936253367888098311270698540073182733605077834901); + _positionHandler.burn(1837, 3758, 4879, 13114); + _positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 725406937207957973195478707487444742436477165056); + _positionHandler.moveLiquidity(4658405713153015933137719, 838417, 59, 25831175927826091855814245548488793681463667893532830343974308118799, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _positionHandler.memorializePositions(12016, 6319, 6900, 8690); + + invariant_positions_PM1_PM2_PM3(); + } + + function test_regression_position_manager() external { + _positionHandler.redeemPositions(79335468733065507138817566659594782917024872257218805, 1889027018179489664211573893, 43578107449528230070726540147644518395094194018887636259089111851, 0); + + } +} diff --git a/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol new file mode 100644 index 000000000..7f3f0a241 --- /dev/null +++ b/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol @@ -0,0 +1,289 @@ + +pragma solidity 0.8.18; + +import { RewardsInvariants } from "../../invariants/PositionsAndRewards/RewardsInvariants.t.sol"; +import { PoolInfoUtils } from 'src/PoolInfoUtils.sol'; + +import '@std/console.sol'; + +contract RegressionRewardsManager is RewardsInvariants { + + 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 { + _rewardsHandler.unstake(156983341, 3, 1057, 627477641256361); + _rewardsHandler.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 { + _rewardsHandler.addCollateral(378299828523348996450409252968204856717337200844620995950755116109442848, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 52986329559447389847739820276326448003115507778858588690614563138365, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.memorializePositions(2386297678015684371711534521507, 1, 2015255596877246640, 0); + _rewardsHandler.moveLiquidity(999999999999999999999999999999999999999542348, 2634, 6160, 4579, 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 { + _rewardsHandler.memorializePositions(1072697513541617411598352761547948569235246260453338, 49598781763341098132796575116941537, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 59786055813720421827623480119157950185156928336); + _rewardsHandler.drawDebt(71602122977707056985766204553433920464603022469065, 0, 3); + _rewardsHandler.settleAuction(1533, 6028992255037431023, 999999999999998827363045226813101730497689206, 3712); + _rewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14721144691130718757631011689447950991492275176685060291564256, false, 136782600565674582447300799997512602488616407787063657498, 12104321153503350510632448265168933687786653851546540372949180052575211); + _rewardsHandler.unstake(5219408520630054730985988951364206956803005171136246340104521696738150, 2, 0, 7051491938468651247212916289972038814809873); + _rewardsHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 120615857050623137463512130550262626813346106); + invariant_positions_PM1_PM2_PM3(); + } + + function test_regression_rewards_PM1_4() public { + _rewardsHandler.moveLiquidity(832921267658491751933537549, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 62241022956197145532, 1165012150, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 108613063553696015935192567274231711586207468226993603118670370534031542, 2, 1); + _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); + _rewardsHandler.settleAuction(1694548149298356876485941302354, 9052, 1444291546717740702970, 1303240033616582679504132393648); + _rewardsHandler.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 { + _rewardsHandler.kickAuction(4927, 15287, 1672621391, 7794); + _rewardsHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); + _rewardsHandler.takeAuction(2575, 5650, 2711, 12004413); + _rewardsHandler.mint(1515215594322469882937526919173, 2864); + _rewardsHandler.removeQuoteToken(11445, 2303142144561970723486793685729, 3879, 1008905021187010892); + _rewardsHandler.redeemPositions(23630504830242022841459200705989645184404322170375013590678501625107, 1, 282473030835977356124316597209309127812, 0); + _rewardsHandler.redeemPositions(4829, 7399, 20165, 19797); + _rewardsHandler.addQuoteToken(8330901901683684346410, 1944730599598704240629, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.mint(52483, 375); + _rewardsHandler.removeQuoteToken(242161003333451991910682, 833804465517702, 0, 153306087017); + _rewardsHandler.claimRewards(5460042422485935527540305190804180316252530934172557782973004, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2317020199583405169185090105199, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + } + + // 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 { + _rewardsHandler.redeemPositions(535, 10526, 16402, 90638196); + _rewardsHandler.moveQuoteToken(3, 3, 3665933105380066469, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 35609320936341689682324970775); + _rewardsHandler.kickWithDeposit(65195123838887638071598468995195715179071041842210505440218069543269527898574, 1428, 1550); + _rewardsHandler.updateExchangeRate(3324, 3433, 385); + _rewardsHandler.removeQuoteToken(487993211956248337274085963929265840000354071708865988088685578811819, 8714694397591072960002001972219030782403253520, 0, 0); + _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 3, 0); + _rewardsHandler.addQuoteToken(8049702985159192133654841011926250176578891096284667148191654768576101, 420390974052856985135062265979816823871512, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6168047604119363323178237637165700555180739052007127817776433423995137133826); + _rewardsHandler.pledgeCollateral(38623724134600076305519407, 1, 42313782903); + _rewardsHandler.takeAuction(2520288506, 56779, 10626, 2578); + _rewardsHandler.updateExchangeRate(2374, 3180, 11271); + _rewardsHandler.moveQuoteToken(3, 84452381279, 65209096465360247728023547148755401892588275436, 1, 97710781974409185143365462469280072552935020234615584635942788); + _rewardsHandler.claimRewards(4219, 7299, 3792253, 3829); + } + + // 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 { + _rewardsHandler.takeAuction(7657762660104020786102326341030666744203129169035726688092178, 1, 3, 63603943629412590405183648739466756021204); + _rewardsHandler.moveLiquidity(853498184631967766239539459019, 860800972267934599, 2712933514310088838415608172991, 672432889047616138980078995830, 1940131010529342263123392466824); + _rewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 427572220473655037333866875012561018809807470070214697627941860984, 44890261877119855592686274106685080718432502924958626579185298373762938186596); + // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) + // epoch: 1 + // burned 27895 + _rewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _rewardsHandler.pledgeCollateral(1, 0, 2); + _rewardsHandler.pledgeCollateral(46380480507328, 10, 1); + // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) + // epoch: 2 + // burned 27895 + _rewardsHandler.claimRewards(1852732090424016924140170274064383911484, 183940675308906, 0, 53861119148520095956903865568282398357460507464813555898544376318790433189); + _rewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 395769107397432386894162390920154234120, 10606604808645482457593038172768629927057694502686); + _rewardsHandler.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 + _rewardsHandler.unstake(10754921060610721338628656060623251463708357833056948746687720475, 2630, 3678, 47729066275298389217682475444047844926190); + } + + // 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 { + _rewardsHandler.repayDebt(85714, 1049291847999068770, 999999999999999999999999628872336833145697942); + _rewardsHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 36806208, 15184194898560474755071902858637273513435561597233554208311133688, 467793045980282819019245873531034252276885664851); + _rewardsHandler.takeReserves(430754706367378, 137895823818768170443343531843552347803975, 136256767494531323); + _rewardsHandler.removeQuoteToken(151907177410358060568159872791300321117419489937830, 7129107044982420534725125240530941606156790404561718416111313794090, 9379839670333585391370, 64411724624691339174378); + _rewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4761347487120837320733494601307653768982862843053132338897249261174, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.moveLiquidity(1387083372699602, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 19432349521828210006920603112382926535859550351439231094, 1); + _rewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 28562572353266841739143693967402627296578365988173585532380692, 0); + _rewardsHandler.removeCollateral(880053353375737921406212405707, 1753558590, 6280826978696699921318109415672827430264350217031853972826832132306719032380, 787979188955935138704416864067); + _rewardsHandler.moveLiquidity(11088, 1034959661872260168, 999999999999999212021821301557602448736097220, 25426918372734382433143072945767633116982163690088039971661147586959577591865, 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 { + _rewardsHandler.unstake(4735, 7947, 99648028073174186569406251043082614463523861559444314198794141049070931765266, 165); + _rewardsHandler.memorializePositions(1017586779835017595, 2000093450358386131913319801132, 999999999999999994705800289221, 5936); + _rewardsHandler.kickWithDeposit(0, 552702177486359210209998874773373639789414577510403177176780671, 1); + _rewardsHandler.kickWithDeposit(5408465446957, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1244705446892222810789723108370662428040158); + _rewardsHandler.pledgeCollateral(17006067685850655253277243263894458277559455, 365821919836536381007791134, 3); + _rewardsHandler.transferLps(1020398235799939978, 8615, 10094997325303278, 6365, 16905); + _rewardsHandler.moveQuoteToken(31568984050285372419235475362633334556373463, 2459831956710974374263868230506844670431779539018807045, 5569725293573705060280053370462598629680698918, 3, 0); + _rewardsHandler.drawDebt(2189769129255122063229251712703191878940949, 1, 30); + _rewardsHandler.redeemPositions(4988, 1000000019294578543, 113393, 20000); + _rewardsHandler.moveLiquidity(11546346822809939448153205354420218227887882771387, 17456495056515572411115147660, 182412808598764326152439106919570567805594493064808060386470, 55874229446601275, 34611500787879233737900); + } + + function test_regression_PM1_PM2_PM3_failure() external { + _rewardsHandler.addQuoteToken(1000476160430240196, 31831819542854202372682438294297749483895311991281138887779537875208920731861, 1690250244645061953490579723838, 8303344632134790875350129671); + _rewardsHandler.redeemPositions(24517164785660125111092467892090015256239780879372312856314705897654233071616, 789619793367986175384776327373, 17366, 27337330393966417869011597343142520438331591211099340735032445540394415961142); + _rewardsHandler.mint(4918260799182, 7979); + _rewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _rewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 541386860615883, 3, 1427594577268427); + _rewardsHandler.repayDebt(3, 73, 14148592833); + _rewardsHandler.withdrawBonds(408448193972491682247856759691, 6725156476034981825430803209361659548467896941475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.burn(207659258550486295439876272535780992392904995291122705229127151, 747338929, 1252191612369811194685436, 1); + _rewardsHandler.settleAuction(40898023934445005959403090083409155881516500501072076223, 14829255767842040071, 22556694249976650341045163634875596221258685026085348004092232963852919995373, 0); + _rewardsHandler.kickWithDeposit(3, 1763503097380079097391449321238134748267573906097584829633224009446989852620, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.failed(); + _rewardsHandler.pledgeCollateral(992967362603883335031186827777494890596884348, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.moveLiquidity(1439924512892792038061585821476, 12312838412972807476774254, 1386973529615993967509458441, 3153442172782088538684911, 25874047955237976217666127598767369999822558723350386077928985570803529547776); + + invariant_positions_PM1_PM2_PM3(); + } + + // exchange rate is below one and a moveLiquidity() call occurs + function test_regression_exchangerate_lt_one_failure() external { + _rewardsHandler.settleAuction(1, 38076326081732675084782953958723025268483402, 32122014834284740581605218790860586945, 675323572528116699998584163938054267674059083708770338684825); + _rewardsHandler.takeAuction(3187233434979664450766064117497382244786499427506246277958134435335, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 68185348, 0); + _rewardsHandler.removeQuoteToken(9799774902, 0, 171307717744339938462212153344256080, 22090621942183459004431027189984935997454202251794379); + _rewardsHandler.settleAuction(10469641420936113, 158810559950203569266889779145, 2729976800298283367181, 629830085692443228137978633631); + _rewardsHandler.kickAuction(1999638989041095890000000, 2621683063801908884388370586075, 5202919328337784754771241, 1704327030); + _rewardsHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 16473, 1298950632239640199, 92988305527741837015515230); + _rewardsHandler.addQuoteToken(4513829468825775442619016612, 119081395592772229137, 2956368200448621153724264764841, 43337887745458188956665754735863930); + _rewardsHandler.redeemPositions(1280000, 107418549682317941, 373995538053150407541675996799144040378996115919481128822550428, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.moveLiquidity(67209037983603756736, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 107047380550, 251040383784310909950712987871787320169957089, 136465421231555); + _rewardsHandler.burn(0, 215634488088281622713592282980500574552450094015166108001671516324248273978, 2872470631302225600444008164197436445, 3825369962689014919985865); + _rewardsHandler.redeemPositions(9321565985916881685418690197371166789551668163901391336422536021610052010235, 1000001049598692774037881, 1000916926448247166, 1294903748407840); + _rewardsHandler.memorializePositions(11357398784982391024848846139138331345877617925164801651509999164448020739, 129054800695, 2, 0); + _rewardsHandler.unstake(1008040767152967082, 2705590298374864519261, 2711436202524373179865882211354132, 1058992097359326876866506180); + _rewardsHandler.drawDebt(0, 2, 2); + _rewardsHandler.settleAuction(3, 109119248607504264825921197422518323470603, 2736316384792465597, 12368015967168137); + _rewardsHandler.kickWithDeposit(1, 34593728349238363, 2); + _rewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _rewardsHandler.takeReserves(37288205583577963230409441522973702491285105267336919446, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _rewardsHandler.redeemPositions(46789, 6151865526048672236676594, 9043006728606892937350259542, 93268112651994959075836677); + _rewardsHandler.moveLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3563135139286698066907701283845339, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1711, 0); + } + + // exchange rate was less than one in fromBucket during `moveLiquidity()` call + function test_regression_exchangerate_lt_one_unstake_failure() external { + _rewardsHandler.addQuoteToken(6142020986804765534920167884740010286243484147097745265674427, 112422117, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.removeCollateral(10151503789076003424768351930, 50838311790159949733482050440261, 787978286748398677564101888697, 743157368739340183819239223268107466431333883452773104647798952518671555); + _rewardsHandler.updateExchangeRate(21755610456008175749216891385815221667397636280908693792396899755901148039675, 76822710358333592680973548681291198, 183811652651622670286097901303322315169696013956957316331731965); + _rewardsHandler.moveQuoteToken(3843466665413066001504591, 1000009389351870783, 1000172353696212579, 2796008107630611079450058960364, 10168864164675898312163); + _rewardsHandler.moveLiquidity(673087759601966739507343763016554, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2339943610295551416526796192911912414311026002620, 1767503704449485978933058571939541599529908587415055225570810956, 9446221296393433187709657992720367407411357294298157052447175); + _rewardsHandler.stake(999999999999999505134320049118757567405586786, 1025431341927257246, 1090, 13569953566136947230136843); + _rewardsHandler.moveQuoteToken(1051099440087016359, 1357438875313834074678021636760282066916630639717893146590321, 63313628, 84622650405653151060672, 28876); + _rewardsHandler.bucketTake(7462, 1121098501725271973, false, 999999999999999999999989741489665556227804536, 442072679406687075418827994186); + _rewardsHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 515992583720, 11542363425921008807915173674517106); + } + + // auction was clearable when `moveLiquidity()` was called, which fired a revert + function test_regression_auction_clearable_remove_collateral() external { + _rewardsHandler.takeReserves(1033259874529284986, 115792089237316195423570985008687907853269984665640564039457584007913129537237, 999999999999999999999999999611297087410149302); + _rewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _rewardsHandler.settleAuction(1019166912441147606, 1174, 24356906371720, 1427315247291615855384771361467057592874190974); + _rewardsHandler.drawDebt(31570870468988913, 2490457201062127395317721901417, 14518); + _rewardsHandler.removeQuoteToken(234409660495649, 601338041799139892223226281710979, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 51209466403350773952498018); + _rewardsHandler.removeCollateral(1615097416247525221325833769791620, 999999999999998491682012949797990382689794890, 72294939771647531696639626124859859519954417706042013154, 1123754474529168009989296); + _rewardsHandler.addQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1418766863689180288802735178388574160614681714182842545424322601317331241, 0); + _rewardsHandler.burn(10779801302631984284074768919, 1022785462636254549, 4247197939956962367856295710228836, 714087046845131802724051059732250799440226582946566742486292756992468224); + _rewardsHandler.settleAuction(44188076061165790147414944966563643572374763434799334, 1, 6140, 982305872882119302926935288339691246129501298); + _rewardsHandler.failed(); + _rewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0, 1373087264969562284412462993767160637254468276739905307938530638280854638702); + _rewardsHandler.pledgeCollateral(10321692057145851776062997, 45715379632908488147290369180827577791327034825339732187105428425706, 73584310749102695099025849803685991935361634); + _rewardsHandler.moveQuoteToken(267424702347976937182244333, 53012, 1000122761636267185545584328894, 81844228617571507568624913, 2091433423541324315018709); + _rewardsHandler.memorializePositions(4341569243600918031477893648, 1037146955303444803059178, 541740178036862, 1079117209305474618); + _rewardsHandler.moveLiquidity(7990221475142856060836580, 5177379241789726416494109766258664604084660827937056770440668685154449638506, 270858793106233, 255697520996289263807310886, 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 { + _rewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639933, 486888075223510502299880936499251496488108390102993365331518154575959314103, 1489390063300625330233647743808860618285793249553177794776030333650229253556, 29413051449830420745080834496160737679746193111333313068326); + _rewardsHandler.takeAuction(2000097453768943289819883643139, 1616, 9008, 2957522668165515327594480); + _rewardsHandler.kickAuction(1023868299540571449491438, 2726, 3501, 1009546288143049196); + _rewardsHandler.claimRewards(1850558667714835415003, 1128770330214, 48160424827244602174656651208212101506580, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.memorializePositions(2706256741681, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1224263559891519537412449982749693535319617589850332219938434821323); + _rewardsHandler.kickAuction(2470057927126901389325412029621991572541444590040210706345694, 33212171733138561367109746153438995283000410403806989, 1143982811769352536641977506, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.addQuoteToken(11577, 2847, 701077953563936355129549681402475369359939627904709959917807724349081600, 6164); + _rewardsHandler.mint(7455, 2274); + _rewardsHandler.transferLps(3, 461323124985628625982, 3, 2265109234892451242814665907719473205880324711447657612395270, 36536442103629333036112242276175423646850388752964235954199714605113762301); + _rewardsHandler.addCollateral(4807, 1257702269788440403102767606588, 10232361733685599944417, 8154); + _rewardsHandler.moveLiquidity(1147643, 1101373970, 1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _rewardsHandler.redeemPositions(715216745373273013565709474193709288265853036742499324291033262974521344, 925844451104042264560, 21216664920724276219251928893592593152072674630296951273414530379050570789349, 64994818096056336519112112386345118349558865048523329927782158963716200486113); + _rewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _rewardsHandler.drawDebt(7803620494871325091384326, 1000000000005890305, 808187899175442127626759093647); + _rewardsHandler.stake(1881897373701350, 1, 384457493842895898324057, 2); + _rewardsHandler.kickAuction(1801888015, 36313972, 14589, 68230236911552087964619588008895983939113692817643498711581573912769382961420); + _rewardsHandler.kickWithDeposit(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 { + _rewardsHandler.settleAuction(2, 3, 132571599922733151315276632984852300695962190184833433609822587845, 7127747531336); + _rewardsHandler.failed(); + _rewardsHandler.pledgeCollateral(66498430692251244700, 1672526787, 999118417682487042682458556356); + _rewardsHandler.settleAuction(102521875, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _rewardsHandler.redeemPositions(0, 11874544000691612616189791308069964024776658688403726762, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.moveLiquidity(6932062779809046417357379434, 37304063095178465963, 289377204519251903, 24040659239847326449, 688903335135867866827970099664435153097141537805976741866417852208381952); + _rewardsHandler.settleAuction(86639131860678742534809729831583343741269560864832321, 261140637, 18623697431831025536282119954975103467560305081672865, 18753717689854910664818243334489713190658697158135381); + _rewardsHandler.moveLiquidity(688023305723199887936675774367107725948935104557465010923465143476322304, 426, 1361140653919103091484439143, 2492532610214694144077601771204, 1690059365); + _rewardsHandler.removeCollateral(3, 75640118, 25456, 2); + _rewardsHandler.stake(1201518266017002700145955555, 422051400149996, 191695523226259206952824982, 2575958376257460112331288247217); + _rewardsHandler.removeCollateral(1724406295, 1153800818710038190908366, 198135760955974969122979112, 4072468695723038050466180656348448601624931627598867728374067772641581); + _rewardsHandler.moveQuoteToken(1, 2, 7848862956757903893727, 108398233646184752124495509729309782170036195843104530456166511127401848014, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.kickAuction(1033780344472464085003, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 4939129467716821333159227066); + _rewardsHandler.memorializePositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5339231111427732, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 49134859377105172171787763664088172754470175); + _rewardsHandler.takeReserves(1000017062814174578, 695225158368402414621475732431414969707809712405441717937557041383099862, 1000099679120030632); + _rewardsHandler.updateExchangeRate(1798084723794266922073360424201, 1000261123000933782, 1010104555201180320207069905273); + _rewardsHandler.kickReserveAuction(14193, 4151); + _rewardsHandler.claimRewards(84674527179871518692009907151225958831784072125472174554, 1123074827467033894904599425374, 0, 2); + } + + // 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 { + _rewardsHandler.redeemPositions(1513, 5414, 496, 2041); + _rewardsHandler.moveLiquidity(1634580778705039759, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3513140137853878345040965, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6059353902491193986166404361793496); + _rewardsHandler.takeAuction(20887, 7435, 2230322682, 5173); + _rewardsHandler.removeQuoteToken(1, 37847095259185386235427787, 7586404791082, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.kickReserveAuction(746270214, 3227); + _rewardsHandler.claimRewards(3, 17838572802108205165768007139310483904447158906777650273909618150730155082, 179308467167974215120170861599730499666095743876089926251458944458077, 3); + _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 410137998186978556584901507876419312185968499332529, 0); + _rewardsHandler.repayDebt(17165, 29, 4926); + _rewardsHandler.redeemPositions(10181896186129835628862076, 4191, 2070, 4316); + _rewardsHandler.unstake(2, 721416428842444814, 1, 1); + _rewardsHandler.bucketTake(1701628611252955073601757907075824586952502043588380, 9931050451872161232934786702827793159570303822, true, 2925965874111818002623246439633594772, 3); + _rewardsHandler.bucketTake(2, 15470539950385543111949808932971047871463497008525518386, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _rewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2652132885321220255, 2, 1557926034); + } + + function test_regression_PM6_failure() external { + _rewardsHandler.bucketTake(29456557203126366201854827466482433206831494327361303, 19307664601998129837361, false, 3492651658979151995106448, 0); + _rewardsHandler.kickWithDeposit(4429580015302257459201655018526, 2770867242698718418626, 9388); + _rewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); + _rewardsHandler.moveLiquidity(41132919728951221583605488, 1102564553356549573347, 3410238307441803358653636, 52534, 4545656474572434187813557497); + } +} diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index 564f5de82..d97415854 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -1488,5 +1488,18 @@ abstract contract DSTestPlus is Test, IPoolEvents { // calculate the fee rate based upon the interest rate feeRate_ = _borrowFeeRate(newInterestRate) + Maths.WAD; } - } + + function getDiff(uint256 x, uint256 y) pure returns (uint256 diff) { + diff = x > y ? x - y : y - x; + } + + function requireWithinDiff(uint256 x, uint256 y, uint256 expectedDiff, string memory err) pure { + require(getDiff(x, y) <= expectedDiff, err); + } + + function greaterThanWithinDiff(uint256 x, uint256 y, uint256 expectedDiff, string memory err) pure { + require(x > y || getDiff(x, y) <= expectedDiff, err); + } + + From a452b83826a05db862d1e392873e41315a2b5cd9 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 8 Jun 2023 17:48:55 +0300 Subject: [PATCH 02/32] Revert position NFT transfer lock (#875) * Revert position NFT lock * Changes after review: put back unit tests, add Caveats section in README --- README.md | 9 +++- src/PositionManager.sol | 43 +---------------- .../position/IPositionManagerErrors.sol | 5 -- .../position/IPositionManagerState.sol | 2 - tests/forge/unit/PositionManager.t.sol | 3 +- .../unit/Positions/CodearenaReports.t.sol | 46 +++---------------- 6 files changed, 16 insertions(+), 92 deletions(-) diff --git a/README.md b/README.md index ac2269b8c..5d086c12d 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,19 @@ The Ajna protocol is a non-custodial, peer-to-peer, permissionless lending, borr - Fungible tokens (following the [ERC20 token standard](https://eips.ethereum.org/EIPS/eip-20)). - Non-fungible tokens (following the [ERC721 token standard](https://eips.ethereum.org/EIPS/eip-721)) +## Caveats: ### Token limitations - The following types of tokens are incompatible with Ajna, and no countermeasures exist to explicitly prevent creating a pool with such tokens, actors should use them at their own risk: - NFT and fungible tokens which charge a fee on transfer. - Fungible tokens whose balance rebases. +- The following types of tokens are incompatible with Ajna, and countermeasures exist to explicitly prevent creating a pool with such tokens: - Fungible tokens with more than 18 decimals or 0 decimals, whose `decimals()` function does not return a constant value, or which do not implement the optional [decimals()](https://eips.ethereum.org/EIPS/eip-20#decimals) function. +### Pool limitations - Borrowers cannot draw debt from a pool in the same block as when the pool was created. -- With the exception of quantized prices, pool inputs and most accumulators are not explicitly limited. The pool will stop functioning when the bounds of a `uint256` need to be exceeded to process a request. - +- With the exception of quantized prices, pool inputs and most accumulators are not explicitly limited. The pool will stop functioning when the bounds of a `uint256` need to be exceeded to process a request. +### Position NFT limitations +- Position NFTs are vulnerable to front running attacks when buying from open markets. Seller of such NFT could redeem positions before transfer, and then transfer an NFT without any value to the buyer. +Ajna positions NFTs should not be purchased from open markets. ## Development diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 4379a60dc..9a63f10c4 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -41,13 +41,6 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc using EnumerableSet for EnumerableSet.UintSet; using SafeERC20 for ERC20; - /*****************/ - /*** Constants ***/ - /*****************/ - - /// @dev Period of time the token transfer is locked after redeeming from. - uint256 internal constant TRANSFER_LOCK_PERIOD = 1 hours; - /***********************/ /*** State Variables ***/ /***********************/ @@ -115,17 +108,6 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc _; } - /** - * @dev Modifier used to record time when a position is adjusted through positions NFT. - * @dev Position adjustment can be done by redeeming or moving liquidity. - * @param tokenId_ Id of positions `NFT`. - */ - modifier recordAdjustmentTime(uint256 tokenId_) { - _; - - positionTokens[tokenId_].adjustmentTime = uint96(block.timestamp); - } - /*******************/ /*** Constructor ***/ /*******************/ @@ -309,7 +291,7 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc uint256 fromIndex_, uint256 toIndex_, uint256 expiry_ - ) external override nonReentrant mayInteract(pool_, tokenId_) recordAdjustmentTime(tokenId_) { + ) external override nonReentrant mayInteract(pool_, tokenId_) { TokenInfo storage tokenInfo = positionTokens[tokenId_]; Position storage fromPosition = tokenInfo.positions[fromIndex_]; @@ -414,7 +396,7 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc address pool_, uint256 tokenId_, uint256[] calldata indexes_ - ) external override mayInteract(pool_, tokenId_) recordAdjustmentTime(tokenId_) { + ) external override mayInteract(pool_, tokenId_) { TokenInfo storage tokenInfo = positionTokens[tokenId_]; IPool pool = IPool(pool_); @@ -460,27 +442,6 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc /*** Internal Functions ***/ /**************************/ - /** - * @dev Called before the NFT position transfer, reverts if transfer attempted in less than one hour since last redeem. - * @dev === Revert on === - * @dev - positions changed in the last hour `TransferLocked()` - */ - function _beforeTokenTransfer( - address, - address to_, - uint256 tokenId_, - uint256 - ) internal override { - // burning is not constrained by any redeem action - if (to_ != address(0)) { - TokenInfo storage token = positionTokens[tokenId_]; - // revert transfer in case token positions were redeem in the last transfer lock period - if (block.timestamp - token.adjustmentTime <= TRANSFER_LOCK_PERIOD) revert TransferLocked(); - - token.adjustmentTime = 0; - } - } - /** * @notice Checks that a provided pool address was deployed by an `Ajna` factory. * @param pool_ Address of the `Ajna` pool. diff --git a/src/interfaces/position/IPositionManagerErrors.sol b/src/interfaces/position/IPositionManagerErrors.sol index c4134eba8..948c74b8c 100644 --- a/src/interfaces/position/IPositionManagerErrors.sol +++ b/src/interfaces/position/IPositionManagerErrors.sol @@ -47,11 +47,6 @@ interface IPositionManagerErrors { */ error RemovePositionFailed(); - /** - * @notice User cannot transfer a position NFT in an interval less than 1 hour since last change. - */ - error TransferLocked(); - /** * @notice User attempting to interact with a pool that doesn't match the pool associated with the `tokenId`. */ diff --git a/src/interfaces/position/IPositionManagerState.sol b/src/interfaces/position/IPositionManagerState.sol index a48399bd1..f5aaf695c 100644 --- a/src/interfaces/position/IPositionManagerState.sol +++ b/src/interfaces/position/IPositionManagerState.sol @@ -22,13 +22,11 @@ interface IPositionManagerState { /** * @dev Struct tracking a position token info. * @param pool The pool address associated with the position. - * @param adjustmentTime The time of last adjustment to the position. * @param positionIndexes Mapping tracking indexes to which a position is associated. * @param positions Mapping tracking a positions state in a bucket index. */ struct TokenInfo { address pool; - uint96 adjustmentTime; EnumerableSet.UintSet positionIndexes; mapping(uint256 index => Position) positions; } diff --git a/tests/forge/unit/PositionManager.t.sol b/tests/forge/unit/PositionManager.t.sol index 0e4ace6f2..7beef940f 100644 --- a/tests/forge/unit/PositionManager.t.sol +++ b/tests/forge/unit/PositionManager.t.sol @@ -3299,8 +3299,7 @@ contract PositionManagerERC721PoolTest is PositionManagerERC721PoolHelperContrac assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[1])); assertTrue(_positionManager.isIndexInPosition(tokenId, indexes[2])); - // approve and transfer NFT to testAddress2 address after 1 hour locked time - skip(61 minutes); + // approve and transfer NFT to testAddress2 address _positionManager.approve(address(this), tokenId); _positionManager.safeTransferFrom(testAddress1, testAddress2, tokenId); diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/Positions/CodearenaReports.t.sol index e297ec8ca..b88e7f042 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/Positions/CodearenaReports.t.sol @@ -812,7 +812,6 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract Alice no has the 10 eth worth of lp Bob's transaction completes and he gets a worthless NFT Alice gets Bobs 9 eth - Fixed by recording block of last redeem and revert if same as transfer block. */ function testAdjustPositionBeforeTransfer_report_196() external { @@ -855,57 +854,24 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _pool.approveLPTransferors(transferors); _positionManager.memorializePositions(address(_pool), tokenId, indexes); - /*******************************/ - /*** Move liquidity scenario ***/ - /*******************************/ - - uint256 beforeMove = vm.snapshot(); - // alice moves positions from bucket before transferring NFT to bob - _positionManager.moveLiquidity(address(_pool), tokenId, 2551, 5000, block.timestamp + 5 hours); - - // alice transfer NFT to bob in the same block as move liquidity, transfer should fail - _positionManager.approve(address(this), tokenId); - vm.expectRevert(IPositionManagerErrors.TransferLocked.selector); - _positionManager.safeTransferFrom(alice, bob, tokenId); - vm.revertTo(beforeMove); + // FIXME - positions NFT can be subject of front running if buying from open markets - /*******************************/ - /*** Redeem position scenario ***/ - /*******************************/ - - // alice redeems positions from a bucket before transferring NFT to bob _pool.approveLPTransferors(transferors); - _positionManager.redeemPositions(address(_pool),tokenId, aliceRedeemIndex); + // alice redeems positions from a bucket before transferring NFT to bob + _positionManager.redeemPositions(address(_pool), tokenId, bobRedeemIndex); - // alice transfer NFT to bob in the same block as redeem, transfer should fail _positionManager.approve(address(this), tokenId); - vm.expectRevert(IPositionManagerErrors.TransferLocked.selector); _positionManager.safeTransferFrom(alice, bob, tokenId); - // alice transfer NFT to bob after 1 hour lock period since last redeem - skip(61 minutes); - _positionManager.safeTransferFrom(alice, bob, tokenId); - - // bob owns position NFT - assertEq(_positionManager.ownerOf(tokenId), bob); - - // bob redeems positions + // bob redeem positions revert since there's no index memorialized changePrank(bob); _pool.approveLPTransferors(transferors); + vm.expectRevert(IPositionManagerErrors.RemovePositionFailed.selector); _positionManager.redeemPositions(address(_pool), tokenId, bobRedeemIndex); - // bob should be able to burn NFT in same block as redeem - _positionManager.burn(address(_pool), tokenId); - - // check balances, alice should have LP in bucket 2550, bob should have LP in bucket 2551 + // alice has LP redeemed before transfer at index 2551 _assertLenderLpBalance({ lender: alice, - index: 2550, - lpBalance: 15_000 * 1e18, - depositTime: _startTime - }); - _assertLenderLpBalance({ - lender: bob, index: 2551, lpBalance: 10_000 * 1e18, depositTime: _startTime From 7827d189e69e41a0d184db2498c187815b644e7e Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Fri, 9 Jun 2023 22:20:00 +0300 Subject: [PATCH 03/32] Check for specific Positions / rewards manager errors when calling their functions (#885) --- .../unbounded/UnboundedPositionsHandler.sol | 27 +++++++++++++++---- .../unbounded/UnboundedRewardsHandler.sol | 25 +++++++++++++---- .../RegressionRewardsManager.t.sol | 18 +++++++++++++ 3 files changed, 60 insertions(+), 10 deletions(-) diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol index b66dff4a9..f96e132b6 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol @@ -88,7 +88,7 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { } } catch (bytes memory err) { - _ensurePoolError(err); + _ensurePositionsManagerError(err); } } @@ -111,7 +111,7 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { require(posIndexes.length == 0, "PM4: positions are associated with tokenId"); } catch (bytes memory err) { - _ensurePoolError(err); + _ensurePositionsManagerError(err); } } @@ -192,7 +192,7 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { } } catch (bytes memory err) { - _ensurePoolError(err); + _ensurePositionsManagerError(err); } } @@ -283,7 +283,7 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { } catch (bytes memory err) { - _ensurePoolError(err); + _ensurePositionsManagerError(err); } } @@ -307,7 +307,24 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { uint256[] memory posIndexes = _positionManager.getPositionIndexes(tokenId_); require(posIndexes.length == 0, "PM5: positions still exist after burn"); } catch (bytes memory err) { - _ensurePoolError(err); + _ensurePositionsManagerError(err); } } + + function _ensurePositionsManagerError(bytes memory err_) internal pure { + bytes32 err = keccak256(err_); + + require( + err == keccak256(abi.encodeWithSignature("AllowanceTooLow()")) || + err == keccak256(abi.encodeWithSignature("BucketBankrupt()")) || + err == keccak256(abi.encodeWithSignature("DeployWithZeroAddress()")) || + err == keccak256(abi.encodeWithSignature("LiquidityNotRemoved()")) || + err == keccak256(abi.encodeWithSignature("NoAuth()")) || + err == keccak256(abi.encodeWithSignature("NoToken()")) || + err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) || + err == keccak256(abi.encodeWithSignature("RemovePositionFailed()")) || + err == keccak256(abi.encodeWithSignature("WrongPool()")), + "Unexpected revert error" + ); + } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol index 59788fc5f..ac2488af5 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol @@ -9,7 +9,7 @@ import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionM import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; -import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; +import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; @@ -34,7 +34,7 @@ abstract contract UnboundedRewardsHandler is UnboundedBasePositionHandler { tokenIdsByActor[address(_actor)].remove(tokenId_); } catch (bytes memory err) { - _ensurePoolError(err); + _ensureRewardsManagerError(err); } } @@ -61,7 +61,7 @@ abstract contract UnboundedRewardsHandler is UnboundedBasePositionHandler { } } catch (bytes memory err) { - _ensurePoolError(err); + _ensureRewardsManagerError(err); } } @@ -81,7 +81,7 @@ abstract contract UnboundedRewardsHandler is UnboundedBasePositionHandler { } } catch (bytes memory err) { - _ensurePoolError(err); + _ensureRewardsManagerError(err); } } @@ -93,7 +93,22 @@ abstract contract UnboundedRewardsHandler is UnboundedBasePositionHandler { try _rewardsManager.claimRewards(tokenId_, epoch_, 0) { } catch (bytes memory err) { - _ensurePoolError(err); + _ensureRewardsManagerError(err); } } + + 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" + ); + } } diff --git a/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol index 7f3f0a241..4117f7d28 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol @@ -286,4 +286,22 @@ contract RegressionRewardsManager is RewardsInvariants { _rewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); _rewardsHandler.moveLiquidity(41132919728951221583605488, 1102564553356549573347, 3410238307441803358653636, 52534, 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_unexpected_revert() external { + _rewardsHandler.redeemPositions(696309158766729979589534440166220067073887038152281856742599135926157312, 1870474563221356095022900189266, 18339, 1788135699833095102184812046279); + _rewardsHandler.kickReserveAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.memorializePositions(3671371551743995865, 99428, 1769100398, 7346319752739159); + _rewardsHandler.removeQuoteToken(2192844669750518881733689799257684129590332632218546259991943830203, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 419); + _rewardsHandler.bucketTake(1606233188525778759956925750889, 999999999999999529711266919982837439648513939, false, 9949287379244091378213227, 3763880249088816172848545904993); + _rewardsHandler.settleAuction(55047125510583885662282424543762268712076435621770843340435135, 110421716658405583291991613217254392572785222796303390816855215908218229630, 1, 292423500273437202726891613067834132052054453755096719350366291073639790); + _rewardsHandler.takeAuction(6950266099624730892351521874528127288800419, 193622918230501420262501464441837, 3, 20111879376924408726124755543747277966848148390627132304350); + _rewardsHandler.bucketTake(2, 747496798808534888002766542, true, 221618799467305555283, 661410089069342); + _rewardsHandler.settleAuction(39300471897997857700471, 363003327028528645286555715801688230394596448247050, 10248673406547114848805417911883714616830860910846335722973488061592062643, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.updateExchangeRate(3, 4485331781540521052468660062240, 3); + _rewardsHandler.burn(20137826853855347137082717445, 194771708143610511040376640, 3706358530371129512271612, 14017756049926664649805910646); + } } From 60a20e2d27eb860f3a0c87b031a7a1cc2f980065 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 15 Jun 2023 01:40:53 +0300 Subject: [PATCH 04/32] Bug fix: A1 invariant failure - revert if amount to repay is 0, consistently update `t0debInAuction` accumulator (#886) * Fix LUP invariant discrepancy * Add fix for t0debt in auction accumulator - revert if calculated amount to repay is 0 (due to roundings) - better organize t0debtInAuction accumulator update * Fix reserves discrepancies in invariant logic --- src/ERC20Pool.sol | 28 ++- src/ERC721Pool.sol | 28 ++- src/libraries/external/BorrowerActions.sol | 9 +- .../base/handlers/unbounded/BaseHandler.sol | 10 +- .../unbounded/UnboundedBasicPoolHandler.sol | 8 +- .../UnboundedLiquidationPoolHandler.sol | 4 +- .../RegressionTestBasicERC20Pool.t.sol | 17 ++ .../RegressionTestReservesERC20Pool.t.sol | 216 +++++++++++++++++- 8 files changed, 285 insertions(+), 35 deletions(-) diff --git a/src/ERC20Pool.sol b/src/ERC20Pool.sol index 344f79140..20ee2f00a 100644 --- a/src/ERC20Pool.sol +++ b/src/ERC20Pool.sol @@ -159,9 +159,14 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; - if (result.t0DebtInAuctionChange != 0) poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; poolState.collateral = result.poolCollateral; + // update t0 debt in auction in memory pool state struct and pool balances state + if (result.t0DebtInAuctionChange != 0) { + poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; + poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; + } + // adjust t0Debt2ToCollateral ratio if loan not in auction if (!result.inAuction) { _updateT0Debt2ToCollateral( @@ -176,10 +181,7 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { _updateInterestState(poolState, result.newLup); if (collateralToPledge_ != 0) { - // update pool balances state - if (result.t0DebtInAuctionChange != 0) { - poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; - } + // update pool balances pledged collateral state poolBalances.pledgedCollateral = poolState.collateral; // move collateral from sender to pool @@ -187,7 +189,7 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { } if (amountToBorrow_ != 0) { - // update pool balances state + // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; // move borrowed amount from pool to sender @@ -236,9 +238,14 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; - if (result.t0DebtInAuctionChange != 0) poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; poolState.collateral = result.poolCollateral; + // update t0 debt in auction in memory pool state struct and pool balances state + if (result.t0DebtInAuctionChange != 0) { + poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; + poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; + } + // adjust t0Debt2ToCollateral ratio if loan not in auction if (!result.inAuction) { _updateT0Debt2ToCollateral( @@ -253,17 +260,14 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { _updateInterestState(poolState, result.newLup); if (result.quoteTokenToRepay != 0) { - // update pool balances state + // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; - if (result.t0DebtInAuctionChange != 0) { - poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; - } // move amount to repay from sender to pool _transferQuoteTokenFrom(msg.sender, result.quoteTokenToRepay); } if (collateralAmountToPull_ != 0) { - // update pool balances state + // update pool balances pledged collateral state poolBalances.pledgedCollateral = poolState.collateral; // move collateral from pool to address specified as collateral receiver diff --git a/src/ERC721Pool.sol b/src/ERC721Pool.sol index ef4fc6dc0..668980fa5 100644 --- a/src/ERC721Pool.sol +++ b/src/ERC721Pool.sol @@ -171,9 +171,14 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; - if (result.t0DebtInAuctionChange != 0) poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; poolState.collateral = result.poolCollateral; + // update t0 debt in auction in memory pool state struct and pool balances state + if (result.t0DebtInAuctionChange != 0) { + poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; + poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; + } + // adjust t0Debt2ToCollateral ratio if loan not in auction if (!result.inAuction) { _updateT0Debt2ToCollateral( @@ -188,10 +193,7 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { _updateInterestState(poolState, result.newLup); if (tokenIdsToPledge_.length != 0) { - // update pool balances state - if (result.t0DebtInAuctionChange != 0) { - poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; - } + // update pool balances pledged collateral state poolBalances.pledgedCollateral = poolState.collateral; // move collateral from sender to pool @@ -202,7 +204,7 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // move borrowed amount from pool to sender if (amountToBorrow_ != 0) { - // update pool balances state + // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; // move borrowed amount from pool to sender @@ -251,9 +253,14 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // update in memory pool state struct poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; - if (result.t0DebtInAuctionChange != 0) poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; poolState.collateral = result.poolCollateral; + // update t0 debt in auction in memory pool state struct and pool balances state + if (result.t0DebtInAuctionChange != 0) { + poolState.t0DebtInAuction -= result.t0DebtInAuctionChange; + poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; + } + if (result.settledAuction) _rebalanceTokens(borrowerAddress_, result.remainingCollateral); // adjust t0Debt2ToCollateral ratio if loan not in auction @@ -269,15 +276,12 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { // update pool interest rate state _updateInterestState(poolState, result.newLup); - // update pool balances state + // update pool balances pledged collateral state poolBalances.pledgedCollateral = poolState.collateral; if (result.quoteTokenToRepay != 0) { - // update pool balances state + // update pool balances t0 debt state poolBalances.t0Debt = poolState.t0Debt; - if (result.t0DebtInAuctionChange != 0) { - poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; - } // move amount to repay from sender to pool _transferQuoteTokenFrom(msg.sender, result.quoteTokenToRepay); diff --git a/src/libraries/external/BorrowerActions.sol b/src/libraries/external/BorrowerActions.sol index da6262cd8..a48af0de0 100644 --- a/src/libraries/external/BorrowerActions.sol +++ b/src/libraries/external/BorrowerActions.sol @@ -311,9 +311,12 @@ library BorrowerActions { ); } - result_.t0PoolDebt -= vars.t0RepaidDebt; - result_.poolDebt = Maths.wmul(result_.t0PoolDebt, poolState_.inflator); - result_.quoteTokenToRepay = Maths.ceilWmul(vars.t0RepaidDebt, poolState_.inflator); + result_.quoteTokenToRepay = Maths.ceilWmul(vars.t0RepaidDebt, poolState_.inflator); + // revert if (due to roundings) calculated token amount to repay is 0 + if (result_.quoteTokenToRepay == 0) revert InvalidAmount(); + + result_.t0PoolDebt -= vars.t0RepaidDebt; + result_.poolDebt = Maths.wmul(result_.t0PoolDebt, poolState_.inflator); vars.borrowerDebt = Maths.wmul(borrower.t0Debt - vars.t0RepaidDebt, poolState_.inflator); diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 22cde9594..fe9c82be5 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -453,12 +453,18 @@ abstract contract BaseHandler is Test { bond_ = claimableBond + lockedBond; } - function _updateCurrentTakeState(address borrower_, uint256 borrowerDebt_) internal { + function _updateCurrentTakeState(address borrower_, uint256 borrowert0Debt_) internal { if (!alreadyTaken[borrower_]) { alreadyTaken[borrower_] = true; + (uint256 inflator, ) = _pool.inflatorInfo(); + // **RE7**: Reserves increase by 7% of the loan quantity upon the first take. - increaseInReserves += Maths.wmul(borrowerDebt_, 0.07 * 1e18); + increaseInReserves += Maths.wmul( + Maths.wmul(borrowert0Debt_, 0.07 * 1e18), + inflator + ); + firstTake = true; } else firstTake = false; diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol index 768ecee39..b41d813ab 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol @@ -28,9 +28,11 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { numberOfCalls['UBBasicHandler.addQuoteToken']++; (uint256 lpBalanceBeforeAction, ) = _pool.lenderInfo(bucketIndex_, _actor); - (uint256 poolDebt, , ,) = _pool.debtInfo(); - uint256 lupIndex = _pool.depositIndex(poolDebt); - (uint256 interestRate, ) = _pool.interestRateInfo(); + + (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_); diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index c0ea71164..d8b1aec33 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -208,7 +208,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.bucketTake']++; - (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + (uint256 borrowerT0Debt, , ) = _pool.borrowerInfo(borrower_); (address kicker, , , , , , , , , ) = _pool.auctionInfo(borrower_); ( , , , , uint256 auctionPrice, ) = _poolInfo.auctionStatus(address(_pool), borrower_); @@ -252,7 +252,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // assign value to fenwick tree to mitigate rounding error that could be created in a _fenwickRemove call fenwickDeposits[bucketIndex_] = afterBucketTakeVars.deposit; - _updateCurrentTakeState(borrower_, borrowerDebt); + _updateCurrentTakeState(borrower_, borrowerT0Debt); } catch (bytes memory err) { _ensurePoolError(err); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol index 1695498d9..c83d916df 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestBasicERC20Pool.t.sol @@ -506,6 +506,23 @@ contract RegressionTestBasicERC20Pool is BasicERC20PoolInvariants { invariant_fenwick(); } + /** + Test was failing because LUP index calculated in PoolInfoUtils was different than the LUP index used in the pool, due to inconsistent roundings. + This happened because in Pool.debtInfo function (used by PoolInfoUtils) the pool debt is always rounded up by using `ceilWmul` while in Pool._accruePoolInterest it was rounded to nearest (by using plain `wmul`). + Fixed by updating invariant logic to use wmul when calculating debt / lup. + */ + function test_regression_failure_LUP_mismatch() external { + _basicERC20PoolHandler.drawDebt(4, 1, 42459383782278435142046724305658135311267691438915386859799265271); + _basicERC20PoolHandler.addCollateral(2, 3572424784607357932832428669711146305449422791284409705, 1, 1752415137925225987066876882519442642128283316); + _basicERC20PoolHandler.addCollateral(30078934951760, 0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _basicERC20PoolHandler.moveQuoteToken(2, 11207742869589877097265928651764717357996863058171818762054716764203431567, 6796354451919795359973416899961151626146, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 32814191648934779166830307328480393297962496735); + _basicERC20PoolHandler.pledgeCollateral(3, 20079583599722223374347036794412006835499328132, 6223592858454677803546394015384818276973676161160300268239); + _basicERC20PoolHandler.removeQuoteToken(28027, 640566200129155933206676634319, 1000078878247711703, 688108825063300706996495631347979005290704814814505786503857665710213120); + _basicERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + + _invariant_F1(); + } + } contract RegressionTestBasicWith10BucketsERC20Pool is BasicERC20PoolInvariants { diff --git a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol index ad4a2fbf7..b466d1fce 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -841,6 +841,220 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _invariant_F1(); } + /** + Test was failing because t0 debt in auction accumulator was in an inconsistent state after repayDebt action: + - auction was settled, the quote token amount to repay was rounded down to 0 therefore t0 debt in auction accumulator not updated (updated only when token to repay was not 0) + Fixed by guarding against repayments of 0 amount and properly updating t0 debt in auction accumulator every time t0DebtInAuctionChange is different than 0. + */ + function test_regression_failure_A1_repaydebt_t0_rounding() external { + _reserveERC20PoolHandler.transferLps(883172166925196014153612741, 1011874887306145524, 1560280797611982634762545, 2999999999999999999999999999999999999999988581, 166067911958117829389897753); + _reserveERC20PoolHandler.drawDebt(109748618821205351803014988731482981932, 1, 1946224850931); + _reserveERC20PoolHandler.kickWithDeposit(23120646526972050226088733811, 114506716413332403306176469, 85883); + _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.removeQuoteToken(16015765038220222984273010530, 1020363514639207733373983, 1014737335754083714, 673321911366647590987964); + _reserveERC20PoolHandler.repayDebt(266183799725795118552059050547, 999999999999998990000017889368360594282917314, 25104380621850820); + _reserveERC20PoolHandler.settleAuction(86115324240622909644348503594191331907, 3, 13415589128718995512776336035268391001749531136, 339085840303819); + _reserveERC20PoolHandler.pullCollateral(1000001909488749440, 23120, 7111290336193937); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 233802727051342750, true, 0, 2); + _reserveERC20PoolHandler.repayDebt(263170258309, 5080744165795717982603, 55117253660090837057621764590); + _reserveERC20PoolHandler.bucketTake(993917833171661375516941909496, 745631306942772834416252, false, 1371855054152529049, 43724538864552400563951010712842); + _reserveERC20PoolHandler.pullCollateral(3, 25743313275914362980617822412296162738, 16762886985273); + _reserveERC20PoolHandler.kickReserveAuction(3078150006564196, 7396882861103323249736713); + _reserveERC20PoolHandler.removeCollateral(16468976271668126152885936984970, 1487154400729783333282192, 5478375424271713063891503967473762210131012071710882253815092609, 0); + _reserveERC20PoolHandler.pledgeCollateral(1959756081363182154945484, 695184912617939452564096706195147982029158844651640050845541975060105216, 20953); + _reserveERC20PoolHandler.removeCollateral(0, 8429530503692258767600766472296295879485010785135841986, 27382077361849487290924013, 110712338779070583237865355301234737011758479442161592032064020); + _reserveERC20PoolHandler.bucketTake(10735866914, 6938610560402955446652241, true, 2155641559294868879304378353988888425791710176590436362969520343, 652324170013566633900821571929737900067); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 656209644453247396627537146682850200028671428518089); + _reserveERC20PoolHandler.addCollateral(1188072877812797985369622751974814986783160701880309, 1, 1147849554826063753972872541, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + + _invariant_A1(); + } + + /** + Test was failing due to invariant paralel logic applying take penalty on the current borrower debt instead borrower t0 debt. + Fixed by making invariant logic inline with pool logic (applying penalty take to t0 debt). + */ + function test_regression_rw_reserves_failure() external { + _reserveERC20PoolHandler.kickWithDeposit(2745, 24455, 13722); + _reserveERC20PoolHandler.pledgeCollateral(123337267943716142615242382731926630930323989357616310, 831733227434971474, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.withdrawBonds(15840, 11617, 226); + _reserveERC20PoolHandler.bucketTake(1365, 2902, false, 18724, 939); + _reserveERC20PoolHandler.pledgeCollateral(539326432733374732884941193, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 153518275391877220937979377471); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.drawDebt(2, 1620636476530426914005760203730864495513993450783166013428737958399072815940, 340874209460801802727144333948073099617657); + _reserveERC20PoolHandler.repayDebt(688556596275, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 368094257615470101907295); + _reserveERC20PoolHandler.takeAuction(3585219579480534231848357301825602838866679189897607958322726920257536, 14457, 1954, 13154); + _reserveERC20PoolHandler.repayDebt(4617, 8718, 365); + _reserveERC20PoolHandler.drawDebt(59776, 5221, 3265); + _reserveERC20PoolHandler.drawDebt(7264, 76160, 1354); + _reserveERC20PoolHandler.pledgeCollateral(2, 76961268213505018630059906018712883113465719035691941927061520, 0); + _reserveERC20PoolHandler.takeReserves(3097519512, 94653314286117312, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.kickWithDeposit(3417, 5313, 1065); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 262723374, 3); + _reserveERC20PoolHandler.settleAuction(18592, 23024, 59620, 1130); + _reserveERC20PoolHandler.transferLps(17904054251994466560905859484014215462564, 15888216163148783188069980097884298806041869, 2, 79507040, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.settleAuction(25044, 2839, 3625, 10348); + _reserveERC20PoolHandler.takeReserves(982635115242346064607322395786817600531455973005452194083, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 889370); + _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 89167707403713776180830955605269008311134343539); + _reserveERC20PoolHandler.takeAuction(6470269723793827696552427938265598607645887801758057431297364941052293, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2866630568615781311922993476096073, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.bucketTake(68664, 7326, false, 4233, 5677); + _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _reserveERC20PoolHandler.kickWithDeposit(0, 1218898441896362378535137262535177203, 21798664731976227158610477457991755208543783402036139286216); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.bucketTake(13445613122200147477792608151727, 270565483187498024573987287835057900370441980356809225245307134, false, 172971071584471702836978258371210100661094308, 0); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3168, 69361987003667393973146886443285869929, 151854736120); + _reserveERC20PoolHandler.withdrawBonds(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(1, 315546839809342740045193554800216, 16032, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(3303, 1618, 2392); + _reserveERC20PoolHandler.removeCollateral(38396, 3984, 43724, 801); + _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 4136243925327015826551896052210933199888246316718789990226072929761635355, 17017692613008421741158348905143822); + _reserveERC20PoolHandler.pullCollateral(576878529233854490611652048799820558153187703902, 23345238424267457, 678151723892535345234384954426157441012880665738860910379295890697763880); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 8022761294074727038680587196911881844164552093948646494354); + _reserveERC20PoolHandler.kickWithDeposit(22192, 33876, 1849); + _reserveERC20PoolHandler.kickAuction(3, 54344449090570270030575794, 41331735998982754712822, 413913523436635659969293009110325); + _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 590921270504087763943624823522978007950936); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.takeAuction(2147, 4584, 3843, 5018); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.kickWithDeposit(14340, 48434856810956849965736021604069675576075951470372408084823421939858231806374, 3299); + _reserveERC20PoolHandler.moveQuoteToken(68852, 7424, 1038525076100356668671255, 492568651, 13139); + _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 505628); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.drawDebt(314, 67784, 21539); + _reserveERC20PoolHandler.takeReserves(16631, 7641, 15813304800480849075013522109620); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.kickAuction(78347310717410332489887175069473254630037478751251177540284229024971, 3, 2, 1233824434582477798584326375008130503551039483729831882824086787424); + _reserveERC20PoolHandler.kickAuction(242768334464864707264952, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 14074, 1721284543988222482907417); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 11105967986029427869076715, 3, 406604372117093127509064484362759301341600801659247); + _reserveERC20PoolHandler.addQuoteToken(1, 18774027645564423189902454159, 442346924783177633612644226567494995513426265637554153229004729, 1); + _reserveERC20PoolHandler.pullCollateral(1004522438786235492048468453, 164705218122715295049806191381208816998911604105097332, 643240014155684032904315471687858800596406618599250399743645325); + _reserveERC20PoolHandler.bucketTake(211, 70894767171094701924380241813678321351874967904284301036263, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 587524960523350577531110494565315845260665710571); + _reserveERC20PoolHandler.takeReserves(2129636942992548828843421325074058252047527111840809862524997997604655480567, 0, 2); + _reserveERC20PoolHandler.takeAuction(1995, 52592, 16411, 61000); + _reserveERC20PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 4624698904533685297229897439094843595668654826825810413531371864545943304, 165550145956386111276459080941583520428362226); + _reserveERC20PoolHandler.repayDebt(2, 35417841946221182133768342906925, 81560474795151136303307655218174579269488251191295053167523); + _reserveERC20PoolHandler.pullCollateral(262005231982037012071095053951950726890, 165897178866840433455273519, 3888558842537780612354835116962744581018); + _reserveERC20PoolHandler.removeQuoteToken(67601320205637231575518551341855435078757081656, 42506491712172925477842742026585129736172, 0, 3); + _reserveERC20PoolHandler.removeCollateral(2735948757698, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); + _reserveERC20PoolHandler.drawDebt(69604, 66364, 62708); + _reserveERC20PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickReserveAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.kickAuction(42696, 53948, 4098, 80208); + _reserveERC20PoolHandler.kickWithDeposit(11168, 4687, 46203667883211236176009300351222888745161251164121910689922122206957300538260); + _reserveERC20PoolHandler.bucketTake(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 52717956413245182495690438857638203602407222750947906512913358177748309461, 1830655722053423400022802920473021837); + _reserveERC20PoolHandler.transferLps(8648942085539954219328447003223809341519, 950885841320713403982849019036607701793496635, 1864492050351847862134365417027951703327712, 0, 12365193093817834339793997848323656585885308060548800349); + _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 441041722731880847112545726224); + _reserveERC20PoolHandler.drawDebt(2, 5637245938950027975241707143245277554697641348009134206336950495061, 0); + _reserveERC20PoolHandler.pullCollateral(77076, 1029781823869605113168706583, 728102202963728405455246); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 322, 158131966158438559143880652910421535378683600, 552124628095494158214465237746987896396049733188757299922485316684095); + _reserveERC20PoolHandler.removeCollateral(63832, 14378, 14464, 7199126569176769759713715016380); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.takeAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1676984243940844902856884113511719636660353869679548995883472046500284900, 194762926621741009790380454595699099505044650049277809140105); + _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 86702800819952145885, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.settleAuction(68836, 6293, 3646, 40652); + _reserveERC20PoolHandler.removeQuoteToken(1435, 88274, 27344, 59680); + _reserveERC20PoolHandler.addQuoteToken(9653, 36884, 43164, 34240); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, false, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.kickAuction(14030, 78156646155174841979727994598816262306175212592076161876661508869554232690281, 14958, 26760); + _reserveERC20PoolHandler.pullCollateral(31354931781638678487916134672869638484047149969764982831501014746446650500196, 20100, 1934); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.transferLps(5228, 38484, 4990035944185332538707557538917939723630454073884429990845069690000830, 69516, 21665778744210722290811484629); + _reserveERC20PoolHandler.pledgeCollateral(2, 75422987196044127630761837780987325699862235109119318162336547749, 6179987597); + _reserveERC20PoolHandler.removeCollateral(6378, 2588077117166263351284689902931333654327841381007133193817924669990258558652, 42920, 59652); + _reserveERC20PoolHandler.addQuoteToken(212393376599363843461142355438411176318797499816971, 1082626922, 2, 1902339354244380); + _reserveERC20PoolHandler.addQuoteToken(1041777794389919310, 74308, 47400, 2747); + _reserveERC20PoolHandler.kickAuction(485935523377801208785095832858151873122377611590354602078,9372151449027021227981818334816093164047701121915049579602971879, 1, 1350089742552569926514612646160420107975090607927746546952709); + _reserveERC20PoolHandler.addCollateral(42292, 7344, 1359, 54977386430942545964497351608958257571213157214788288810916378935044424854184); + _reserveERC20PoolHandler.kickReserveAuction(1000236603027803172, 21754741055016307934840204006); + _reserveERC20PoolHandler.withdrawBonds(373702251020986977207790889868085050901394374965, 4140, 53424); + _reserveERC20PoolHandler.transferLps(58808, 53864, 35788, 74796, 55652); + _reserveERC20PoolHandler.kickWithDeposit(1764, 5382, 31700); + _reserveERC20PoolHandler.pledgeCollateral(1058781579682788238311, 3595163542440, 1174127066216041681081057); + _reserveERC20PoolHandler.withdrawBonds(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _reserveERC20PoolHandler.repayDebt(3, 577096421800264625310269861, 6069872263612439813277667159763490263920271842304881717238); + _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 19, 2); + _reserveERC20PoolHandler.kickReserveAuction(4210960525909156020704, 150717425581035467460005734401755); + _reserveERC20PoolHandler.transferLps(19525089915530989, 200896599144468014944428982, 31856939995214172578550674772713104925855484, 1, 15450231414793903579649709108337); + _reserveERC20PoolHandler.transferLps(9999999999999999999999998904, 51624, 9971, 1342211067070467, 16700); + _reserveERC20PoolHandler.addCollateral(119764603467019941961977205, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 1); + _reserveERC20PoolHandler.removeQuoteToken(59800, 37640, 8317, 74040); + _reserveERC20PoolHandler.takeAuction(263046553377839595733555, 17173744718130880047583445834558963405893, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4833604285229578029430100810341); + _reserveERC20PoolHandler.addQuoteToken(14956, 27115, 8262, 1393686142056213573); + _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 37633653110846165980514994245971462730370047059165, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2811764013130114534361640788272261420507665322357890541394754); + _reserveERC20PoolHandler.kickReserveAuction(1522557716685203217262503, 2073); + _reserveERC20PoolHandler.repayDebt(53376, 9700, 77016); + _reserveERC20PoolHandler.withdrawBonds(41472, 22556, 515544862944662148599477108050029971417792571756); + _reserveERC20PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 9406223615136939066939078713383); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 12096, false, 26257948, 868853496937525842673186021209); + _reserveERC20PoolHandler.withdrawBonds(83049693977262618120718736926118174180340700, 514841, 1); + _reserveERC20PoolHandler.addCollateral(1548735198738205401485330251216522, 3732433568614, 2180862107850515031333, 125942509745293258656006517886029838705216318787717437080279894744491); + _reserveERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 340960440, 3); + _reserveERC20PoolHandler.kickAuction(162709566598368579437817, 1332873599505451132354360677515123340395328204920455806150312990831427444461, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 633026962134701401242064608840823919980052438526687733234921642689608023933); + _reserveERC20PoolHandler.takeAuction(322, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 773873574571235061415839771570789947238402953522597705649743297428242994, 7758586519239924744171); + _reserveERC20PoolHandler.addQuoteToken(6249681088590046484676031495866526227464307055320967, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3); + _reserveERC20PoolHandler.moveQuoteToken(702067896002955667744486226077, 1851755658, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 25424747081166118510931721327439432401626401971457982577840174748229701584345); + _reserveERC20PoolHandler.addCollateral(1413, 49095168302549099840713749279118697142645461715153932419307502388083636811957, 59312, 63044); + _reserveERC20PoolHandler.pledgeCollateral(265113518, 26743690141064050503543535875740594379319460156696308243384294412911045650, 6857685657629659715371385916444198334380046347135735206631285400); + _reserveERC20PoolHandler.removeQuoteToken(264755099108448404874526611938161139982716097780249605324091382474858483, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 29555907885141198250374421455396897600803290868687224178413745256); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 913445681, 24016, 3); + _reserveERC20PoolHandler.removeQuoteToken(1318962590322040984799347, 10975, 11423, 991989158181821594939988); + _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 14312416314106325, 1210); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.takeReserves(1, 438727355721426477239898491851681108155220538380850414154, 13847678296111811789794085392979441933736231); + _reserveERC20PoolHandler.withdrawBonds(0, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.pledgeCollateral(2, 8524283102799585244522974229466876622939214, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.repayDebt(3433, 846284097141101951348951915496082269416134646619748038244302899114646796, 95136396632074037836788541112); + _reserveERC20PoolHandler.removeCollateral(430312666383248217368835965751, 608359823, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.pullCollateral(1000251480639075482, 1694, 2861); + _reserveERC20PoolHandler.drawDebt(43388, 15271340786116372574138093141534396687613031025591758746939347758077531181799, 44324); + _reserveERC20PoolHandler.withdrawBonds(2, 1, 0); + _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.bucketTake(11273382872855962494616156929227174104394223152675369,563071629684930228962, true, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.settleAuction(120876873422711933, 13123, 1202025693345828720, 86474506389175276555789104803); + _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 2153576920718485934032590649534232750065468526); + _reserveERC20PoolHandler.drawDebt(56176, 15280, 2027); + _reserveERC20PoolHandler.takeReserves(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 69287402946168098504); + _reserveERC20PoolHandler.pledgeCollateral(2513453083628410660, 354836047215678049566111164509186528820097440614198, 1440945232); + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 122203289258304993638271269094949); + _reserveERC20PoolHandler.addQuoteToken(53679, 62040, 5947, 2103); + _reserveERC20PoolHandler.addCollateral(18774795145391113931569311773, 13864, 22198, 249890409261739105535806062594); + _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 402481164733638687888213, 3, 1); + _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6570343599); + _reserveERC20PoolHandler.removeCollateral(904, 62088, 2606493574, 1568); + _reserveERC20PoolHandler.transferLps(386809077963557983132, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 148380917210836178473325853580934307774647345526133, 1471892031300499403); + _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1198429820689537065749, 243483583504501197526845158753139835924066659); + _reserveERC20PoolHandler.takeAuction(1199779041428331153, 71740, 29306, 212074468834203469445731314306); + _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.withdrawBonds(5886, 6118, 31095594184158051362419323440); + _reserveERC20PoolHandler.settleAuction(73104, 19886, 67842558439608731261142755949781586203409010660475186688055685950916002409738, 252057734655093500419854976371); + _reserveERC20PoolHandler.takeAuction(7196998050564854545778916884105598407810383237719695, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7255413239007126458982904756151267359533146366352519669325613874036, 2047248371259122735965487218913991798927990); + _reserveERC20PoolHandler.removeCollateral(1864213972, 640566951528318811482719954179,23306860749941827438288665513, 17991); + _reserveERC20PoolHandler.repayDebt(1829308781, 10466, 10844); + _reserveERC20PoolHandler.withdrawBonds(2653308208712636950001934534323483618764, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 102999660873007284); + _reserveERC20PoolHandler.pledgeCollateral(31720, 70932, 2780794693417059803); + _reserveERC20PoolHandler.settleAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 854671780727979439081563500191, 225262438160); + _reserveERC20PoolHandler.bucketTake(629940976225716059962960082771, 1, false, 225849678556989118720101007068792997916417849594324517755148263306, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.kickReserveAuction(606348554034558493679860454709431448, 89966888302392); + _reserveERC20PoolHandler.failed(); + _reserveERC20PoolHandler.moveQuoteToken(41440, 21699326946127593872059764476,4710, 6203, 14804396475113080648507077369666489796844133507008083789207787640816145781579); + _reserveERC20PoolHandler.withdrawBonds(2, 17699682295103685686607846447761536549069783056697648210356871, 32242429915466227126678114985365834118645100); + _reserveERC20PoolHandler.pullCollateral(1251991137329864999647595984957979509770972143957828381127002, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + _reserveERC20PoolHandler.settleAuction(2928541728928580567000226390336957184553436628091154283961253785794613, 2, 2875303751127784380477338443990777660043197429138675174892500, 521967551); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 5760141916331935256020319985050770378843488870096130251085692594128, false, 252114383392869660254, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + + invariant_reserves(); + } + } contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvariants { @@ -1041,4 +1255,4 @@ contract RegressionTestReserveWith12CollateralPrecisionERC20Pool is ReserveERC20 _reserveERC20PoolHandler.kickReserveAuction(11114, 133084258667509499441); invariant_quote(); } -} \ No newline at end of file +} From 82aac73b00bf56282403cfe1e760ac7816c9291e Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 15 Jun 2023 06:41:22 +0300 Subject: [PATCH 05/32] Bug fix: Recalculate `LUP` after add in to bucket on `moveQuoteToken` (#891) * Recalculate LUP after moveQuoteToken add step * Recalculate LUP only if to bucket price is greater than LUP * Changes after review: style --- src/libraries/external/LenderActions.sol | 4 +++- tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/external/LenderActions.sol b/src/libraries/external/LenderActions.sol index 69d2bd488..7d384da5c 100644 --- a/src/libraries/external/LenderActions.sol +++ b/src/libraries/external/LenderActions.sol @@ -49,7 +49,6 @@ library LenderActions { uint256 toBucketUnscaledDeposit; // Amount of unscaled deposit in to bucket. uint256 toBucketDeposit; // Amount of scaled deposit in to bucket. uint256 toBucketScale; // Scale deposit of to bucket. - uint256 ptp; // [WAD] Pool Threshold Price. uint256 htp; // [WAD] Highest Threshold Price. } @@ -306,6 +305,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); // check loan book's htp against new lup, revert if move drives LUP below HTP diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index b71ed98a7..f3da70f0d 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -1099,7 +1099,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { toIndex: 4550, lpRedeemFrom: amountToMove, lpAwardTo: amountToMove, - newLup: _priceAt(4651) + newLup: 0.139445853940958153 * 1e18 }); } From b22a4ac01390384b2fa5e19a74786e1894d9bd70 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Fri, 16 Jun 2023 10:38:37 +0530 Subject: [PATCH 06/32] Invariants improvements: Position Manager invariants for ERC721Pool and multiple token precisions (#889) * Add Position Manager with ERC721Pool invariants * Catch MoveToSameIndex error in _ensurePositionsManagerError * Add moveQuoteToken reverts in _ensurePositionsManagerError * Add script to run position invariants with ERC20/ERC721Pool for multiple token precisions (#890) --- Makefile | 23 +- tests/README.md | 16 +- .../ERC20PoolPositionsInvariants.t.sol | 64 ++++ .../ERC721PoolPositionsInvariants.t.sol | 63 ++++ ...variants.t.sol => PositionsInvariants.sol} | 48 +-- .../RewardsInvariants.t.sol | 6 +- ...r.sol => BaseERC20PoolPositionHandler.sol} | 5 +- .../BaseERC721PoolPositionHandler.sol | 197 +++++++++++ ...ndler.sol => ERC20PoolPositionHandler.sol} | 4 +- .../handlers/ERC721PoolPositionHandler.sol | 26 ++ .../handlers/RewardsHandler.sol | 6 +- .../UnboundedBasePositionHandler.sol | 27 +- ...=> UnboundedERC20PoolPositionsHandler.sol} | 21 +- .../UnboundedERC721PoolPositionsHandler.sol | 313 ++++++++++++++++++ .../unbounded/UnboundedRewardsHandler.sol | 4 +- ...test-invariant-position-erc20-precision.sh | 12 + ...est-invariant-position-erc721-precision.sh | 8 + .../RegressionPositionManager.t.sol | 140 ++++---- .../unit/Positions/CodearenaReports.t.sol | 2 +- .../{ => Positions}/PositionManager.t.sol | 8 +- 20 files changed, 824 insertions(+), 169 deletions(-) create mode 100644 tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol rename tests/forge/invariants/PositionsAndRewards/{PositionsInvariants.t.sol => PositionsInvariants.sol} (68%) rename tests/forge/invariants/PositionsAndRewards/handlers/{BasePositionHandler.sol => BaseERC20PoolPositionHandler.sol} (96%) create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol rename tests/forge/invariants/PositionsAndRewards/handlers/{PositionHandler.sol => ERC20PoolPositionHandler.sol} (81%) create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol rename tests/forge/invariants/PositionsAndRewards/handlers/unbounded/{UnboundedPositionsHandler.sol => UnboundedERC20PoolPositionsHandler.sol} (93%) create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol create mode 100755 tests/forge/invariants/test-invariant-position-erc20-precision.sh create mode 100755 tests/forge/invariants/test-invariant-position-erc721-precision.sh rename tests/forge/unit/{ => Positions}/PositionManager.t.sol (99%) diff --git a/Makefile b/Makefile index efbd3f870..add7a8466 100644 --- a/Makefile +++ b/Makefile @@ -24,16 +24,19 @@ test-with-gas-report :; forge test --no-match-test ${TEST_EXCLUDES} - test-load :; forge test --match-test testLoad --gas-report # Invariant Tests -test-invariant-all :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} -test-invariant-erc20 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC20 -test-invariant-erc721 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC721 -test-invariant-position :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Position -test-invariant-rewards :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Rewards -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 -test-invariant-erc20-buckets :; ./tests/forge/invariants/test-invariant-erc20-buckets.sh -test-invariant-erc721-buckets :; ./tests/forge/invariants/test-invariant-erc721-buckets.sh +test-invariant-all :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} +test-invariant-erc20 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc ERC20 +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 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Rewards +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 +test-invariant-erc20-buckets :; ./tests/forge/invariants/test-invariant-erc20-buckets.sh +test-invariant-erc721-buckets :; ./tests/forge/invariants/test-invariant-erc721-buckets.sh +test-invariant-position-erc20-precision :; ./tests/forge/invariants/test-invariant-position-erc20-precision.sh +test-invariant-position-erc721-precision :; ./tests/forge/invariants/test-invariant-position-erc721-precision.sh # Real-world simulation scenarios test-rw-simulation-erc20 :; FOUNDRY_INVARIANT_SHRINK_SEQUENCE=false RUST_LOG=forge=info,foundry_evm=info,ethers=info forge t --mt invariant_all_erc20 --mc RealWorldScenario diff --git a/tests/README.md b/tests/README.md index 2a4072fed..4ee047dc4 100644 --- a/tests/README.md +++ b/tests/README.md @@ -146,9 +146,13 @@ make test-invariant-erc20 ```bash make test-invariant-erc721 ``` -- run all invariant tests for Position Manager: +- run all invariant tests for Position Manager with ERC20Pool: ```bash -make test-invariant-position +make test-invariant-position-erc20 +``` +- run all invariant tests for Position Manager with ERC721Pool: +```bash +make test-invariant-position-erc721 ``` - run all invariant tests for Rewards Manager: ```bash @@ -182,6 +186,14 @@ make test-invariant-erc20-buckets ```bash make test-invariant-erc721-buckets ``` +- run Position manager with ERC20 pool invariant tests for most popular token precision combinations(6, 8 and 18): +```bash +make test-invariant-position-erc20-precision +``` +- run Position manager with ERC721 pool invariant tests for most popular token precision(6, 8 and 18): +```bash +make test-invariant-position-erc721-precision +``` ### Code coverage: ```bash diff --git a/tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol new file mode 100644 index 000000000..9e138c2df --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.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 { Maths } from 'src/libraries/internal/Maths.sol'; + +import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; +import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; +import { TokenWithNDecimals } from '../../utils/Tokens.sol'; + +import { ERC20PoolPositionHandler } from './handlers/ERC20PoolPositionHandler.sol'; +import { PositionsInvariants } from './PositionsInvariants.sol'; + +contract ERC20PoolPositionsInvariants is PositionsInvariants { + + TokenWithNDecimals internal _collateral; + ERC20Pool internal _erc20pool; + ERC20PoolPositionHandler internal _erc20positionHandler; + + function setUp() public override virtual { + + super.setUp(); + _collateral = new TokenWithNDecimals("Collateral", "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18)))); + _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); + _erc20impl = _erc20poolFactory.implementation(); + _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); + _erc721impl = _erc721poolFactory.implementation(); + _erc20pool = ERC20Pool(_erc20poolFactory.deployPool(address(_collateral), address(_quote), 0.05 * 10**18)); + _pool = Pool(address(_erc20pool)); + _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); + + excludeContract(address(_ajna)); + excludeContract(address(_collateral)); + excludeContract(address(_quote)); + excludeContract(address(_erc20poolFactory)); + excludeContract(address(_erc721poolFactory)); + excludeContract(address(_erc20pool)); + excludeContract(address(_poolInfo)); + excludeContract(address(_erc20impl)); + excludeContract(address(_erc721impl)); + excludeContract(address(_positionManager)); + + _erc20positionHandler = new ERC20PoolPositionHandler( + address(_positionManager), + address(_erc20pool), + address(_ajna), + address(_quote), + address(_collateral), + address(_poolInfo), + NUM_ACTORS, + address(this) + ); + + _handler = address(_erc20positionHandler); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol new file mode 100644 index 000000000..66a8eed06 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.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 { NFTCollateralToken } from '../../utils/Tokens.sol'; + +import { ERC721PoolPositionHandler } from './handlers/ERC721PoolPositionHandler.sol'; +import { PositionsInvariants } from './PositionsInvariants.sol'; + +contract ERC721PoolPositionsInvariants is PositionsInvariants { + + NFTCollateralToken internal _collateral; + ERC721Pool internal _erc721pool; + ERC721PoolPositionHandler internal _erc721positionHandler; + + function setUp() public override virtual { + + super.setUp(); + + uint256[] memory tokenIds; + _collateral = new NFTCollateralToken(); + _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); + _erc20impl = _erc20poolFactory.implementation(); + _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); + _erc721pool = ERC721Pool(_erc721poolFactory.deployPool(address(_collateral), address(_quote), tokenIds, 0.05 * 10**18)); + _erc721impl = _erc721poolFactory.implementation(); + _pool = Pool(address(_erc721pool)); + _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); + + excludeContract(address(_ajna)); + excludeContract(address(_collateral)); + excludeContract(address(_quote)); + excludeContract(address(_erc20poolFactory)); + excludeContract(address(_erc721poolFactory)); + excludeContract(address(_erc721pool)); + excludeContract(address(_poolInfo)); + excludeContract(address(_erc20impl)); + excludeContract(address(_erc721impl)); + excludeContract(address(_positionManager)); + + _erc721positionHandler = new ERC721PoolPositionHandler( + address(_positionManager), + address(_erc721pool), + address(_ajna), + address(_quote), + address(_collateral), + address(_poolInfo), + NUM_ACTORS, + address(this) + ); + + _handler = address(_erc721positionHandler); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol similarity index 68% rename from tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol rename to tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol index 80cc47880..54668d354 100644 --- a/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.t.sol +++ b/tests/forge/invariants/PositionsAndRewards/PositionsInvariants.sol @@ -15,61 +15,17 @@ import { Maths } from 'src/libraries/internal/Maths.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; import { BaseInvariants } from '../base/BaseInvariants.sol'; -import { ReserveERC20PoolInvariants } from '../ERC20Pool/ReserveERC20PoolInvariants.t.sol'; -import { ReserveERC20PoolHandler } from '../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; import { TokenWithNDecimals } from '../../utils/Tokens.sol'; -import { PositionHandler } from './handlers/PositionHandler.sol'; +abstract contract PositionsInvariants is BaseInvariants { -contract PositionsInvariants is BaseInvariants { + uint256 internal constant NUM_ACTORS = 10; - uint256 internal constant NUM_ACTORS = 10; - - TokenWithNDecimals internal _collateral; - ERC20Pool internal _erc20pool; ERC20Pool internal _erc20impl; ERC20PoolFactory internal _erc20poolFactory; ERC721PoolFactory internal _erc721poolFactory; ERC721Pool internal _erc721impl; PositionManager internal _positionManager; - PositionHandler internal _positionHandler; - - function setUp() public override virtual { - - super.setUp(); - _collateral = new TokenWithNDecimals("Collateral", "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18)))); - _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); - _erc20impl = _erc20poolFactory.implementation(); - _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); - _erc721impl = _erc721poolFactory.implementation(); - _erc20pool = ERC20Pool(_erc20poolFactory.deployPool(address(_collateral), address(_quote), 0.05 * 10**18)); - _pool = Pool(address(_erc20pool)); - _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); - - excludeContract(address(_ajna)); - excludeContract(address(_collateral)); - excludeContract(address(_quote)); - excludeContract(address(_erc20poolFactory)); - excludeContract(address(_erc721poolFactory)); - excludeContract(address(_erc20pool)); - excludeContract(address(_poolInfo)); - excludeContract(address(_erc20impl)); - excludeContract(address(_erc721impl)); - excludeContract(address(_positionManager)); - - _positionHandler = new PositionHandler( - address(_positionManager), - address(_erc20pool), - address(_ajna), - address(_quote), - address(_collateral), - address(_poolInfo), - NUM_ACTORS, - address(this) - ); - - _handler = address(_positionHandler); - } function invariant_positions_PM1_PM2_PM3() public useCurrentTimestamp { uint256[] memory bucketIndexes = IPositionsAndRewardsHandler(_handler).getBucketIndexesWithPosition(); diff --git a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol index 2ef8cb822..d9c37c8d5 100644 --- a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol +++ b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol @@ -10,9 +10,9 @@ import { _getEpochInfo } from 'src/RewardsManager.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; import { IPositionsAndRewardsHandler } from '../interfaces/IPositionsAndRewardsHandler.sol'; import { RewardsHandler } from './handlers/RewardsHandler.sol'; -import { PositionsInvariants } from './PositionsInvariants.t.sol'; +import { ERC20PoolPositionsInvariants } from './ERC20PoolPositionsInvariants.t.sol'; -contract RewardsInvariants is PositionsInvariants { +contract RewardsInvariants is ERC20PoolPositionsInvariants { RewardsManager internal _rewardsManager; RewardsHandler internal _rewardsHandler; @@ -26,7 +26,7 @@ contract RewardsInvariants is PositionsInvariants { // fund the rewards manager with 100M ajna _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); - excludeContract(address(_positionHandler)); + excludeContract(address(_erc20positionHandler)); excludeContract(address(_rewardsManager)); _rewardsHandler = new RewardsHandler( diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol similarity index 96% rename from tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol index 69f25ca51..075e7cc2b 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BasePositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol @@ -13,10 +13,9 @@ import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionM import { PositionManager } from 'src/PositionManager.sol'; import { ERC20Pool } from 'src/ERC20Pool.sol'; -import { UnboundedPositionsHandler } from './unbounded/UnboundedPositionsHandler.sol'; -import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; +import { UnboundedERC20PoolPositionsHandler } from './unbounded/UnboundedERC20PoolPositionsHandler.sol'; -abstract contract BasePositionHandler is UnboundedPositionsHandler { +abstract contract BaseERC20PoolPositionHandler is UnboundedERC20PoolPositionsHandler { using EnumerableSet for EnumerableSet.UintSet; diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol new file mode 100644 index 000000000..ff1995f3e --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import '@std/console.sol'; + +import { Maths } from 'src/libraries/internal/Maths.sol'; + +import { _priceAt } from 'src/libraries/helpers/PoolHelper.sol'; + +import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; +import { PositionManager } from 'src/PositionManager.sol'; + +import { UnboundedERC721PoolPositionsHandler } from './unbounded/UnboundedERC721PoolPositionsHandler.sol'; + +abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsHandler { + + using EnumerableSet for EnumerableSet.UintSet; + + /********************************/ + /*** Positions Test Functions ***/ + /********************************/ + + function memorializePositions( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.memorialize']++; + // Pre action // + (uint256 tokenId, uint256[] memory indexes) = _preMemorializePositions(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _memorializePositions(tokenId, indexes); + } + + function redeemPositions( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.redeem']++; + // Pre action // + (uint256 tokenId, uint256[] memory indexes) = _preRedeemPositions(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _redeemPositions(tokenId, indexes); + } + + function mint( + uint256 actorIndex_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.mint']++; + + // Action phase // + _mint(); + } + + function burn( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 skippedTime_, + uint256 amountToAdd_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.burn']++; + // Pre action // + (uint256 tokenId_) = _preBurn(_lenderBucketIndex, amountToAdd_); + + // Action phase // + _burn(tokenId_); + } + + function moveLiquidity( + uint256 actorIndex_, + uint256 skippedTime_, + uint256 amountToMove_, + uint256 fromIndex_, + uint256 toIndex_ + ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BPositionHandler.moveLiquidity']++; + // Pre action // + ( + uint256 tokenId, + uint256 fromIndex, + uint256 toIndex + ) = _preMoveLiquidity(amountToMove_, fromIndex_, toIndex_); + + // retrieve info of bucket from pool + ( + , + uint256 bucketCollateral, + , + , + ) = _pool.bucketInfo(fromIndex); + + // to avoid LP mismatch revert return if bucket has collateral or exchangeRate < 1e18 + if (bucketCollateral != 0) return; + if (_pool.bucketExchangeRate(fromIndex) < 1e18) return; + + // Action phase // + _moveLiquidity(tokenId, fromIndex, toIndex); + } + + function _preMemorializePositions( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, 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) { + // Prepare test phase + uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); + _ensureQuoteAmount(_actor, boundedAmount); + try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes) { + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + + indexes_ = new uint256[](1); + indexes_[0] = bucketIndex_; + + uint256[] memory lpBalances = new uint256[](1); + + // mint position NFT + tokenId_ = _mint(); + + (lpBalances[0], ) = _pool.lenderInfo(bucketIndex_, _actor); + _pool.increaseLPAllowance(address(_positionManager), indexes_, lpBalances); + } + + function _preRedeemPositions( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + (tokenId_, indexes_) = _getNFTPosition(bucketIndex_, amountToAdd_); + + // approve positionManager to transfer LP tokens + address[] memory transferors = new address[](1); + transferors[0] = address(_positionManager); + + _pool.approveLPTransferors(transferors); + } + + function _preBurn( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_) { + uint256[] memory indexes; + + // check and create the position + (tokenId_, indexes) = _preRedeemPositions(bucketIndex_, amountToAdd_); + + _redeemPositions(tokenId_, indexes); + } + + function _preMoveLiquidity( + uint256 amountToMove_, + uint256 fromIndex_, + uint256 toIndex_ + ) internal returns (uint256 tokenId_, uint256 boundedFromIndex_, uint256 boundedToIndex_) { + boundedFromIndex_ = constrictToRange(fromIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + boundedToIndex_ = constrictToRange(toIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); + + uint256[] memory indexes; + (tokenId_, indexes) = _getNFTPosition(boundedFromIndex_, amountToMove_); + boundedFromIndex_ = indexes[0]; + + } + + function _getNFTPosition( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + // Check for exisiting nft positions in PositionManager + uint256[] memory tokenIds = getTokenIdsByActor(address(_actor)); + + if (tokenIds.length != 0 ) { + // use existing position NFT + tokenId_ = tokenIds[0]; + indexes_ = getBucketIndexesByTokenId(tokenId_); + } else { + // create a position for the actor + (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); + _memorializePositions(tokenId_, indexes_); + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol similarity index 81% rename from tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol index 3e2e48a10..e856860fd 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/PositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol @@ -4,10 +4,10 @@ pragma solidity 0.8.18; import { PositionManager } from 'src/PositionManager.sol'; -import { BasePositionHandler } from './BasePositionHandler.sol'; +import { BaseERC20PoolPositionHandler } from './BaseERC20PoolPositionHandler.sol'; import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; -contract PositionHandler is BasePositionHandler { +contract ERC20PoolPositionHandler is BaseERC20PoolPositionHandler { constructor( address positions_, diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol new file mode 100644 index 000000000..856f87f4f --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { PositionManager } from 'src/PositionManager.sol'; + +import { BaseERC721PoolPositionHandler } from './BaseERC721PoolPositionHandler.sol'; +import { BaseERC721PoolHandler } from '../../ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol'; + +contract ERC721PoolPositionHandler is BaseERC721PoolPositionHandler { + + constructor( + address positions_, + address pool_, + address ajna_, + address quote_, + address collateral_, + address poolInfo_, + uint256 numOfActors_, + address testContract_ + ) BaseERC721PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { + + // Position manager + _positionManager = PositionManager(positions_); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol index 7de658e2e..cbffaab08 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol @@ -9,10 +9,10 @@ import { RewardsManager } from 'src/RewardsManager.sol'; import { UnboundedRewardsHandler } from './unbounded/UnboundedRewardsHandler.sol'; -import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; -import { BasePositionHandler } from './BasePositionHandler.sol'; +import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; +import { BaseERC20PoolPositionHandler } from './BaseERC20PoolPositionHandler.sol'; -contract RewardsHandler is UnboundedRewardsHandler, BasePositionHandler, ReserveERC20PoolHandler { +contract RewardsHandler is UnboundedRewardsHandler, BaseERC20PoolPositionHandler, ReserveERC20PoolHandler { constructor( address rewards_, diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol index 49dc5384b..55fe0d4c5 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.18; +import '@std/Test.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; @@ -10,18 +11,15 @@ import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionM import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; -import { BaseERC20PoolHandler } from '../../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; - import { PositionManager } from 'src/PositionManager.sol'; import { RewardsManager } from 'src/RewardsManager.sol'; -import { ERC20Pool } from 'src/ERC20Pool.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 UnboundedBasePositionHandler is BaseERC20PoolHandler { +abstract contract UnboundedBasePositionHandler is Test { PositionManager internal _positionManager; RewardsManager internal _rewardsManager; @@ -67,4 +65,25 @@ abstract contract UnboundedBasePositionHandler is BaseERC20PoolHandler { function getTokenIdsByActor(address actor_) public view returns(uint256[] memory) { return tokenIdsByActor[actor_].values(); } + + function _ensurePositionsManagerError(bytes memory err_) internal pure { + bytes32 err = keccak256(err_); + + require( + err == keccak256(abi.encodeWithSignature("AllowanceTooLow()")) || + err == keccak256(abi.encodeWithSignature("BucketBankrupt()")) || + err == keccak256(abi.encodeWithSignature("DeployWithZeroAddress()")) || + err == keccak256(abi.encodeWithSignature("LiquidityNotRemoved()")) || + err == keccak256(abi.encodeWithSignature("NoAuth()")) || + err == keccak256(abi.encodeWithSignature("NoToken()")) || + err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) || + err == keccak256(abi.encodeWithSignature("RemovePositionFailed()")) || + err == keccak256(abi.encodeWithSignature("WrongPool()")) || + err == keccak256(abi.encodeWithSignature("MoveToSameIndex()")) || + err == keccak256(abi.encodeWithSignature("RemoveDepositLockedByAuctionDebt()")) || + err == keccak256(abi.encodeWithSignature("DustAmountNotExceeded()")) || + err == keccak256(abi.encodeWithSignature("InvalidIndex()")), + "Unexpected revert error" + ); + } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol similarity index 93% rename from tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol index f96e132b6..e61f796bc 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol @@ -14,14 +14,14 @@ import { import { Maths } from "src/libraries/internal/Maths.sol"; import { BaseERC20PoolHandler } from '../../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; -import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; +import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.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 UnboundedPositionsHandler is UnboundedBasePositionHandler { +abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHandler, BaseERC20PoolHandler { using EnumerableSet for EnumerableSet.UintSet; @@ -310,21 +310,4 @@ abstract contract UnboundedPositionsHandler is UnboundedBasePositionHandler { _ensurePositionsManagerError(err); } } - - function _ensurePositionsManagerError(bytes memory err_) internal pure { - bytes32 err = keccak256(err_); - - require( - err == keccak256(abi.encodeWithSignature("AllowanceTooLow()")) || - err == keccak256(abi.encodeWithSignature("BucketBankrupt()")) || - err == keccak256(abi.encodeWithSignature("DeployWithZeroAddress()")) || - err == keccak256(abi.encodeWithSignature("LiquidityNotRemoved()")) || - err == keccak256(abi.encodeWithSignature("NoAuth()")) || - err == keccak256(abi.encodeWithSignature("NoToken()")) || - err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) || - err == keccak256(abi.encodeWithSignature("RemovePositionFailed()")) || - err == keccak256(abi.encodeWithSignature("WrongPool()")), - "Unexpected revert error" - ); - } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol new file mode 100644 index 000000000..9523c437b --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol @@ -0,0 +1,313 @@ +// 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 { BaseERC721PoolHandler } from '../../../ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol'; +import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.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 UnboundedERC721PoolPositionsHandler is UnboundedBasePositionHandler, BaseERC721PoolHandler { + + using EnumerableSet for EnumerableSet.UintSet; + + function _memorializePositions( + uint256 tokenId_, + uint256[] memory indexes_ + ) internal { + numberOfCalls['UBPositionHandler.memorialize']++; + + for(uint256 i=0; i < indexes_.length; i++) { + + // store vals pre action to check after memorializing: + (uint256 actorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); + (uint256 posManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + + bucketIndexToActorPoolLps[indexes_[i]] = actorLps; + bucketIndexToPositionManPoolLps[indexes_[i]] = posManLps; + + // positionManager is assigned the most recent depositTime + bucketIndexToDepositTime[indexes_[i]] = (actorDepositTime >= posManDepositTime) ? actorDepositTime : posManDepositTime; + + // assert that the underlying LP balance in PositionManager is 0 + (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); + require(posPreActionLps == 0, "tokenID already has lps associated on memorialize"); + + } + + try _positionManager.memorializePositions(address(_pool), tokenId_, indexes_) { + + // track created positions + for ( uint256 i = 0; i < indexes_.length; i++) { + // PM1_PM2_PM3 tracking + bucketIndexesWithPosition.add(indexes_[i]); + tokenIdsByBucketIndex[indexes_[i]].add(tokenId_); + + // info used to tearDown buckets + bucketIndexesByTokenId[tokenId_].add(indexes_[i]); + } + + // info used track actors positions + actorByTokenId[tokenId_] = address(_actor); + tokenIdsByActor[address(_actor)].add(tokenId_); + + // Post action Checks // + for(uint256 i=0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + + // assert that the LP that now exists in the pool contract matches the amount added by the actor + (uint256 poolLps, uint256 poolDepositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + require(poolLps == bucketIndexToActorPoolLps[bucketIndex] + bucketIndexToPositionManPoolLps[bucketIndex], + "PM7: pool contract lps do not match amount added by actor"); + + require(poolDepositTime == bucketIndexToDepositTime[bucketIndex], + "PM7: positionManager depositTime does not match most recent depositTime"); + + // assert that the positionManager LP balance of the actor has increased + (uint256 posLps,) = _positionManager.getPositionInfo(tokenId_, bucketIndex); + require(posLps == bucketIndexToActorPoolLps[bucketIndex], + "PM7: positionManager lps do not match amount added by actor"); + + delete bucketIndexToActorPoolLps[bucketIndex]; + delete bucketIndexToPositionManPoolLps[bucketIndex]; + delete bucketIndexToDepositTime[bucketIndex]; + } + + } catch (bytes memory err) { + _ensurePositionsManagerError(err); + } + } + + function _mint() internal returns (uint256 tokenIdResult) { + numberOfCalls['UBPositionHandler.mint']++; + try _positionManager.mint(address(_pool), _actor, keccak256("ERC721_NON_SUBSET_HASH")) 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"); + + // assert that poolKey is returns correct pool address + address poolAddress = _positionManager.poolKey(tokenId); + 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"); + + } catch (bytes memory err) { + _ensurePositionsManagerError(err); + } + } + + function _redeemPositions( + uint256 tokenId_, + uint256[] memory indexes_ + ) internal { + numberOfCalls['UBPositionHandler.redeem']++; + + address preActionOwner = _positionManager.ownerOf(tokenId_); + + for (uint256 i=0; i < indexes_.length; i++) { + + // store vals in mappings to check lps + (uint256 poolPreActionActorLps,) = _pool.lenderInfo(indexes_[i], preActionOwner); + (uint256 poolPreActionPosManLps,) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + + bucketIndexToActorPoolLps[indexes_[i]] = poolPreActionActorLps; + bucketIndexToPositionManPoolLps[indexes_[i]] = poolPreActionPosManLps; + + // assert that the underlying LP balance in PositionManager is greater than 0 + (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); + require(posPreActionLps > 0, "tokenID does not have lps associated on redemption"); + } + + try _positionManager.redeemPositions(address(_pool), tokenId_, indexes_) { + // remove tracked positions + for ( uint256 i = 0; i < indexes_.length; i++) { + bucketIndexesWithPosition.remove(indexes_[i]); + tokenIdsByBucketIndex[indexes_[i]].remove(tokenId_); + } + + // info for tear down + delete actorByTokenId[tokenId_]; + delete bucketIndexesByTokenId[tokenId_]; + tokenIdsByActor[address(_actor)].remove(tokenId_); + + // Post action Checks // + // assert that the minter is still the owner + require(_positionManager.ownerOf(tokenId_) == preActionOwner, + 'PM8: previous owner is no longer owner on redemption'); + + // assert that poolKey is still same + address poolAddress = _positionManager.poolKey(tokenId_); + require(poolAddress == address(_pool), 'PM8: poolKey has changed on redemption'); + + // 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'); + + for(uint256 i=0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + + uint256 actorPoolLps = bucketIndexToActorPoolLps[bucketIndex]; + uint256 positionManPoolLps = bucketIndexToPositionManPoolLps[bucketIndex]; + + (uint256 poolActorLps,) = _pool.lenderInfo(bucketIndex, preActionOwner); + (uint256 poolPosLps,) = _pool.lenderInfo(bucketIndex, address(_positionManager)); + + // assert PositionsMan LP in pool matches the amount redeemed by actor + // positionMan has now == positionMan pre - actor's LP change + require(poolPosLps == positionManPoolLps - (poolActorLps - actorPoolLps), + "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 == actorPoolLps + (positionManPoolLps - 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"); + + // delete mappings for reuse + delete bucketIndexToActorPoolLps[bucketIndex]; + delete bucketIndexToPositionManPoolLps[bucketIndex]; + } + + } catch (bytes memory err) { + _ensurePositionsManagerError(err); + } + + } + + function _getQuoteAtIndex( + uint256 lp, + uint256 index + ) internal view returns (uint256 quoteAtIndex_) { + // retrieve info of bucket from pool + ( + uint256 bucketLP, + uint256 bucketCollateral, + , + uint256 bucketDeposit, + ) = _pool.bucketInfo(index); + + // calculate the max amount of quote tokens that can be moved, given the tracked LP + quoteAtIndex_ = _lpToQuoteToken( + bucketLP, + bucketCollateral, + bucketDeposit, + lp, + bucketDeposit, + _priceAt(index) + ); + } + + function _moveLiquidity( + uint256 tokenId_, + uint256 fromIndex_, + uint256 toIndex_ + ) internal { + numberOfCalls['UBPositionHandler.moveLiquidity']++; + + // update interest so pre and post token amounts are equal + _pool.updateInterest(); + + // fromIndex values + (uint256 preActionFromLps,) = _positionManager.getPositionInfo(tokenId_, fromIndex_); + uint256 preActionFromIndexQuote = _getQuoteAtIndex(preActionFromLps, fromIndex_); + + // toIndex values + (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) { + + bucketIndexesByTokenId[tokenId_].add(toIndex_); + bucketIndexesByTokenId[tokenId_].remove(fromIndex_); + + // Post Action Checks // + // remove tracked positios + bucketIndexesWithPosition.remove(fromIndex_); + tokenIdsByBucketIndex[fromIndex_].remove(tokenId_); + + // track created positions + bucketIndexesWithPosition.add(toIndex_); + tokenIdsByBucketIndex[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"); + + // 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"); + + // get post action QT represented in positionManager for tokenID + uint256 postActionFromIndexQuote = _getQuoteAtIndex(fromLps, fromIndex_); + uint256 postActionToIndexQuote = _getQuoteAtIndex(toLps, toIndex_); + + // positionManager's total QT postAction is less than or equal to preAction + // can be less than or equal due to fee on movements above -> below LUP + + greaterThanWithinDiff( + preActionFromIndexQuote + preActionToIndexQuote, + postActionFromIndexQuote + postActionToIndexQuote, + 1, + "PM6: positiionManager QT balance has increased by `1` margin" + ); + + + } catch (bytes memory err) { + _ensurePositionsManagerError(err); + } + } + + + + function _burn( + uint256 tokenId_ + ) internal { + numberOfCalls['UBPositionHandler.burn']++; + 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"); + + // assert that poolKey is returns zero address + address poolAddress = _positionManager.poolKey(tokenId_); + 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"); + } catch (bytes memory err) { + _ensurePositionsManagerError(err); + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol index ac2488af5..9c50a3dbc 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol @@ -9,7 +9,7 @@ import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionM import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; -import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; +import { UnboundedERC20PoolPositionsHandler } from './UnboundedERC20PoolPositionsHandler.sol'; import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; @@ -19,7 +19,7 @@ import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; * @dev methods in this contract are called in random order * @dev randomly selects a lender contract to make a txn */ -abstract contract UnboundedRewardsHandler is UnboundedBasePositionHandler { +abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler { using EnumerableSet for EnumerableSet.UintSet; diff --git a/tests/forge/invariants/test-invariant-position-erc20-precision.sh b/tests/forge/invariants/test-invariant-position-erc20-precision.sh new file mode 100755 index 000000000..d79dbfb71 --- /dev/null +++ b/tests/forge/invariants/test-invariant-position-erc20-precision.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e +for quote_precision in 6 8 18 +do + for collateral_precision in 6 8 18 + do + export QUOTE_PRECISION=${quote_precision} + export COLLATERAL_PRECISION=${collateral_precision} + echo "Running test with ${QUOTE_PRECISION} quote precision and ${COLLATERAL_PRECISION} collateral precision" + forge t --mt invariant --nmc RegressionTest --mc ERC20PoolPosition + done +done \ No newline at end of file diff --git a/tests/forge/invariants/test-invariant-position-erc721-precision.sh b/tests/forge/invariants/test-invariant-position-erc721-precision.sh new file mode 100755 index 000000000..fe7b9dc2f --- /dev/null +++ b/tests/forge/invariants/test-invariant-position-erc721-precision.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +for quote_precision in 6 8 18 +do + export QUOTE_PRECISION=${quote_precision} + echo "Running test with ${QUOTE_PRECISION} quote precision" + forge t --mt invariant --nmc RegressionTest --mc ERC721PoolPosition +done \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol index 8ed989272..02586f151 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.18; -import { PositionsInvariants } from "../../invariants/PositionsAndRewards/PositionsInvariants.t.sol"; +import { ERC20PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol"; -contract RegressionPositionManager is PositionsInvariants { +contract RegressionPositionManager is ERC20PoolPositionsInvariants { function setUp() public override { super.setUp(); @@ -13,47 +13,47 @@ contract RegressionPositionManager is PositionsInvariants { // Test was failing because handler was using unbounded bucketIndex // Fixed by bounding bucketIndex function test_regression_position_evm_revert_1() external { - _positionHandler.memorializePositions(265065747026302585864021010218, 462486804883131506688620136159543, 43470270713791727776, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _erc20positionHandler.memorializePositions(265065747026302585864021010218, 462486804883131506688620136159543, 43470270713791727776, 115792089237316195423570985008687907853269984665640564039457584007913129639932); } // Test was failing because handler was using unbounded bucketIndex // Fixed by bounding bucketIndex function test_regression_position_evm_revert_2() external { - _positionHandler.burn(3492, 4670, 248, 9615); + _erc20positionHandler.burn(3492, 4670, 248, 9615); } // Test was failing due to incorrect check in moveLiquidity handler // Fixed by updating Lps and depositTime checks in moveLiquidity function test_regression_position_moveLiquidity_assertions() external { - _positionHandler.redeemPositions(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 383, 55401367687647196204681805934009816110); - _positionHandler.memorializePositions(63114273171442586497890388, 154152435409657628166549200091090874517100159073873, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _positionHandler.memorializePositions(5108, 999999999999999999, 18382, 12291); - _positionHandler.burn(138176025109205882910260935173830393, 486526542428702931007164500131103382164, 909564196488498523878255414236, 25516699); - _positionHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3, 2); + _erc20positionHandler.redeemPositions(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 383, 55401367687647196204681805934009816110); + _erc20positionHandler.memorializePositions(63114273171442586497890388, 154152435409657628166549200091090874517100159073873, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc20positionHandler.memorializePositions(5108, 999999999999999999, 18382, 12291); + _erc20positionHandler.burn(138176025109205882910260935173830393, 486526542428702931007164500131103382164, 909564196488498523878255414236, 25516699); + _erc20positionHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 3, 2); } // example has a divergence of the positionManager's depositTime from the actor tokenId's depositTime stored in positionManager function test_regression_position_deposittime_assertions() external { - _positionHandler.burn(2361, 11336, 3859341707, 3646975496); - _positionHandler.mint(68692219213121667537675943993034658256534085966823702, 312562089476538195); - _positionHandler.redeemPositions(14346285029390138384631699352851716037838873523252820863546, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 156099301165664793782770725300034911992745565612292730719535759193816917); - _positionHandler.failed(); - _positionHandler.moveLiquidity(3124, 4851, 22482, 489, 12560); - _positionHandler.failed(); - _positionHandler.failed(); - _positionHandler.redeemPositions(12847, 1716, 21792638192227207103739660380579104546232133259664619746653999669489792464176, 6416); - _positionHandler.failed(); - _positionHandler.mint(1, 1); - _positionHandler.burn(429855229349693967633032639264591, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 16061636408720604028163146864844242179959313271462038759); - _positionHandler.memorializePositions(1000000000000000000000000000, 2339, 9277, 2979); - _positionHandler.failed(); - _positionHandler.moveLiquidity(1126936726725513634974948946146229558794440522269778954941252072750, 28213197928202789385986111147974297715344406983, 0, 1078163238702153671724735140934660154334823619509725521693, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _positionHandler.memorializePositions(218844288525098671251665, 1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _positionHandler.burn(7059, 6750, 15855, 2093); - _positionHandler.redeemPositions(18729, 617, 21015, 14643); - _positionHandler.moveLiquidity(558, 0, 11493693556659833093547598989650493235947229407, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 21934937701560087003712); - _positionHandler.mint(1135715274316739321105, 23206); - _positionHandler.redeemPositions(15334, 3730, 31354931781638678607228669297131712859107492772550336241160036866987736981860, 2012); + _erc20positionHandler.burn(2361, 11336, 3859341707, 3646975496); + _erc20positionHandler.mint(68692219213121667537675943993034658256534085966823702, 312562089476538195); + _erc20positionHandler.redeemPositions(14346285029390138384631699352851716037838873523252820863546, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 156099301165664793782770725300034911992745565612292730719535759193816917); + _erc20positionHandler.failed(); + _erc20positionHandler.moveLiquidity(3124, 4851, 22482, 489, 12560); + _erc20positionHandler.failed(); + _erc20positionHandler.failed(); + _erc20positionHandler.redeemPositions(12847, 1716, 21792638192227207103739660380579104546232133259664619746653999669489792464176, 6416); + _erc20positionHandler.failed(); + _erc20positionHandler.mint(1, 1); + _erc20positionHandler.burn(429855229349693967633032639264591, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 16061636408720604028163146864844242179959313271462038759); + _erc20positionHandler.memorializePositions(1000000000000000000000000000, 2339, 9277, 2979); + _erc20positionHandler.failed(); + _erc20positionHandler.moveLiquidity(1126936726725513634974948946146229558794440522269778954941252072750, 28213197928202789385986111147974297715344406983, 0, 1078163238702153671724735140934660154334823619509725521693, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc20positionHandler.memorializePositions(218844288525098671251665, 1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _erc20positionHandler.burn(7059, 6750, 15855, 2093); + _erc20positionHandler.redeemPositions(18729, 617, 21015, 14643); + _erc20positionHandler.moveLiquidity(558, 0, 11493693556659833093547598989650493235947229407, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 21934937701560087003712); + _erc20positionHandler.mint(1135715274316739321105, 23206); + _erc20positionHandler.redeemPositions(15334, 3730, 31354931781638678607228669297131712859107492772550336241160036866987736981860, 2012); invariant_positions_PM1_PM2_PM3(); } @@ -62,63 +62,63 @@ contract RegressionPositionManager is PositionsInvariants { // assertion check on depositTime -> positionManager takes on larger of the two depositTime's (it's current DT and the incoming pos DT) function test_regression_position_assertions() external { - _positionHandler.redeemPositions(14305804179334726329087114711985529806684597589133, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _positionHandler.redeemPositions(15796477295184955704374920720797, 8371624407570958028199016842329852681, 415665569658864472013466984364553963913525434423794529513837676955108, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _positionHandler.burn(1, 0, 21220, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _positionHandler.redeemPositions(23121, 7032, 1209600, 56750200883517406918163409362901600125139979314138135292026435586444244246336); - _positionHandler.mint(17499, 10155); - _positionHandler.moveLiquidity(4204702690764076468, 49830487004238111081, 3, 8687554674969877, 34664948256017662264545053667706057584168120838401342); - _positionHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25655664119351, 378440596); - _positionHandler.burn(9170, 9504, 11036, 7293); - _positionHandler.memorializePositions(51818345872077820903041, 8835932826797125445564909432711163860901660866650218491158279446532175, 0, 43692); - _positionHandler.moveLiquidity(3233, 18341, 1300, 20191, 9673); + _erc20positionHandler.redeemPositions(14305804179334726329087114711985529806684597589133, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc20positionHandler.redeemPositions(15796477295184955704374920720797, 8371624407570958028199016842329852681, 415665569658864472013466984364553963913525434423794529513837676955108, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _erc20positionHandler.burn(1, 0, 21220, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc20positionHandler.redeemPositions(23121, 7032, 1209600, 56750200883517406918163409362901600125139979314138135292026435586444244246336); + _erc20positionHandler.mint(17499, 10155); + _erc20positionHandler.moveLiquidity(4204702690764076468, 49830487004238111081, 3, 8687554674969877, 34664948256017662264545053667706057584168120838401342); + _erc20positionHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25655664119351, 378440596); + _erc20positionHandler.burn(9170, 9504, 11036, 7293); + _erc20positionHandler.memorializePositions(51818345872077820903041, 8835932826797125445564909432711163860901660866650218491158279446532175, 0, 43692); + _erc20positionHandler.moveLiquidity(3233, 18341, 1300, 20191, 9673); invariant_positions_PM1_PM2_PM3(); } function test_regression_position_PM2_1() external { - _positionHandler.mint(13840, 6533); - _positionHandler.redeemPositions(20893347623242005284621573233176425472191492931621662294445581855285746938414, 4668, 249, 3313); - _positionHandler.burn(106160155011218672810293641622355669764959155203, 5522, 6204, 13310117884160603562225350139269278401977957428370674638691902160380855891484); - _positionHandler.mint(9971, 18762); - _positionHandler.moveLiquidity(4746, 45809833274545460487123239222682366952882889382523246407515296007456152700521, 14885, 14435506720187687976692190077864919062649980910355626804100643005278456306280, 569); - _positionHandler.burn(5618, 3294, 1912023601, 2562); - _positionHandler.redeemPositions(19238, 9370, 18471734244850835106, 3079); - _positionHandler.memorializePositions(840358, 614555546558083013200530954309972982184, 3, 3); - _positionHandler.mint(1336497562, 1); - _positionHandler.moveLiquidity(2, 17729644, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1780470449382083675, 4500661183205373); + _erc20positionHandler.mint(13840, 6533); + _erc20positionHandler.redeemPositions(20893347623242005284621573233176425472191492931621662294445581855285746938414, 4668, 249, 3313); + _erc20positionHandler.burn(106160155011218672810293641622355669764959155203, 5522, 6204, 13310117884160603562225350139269278401977957428370674638691902160380855891484); + _erc20positionHandler.mint(9971, 18762); + _erc20positionHandler.moveLiquidity(4746, 45809833274545460487123239222682366952882889382523246407515296007456152700521, 14885, 14435506720187687976692190077864919062649980910355626804100643005278456306280, 569); + _erc20positionHandler.burn(5618, 3294, 1912023601, 2562); + _erc20positionHandler.redeemPositions(19238, 9370, 18471734244850835106, 3079); + _erc20positionHandler.memorializePositions(840358, 614555546558083013200530954309972982184, 3, 3); + _erc20positionHandler.mint(1336497562, 1); + _erc20positionHandler.moveLiquidity(2, 17729644, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1780470449382083675, 4500661183205373); invariant_positions_PM1_PM2_PM3(); } function test_regression_PM2_2() external { - _positionHandler.redeemPositions(3025, 6080, 5086, 69064799185578049928162507577850320714069641703745944312650055827195794732674); - _positionHandler.memorializePositions(83432655750528826189938123470649849289913398, 47342, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1914359238258985260305115291516); - _positionHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _positionHandler.redeemPositions(0, 251587735425228951994560583717, 0, 814796085823627054357); - _positionHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639934, 94458646023247094980210508097430099597791255713941721593); - _positionHandler.burn(2, 128812301633031168244819496636531096630, 54560285418771898578153, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _positionHandler.moveLiquidity(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1, 16482458); - _positionHandler.burn(2694, 1221913943207264759036595977299, 19113, 24481779477797754811799548851326479703104086113172195246494668587412015886643); - _positionHandler.burn(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _positionHandler.redeemPositions(0, 7413805626748343619920391043, 150386923782054503303407770601037610373899200732399952156206643020965362, 120900543111660751); - _positionHandler.redeemPositions(30227346354289516712800253757043461339716641700294196, 674502096198391694316949722119995662541, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1132758169212807134889911836402520); - _positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); - _positionHandler.burn(313828860859517646886425614636, 208145610429269588268786717871941251049199228446877892696424877907568733235, 455942413, 2); - _positionHandler.burn(19986504, 2423591226355826423555756030845668, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _positionHandler.burn(1, 465288888898469935211527628026186267178198412320, 3, 482209135685696192055); - _positionHandler.mint(119225955014423, 600936253367888098311270698540073182733605077834901); - _positionHandler.burn(1837, 3758, 4879, 13114); - _positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 725406937207957973195478707487444742436477165056); - _positionHandler.moveLiquidity(4658405713153015933137719, 838417, 59, 25831175927826091855814245548488793681463667893532830343974308118799, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _positionHandler.memorializePositions(12016, 6319, 6900, 8690); + _erc20positionHandler.redeemPositions(3025, 6080, 5086, 69064799185578049928162507577850320714069641703745944312650055827195794732674); + _erc20positionHandler.memorializePositions(83432655750528826189938123470649849289913398, 47342, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1914359238258985260305115291516); + _erc20positionHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc20positionHandler.redeemPositions(0, 251587735425228951994560583717, 0, 814796085823627054357); + _erc20positionHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639934, 94458646023247094980210508097430099597791255713941721593); + _erc20positionHandler.burn(2, 128812301633031168244819496636531096630, 54560285418771898578153, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc20positionHandler.moveLiquidity(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1, 16482458); + _erc20positionHandler.burn(2694, 1221913943207264759036595977299, 19113, 24481779477797754811799548851326479703104086113172195246494668587412015886643); + _erc20positionHandler.burn(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc20positionHandler.redeemPositions(0, 7413805626748343619920391043, 150386923782054503303407770601037610373899200732399952156206643020965362, 120900543111660751); + _erc20positionHandler.redeemPositions(30227346354289516712800253757043461339716641700294196, 674502096198391694316949722119995662541, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1132758169212807134889911836402520); + _erc20positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _erc20positionHandler.burn(313828860859517646886425614636, 208145610429269588268786717871941251049199228446877892696424877907568733235, 455942413, 2); + _erc20positionHandler.burn(19986504, 2423591226355826423555756030845668, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc20positionHandler.burn(1, 465288888898469935211527628026186267178198412320, 3, 482209135685696192055); + _erc20positionHandler.mint(119225955014423, 600936253367888098311270698540073182733605077834901); + _erc20positionHandler.burn(1837, 3758, 4879, 13114); + _erc20positionHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 725406937207957973195478707487444742436477165056); + _erc20positionHandler.moveLiquidity(4658405713153015933137719, 838417, 59, 25831175927826091855814245548488793681463667893532830343974308118799, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _erc20positionHandler.memorializePositions(12016, 6319, 6900, 8690); invariant_positions_PM1_PM2_PM3(); } function test_regression_position_manager() external { - _positionHandler.redeemPositions(79335468733065507138817566659594782917024872257218805, 1889027018179489664211573893, 43578107449528230070726540147644518395094194018887636259089111851, 0); + _erc20positionHandler.redeemPositions(79335468733065507138817566659594782917024872257218805, 1889027018179489664211573893, 43578107449528230070726540147644518395094194018887636259089111851, 0); } } diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/Positions/CodearenaReports.t.sol index b88e7f042..a6146bbbe 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/Positions/CodearenaReports.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.18; -import { PositionManagerERC20PoolHelperContract } from '../PositionManager.t.sol'; +import { PositionManagerERC20PoolHelperContract } from './PositionManager.t.sol'; import "@std/console.sol"; diff --git a/tests/forge/unit/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol similarity index 99% rename from tests/forge/unit/PositionManager.t.sol rename to tests/forge/unit/Positions/PositionManager.t.sol index 7beef940f..6591e0e68 100644 --- a/tests/forge/unit/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -3,8 +3,8 @@ pragma solidity 0.8.18; import { Base64 } from '@base64-sol/base64.sol'; -import { ERC20HelperContract } from '../unit/ERC20Pool/ERC20DSTestPlus.sol'; -import { ERC721HelperContract } from '../unit/ERC721Pool/ERC721DSTestPlus.sol'; +import { ERC20HelperContract } from '../ERC20Pool/ERC20DSTestPlus.sol'; +import { ERC721HelperContract } from '../ERC721Pool/ERC721DSTestPlus.sol'; import { IPermit } from 'src/base/PermitERC721.sol'; @@ -15,8 +15,8 @@ import 'src/libraries/helpers/PoolHelper.sol'; import 'src/interfaces/pool/commons/IPoolErrors.sol'; -import '../utils/ContractNFTRecipient.sol'; -import '../utils/ContractNFTSpender.sol'; +import '../../utils/ContractNFTRecipient.sol'; +import '../../utils/ContractNFTSpender.sol'; abstract contract PositionManagerERC20PoolHelperContract is ERC20HelperContract { From 3dee471999a60539dcacc7181b95194eec571820 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Fri, 16 Jun 2023 14:22:50 +0530 Subject: [PATCH 07/32] Invariants Improvements: Add `LUPBelowHTP` revert in `_ensurePositionManagerError` and renamed Position and Rewards regression contract (#896) * Add LUPBelowHTP revert in _ensurePositionManagerError * Rename Position and Rewards regression contract to avoid regression getting run in invariants and unit test --- .../handlers/unbounded/UnboundedBasePositionHandler.sol | 3 ++- ...sitionManager.t.sol => RegressionTestPositionManager.t.sol} | 2 +- ...RewardsManager.t.sol => RegressionTestRewardsManager.t.sol} | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) rename tests/forge/regression/PositionAndRewards/{RegressionPositionManager.t.sol => RegressionTestPositionManager.t.sol} (99%) rename tests/forge/regression/PositionAndRewards/{RegressionRewardsManager.t.sol => RegressionTestRewardsManager.t.sol} (99%) diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol index 55fe0d4c5..ed628f95f 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -82,7 +82,8 @@ abstract contract UnboundedBasePositionHandler is Test { err == keccak256(abi.encodeWithSignature("MoveToSameIndex()")) || err == keccak256(abi.encodeWithSignature("RemoveDepositLockedByAuctionDebt()")) || err == keccak256(abi.encodeWithSignature("DustAmountNotExceeded()")) || - err == keccak256(abi.encodeWithSignature("InvalidIndex()")), + err == keccak256(abi.encodeWithSignature("InvalidIndex()")) || + err == keccak256(abi.encodeWithSignature("LUPBelowHTP()")), "Unexpected revert error" ); } diff --git a/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol similarity index 99% rename from tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol rename to tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol index 02586f151..0e8cb9d97 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionPositionManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.18; import { ERC20PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol"; -contract RegressionPositionManager is ERC20PoolPositionsInvariants { +contract RegressionTestPositionManager is ERC20PoolPositionsInvariants { function setUp() public override { super.setUp(); diff --git a/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol similarity index 99% rename from tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol rename to tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol index 4117f7d28..97b5371f9 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionRewardsManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol @@ -6,7 +6,7 @@ import { PoolInfoUtils } from 'src/PoolInfoUtils.sol'; import '@std/console.sol'; -contract RegressionRewardsManager is RewardsInvariants { +contract RegressionTestRewardsManager is RewardsInvariants { function setUp() public override { super.setUp(); From 8cc084c5e7ad52d3b9d0db0422ef155f8c5b2e05 Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Fri, 16 Jun 2023 13:47:16 -0400 Subject: [PATCH 08/32] Invariants improvement: add remaining rewards invariants (#880) * initial draft * got initial scaffolding running * included Matts invaraints * added PM1 and PM5 * Reward invariants merged (#773) * changes needed for contract verification (#764) * changes needed for contract verification * gotcha * Make NFT tokens claimable after `take`, `bucketTake`, `settle` actions (#763) * Add test failure * When ERC721.bucketTake always rebalance token ids from borrower to pool claimable array * Consistent take with bucketTake, always rebalance tokens * Check invariants in regression test * Always rebalance tokens on settle (settle could enter with 0 collateral but still with bad debt) * Changed epsilon from 1e16 to 1e17 in F1 and F2 invariants (#765) * Add variable token precision for ERC721Pool invariants (#755) * Add multiple precision of quote token in erc721Pool invariants * Add shebang and set -e option * Invariant framework improvements (#769) * Update forge library, set default env vars using envOr instead reading from env file * Remove InvariantsTestHelpers contract and move invariants helper functions to BaseInvariants * env cleanup for invariants * Update invariant testing scripts * Add skipTime in merge collateral handler * Add fuzzed time skip between kick and take/bucketTake --------- Co-authored-by: grandizzy * Removing brownie TODOs as these tests won't be further expanded (#767) * ERC20 R1_R2_R3_R4_R5_R6_R7_R8 invariant failure (#771) * Add failing test * Change cutoff for deminimus check to 1 LP in a bucket for exchange rate diffs --------- Co-authored-by: mwc * Erc721 CT2 invariant failure (#770) * Reproduce CT2 invariant failure * Add collateral that could be compensated in bucket 7388 when auction settled * Make sure MAX bucket not accounted twice. Fix test-regression target * Fix bucketTake invariant logic in place instead in CT2 invariant. Added regression test comments. * Fix CI, lock foundry version until resolution for https://github.com/foundry-rs/foundry/issues/4835 --------- Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: mwc * working through PM3 * wrapped position calls * made getPoolAccumulators a free function & cleaned up logging * included free function * increased logging robustness * working through adding positions without passing positions to baseclass * cleanup * Fix position manager invariant testing setup * Fix EVM reverts * Fix some assertions in moveliquidity handler * Move post action checks in try to run only when transaction is successful * position man initially working * removed redundant invariant check * got rewards structure running * Update Rewards Manager handler structure * Remove redundancy in Rewards Handler * regression PM1 failing * Fix invariant PM1 * Fix invariant RW1 * Add remaining rewards manager handlers * Add drawDebt before kick reserve auction to generate some reserves * Fix drawDebt evm revert in preUnstake * handled broken rewardsCap * Fixed evm revert and PM1 invariant * Add failing regression test * Update make commands for Position and Rewards Manager * added check in moveLiquidity that ensure QT amount for actor doesn't change * cleaned up * revised invariants per Prototech labs suggestion * cleanup invar * added update interest to fix QT diff on moveLiquidity * working through test failure * resolved fee on move liquidity * working through rewards * initial commit * cleanup * low haning fruit feedback * fixed takeReserves in rewards invariant * added NFT position tracking for rewards manager * cleanup * Add comments for failing regression test * responded to Mikes feedback * EOF line addition * added * cleaned up requires, formally added more PositionManager invar * Quote to lps inc on move (#877) * cleaned up requires, formally added more PositionManager invar * cleaned up requires, formally added more PositionManager invar * added logs * works with diff * cleanup --------- Co-authored-by: Ian Harvey * cleaned up rewards and position naming * responded to class naming * cleaned up spaced * working through rewards, tests passing * working through invariants * rewards working cleanly * clean up before looking into RW5 * finnished adding RW6 * cleanup * comment cleanup * updated with emergency unstake * cleaned up error handling --------- Co-authored-by: Ian Harvey Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com> Co-authored-by: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Co-authored-by: Prateek Gupta Co-authored-by: mwc Co-authored-by: prateek105 --- tests/INVARIANTS.md | 12 +- .../RewardsInvariants.t.sol | 47 +++-- .../handlers/RewardsHandler.sol | 15 ++ .../UnboundedBasePositionHandler.sol | 9 +- .../UnboundedERC20PoolPositionsHandler.sol | 3 +- .../unbounded/UnboundedRewardsHandler.sol | 193 ++++++++++++++++-- .../base/handlers/unbounded/BaseHandler.sol | 8 + .../unbounded/UnboundedReservePoolHandler.sol | 4 +- .../IPositionsAndRewardsHandler.sol | 4 +- .../RegressionTestRewardsManager.t.sol | 68 +++++- 10 files changed, 315 insertions(+), 48 deletions(-) diff --git a/tests/INVARIANTS.md b/tests/INVARIANTS.md index 1832ed1ab..8127ff05f 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -83,15 +83,15 @@ - **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()`) -- **RW5**: After unstaking or claiming rewards, `isEpochClaimed` should be equal to `true`, `stakeInfo_.lastClaimedEpoch` be equal to the current epoch and `rewardsClaimed` should be incremented by the claimed amount. -- **RW6**: Each time the bucket rate is updated the `updateRewardsClaimed` accumulator should be properly updated -- **RW7**: 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()`. -- **RW8**: After unstaking, stakeInfo's tokenId mapping should be deleted and all corrosponding values should therefore be zero'd out (`StakeInfo.ajnaPool`, `StakeInfo.lastClaimedEpoch`, `StakeInfo.owner`, `StakeInfo.stakingEpoch`, `StakeInfo.snapshots`) -- **RW9**: Can't claim rewards for an end epoch twice +- **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 +- **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 - **PM3**: Position deposit time (`depositTime`) tracked by tokenId in PositionManager (`positions[tokenId][index]`) should always be of equal or lesser value than the PositionManager's LP at that index in the pool contract. - **PM4**: mint should populate `poolKey[tokenId]`, `positionIndexes` should be empty and the owner of the NFT should be the caller. - **PM5**: burn should reset `poolKey[tokenId]`, `positionIndexes` should be empty and the owner of the NFT should be the zero address. diff --git a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol index d9c37c8d5..e9078afa8 100644 --- a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol +++ b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol @@ -46,24 +46,32 @@ contract RewardsInvariants is ERC20PoolPositionsInvariants { function invariant_rewards_RW1_RW2() public useCurrentTimestamp { - // get current epoch (is incremented every kickReserve() call) - uint256 curEpoch = _pool.currentBurnEpoch(); + uint256 epoch; // incremented every `kickReserve()` call - // get rewards that have been claimed - uint256 claimedRewards = IPositionsAndRewardsHandler(_handler).totalRewardPerEpoch(curEpoch); + while (epoch <= _pool.currentBurnEpoch()) { + // get staking rewards that have been claimed + uint256 rewardsClaimed = IPositionsAndRewardsHandler(_handler).rewardsClaimedPerEpoch(epoch); - // total ajna burned by the pool over the epoch - (, uint256 totalBurnedInPeriod,) = _getEpochInfo(address(_pool), curEpoch); + // get updating rewards that have been claimed + uint256 updateRewardsClaimed = IPositionsAndRewardsHandler(_handler).updateRewardsClaimedPerEpoch(epoch); - // stake rewards cap is 80% of total burned - uint256 stakeRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.8 * 1e18); - // check claimed rewards < rewards cap - if (stakeRewardsCap != 0) require(claimedRewards < stakeRewardsCap, "Rewards invariant RW1"); + // total ajna burned by the pool over the epoch + (, uint256 totalBurnedInPeriod,) = _getEpochInfo(address(_pool), epoch); - // update rewards cap is 10% of total burned - uint256 updateRewardsCap = Maths.wmul(totalBurnedInPeriod, 0.1 * 1e18); - // check claimed rewards < rewards cap - if (updateRewardsCap != 0) require(claimedRewards < updateRewardsCap, "Rewards invariant RW2"); + // 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 { @@ -71,12 +79,21 @@ contract RewardsInvariants is ERC20PoolPositionsInvariants { console.log("--Positions--------"); 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.stake") + + IBaseHandler(_handler).numberOfCalls("BRewardsHandler.updateExchangeRate") + + IBaseHandler(_handler).numberOfCalls("BRewardsHandler.claimRewards") + + IBaseHandler(_handler).numberOfCalls("BRewardsHandler.emergencyUnstake") ); } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol index cbffaab08..b824f6be9 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol @@ -69,6 +69,21 @@ contract RewardsHandler is UnboundedRewardsHandler, BaseERC20PoolPositionHandler _unstake(tokenId); } + function emergencyUnstake( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.emergencyUnstake']++; + + // Pre action + uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); + + // Action phase + _emergencyUnstake(tokenId); + } + function updateExchangeRate( uint256 actorIndex_, uint256 bucketIndex_, diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol index ed628f95f..093b902e1 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -44,9 +44,12 @@ abstract contract UnboundedBasePositionHandler is Test { mapping(uint256 => uint256) internal bucketIndexToDepositTime; // Rewards invariant test state // - mapping(uint256 => uint256) public totalRewardPerEpoch; // total rewards per epoch - uint256 public totalStakerRewPerEpoch; // amount of reserve decrease - uint256 public totalUpdaterRewPerEpoch; // amount of reserve increase + mapping(uint256 => uint256) public rewardsClaimedPerEpoch; // staking rewards per epoch + mapping(uint256 => uint256) public updateRewardsClaimedPerEpoch; // updating rewards per epoch + + mapping(uint256 => uint256) public rewardsAlreadyClaimed; // tracks rewards already claimed + uint256 public totalStakerRewPerEpoch; // amount of reserve decrease + uint256 public totalUpdaterRewPerEpoch; // amount of reserve increase using EnumerableSet for EnumerableSet.UintSet; diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol index e61f796bc..e18c751c1 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol @@ -287,8 +287,6 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan } } - - function _burn( uint256 tokenId_ ) internal { @@ -311,3 +309,4 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan } } } + diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol index 9c50a3dbc..6bd8eb746 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol @@ -2,7 +2,6 @@ pragma solidity 0.8.18; -import '@std/console.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; @@ -13,7 +12,6 @@ import { UnboundedERC20PoolPositionsHandler } from './UnboundedERC20PoolPosition import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; - /** * @dev this contract manages multiple lenders * @dev methods in this contract are called in random order @@ -28,11 +26,15 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler ) 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_); + require(_positionManager.ownerOf(tokenId_) == address(_rewardsManager), "RW5: owner should be rewardsManager"); + } catch (bytes memory err) { _ensureRewardsManagerError(err); } @@ -43,23 +45,117 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBRewardsHandler.unstake']++; - uint256 actorBalanceBeforeClaim = _quote.balanceOf(_actor); + // track balances + uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); + uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); - try _rewardsManager.unstake(tokenId_) { + (,,uint256 preActionLastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - // check token was transferred from rewards contract to actor - require(_positionManager.ownerOf(tokenId_) == _actor, "actor should receive ownership after unstaking"); + // loop over all epochs that are going to be + uint256 totalRewardsEarnedPreAction; + for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { + + // for epochs already claimed by the staker, `rewardsClaimed()` should go unchanged + if (_rewardsManager.isEpochClaimed(tokenId_, epoch)) { + rewardsAlreadyClaimed[epoch] = _rewardsManager.rewardsClaimed(epoch); + } + + // total the rewards earned pre action + totalRewardsEarnedPreAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); + } + + try _rewardsManager.unstake(tokenId_) { // actor should receive tokenId, positionManager loses ownership tokenIdsByActor[address(_actor)].add(tokenId_); tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); - // add to total rewards if actor received reward - if ((_quote.balanceOf(_actor) - actorBalanceBeforeClaim) != 0) { - (,,uint256 lastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); - totalRewardPerEpoch[lastClaimedEpoch] += _quote.balanceOf(_actor) - actorBalanceBeforeClaim; + // 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 (rewardsAlreadyClaimed[epoch] != 0) { + require(rewardsAlreadyClaimed[epoch] == _rewardsManager.rewardsClaimed(epoch), + "RW10: staker has claimed rewards from the same epoch twice"); + } + + // total rewards earned across all actors in epoch post action + totalRewardsEarnedPostAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); + + // reset staking and updating rewards earned in epoch + rewardsClaimedPerEpoch[epoch] = _rewardsManager.rewardsClaimed(epoch); + updateRewardsClaimedPerEpoch[epoch] = _rewardsManager.updateRewardsClaimed(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.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); + } + + try _rewardsManager.emergencyUnstake(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.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); + } + + // actor should receive tokenId, positionManager loses ownership + tokenIdsByActor[address(_actor)].add(tokenId_); + tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); + + 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); } @@ -68,17 +164,25 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler function _updateExchangeRate( uint256[] memory indexes_ ) internal { - numberOfCalls['UBRewardsHandler.exchangeRate']++; + numberOfCalls['UBRewardsHandler.updateExchangeRate']++; - uint256 actorBalanceBeforeClaim = _quote.balanceOf(_actor); + // track balances + uint256 actorAjnaBalanceBeforeClaim = _ajna.balanceOf(_actor); + uint256 contractAjnaBalanceBeforeClaim = _ajna.balanceOf(address(_rewardsManager)); + + // total the rewards earned pre action + uint256 totalRewardsEarnedPreAction = _rewardsManager.updateRewardsClaimed(_pool.currentBurnEpoch()); try _rewardsManager.updateBucketExchangeRatesAndClaim(address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), indexes_) { - // add to total rewards if actor received reward - if ((_quote.balanceOf(_actor) - actorBalanceBeforeClaim) != 0) { - uint256 curBurnEpoch = _pool.currentBurnEpoch(); - totalRewardPerEpoch[curBurnEpoch] += _quote.balanceOf(_actor) - actorBalanceBeforeClaim; - } + // balance changes + uint256 actorAjnaGain = _ajna.balanceOf(_actor) - actorAjnaBalanceBeforeClaim; + + require(actorAjnaGain <= _rewardsManager.updateRewardsClaimed(_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); @@ -91,7 +195,62 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler ) 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; + for (uint256 epoch = preActionLastClaimedEpoch; epoch <= _pool.currentBurnEpoch(); epoch++) { + + // track epochs that have already been claimed + if (_rewardsManager.isEpochClaimed(tokenId_, epoch)) { + rewardsAlreadyClaimed[epoch] = _rewardsManager.rewardsClaimed(epoch); + } + + // total staking rewards earned across all actors in epoch pre action + totalRewardsEarnedPreAction += _rewardsManager.rewardsClaimed(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 (rewardsAlreadyClaimed[epoch] != 0) { + require(rewardsAlreadyClaimed[epoch] == _rewardsManager.rewardsClaimed(epoch), + "RW10: staker has claimed rewards from the same epoch twice"); + } + + // total staking rewards earned across all actors in epoch post action + totalRewardsEarnedPostAction += _rewardsManager.rewardsClaimed(epoch); + + // reset staking rewards earned in epoch + rewardsClaimedPerEpoch[epoch] = _rewardsManager.rewardsClaimed(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); } diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index fe9c82be5..57d2f0b3c 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -265,6 +265,14 @@ abstract contract BaseHandler is Test { _quote.approve(address(_pool), _quote.balanceOf(actor_)); } + function _ensureAjnaAmount(address actor_, uint256 amount_) internal { + uint256 actorBalance = _ajna.balanceOf(actor_); + if (amount_> actorBalance) { + _ajna.mint(actor_, amount_ - actorBalance); + } + _ajna.approve(address(_pool), _ajna.balanceOf(actor_)); + } + function _updatePoolState() internal { _pool.updateInterest(); } diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol index 114160bd8..c6493c439 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedReservePoolHandler.sol @@ -38,8 +38,8 @@ abstract contract UnboundedReservePoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBReserveHandler.takeReserves']++; - deal(address(_ajna), _actor, type(uint256).max); - IERC20(address(_ajna)).approve(address(_pool), type(uint256).max); + // ensure actor always has the amount to take reserves + _ensureAjnaAmount(_actor, 1e45); (, uint256 claimableReservesBeforeAction, ,) = _pool.reservesInfo(); diff --git a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol index 44980f0ed..a9ea056e8 100644 --- a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol +++ b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol @@ -4,7 +4,9 @@ pragma solidity 0.8.18; interface IPositionsAndRewardsHandler { - function totalRewardPerEpoch(uint256) external view returns(uint256); + function rewardsClaimedPerEpoch(uint256) external view returns(uint256); + function updateRewardsClaimedPerEpoch(uint256) external view returns(uint256); + function epochToRewardsSnapshot(uint256) external view returns(uint256); function getBucketIndexesWithPosition() external view returns(uint256[] memory); function getTokenIdsByBucketIndex(uint256) external view returns(uint256[] memory); diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol index 97b5371f9..523753786 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol @@ -280,7 +280,30 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2652132885321220255, 2, 1557926034); } - function test_regression_PM6_failure() external { + function test_regression_rewards_revert() external { + _rewardsHandler.takeReserves(1, 176264227116073539466710292640534, 0); + _rewardsHandler.drawDebt(1, 57859908193408492548049732123715354988106416421644089, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.addQuoteToken(1807664453705980418, 3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.drawDebt(14810, 12501, 11607381230457826577033271); + _rewardsHandler.kickAuction(126, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 296936791599072888382604547047579799590572591); + _rewardsHandler.bucketTake(2084, 265280, false, 621014983179582, 6560); + _rewardsHandler.redeemPositions(7465, 451605496, 3970, 1512); + _rewardsHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1751716589805844630991620468, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.kickReserveAuction(11967, 1005568066651507152); + _rewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 2724518779079179784049138199493777186815675, 1874); + _rewardsHandler.addQuoteToken(3981, 1690101581, 97503618599900271359071534105156178950663445728441824941278920981153136631167, 999999999999999999999989741489665556227804536); + _rewardsHandler.bucketTake(247, 1291084637306870208638, false, 14752, 753); + _rewardsHandler.updateExchangeRate(3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.pullCollateral(1266635973860390773360, 1, 3); + _rewardsHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.takeAuction(2214845414466110799205272778680836428372471699, 49004997820594553259859787080944156522906733, 3, 271825241); + _rewardsHandler.repayDebt(221806598861099254438373725802873431978648517331723635037739192841369, 11212235606391953616223043585188034400902381408644500974587575, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _rewardsHandler.unstake(230323675018036494562757, 21630132699099546696940190603184460107953215649, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + } + + // 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 { _rewardsHandler.bucketTake(29456557203126366201854827466482433206831494327361303, 19307664601998129837361, false, 3492651658979151995106448, 0); _rewardsHandler.kickWithDeposit(4429580015302257459201655018526, 2770867242698718418626, 9388); _rewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); @@ -291,7 +314,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { 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_unexpected_revert() external { + function test_regression_failure_rewards_error_expect() external { _rewardsHandler.redeemPositions(696309158766729979589534440166220067073887038152281856742599135926157312, 1870474563221356095022900189266, 18339, 1788135699833095102184812046279); _rewardsHandler.kickReserveAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _rewardsHandler.memorializePositions(3671371551743995865, 99428, 1769100398, 7346319752739159); @@ -304,4 +327,45 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.updateExchangeRate(3, 4485331781540521052468660062240, 3); _rewardsHandler.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 { + _rewardsHandler.transferLps(13692, 15203, 2000001367681895243673966806260, 13770006083256457112227, 1672449141); + _rewardsHandler.takeReserves(4947313423932616986372909633726, 3107772, 18585868099953215630514); + _rewardsHandler.bucketTake(3, 3, true, 5727003712726959800, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _rewardsHandler.moveLiquidity(3157314460140, 999999999964761098816798416093, 100749181527550271579655357, 73559801971876655830284650454672056023206176402691276845053940498149797, 2453039451665641392603351405279); + _rewardsHandler.pullCollateral(2227999026154255580938434049821, 1929, 21209080205145509799924600234705734221480599); + _rewardsHandler.unstake(77763028316274741760991770148, 889544954655483052642168760960, 1000073821603105106, 14781730360850539958536528862089); + _rewardsHandler.memorializePositions(3, 2, 357097079890085816811291167102020270214, 1); + _rewardsHandler.takeAuction(9839460449437189937506383151267733565283, 75862151750582034326928310158878873987779724, 442512581894915658301040013323770372275116408434438200991, 4465076566725287152347371577222429); + _rewardsHandler.takeReserves(18196, 115792089237316195423570985008687907853269984665640564039457459248091501068020, 7726328457662922431145272); + _rewardsHandler.updateExchangeRate(934079800963406838548241273326154438, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 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 { + _rewardsHandler.bucketTake(4645898402004950106563597036, 1, true, 3, 2); + _rewardsHandler.kickReserveAuction(3, 144); + _rewardsHandler.claimRewards(44705418907931161819765043998797583827, 151688058596538037321153972615358552, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5828173); + _rewardsHandler.kickWithDeposit(1, 0, 58846077910505664190879804); + _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _rewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.moveLiquidity(7886, 1223, 249959471556478, 8036, 957); + _rewardsHandler.drawDebt(3724423259505818275008000000000, 5967, 5194); + _rewardsHandler.claimRewards(1, 0, 0, 330972817125); + } + + // 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 { + _rewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 87088279133912395360162508437887139725077665220, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 564626589538129677125005778268696423, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _rewardsHandler.takeReserves(11684, 194771708143610511040376640, 2726053605342047396811); + _rewardsHandler.repayDebt(3262, 43081368297850871705277077223467592454899175043611071, 10274); + _rewardsHandler.redeemPositions(127647, 176264227116073539466710292640534, 3642, 6424); + _rewardsHandler.unstake(15694742330810166545782643648487796809086809379390, 607818605291333492717424880577475155800497188006507929455743410345480887752, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + + invariant_rewards_RW1_RW2(); + } } From 5693050d595bd73ae33c09337e818106f1525f4b Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Sun, 18 Jun 2023 09:16:14 +0300 Subject: [PATCH 09/32] Bug fix: `kickWithDeposit` likely push `LUP` below `HTP` affecting healthy loans (#894) * Initial proposal: remove internal accounting * Revert if bucket price is lower than current LUP, fix tests * Reorg code and revert, fix tests * Redo QT3 - bond escrowed are always guaranteed * Recalculate LUP after kick actions, with additional debt from kick penalty Fix more tests * Fix commented test * Update kickWithDeposit Natspec, remove obsolete event * Consistent way to return lup and pool debt * Rename kickWithDeposit to lenderKickAuction * Rename lenderKickAuction to lenderKick * Log lender kick in invariants * Fix compile errors after merge --- docs/Functions.md | 89 ++- src/base/Pool.sol | 8 +- .../pool/commons/IPoolInternals.sol | 3 +- .../pool/commons/IPoolKickerActions.sol | 4 +- src/libraries/external/KickerActions.sol | 146 +--- tests/INVARIANTS.md | 2 +- .../handlers/PanicExitERC20PoolHandler.sol | 6 +- .../handlers/PanicExitERC721PoolHandler.sol | 6 +- .../invariants/base/BasicInvariants.t.sol | 31 +- .../base/LiquidationInvariants.t.sol | 8 +- .../invariants/base/ReserveInvariants.t.sol | 8 +- .../base/handlers/LiquidationPoolHandler.sol | 6 +- .../base/handlers/unbounded/BaseHandler.sol | 10 +- .../UnboundedLiquidationPoolHandler.sol | 8 +- .../RegressionTestLiquidationERC20Pool.t.sol | 204 +++--- .../ERC20Pool/RegressionTestRWERC20Pool.t.sol | 12 +- .../RegressionTestReservesERC20Pool.t.sol | 84 +-- .../prototech/PrototechRegression.t.sol | 28 +- .../RegressionTestLiquidationERC721Pool.t.sol | 28 +- .../RegressionTestReservesERC721Pool.t.sol | 178 ++--- .../RegressionTestRewardsManager.t.sol | 16 +- .../unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol | 6 +- ... => ERC20PoolLiquidationsLenderKick.t.sol} | 262 +++---- .../ERC20Pool/ERC20PoolLiquidationsMisc.t.sol | 14 +- .../ERC20PoolLiquidationsScaled.t.sol | 32 +- .../ERC721PoolLiquidationsSettle.t.sol | 52 +- .../ERC721PoolLiquidationsSettleAuction.t.sol | 683 ++++++++---------- tests/forge/utils/DSTestPlus.sol | 25 +- 28 files changed, 892 insertions(+), 1067 deletions(-) rename tests/forge/unit/ERC20Pool/{ERC20PoolLiquidationsKickWithDeposit.t.sol => ERC20PoolLiquidationsLenderKick.t.sol} (85%) diff --git a/docs/Functions.md b/docs/Functions.md index 7eea47cc1..49445287b 100644 --- a/docs/Functions.md +++ b/docs/Functions.md @@ -114,27 +114,27 @@ ### transferLP external libraries call: - - LenderActions.transferLP() + - LPActions.transferLP() write state: - - LenderActions.transferLP(): + - LPActions.transferLP(): - delete allowance mapping - increment new lender.lps accumulator and lender.depositTime state - delete old lender from bucket -> lender mapping reverts on: - - LenderActions.transferLP(): + - LPActions.transferLP(): - invalid index InvalidIndex() - no allowance NoAllowance() emit events: - - LenderActions.transferLP(): + - LPActions.transferLP(): - TransferLP ### kick external libraries call: - PoolCommons.accrueInterest() - - Auctions.kick() + - KickerActions.kick() - PoolCommons.updateInterestRate() write state: @@ -143,7 +143,7 @@ - Deposits.mult() (scale Fenwick tree with new interest accrued): - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - - Auctions.kick(): + - KickerActions.kick(): - _kick(): - _recordAuction(): - borrower -> liquidation mapping update @@ -164,20 +164,20 @@ - pool inflator and inflatorUpdate state reverts on: - - Auctions.kick(): + - KickerActions.kick(): - borrower collateralized BorrowerOk() - auction active AuctionActive() emit events: - - Auctions.kick(): + - KickerActions.kick(): - Kick - PoolCommons.updateInterestRate(): - UpdateInterestRate -### kickWithDeposit +### lenderKick external libraries call: - PoolCommons.accrueInterest() - - Auctions.kickWithDeposit() + - KickerActions.lenderKick() - PoolCommons.updateInterestRate() write state: @@ -186,7 +186,7 @@ - Deposits.mult() (scale Fenwick tree with new interest accrued): - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - - Auctions.kickWithDeposit(): + - KickerActions.lenderKick(): - _kick(): - _recordAuction(): - borrower -> liquidation mapping update @@ -198,10 +198,6 @@ - Loans.remove(): - delete borrower from indices => borrower address mapping - remove loan from loans array - - Deposits.unscaledRemove() (remove amount in Fenwick tree, from index): - - update values array state - - decrement lender.lps accumulator - - decrement bucket.lps accumulator - increment poolBalances.t0DebtInAuction and poolBalances.t0Debt accumulators - _updateInterestState(): - PoolCommons.updateInterestRate(): @@ -210,15 +206,14 @@ - pool inflator and inflatorUpdate state reverts on: - - Auctions.kickWithDeposit(): - - auction active AuctionActive() + - KickerActions.lenderKick(): + - bucket price below current pool LUP PriceBelowLUP() - borrower collateralized BorrowerOk() - insuficient amount InsufficientLiquidity() emit events: - - Auctions.kickWithDeposit(): + - KickerActions.lenderKick(): - Kick - - RemoveQuoteToken - PoolCommons.updateInterestRate(): - UpdateInterestRate @@ -235,10 +230,10 @@ ### kickReserveAuction external libraries call: - - Auctions.kickReserveAuction() + - KickerActions.kickReserveAuction() write state: - - Auctions.kickReserveAuction(): + - KickerActions.kickReserveAuction(): - update reserveAuction.unclaimed accumulator - update reserveAuction.kicked timestamp state - increment latestBurnEpoch counter @@ -246,30 +241,30 @@ reverts on: - 2 weeks not passed ReserveAuctionTooSoon() - - Auctions.kickReserveAuction(): + - KickerActions.kickReserveAuction(): - no reserves to claim NoReserves() emit events: - - Auctions.kickReserveAuction(): + - KickerActions.kickReserveAuction(): - KickReserveAuction ### takeReserves external libraries call: - - Auctions.takeReserves() + - TakerActions.takeReserves() write state: - - Auctions.takeReserves(): + - TakerActions.takeReserves(): - decrement reserveAuction.unclaimed accumulator - increment reserveAuction.totalAjnaBurned accumulator - update burn event totalInterest and totalBurned accumulators reverts on: - - Auctions.takeReserves(): + - TakerActions.takeReserves(): - not kicked or 72 hours didn't pass NoReservesAuction() emit events: - - Auctions.takeReserves(): + - TakerActions.takeReserves(): - ReserveAuction ### stampLoan @@ -387,7 +382,7 @@ - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - BorrowerActions.drawDebt(): - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - _removeAuction(): - decrement kicker locked accumulator, increment kicker claimable accumumlator - decrement auctions count accumulator @@ -417,7 +412,7 @@ emit events: - BorrowerActions.drawDebt(): - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - AuctionNFTSettle or AuctionSettle - DrawDebt - PoolCommons.updateInterestRate(): @@ -436,7 +431,7 @@ - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - BorrowerActions.repayDebt(): - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - _removeAuction(): - decrement kicker locked accumulator, increment kicker claimable accumumlator - decrement auctions count accumulator @@ -466,7 +461,7 @@ emit events: - BorrowerActions.repayDebt(): - - Auctions._settleAuction: + - SettlerActions._settleAuction: - AuctionNFTSettle or AuctionSettle - RepayDebt - PoolCommons.updateInterestRate(): @@ -475,7 +470,7 @@ ### settle external libraries call: - PoolCommons.accrueInterest() - - Auctions.settlePoolDebt() + - SettlerActions.settlePoolDebt() - PoolCommons.updateInterestRate() write state: @@ -484,14 +479,14 @@ - Deposits.mult() (scale Fenwick tree with new interest accrued): - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - - Auctions.settlePoolDebt(): + - SettlerActions.settlePoolDebt(): - Deposits.unscaledRemove() (remove amount in Fenwick tree, from index): - update values array state - Buckets.addCollateral(): - increment bucket.collateral and bucket.lps accumulator - addLenderLP(): - increment lender.lps accumulator and lender.depositTime state - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - _removeAuction(): - decrement kicker locked accumulator, increment kicker claimable accumumlator - decrement auctions count accumulator @@ -508,14 +503,14 @@ - pool inflator and inflatorUpdate state reverts on: - - Auctions.settlePoolDebt(): + - SettlerActions.settlePoolDebt(): - loan not kicked NoAuction() - 72 hours didn't pass and auction still has collateral AuctionNotClearable() emit events: - - Auctions.settlePoolDebt(): + - SettlerActions.settlePoolDebt(): - Settle - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - AuctionNFTSettle or AuctionSettle - BucketBankruptcy - PoolCommons.updateInterestRate(): @@ -524,7 +519,7 @@ ### take external libraries call: - PoolCommons.accrueInterest() - - Auctions.take() + - TakerActions.take() - PoolCommons.updateInterestRate() write state: @@ -533,7 +528,7 @@ - Deposits.mult (scale Fenwick tree with new interest accrued): - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - - Auctions.take(): + - TakerActions.take(): - _take(): - _prepareTake(): - update liquidation.alreadyTaken state @@ -542,7 +537,7 @@ - update kicker's locked balance accumulator - update auctions.totalBondEscrowed accumulator - _takeLoan(): - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - _removeAuction(): - decrement kicker locked accumulator, increment kicker claimable accumumlator - decrement auctions count accumulator @@ -564,7 +559,7 @@ - pool inflator and inflatorUpdate state reverts on: - - Auctions.take(): + - TakerActions.take(): - insufficient collateral InsufficientCollateral() - _prepareTake(): - loan is not in auction NoAuction() @@ -573,7 +568,7 @@ - borrower debt less than pool min debt AmountLTMinDebt() emit events: - - Auctions.take(): + - TakerActions.take(): - Take - PoolCommons.updateInterestRate(): - UpdateInterestRate @@ -581,7 +576,7 @@ ### bucketTake external libraries call: - PoolCommons.accrueInterest() - - Auctions.bucketTake() + - TakerActions.bucketTake() - PoolCommons.updateInterestRate() write state: @@ -590,7 +585,7 @@ - Deposits.mult (scale Fenwick tree with new interest accrued): - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - - Auctions.bucketTake(): + - TakerActions.bucketTake(): - _takeBucket(): - _prepareTake(): - update liquidation.alreadyTaken state @@ -605,7 +600,7 @@ - update values array state - increment bucket.collateral and bucket.lps accumulator - _takeLoan(): - - Auctions._settleAuction(): + - SettlerActions._settleAuction(): - _removeAuction(): - decrement kicker locked accumulator, increment kicker claimable accumumlator - decrement auctions count accumulator @@ -627,7 +622,7 @@ - pool inflator and inflatorUpdate state reverts on: - - Auctions.bucketTake(): + - TakerActions.bucketTake(): - insufficient collateral InsufficientCollateral() - _prepareTake(): - loan is not in auction NoAuction() @@ -636,7 +631,7 @@ - borrower debt less than pool min debt AmountLTMinDebt() emit events: - - Auctions.bucketTake(): + - TakerActions.bucketTake(): - _rewardBucketTake(): - BucketTakeLPAwarded - BucketTake diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 5a3539e83..fba318b41 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -291,7 +291,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { ); // update in memory pool state struct - poolState.debt = Maths.wmul(result.t0PoolDebt, poolState.inflator); + poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; poolState.t0DebtInAuction += result.t0KickedDebt; @@ -318,14 +318,14 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { * @dev increment `poolBalances.t0DebtInAuction` and `poolBalances.t0Debt` accumulators * @dev update `t0Debt2ToCollateral` ratio, debt and collateral post action are considered 0 */ - function kickWithDeposit( + function lenderKick( uint256 index_, uint256 npLimitIndex_ ) external override nonReentrant { PoolState memory poolState = _accruePoolInterest(); // kick auctions - KickResult memory result = KickerActions.kickWithDeposit( + KickResult memory result = KickerActions.lenderKick( auctions, deposits, buckets, @@ -336,7 +336,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { ); // update in memory pool state struct - poolState.debt = Maths.wmul(result.t0PoolDebt, poolState.inflator); + poolState.debt = result.poolDebt; poolState.t0Debt = result.t0PoolDebt; poolState.t0DebtInAuction += result.t0KickedDebt; diff --git a/src/interfaces/pool/commons/IPoolInternals.sol b/src/interfaces/pool/commons/IPoolInternals.sol index 43bd13d81..7a6e5f3da 100644 --- a/src/interfaces/pool/commons/IPoolInternals.sol +++ b/src/interfaces/pool/commons/IPoolInternals.sol @@ -15,9 +15,10 @@ struct KickResult { uint256 amountToCoverBond; // [WAD] amount of bond that needs to be covered uint256 t0PoolDebt; // [WAD] t0 debt in pool after kick uint256 t0KickedDebt; // [WAD] new t0 debt after kick - uint256 lup; // [WAD] current lup uint256 debtPreAction; // [WAD] The amount of borrower t0 debt before 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 } /// @dev Struct used to hold parameters for `SettlerAction.settlePoolDebt` action. diff --git a/src/interfaces/pool/commons/IPoolKickerActions.sol b/src/interfaces/pool/commons/IPoolKickerActions.sol index 06f24bee4..93e4fa130 100644 --- a/src/interfaces/pool/commons/IPoolKickerActions.sol +++ b/src/interfaces/pool/commons/IPoolKickerActions.sol @@ -22,11 +22,11 @@ interface IPoolKickerActions { ) external; /** - * @notice Called by lenders to liquidate the top loan using their deposits. + * @notice Called by lenders to liquidate the top loan. * @param index_ The deposit index to use for kicking the top loan. * @param npLimitIndex_ Index of the lower bound of `NP` tolerated when kicking the auction. */ - function kickWithDeposit( + function lenderKick( uint256 index_, uint256 npLimitIndex_ ) external; diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index c1e95b3ee..909a7ebe0 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -67,17 +67,12 @@ library KickerActions { uint256 kickPenalty; // [WAD] current debt added as kick penalty } - /// @dev Struct used for `kickWithDeposit` function local vars. - struct KickWithDepositLocalVars { - uint256 amountToDebitFromDeposit; // [WAD] the amount of quote tokens used to kick and debited from lender deposit - uint256 bucketCollateral; // [WAD] amount of collateral in bucket - uint256 bucketDeposit; // [WAD] amount of quote tokens in bucket - uint256 bucketLP; // [WAD] LP of the bucket - uint256 bucketPrice; // [WAD] bucket price - uint256 bucketScale; // [WAD] bucket scales - uint256 bucketUnscaledDeposit; // [WAD] unscaled amount of quote tokens in bucket - uint256 lenderLP; // [WAD] LP of lender in bucket - uint256 redeemedLP; // [WAD] LP used by kick action + /// @dev Struct used for `lenderKick` function local vars. + struct LenderKickLocalVars { + uint256 bucketDeposit; // [WAD] amount of quote tokens in bucket + uint256 bucketPrice; // [WAD] bucket price + uint256 entitledAmount; // [WAD] amount that lender is entitled to remove at specified index + uint256 lenderLP; // [WAD] LP of lender in bucket } /**************/ @@ -135,18 +130,12 @@ library KickerActions { /** * @notice See `IPoolKickerActions` for descriptions. - * @dev === Write state === - * @dev - `Deposits.unscaledRemove` (remove amount in `Fenwick` tree, from index): update `values` array state - * @dev - decrement `lender.lps` accumulator - * @dev - decrement `bucket.lps` accumulator * @dev === Reverts on === + * @dev bucket price below current pool `LUP` `PriceBelowLUP()` * @dev insufficient deposit to kick auction `InsufficientLiquidity()` - * @dev no `LP` redeemed to kick auction `InsufficientLP()` - * @dev === Emit events === - * @dev - `RemoveQuoteToken` * @return kickResult_ The `KickResult` struct result of the kick action. */ - function kickWithDeposit( + function lenderKick( AuctionsState storage auctions_, DepositsState storage deposits_, mapping(uint256 => Bucket) storage buckets_, @@ -157,35 +146,34 @@ library KickerActions { ) external returns ( KickResult memory kickResult_ ) { - Bucket storage bucket = buckets_[index_]; - Lender storage lender = bucket.lenders[msg.sender]; + LenderKickLocalVars memory vars; - KickWithDepositLocalVars memory vars; + vars.bucketPrice = _priceAt(index_); - if (bucket.bankruptcyTime < lender.depositTime) vars.lenderLP = lender.lps; + // revert if the bucket price is below current LUP + if (vars.bucketPrice < Deposits.getLup(deposits_, poolState_.debt)) revert PriceBelowLUP(); + + Bucket storage bucket = buckets_[index_]; + Lender storage lender = bucket.lenders[msg.sender]; - vars.bucketLP = bucket.lps; - vars.bucketCollateral = bucket.collateral; - vars.bucketPrice = _priceAt(index_); - vars.bucketUnscaledDeposit = Deposits.unscaledValueAt(deposits_, index_); - vars.bucketScale = Deposits.scale(deposits_, index_); - vars.bucketDeposit = Maths.wmul(vars.bucketUnscaledDeposit, vars.bucketScale); + vars.lenderLP = bucket.bankruptcyTime < lender.depositTime ? lender.lps : 0; + vars.bucketDeposit = Deposits.valueAt(deposits_, index_); - // calculate amount to remove based on lender LP in bucket - vars.amountToDebitFromDeposit = Buckets.lpToQuoteTokens( - vars.bucketCollateral, - vars.bucketLP, + // calculate amount lender is entitled in current bucket (based on lender LP in bucket) + vars.entitledAmount = Buckets.lpToQuoteTokens( + bucket.collateral, + bucket.lps, vars.bucketDeposit, vars.lenderLP, vars.bucketPrice, Math.Rounding.Down ); - // cap the amount to remove at bucket deposit - if (vars.amountToDebitFromDeposit > vars.bucketDeposit) vars.amountToDebitFromDeposit = vars.bucketDeposit; + // cap the amount entitled at bucket deposit + if (vars.entitledAmount > vars.bucketDeposit) vars.entitledAmount = vars.bucketDeposit; - // revert if no amount that can be removed - if (vars.amountToDebitFromDeposit == 0) revert InsufficientLiquidity(); + // revert if no entitled amount + if (vars.entitledAmount == 0) revert InsufficientLiquidity(); // kick top borrower kickResult_ = _kick( @@ -195,80 +183,7 @@ library KickerActions { poolState_, Loans.getMax(loans_).borrower, limitIndex_, - vars.amountToDebitFromDeposit - ); - - // amount to remove from deposit covers entire bond amount - if (vars.amountToDebitFromDeposit > kickResult_.amountToCoverBond) { - // cap amount to remove from deposit at amount to cover bond - vars.amountToDebitFromDeposit = kickResult_.amountToCoverBond; - - // recalculate the LUP with the amount to cover bond - kickResult_.lup = Deposits.getLup(deposits_, poolState_.debt + vars.amountToDebitFromDeposit); - // entire bond is covered from deposit, no additional amount to be send by lender - kickResult_.amountToCoverBond = 0; - } else { - // lender should send additional amount to cover bond - kickResult_.amountToCoverBond -= vars.amountToDebitFromDeposit; - } - - // revert if the bucket price used to kick and remove is below new LUP - if (vars.bucketPrice < kickResult_.lup) revert PriceBelowLUP(); - - // remove amount from deposits - if (vars.amountToDebitFromDeposit == vars.bucketDeposit && vars.bucketCollateral == 0) { - // In this case we are redeeming the entire bucket exactly, and need to ensure bucket LP are set to 0 - vars.redeemedLP = vars.bucketLP; - - Deposits.unscaledRemove(deposits_, index_, vars.bucketUnscaledDeposit); - vars.bucketUnscaledDeposit = 0; - - } else { - vars.redeemedLP = Buckets.quoteTokensToLP( - vars.bucketCollateral, - vars.bucketLP, - vars.bucketDeposit, - vars.amountToDebitFromDeposit, - vars.bucketPrice, - Math.Rounding.Up - ); - - uint256 unscaledAmountToRemove = Maths.floorWdiv(vars.amountToDebitFromDeposit, vars.bucketScale); - - // revert if calculated unscaled amount is 0 - if (unscaledAmountToRemove == 0) revert InsufficientLiquidity(); - - Deposits.unscaledRemove(deposits_, index_, unscaledAmountToRemove); - vars.bucketUnscaledDeposit -= unscaledAmountToRemove; - } - - vars.redeemedLP = Maths.min(vars.lenderLP, vars.redeemedLP); - - // revert if LP redeemed amount to kick auction is 0 - if (vars.redeemedLP == 0) revert InsufficientLP(); - - uint256 bucketRemainingLP = vars.bucketLP - vars.redeemedLP; - - if (vars.bucketCollateral == 0 && vars.bucketUnscaledDeposit == 0 && bucketRemainingLP != 0) { - bucket.lps = 0; - bucket.bankruptcyTime = block.timestamp; - - emit BucketBankruptcy( - index_, - bucketRemainingLP - ); - } else { - // update lender and bucket LP balances - lender.lps -= vars.redeemedLP; - bucket.lps -= vars.redeemedLP; - } - - emit RemoveQuoteToken( - msg.sender, - index_, - vars.amountToDebitFromDeposit, - vars.redeemedLP, - kickResult_.lup + vars.entitledAmount ); } @@ -381,8 +296,11 @@ library KickerActions { kickResult_.debtPreAction = borrower.t0Debt; kickResult_.collateralPreAction = borrower.collateral; kickResult_.t0KickedDebt = kickResult_.debtPreAction ; + // add amount to remove to pool debt in order to calculate proposed LUP - kickResult_.lup = Deposits.getLup(deposits_, poolState_.debt + additionalDebt_); + // 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); @@ -442,6 +360,10 @@ library KickerActions { kickResult_.t0PoolDebt = poolState_.t0Debt + vars.t0KickPenalty; kickResult_.t0KickedDebt += vars.t0KickPenalty; + // recalculate LUP with new pool debt (including kick penalty) + kickResult_.poolDebt = Maths.wmul(kickResult_.t0PoolDebt, poolState_.inflator); + kickResult_.lup = Deposits.getLup(deposits_, kickResult_.poolDebt); + // update borrower debt with kicked debt penalty borrower.t0Debt = kickResult_.t0KickedDebt; diff --git a/tests/INVARIANTS.md b/tests/INVARIANTS.md index 8127ff05f..67c2cced0 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -15,7 +15,7 @@ ## Quote Token - **QT1**: pool quote token balance (`Quote.balanceOf(pool)`) >= liquidation bonds (`AuctionsState.totalBondEscrowed`) + pool deposit size (`Pool.depositSize()`) + reserve auction unclaimed amount (`reserveAuction.unclaimed`) - pool t0 debt (`PoolBalancesState.t0Debt`) (with a `1e13` margin) - **QT2**: pool t0 debt (`PoolBalancesState.t0Debt`) = sum of t0 debt across all borrowers (`Borrower.t0Debt`) -- **QT3**: pool quote token balance (`Quote.balanceOf(pool)`) >= claimable liquidation bonds + reserve auction unclaimed amount (`reserveAuction.unclaimed`) +- **QT3**: pool quote token balance (`Quote.balanceOf(pool)`) >= liquidation bonds (`AuctionsState.totalBondEscrowed`) + reserve auction unclaimed amount (`reserveAuction.unclaimed`) ## Auctions - **A1**: total t0 debt auctioned (`PoolBalancesState.t0DebtInAuction`) = sum of debt across all auctioned borrowers (`Borrower.t0Debt` where borrower's `kickTime != 0`) diff --git a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol index 60dfdd8c0..6243cdc41 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol @@ -133,19 +133,19 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded _resetSettledAuction(borrower, borrowerIndex_); } - function kickWithDeposit( + function lenderKickAuction( uint256 kickerIndex_, uint256 bucketIndex_, uint256 skippedTime_ ) external useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BPanicExitPoolHandler.kickWithDeposit']++; + numberOfCalls['BPanicExitPoolHandler.lenderKickAuction']++; kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); address kicker = _lenders[kickerIndex_]; _actor = kicker; changePrank(_actor); - _kickWithDeposit(_lenderBucketIndex); + _lenderKickAuction(_lenderBucketIndex); } function withdrawBonds( diff --git a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol index c4be49346..9a5d3276d 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol @@ -131,19 +131,19 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde _resetSettledAuction(borrower, borrowerIndex_); } - function kickWithDeposit( + function lenderKickAuction( uint256 kickerIndex_, uint256 bucketIndex_, uint256 skippedTime_ ) external useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BPanicExitPoolHandler.kickWithDeposit']++; + numberOfCalls['BPanicExitPoolHandler.lenderKickAuction']++; kickerIndex_ = constrictToRange(kickerIndex_, 0, LENDERS - 1); address kicker = _lenders[kickerIndex_]; _actor = kicker; changePrank(_actor); - _kickWithDeposit(_lenderBucketIndex); + _lenderKickAuction(_lenderBucketIndex); } function withdrawBonds( diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index 956d679e5..8c92219f8 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -178,28 +178,19 @@ abstract contract BasicInvariants is BaseInvariants { require(poolDebt == totalDebt, "Quote Token Invariant QT2"); } - /// @dev checks pool quote token balance is greater than or equal with unclaimed reserves plus claimable auction bonds + /// @dev checks pool quote token balance is greater than or equal with sum of escrowed bonds and unclaimed reserves function _invariant_QT3() internal view { // convert pool quote balance into WAD uint256 poolBalance = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); - (, uint256 unClaimed, , ) = _pool.reservesInfo(); - - uint256 actorCount = IBaseHandler(_handler).getActorsCount(); - uint256 claimableAuctionBonds; - for (uint256 i = 0; i < actorCount; i++) { - address kicker = IBaseHandler(_handler).actors(i); - (uint256 claimable, ) = _pool.kickerInfo(kicker); - - claimableAuctionBonds += claimable; - } - - console.log("poolBalance -> ", poolBalance); - console.log("claimable reserves -> ", unClaimed); - console.log("claimable bonds -> ", claimableAuctionBonds); + ( + uint256 totalBondEscrowed, + uint256 unClaimed, + , + ) = _pool.reservesInfo(); require( - poolBalance >= unClaimed + claimableAuctionBonds, - "QT3: claimable escrowed bonds and claimable reserves not guaranteed" + poolBalance >= totalBondEscrowed + unClaimed, + "QT3: escrowed bonds and claimable reserves not guaranteed" ); } @@ -469,8 +460,8 @@ abstract contract BasicInvariants is BaseInvariants { console.log("--Liquidation--------"); console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); - console.log("BLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); - console.log("UBLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); + console.log("BLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction")); + console.log("UBLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.lenderKickAuction")); console.log("BLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction")); console.log("UBLiquidationHandler.takeAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.takeAuction")); console.log("BLiquidationHandler.bucketTake ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake")); @@ -515,7 +506,7 @@ abstract contract BasicInvariants is BaseInvariants { IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction") + - IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds") + diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index 9ce277173..b6206e521 100644 --- a/tests/forge/invariants/base/LiquidationInvariants.t.sol +++ b/tests/forge/invariants/base/LiquidationInvariants.t.sol @@ -180,8 +180,8 @@ abstract contract LiquidationInvariants is BasicInvariants { console.log("UBLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.settleAuction")); console.log("BLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds")); console.log("UBLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.withdrawBonds")); - console.log("BLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); - console.log("UBLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); + console.log("BLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction")); + console.log("UBLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.lenderKickAuction")); console.log("------------------"); console.log( "Sum", @@ -200,12 +200,12 @@ abstract contract LiquidationInvariants is BasicInvariants { IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds") + - IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction") ); console.log("------------------"); console.log("--Successful liquidation actions----"); console.log("kick: ", IBaseHandler(_handler).numberOfActions("kick")); - console.log("kick with deposit: ", IBaseHandler(_handler).numberOfActions("kickWithDeposit")); + console.log("kick with deposit: ", IBaseHandler(_handler).numberOfActions("lenderKickAuction")); console.log("take: ", IBaseHandler(_handler).numberOfActions("take")); console.log("bucket take: ", IBaseHandler(_handler).numberOfActions("bucketTake")); console.log("settle ", IBaseHandler(_handler).numberOfActions("settle")); diff --git a/tests/forge/invariants/base/ReserveInvariants.t.sol b/tests/forge/invariants/base/ReserveInvariants.t.sol index e5c349566..ab9ed8bb8 100644 --- a/tests/forge/invariants/base/ReserveInvariants.t.sol +++ b/tests/forge/invariants/base/ReserveInvariants.t.sol @@ -68,8 +68,8 @@ abstract contract ReserveInvariants is LiquidationInvariants { console.log("UBLiquidationHandler.settleAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.settleAuction")); console.log("BLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds")); console.log("UBLiquidationHandler.withdrawBonds ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.withdrawBonds")); - console.log("BLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit")); - console.log("UBLiquidationHandler.kickWithDeposit ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickWithDeposit")); + console.log("BLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction")); + console.log("UBLiquidationHandler.lenderKickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.lenderKickAuction")); console.log("--Reserves--------"); console.log("BReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves")); console.log("UBReserveHandler.takeReserves ", IBaseHandler(_handler).numberOfCalls("UBReserveHandler.takeReserves")); @@ -92,14 +92,14 @@ abstract contract ReserveInvariants is LiquidationInvariants { IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.bucketTake") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.settleAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.withdrawBonds") + - IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickWithDeposit") + + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction") + IBaseHandler(_handler).numberOfCalls("BReserveHandler.kickReserveAuction") + IBaseHandler(_handler).numberOfCalls("BReserveHandler.takeReserves") ); console.log("------------------"); console.log("--Successful liquidation actions----"); console.log("kick: ", IBaseHandler(_handler).numberOfActions("kick")); - console.log("kick with deposit: ", IBaseHandler(_handler).numberOfActions("kickWithDeposit")); + console.log("kick with deposit: ", IBaseHandler(_handler).numberOfActions("lenderKickAuction")); console.log("take: ", IBaseHandler(_handler).numberOfActions("take")); console.log("bucket take: ", IBaseHandler(_handler).numberOfActions("bucketTake")); console.log("settle ", IBaseHandler(_handler).numberOfActions("settle")); diff --git a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol index 31df43077..db7e2551f 100644 --- a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol @@ -23,13 +23,13 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas _kickAuction(borrowerIndex_, amount_, kickerIndex_); } - function kickWithDeposit( + function lenderKickAuction( uint256 kickerIndex_, uint256 bucketIndex_, uint256 skippedTime_ ) external useRandomActor(kickerIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) writeLogs { - numberOfCalls['BLiquidationHandler.kickWithDeposit']++; - _kickWithDeposit(_lenderBucketIndex); + numberOfCalls['BLiquidationHandler.lenderKickAuction']++; + _lenderKickAuction(_lenderBucketIndex); } function withdrawBonds( diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 57d2f0b3c..1e9691175 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -566,11 +566,11 @@ abstract contract BaseHandler is Test { printLog("Total reserves unclaimed = ", reserveUnclaimed); printLog("Total interest earned = ", totalInterest); printLine(""); - printLog("Successful kicks = ", numberOfActions["kick"]); - printLog("Successful deposit kicks = ", numberOfActions["kickWithDeposit"]); - printLog("Successful takes = ", numberOfActions["take"]); - printLog("Successful bucket takes = ", numberOfActions["bucketTake"]); - printLog("Successful settles = ", numberOfActions["settle"]); + printLog("Successful kicks = ", numberOfActions["kick"]); + printLog("Successful lender kicks = ", numberOfActions["lenderKick"]); + printLog("Successful takes = ", numberOfActions["take"]); + printLog("Successful bucket takes = ", numberOfActions["bucketTake"]); + printLog("Successful settles = ", numberOfActions["settle"]); printInNextLine("======================="); } diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index d8b1aec33..897851dff 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -55,10 +55,10 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { } } - function _kickWithDeposit( + function _lenderKickAuction( uint256 bucketIndex_ ) internal updateLocalStateAndPoolInterest { - numberOfCalls['UBLiquidationHandler.kickWithDeposit']++; + numberOfCalls['UBLiquidationHandler.lenderKickAuction']++; (address maxBorrower, , ) = _pool.loansInfo(); (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), maxBorrower); @@ -71,8 +71,8 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // ensure actor always has the amount to add for kick _ensureQuoteAmount(_actor, borrowerDebt); - try _pool.kickWithDeposit(bucketIndex_, 7388) { - numberOfActions['kickWithDeposit']++; + try _pool.lenderKick(bucketIndex_, 7388) { + numberOfActions['lenderKick']++; ( , , , uint256 depositAfterAction, ) = _pool.bucketInfo(bucketIndex_); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol index c85b68783..f3d5514f2 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol @@ -91,7 +91,7 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { function test_regression_depositKick() external { _liquidationERC20PoolHandler.repayDebt(13418, 1160, 0); - _liquidationERC20PoolHandler.kickWithDeposit(143703836638834364678, 470133688850921941603, 0); + _liquidationERC20PoolHandler.lenderKickAuction(143703836638834364678, 470133688850921941603, 0); invariant_fenwick(); } @@ -252,12 +252,12 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { function test_regression_invariant_F4_3() external { _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 88, 0); - _liquidationERC20PoolHandler.kickWithDeposit(454046303796091226235, 1, 0); + _liquidationERC20PoolHandler.lenderKickAuction(454046303796091226235, 1, 0); _liquidationERC20PoolHandler.addQuoteToken(22366532024867500041595597535594488494092956872779970834638, 2056702511, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); _liquidationERC20PoolHandler.takeAuction(7409458575819003489055485098, 19999999999999999999998047232, 160427188541373972791114, 0); _liquidationERC20PoolHandler.drawDebt(54, 1078707919809097500728008, 0); _liquidationERC20PoolHandler.takeAuction(2, 11014481, 0, 0); - _liquidationERC20PoolHandler.kickWithDeposit(6261145081390052923416, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _liquidationERC20PoolHandler.lenderKickAuction(6261145081390052923416, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _liquidationERC20PoolHandler.repayDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _liquidationERC20PoolHandler.repayDebt(19522111312004366551699434321235702562902449, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _liquidationERC20PoolHandler.removeQuoteToken(2, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); @@ -318,7 +318,7 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { _liquidationERC20PoolHandler.bucketTake(2, 75288272353, true, 1, 0); _liquidationERC20PoolHandler.addCollateral(5005, 147331, 401909674630078222417654, 0); _liquidationERC20PoolHandler.transferLps(1029198447942867385425606035931054127523339423727036067, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 0); - _liquidationERC20PoolHandler.kickWithDeposit(293745346792645466008958291, 16403, 0); + _liquidationERC20PoolHandler.lenderKickAuction(293745346792645466008958291, 16403, 0); _liquidationERC20PoolHandler.withdrawBonds(2, 2, 0); _liquidationERC20PoolHandler.moveQuoteToken(32224, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6849415706965240690489344969517578351041775953402620986, 2148695314889429664161453614417855608352221, 0); _liquidationERC20PoolHandler.takeAuction(94448273410401913677340426062, 725811011514389123331573619988789182755239580450547667740684, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); @@ -400,7 +400,7 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { _liquidationERC20PoolHandler.drawDebt(1650395907908375370646803, 1139089764268016448008730470211, 13082959110942300185021122222306626); _liquidationERC20PoolHandler.moveQuoteToken(93610, 142089797548946945081634619871556783127580529081355187339115302, 149, 13913579372905540408633068050774982611379962730, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.transferLps(6292165613120549248648866955393, 1060631736309413465, 3996, 5500900090246881585205428293671181, 91068871115322271162237280834); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 21453159328299531749810384996740705004989165577317322746872305568189); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 21453159328299531749810384996740705004989165577317322746872305568189); _liquidationERC20PoolHandler.drawDebt(10636347319675315313277232412888, 3051548607055529278657663362826, 5726786973904835518002557614676); _liquidationERC20PoolHandler.moveQuoteToken(1253192623581620772476304176589, 1004709840617137359, 1363507508709197960, 1733464339886107498992567200861, 7507); _liquidationERC20PoolHandler.withdrawBonds(1999999999999997715165989367948945659933163524, 1668463998534567849013477923041, 6990477785303516774672173634812); @@ -506,9 +506,9 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { _liquidationERC20PoolHandler.bucketTake(3, 591142574804529212382680063256514252284508713761552453802058, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); _liquidationERC20PoolHandler.repayDebt(3619, 2244, 14976); _liquidationERC20PoolHandler.settleAuction(22322536288829078015923987087, 3562, 8085, 2188); - _liquidationERC20PoolHandler.kickWithDeposit(182452440584770651626488608563224813823444276, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC20PoolHandler.lenderKickAuction(182452440584770651626488608563224813823444276, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 3); - _liquidationERC20PoolHandler.kickWithDeposit(597337470804484617799079208131011946583, 1207, 11344); + _liquidationERC20PoolHandler.lenderKickAuction(597337470804484617799079208131011946583, 1207, 11344); invariant_auction(); } @@ -555,15 +555,15 @@ contract RegressionTestLiquidationWith10BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.kickAuction(753584878874314971560083424557701850385530947431429367465802634481950940, 5920047275579788758504875392370, 1999999999999997999999999999999999975432674289, 1617686819026547128896308045862); _liquidationERC20PoolHandler.repayDebt(1293975714214592046746302918212, 4120612120495322420373192252489155, 1024806532799439823); _liquidationERC20PoolHandler.withdrawBonds(1756571070747610033910708799907, 4992714850142500950348469934408, 71853405850320900287309042479); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 255652551437322786266554952841707415273736061159634274, 3); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 255652551437322786266554952841707415273736061159634274, 3); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2629879431337829208207060362473075397414785556989661565150017094211890122, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(51659023878042301277250997073244982, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _liquidationERC20PoolHandler.lenderKickAuction(51659023878042301277250997073244982, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _liquidationERC20PoolHandler.takeAuction(3, 78870668732016785292671569665085729080988158423724783395594, 2, 298022583549501475423287040108577818982202642818477386026973054777161860); _liquidationERC20PoolHandler.drawDebt(2, 20603317378542628263862915818716754475651, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.repayDebt(26669578884974905602, 0, 3); _liquidationERC20PoolHandler.removeCollateral(507150490380447805360057803027478333131790920318917457, 43252107287618289443232617966241210, 2132729817631783392477, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.pledgeCollateral(512749894191567190, 97125321645749610390633951148, 1351723596887747991077); - _liquidationERC20PoolHandler.kickWithDeposit(832281773276003, 1519877355124224435567616538384644313965108820073744607071499955933, 5378892505461270614716635938787813579702576674795498437957908068289601320395); + _liquidationERC20PoolHandler.lenderKickAuction(832281773276003, 1519877355124224435567616538384644313965108820073744607071499955933, 5378892505461270614716635938787813579702576674795498437957908068289601320395); _liquidationERC20PoolHandler.bucketTake(1407932162560559427259739991332, 1002614712016360732542515, false, 1000071273663475130253763, 10288978422409877239560234465672744); _liquidationERC20PoolHandler.takeAuction(1096654327376952234, 1991771954302555237620077890654, 1947500794342808708167078440906, 1553940794741961421063317210972); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -636,11 +636,11 @@ contract RegressionTestLiquidationWith10BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(145373054532925972698679300543022484929791768381534863557152788448434555, 2051718385573247, 8275151039767993600355, 8539222545129872601752); _liquidationERC20PoolHandler.settleAuction(1000092199457610848, 4477250341921706529809424808543096, 1759906476, 358140679410375588106283137874); _liquidationERC20PoolHandler.withdrawBonds(534027600895509751515490844155351150631870219925, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 61243160953593509302972736662431); - _liquidationERC20PoolHandler.kickWithDeposit(701526431949095526598535866533, 1449458996839103557396370018491, 121422685529945075360217992683); + _liquidationERC20PoolHandler.lenderKickAuction(701526431949095526598535866533, 1449458996839103557396370018491, 121422685529945075360217992683); _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 2); _liquidationERC20PoolHandler.removeQuoteToken(5968384957546835262263929945678, 10680234826966895449041551120832, 1999999999999999421285482542339687521344072398, 3797832184901628682584203427760); _liquidationERC20PoolHandler.transferLps(2053053570255639055192486311504, 97597786894111403201399886, 70062261776809949709510846875, 503187341591428523, 999999999999999999999999998998230526966508458); - _liquidationERC20PoolHandler.kickWithDeposit(2459101563294021562857605502340, 1012888438550910767, 2811569804158661169503090013969); + _liquidationERC20PoolHandler.lenderKickAuction(2459101563294021562857605502340, 1012888438550910767, 2811569804158661169503090013969); _liquidationERC20PoolHandler.kickAuction(1796293217, 2015061556239435218271418713619, 3633516890615431898701348517436, 148143307963895766786875020014); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 751962010052996, 2); _liquidationERC20PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); @@ -702,7 +702,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(1370103067227011175696451973278456337034511090566396230238788097810, 166578894785869488938249498768650137375178, 1, 3, 1); _liquidationERC20PoolHandler.settleAuction(5122, 17565, 2806, 3133); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1091200567137095905); - _liquidationERC20PoolHandler.kickWithDeposit(4627, 5236, 104386040240941262918860776002963788519163859829196702135414660947633678111899); + _liquidationERC20PoolHandler.lenderKickAuction(4627, 5236, 104386040240941262918860776002963788519163859829196702135414660947633678111899); _liquidationERC20PoolHandler.kickAuction(5721, 1838496690882922150554110976692, 24328, 3877); _liquidationERC20PoolHandler.kickAuction(64133339368743336216198820457544654768502375395293128963079, 0, 2, 55348385068903244952784485280466231984952696649704395838109835855761543894); _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 305234975145, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -729,7 +729,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1948512664518372242626245220758406472494512238624, 0); _liquidationERC20PoolHandler.bucketTake(3650336609082397343184715679664, 843, false, 1680, 10196); _liquidationERC20PoolHandler.transferLps(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 39067377810949119167902687441371, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 40844600354171183615435542876686573); - _liquidationERC20PoolHandler.kickWithDeposit(6161, 4899, 5225); + _liquidationERC20PoolHandler.lenderKickAuction(6161, 4899, 5225); _liquidationERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, true, 16350119941455120065637926002331453550462375801376026, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.repayDebt(110581925320786785962730, 2802543930628172497422234832874515346475336547986123758826140778347966, 96275912248435674590526934211234266); _liquidationERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1476739938730304829907); @@ -746,11 +746,11 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(958357608290017860184676424, 22177127062375358494343615834726453635971486295546280118497398739260170, 3, 1, 604900478654504417903); _liquidationERC20PoolHandler.kickAuction(6646, 5993, 1004085701595904695, 12288); _liquidationERC20PoolHandler.takeAuction(1025560185296548619846, 196, 1649524542, 1020178504205891711541470631913); - _liquidationERC20PoolHandler.kickWithDeposit(16548, 1023786991681229765157801, 101991232049794109919362754054997835793635908174801124817519862639518044289939); + _liquidationERC20PoolHandler.lenderKickAuction(16548, 1023786991681229765157801, 101991232049794109919362754054997835793635908174801124817519862639518044289939); _liquidationERC20PoolHandler.removeQuoteToken(3253077405177930508120431970343418543573435822, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1); _liquidationERC20PoolHandler.removeQuoteToken(172107339793732568366098241905255547555197833963459312531344723714, 297672088947883095904, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 1, 123170547406971085598528554986610520434555621719009234445); - _liquidationERC20PoolHandler.kickWithDeposit(3, 2, 0); + _liquidationERC20PoolHandler.lenderKickAuction(3, 2, 0); _liquidationERC20PoolHandler.pullCollateral(322772039577017391790479942111198908569, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); _liquidationERC20PoolHandler.moveQuoteToken(1, 24055030812512964883367933606686, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 13719284756101, 5570034086544798556891892550002397129682065655); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3209869110177677916637469054026099930825063682516465, 1804366688964539791838228279556028340784401536415571033847007614284215014, 35695417500494507465515345091384999); @@ -776,12 +776,12 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(478, 1999999999999999991792334876841191237617229513, 5227, 20372); _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 271381343865064746864401126460375223152741973041452019593513355208558201074, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 27321819381658409927609952545813353473629816386195559462739295586, 13726394349170228723); _liquidationERC20PoolHandler.transferLps(7985689849617913495736527480758, 16907, 3503, 862216647626184868947534738, 5134); - _liquidationERC20PoolHandler.kickWithDeposit(3225, 4102, 794659472355482837); + _liquidationERC20PoolHandler.lenderKickAuction(3225, 4102, 794659472355482837); _liquidationERC20PoolHandler.bucketTake(1202302901775116723741158164108924473100399829590296777239731654861447033, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 104312590598377504832223664579173854144175158867, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.repayDebt(2756335556621242120045894785304048236036931384631589912015295458960748269633, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1563810748755820515007452912829030573927148); - _liquidationERC20PoolHandler.kickWithDeposit(14340, 1900924243461948174045789652866, 4843298302506); + _liquidationERC20PoolHandler.lenderKickAuction(14340, 1900924243461948174045789652866, 4843298302506); _liquidationERC20PoolHandler.transferLps(0, 4415247343328520873596726, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 443253526615348022374537801250730150519364433891); - _liquidationERC20PoolHandler.kickWithDeposit(9753, 2703, 1013386378035063693331483860779); + _liquidationERC20PoolHandler.lenderKickAuction(9753, 2703, 1013386378035063693331483860779); _liquidationERC20PoolHandler.removeCollateral(1565334953690036338413962469894, 452739465391725139, 80781344633523, 29525750244093134067807977746644013238168127446252019528282043565); _liquidationERC20PoolHandler.moveQuoteToken(22312067290375148414725115792608820157692896383893361933693626234820, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 768492032747934500735364458924935535281071488253287408490457596); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 4790969178603704085770956926455437, 90267103937059731051775312596194723513466767904029049098); @@ -816,7 +816,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 386453877844466602127978228201932014060300801157402846451628, 307159810975233782659789186708720512); _liquidationERC20PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 15811563904, 6708099498377070874207525178973154181845192549256665880256051979206); _liquidationERC20PoolHandler.addCollateral(3681, 5223, 1839, 9812); - _liquidationERC20PoolHandler.kickWithDeposit(354914638246046703381925281849461577313262819947878625538344375470, 2, 55811817762207436860881); + _liquidationERC20PoolHandler.lenderKickAuction(354914638246046703381925281849461577313262819947878625538344375470, 2, 55811817762207436860881); _liquidationERC20PoolHandler.withdrawBonds(6009, 1014755098754446198174207, 14340); _liquidationERC20PoolHandler.repayDebt(7168537365031830199147467677381, 12461, 6006); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 11801793812113601834572309746821970853481341127414402977203345, 1161653986079240988071138); @@ -842,7 +842,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pledgeCollateral(22583037618291764913005443314454606312474046894231169183, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _liquidationERC20PoolHandler.bucketTake(4733, 7333731295438493437298919088325, false, 2197645934, 11246); _liquidationERC20PoolHandler.addQuoteToken(19336, 33812, 7407468124461038759054257472180, 22834713379924531442594085989552); - _liquidationERC20PoolHandler.kickWithDeposit(4358, 861159742600722510787517768, 3617); + _liquidationERC20PoolHandler.lenderKickAuction(4358, 861159742600722510787517768, 3617); _liquidationERC20PoolHandler.transferLps(3, 554834996060342704862553541813410209298165977451749781311986251299884755653, 1, 2337045486350598691199268081267551901863352575748991482139987262965740863, 26702723190098990940); _liquidationERC20PoolHandler.pullCollateral(993669593100804651037032066962783544, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.repayDebt(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); @@ -882,14 +882,14 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 213333006387800105687, 0); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 53156430850148109053724575950754942818567506607636892379, 404965570612739643740371854748460441513317859, 2); _liquidationERC20PoolHandler.drawDebt(1953, 3152892415559031078552564090553, 5366027547660915658476525046334); - _liquidationERC20PoolHandler.kickWithDeposit(71269295469799071464468712924126, 16672, 1808239087676713445175337587520); + _liquidationERC20PoolHandler.lenderKickAuction(71269295469799071464468712924126, 16672, 1808239087676713445175337587520); _liquidationERC20PoolHandler.pledgeCollateral(1, 178, 2); _liquidationERC20PoolHandler.addCollateral(1020179552508696328714450317540, 2400, 5800, 6151); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1397512, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC20PoolHandler.kickWithDeposit(18004, 811731044728185024284469764589, 19761538717419569590757685679889301866100247274988300923249721979967931031494); + _liquidationERC20PoolHandler.lenderKickAuction(18004, 811731044728185024284469764589, 19761538717419569590757685679889301866100247274988300923249721979967931031494); _liquidationERC20PoolHandler.pullCollateral(3, 29599514873069859397976550509252240100468990327, 1173060562074542894471046788702646232217); _liquidationERC20PoolHandler.settleAuction(190507665868, 159564982550664243691273953799842145057480256, 8812500210365573722357114124082828592523100039678372534478335569131385, 87621761186195841780727041807676462148298117240625124); - _liquidationERC20PoolHandler.kickWithDeposit(54543, 3, 0); + _liquidationERC20PoolHandler.lenderKickAuction(54543, 3, 0); _liquidationERC20PoolHandler.settleAuction(1, 71948065251156301211532537617621585537513653890, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 393075123993318492319362409397083987987991917599828669067198510543060); _liquidationERC20PoolHandler.pullCollateral(1, 10136439487938919943645788821649, 1525611472174438420726976624374629306692346940108286201299593771800693); _liquidationERC20PoolHandler.moveQuoteToken(817295296434982840461474974014221989145826674159930889623, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 8822004847588393068813964146, 4130189183215450097401635509, 210322908515933728511715327101773093650079995513900060355080223125179); @@ -911,9 +911,9 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.repayDebt(0, 3263180366223418726332425327208, 1743811046578291753383292467076526830); _liquidationERC20PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 5, 216814); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 1584807505201036, 21819891234459380077606); - _liquidationERC20PoolHandler.kickWithDeposit(8611729861443627261679311396797280627133877238864133496379845814, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.lenderKickAuction(8611729861443627261679311396797280627133877238864133496379845814, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.bucketTake(683338786247575831872948294875544668, 115792089237316195423570985008687907853269984665640564039457584007913129639933, false, 9963237928546435409876148141275225428376123491, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC20PoolHandler.kickWithDeposit(17000, 3615, 3469); + _liquidationERC20PoolHandler.lenderKickAuction(17000, 3615, 3469); _liquidationERC20PoolHandler.kickAuction(25172197882706756023742, 3837785839624629010448858802571700273587964882935332965195175228512291, 6387, 3375734291957121359); _liquidationERC20PoolHandler.withdrawBonds(3, 367043431289133579893, 2426046554167808046446397784554654454); _liquidationERC20PoolHandler.drawDebt(61904084357905511157470322736698, 1497496893588931806, 6390); @@ -924,14 +924,14 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.drawDebt(23400, 23980, 104840085623197258403977897537199410562118047964227451692804812514219625756594); _liquidationERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC20PoolHandler.kickWithDeposit(958, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.lenderKickAuction(958, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.addCollateral(3938141390048693701847196824102, 1864729267, 1161500271334936669, 1030274797347608509); _liquidationERC20PoolHandler.pullCollateral(1698108582560339947405192917569559028133808, 1, 64029364906659); _liquidationERC20PoolHandler.removeQuoteToken(694, 1256450943196961316, 5819, 889625192651428331513926016513882824003783758750686563057430236970834261); _liquidationERC20PoolHandler.moveQuoteToken(3303063, 622655458, 836974672997607380671063680001528893211972464224929775599268792223532, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 786037603045454529101403996544); - _liquidationERC20PoolHandler.kickWithDeposit(2232900406, 1030274797305031155463625, 6505); + _liquidationERC20PoolHandler.lenderKickAuction(2232900406, 1030274797305031155463625, 6505); _liquidationERC20PoolHandler.settleAuction(8572, 650036754385967122642087316784, 46239, 8151); - _liquidationERC20PoolHandler.kickWithDeposit(2109, 1727063608, 4796948359709353116569441925411456299708878408219759218759481864883); + _liquidationERC20PoolHandler.lenderKickAuction(2109, 1727063608, 4796948359709353116569441925411456299708878408219759218759481864883); _liquidationERC20PoolHandler.pullCollateral(124495333526015378361714646, 764167120170977559997915934127132272, 22661075646710341534612480788361277086580670925); _liquidationERC20PoolHandler.pledgeCollateral(2092375151, 918561375893756863204668280733173485257088250348914242875199720070935048, 5823); _liquidationERC20PoolHandler.takeAuction(3307152019989773420047156042906112165, 3268431003071, 2, 3486721580009490751180212074842184769652696206115608157622022468104); @@ -954,7 +954,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.drawDebt(64156003358989711139932164170218739478365299, 689999123894668915458766490334272565843598785955280884347956, 20174980797); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 90274539885046931065309928304272846509927196301524662069677774311, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.moveQuoteToken(425378266987136543731207643195, 11073693098980284087011875815545, 1037435872805888617, 145503426094396358, 1075490592770460865); - _liquidationERC20PoolHandler.kickWithDeposit(675842230308748959361293270898068952118065854500743555, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.lenderKickAuction(675842230308748959361293270898068952118065854500743555, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.settleAuction(1, 101380667825908973265607582353404532964700541312, 579721524590480169103371220745602172854378457190564570323776, 92577943061); _liquidationERC20PoolHandler.takeAuction(2625, 12344, 2745641597491456055104200193654, 41320); _liquidationERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3, 2); @@ -1017,7 +1017,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeQuoteToken(26595339367327581743902209211978986059949321162756394034092674970144280, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1026174322255285319887578, 0); _liquidationERC20PoolHandler.settleAuction(1919068160839404076778292078, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 216965491778105351258468947327175078036211213948044555903487119005572707); _liquidationERC20PoolHandler.transferLps(2334854984330509919, 6382109749365246024353814223472801, 1000003986880047404, 1678, 34801918684169167725149645673708); - _liquidationERC20PoolHandler.kickWithDeposit(1, 1, 0); + _liquidationERC20PoolHandler.lenderKickAuction(1, 1, 0); _liquidationERC20PoolHandler.addQuoteToken(92619026354654679839851207723920993, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.kickAuction(109981004093362104638008355582, 71488348429, 3, 3); _liquidationERC20PoolHandler.drawDebt(73740774801381544986955729830731314857498253325705971315346268034000, 837, 48332479279137694379031623767529560169192319981456135364); @@ -1026,7 +1026,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addQuoteToken(4067482921992213258, 9260, 5196756089998411484, 3919); _liquidationERC20PoolHandler.removeQuoteToken(23188667972994424856250, 2017103575387026142, 425378266987136543731207643195, 363481960551815251945962924583801202217685635938); _liquidationERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 139240371575729732083859073007814, 0, 8085975866384996939631928055395041580, 683384515114); - _liquidationERC20PoolHandler.kickWithDeposit(105477872244131878996670077789791573035972483970931213034703672696000393, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 203325931983809853949980933245339483771331722206569313716601607348); + _liquidationERC20PoolHandler.lenderKickAuction(105477872244131878996670077789791573035972483970931213034703672696000393, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 203325931983809853949980933245339483771331722206569313716601607348); _liquidationERC20PoolHandler.settleAuction(4117868951218824289357518469861188961417605165417296941629248248927649, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _liquidationERC20PoolHandler.removeQuoteToken(312727169768323281, 1, 3, 38232233652652215132236686870167633559276); _liquidationERC20PoolHandler.takeAuction(0, 16003196547748791261183204635703544781570253710903400721613164590, 1, 869103393552363122086838337); @@ -1062,7 +1062,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 758735188388531567219881106462, 4975382883352998538994039599843747993267476871732267007342930624806195646); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2249170651770539863853601213281750485068624433494896); _liquidationERC20PoolHandler.addCollateral(6204580536458029646768441127858, 10599, 4716385834122172636221508206945, 14845); - _liquidationERC20PoolHandler.kickWithDeposit(13032282838528861986082232016135, 886551274601799817243254636996, 1006251318689026780); + _liquidationERC20PoolHandler.lenderKickAuction(13032282838528861986082232016135, 886551274601799817243254636996, 1006251318689026780); _liquidationERC20PoolHandler.addQuoteToken(3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 12122); _liquidationERC20PoolHandler.pledgeCollateral(0, 96479134312696651161161813, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.repayDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -1093,7 +1093,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.transferLps(8409222723822611255, 2, 1150840829371173875351233503269821056024495422, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 4496389453370271801); _liquidationERC20PoolHandler.moveQuoteToken(183532285628218633348402426804625953433406990307683696594756496757868022, 5962912878415021617058386259327395629308182154181812610144, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 63834265782950701362154); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1388901763374434672583512486137340268414649, 3); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1388901763374434672583512486137340268414649, 3); _liquidationERC20PoolHandler.settleAuction(15092, 234525661307290245083562612747625, 4239271536698724432862471109431, 6930095758229465874267100234286); _liquidationERC20PoolHandler.transferLps(9111, 1279096210496229235507056385915, 172097148181729751295466800702135, 999999999999989140484301343665390141511455882, 1079989034218997860262427); _liquidationERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 438064170421742368812615, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1114,7 +1114,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeQuoteToken(3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _liquidationERC20PoolHandler.kickAuction(1042, 2819, 11475, 3508); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC20PoolHandler.kickWithDeposit(7683874001439359295576156307642, 1140297878831812517795, 175214613747597); + _liquidationERC20PoolHandler.lenderKickAuction(7683874001439359295576156307642, 1140297878831812517795, 175214613747597); _liquidationERC20PoolHandler.settleAuction(102687085535969374890, 42224836802461644668721075194655815, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.addCollateral(41657739216, 231280981, 20358802671972803, 2); _liquidationERC20PoolHandler.withdrawBonds(9289138584507141488747887480038742698899398115592932794502577830356218587, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1162,7 +1162,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(1005875040462528413659383675316, 51981293385613155732639067926722, 7340, 202913, 210695084383105944481316014458345545877); _liquidationERC20PoolHandler.kickAuction(1633085953291005772, 56832503734027744327717725040226792332, 36435460262844598967, 41958624552868565243062985357325); _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); - _liquidationERC20PoolHandler.kickWithDeposit(569741871604597679568822114464043869028734395360471736942, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 92539044478284511378154077479271358769449761682576); + _liquidationERC20PoolHandler.lenderKickAuction(569741871604597679568822114464043869028734395360471736942, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 92539044478284511378154077479271358769449761682576); _liquidationERC20PoolHandler.pledgeCollateral(6407, 680, 13034608679712455485596722869417430); _liquidationERC20PoolHandler.removeCollateral(22201902790500374416235767121490, 815, 22350, 784795859804094444); _liquidationERC20PoolHandler.moveQuoteToken(1, 1755716966610392456643217806677048547695, 1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -1175,7 +1175,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5509529691372430696367953031); _liquidationERC20PoolHandler.pledgeCollateral(3, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(289943216918156833422, 19533908736052170437088354570020392461735971265787127202700199878868341068814, 2866016979, 3507386099443310515578839447764255); - _liquidationERC20PoolHandler.kickWithDeposit(20146340456943526073577757050603, 14534743142197001207, 4803); + _liquidationERC20PoolHandler.lenderKickAuction(20146340456943526073577757050603, 14534743142197001207, 4803); _liquidationERC20PoolHandler.pledgeCollateral(14975, 9261618417430668158478549080132, 8952); _liquidationERC20PoolHandler.moveQuoteToken(1187479412084626859918063590376, 15427814306433794144032352735255, 505867570428, 2568, 32316); _liquidationERC20PoolHandler.pledgeCollateral(7293479914071008900840943, 0, 3); @@ -1192,7 +1192,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeQuoteToken(4429, 8231809264211395720515904027625, 2051, 164716); _liquidationERC20PoolHandler.bucketTake(567530788985856366232090351815323524161711656517359828, 29538, false, 1451662727515422495802995085427853148775052435999835364, 11541829767380577320941537690432383651242212725595984964404802245500457); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _liquidationERC20PoolHandler.kickWithDeposit(6206, 43519613747518513778130140464612, 6770); + _liquidationERC20PoolHandler.lenderKickAuction(6206, 43519613747518513778130140464612, 6770); _liquidationERC20PoolHandler.takeAuction(644, 2724360160212299624482141111345, 3555, 892); _liquidationERC20PoolHandler.addCollateral(136548789091199752478351650883, 587891517097562214547752107066, 4067483099797407375, 94001466290414890801889865744271627385044851641123410220913856088777564727823); _liquidationERC20PoolHandler.transferLps(224309575649, 183560525756177411974688656526803846207427755147928690106501687, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -1238,19 +1238,19 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.kickAuction(1313373041, 20084, 36168, 22806084563170916898); _liquidationERC20PoolHandler.settleAuction(3411, 813139476308895187754073557553, 26739272214123853249, 19449); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 54909383737039496788500527828578, 1423488065050536789604239589); - _liquidationERC20PoolHandler.kickWithDeposit(5689159845022688114334338445089009574249439552144801392894867430296930255, 10, 189829844906459452511387); + _liquidationERC20PoolHandler.lenderKickAuction(5689159845022688114334338445089009574249439552144801392894867430296930255, 10, 189829844906459452511387); _liquidationERC20PoolHandler.withdrawBonds(3091296769722788186823791540418789568532, 342147, 2); _liquidationERC20PoolHandler.pullCollateral(18448304968436414829, 16342564945930248365114886708545994, 1039); _liquidationERC20PoolHandler.settleAuction(85904710, 0, 3, 115964564592045869014726710579462543481443283980); _liquidationERC20PoolHandler.withdrawBonds(9200728963944368449316239353500522876334407791554131511863431901915407070973, 1069808484140502109469410527262005990230126048051507841, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.bucketTake(1033775094051144098, 2659496865420630475243140133308, false, 2344840401988211, 156963708631597596252150845364); _liquidationERC20PoolHandler.drawDebt(521354054252298454090399864442857430167410307267348724354860, 281805545787652569650787745689073039918592980522063572491761171412827, 5249577218547431070710981864865170852370521033699892314830); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2390368354113189718960913526197827161031, 1140822467304863809064947021938520); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2390368354113189718960913526197827161031, 1140822467304863809064947021938520); _liquidationERC20PoolHandler.pledgeCollateral(2008972424690188319679833736758071979000840703204, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 141434999843009359790); _liquidationERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 464356); _liquidationERC20PoolHandler.takeAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 516054885917270255021417293157771534949649741715962178993); _liquidationERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 1); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 1); _liquidationERC20PoolHandler.kickAuction(4213, 1377019923451246112083537045005, 674873880574344201252329859468, 528296142002651633471327981881); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 138999991, 1639433749240970531912233367285053803756); _liquidationERC20PoolHandler.settleAuction(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1258,7 +1258,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 663474274619624463877118556064713535358677407498, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.transferLps(196836990773332300306089308513314616724159147281, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 213804, 1536345509351797301355987260711978027740404, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.moveQuoteToken(1, 3, 1, 23940598062545401359472793300523409445240177520741467158, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(3184655486878592966035809252972561635416, 3, 1); + _liquidationERC20PoolHandler.lenderKickAuction(3184655486878592966035809252972561635416, 3, 1); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 43387967783772271444577644071452756001024014524953256070842726141889689873, 1); _liquidationERC20PoolHandler.removeQuoteToken(0, 24099592559329642571285870975022279263902461754438922675568801735103, 438123948340379228799750637256921104270284423575331665960555, 3); _liquidationERC20PoolHandler.takeAuction(0, 0, 2, 49); @@ -1269,7 +1269,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(9938280550129850220793261211823992972368346261159, 1, 3); _liquidationERC20PoolHandler.transferLps(0, 0, 5187598828939214282526339921418227724606652613628031965224460014, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 109); _liquidationERC20PoolHandler.kickAuction(10601404809413260334, 12457262691548009084, 224319596445950793300864526038321157021517714736357500455492608335538, 657369137975758140124612261046326127243225639729805065605355833828571); - _liquidationERC20PoolHandler.kickWithDeposit(13728, 8592896088019908068473465769895101, 5426); + _liquidationERC20PoolHandler.lenderKickAuction(13728, 8592896088019908068473465769895101, 5426); _liquidationERC20PoolHandler.pullCollateral(3567253001549910689890853013891, 853536118752000365624168115338311912955880420610164107753892722975520553, 21764392183448802219303); _liquidationERC20PoolHandler.settleAuction(27204, 45629682110811013917, 2025137250458448850402995727651, 3281); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 381955, 129486325426113535176870840165750276691755278); @@ -1277,16 +1277,16 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.bucketTake(36860132080434439111239397392040971292659, 6140658368, false, 3434428180000989612233843243787204130768309934483699, 2); _liquidationERC20PoolHandler.repayDebt(429, 249769630614285455196770, 1456609065555); _liquidationERC20PoolHandler.withdrawBonds(1421553965614715587296087376166, 36370100382023407197197423479698, 905); - _liquidationERC20PoolHandler.kickWithDeposit(25560569930330935292720145809250, 1023786998719848094318700, 1482745622400163722154187794360); + _liquidationERC20PoolHandler.lenderKickAuction(25560569930330935292720145809250, 1023786998719848094318700, 1482745622400163722154187794360); _liquidationERC20PoolHandler.removeQuoteToken(560336109970384512, 5513418326731212939241128643008354159996756965461599944421555050748524, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.repayDebt(1048386399186941594879629, 2866, 13119193529757763312113858903693); _liquidationERC20PoolHandler.drawDebt(631093398156191822518651516119, 8676599700037720577573783786601138, 1001961010500715024); _liquidationERC20PoolHandler.kickAuction(12206628411166106422434556502173555, 4239, 6974, 28248); _liquidationERC20PoolHandler.moveQuoteToken(1023786991638922594, 2832874904372025650466411785847, 21208, 3770440096807019498247337156703, 40845672184773827186498527497991329242997358214796934548138039489096043683678); - _liquidationERC20PoolHandler.kickWithDeposit(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _liquidationERC20PoolHandler.lenderKickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 265624127801472923531); - _liquidationERC20PoolHandler.kickWithDeposit(1, 3, 21875270236751151045718096387782600796076819); - _liquidationERC20PoolHandler.kickWithDeposit(8538459019282634988872350469, 13705801162117899970864518389004, 188); + _liquidationERC20PoolHandler.lenderKickAuction(1, 3, 21875270236751151045718096387782600796076819); + _liquidationERC20PoolHandler.lenderKickAuction(8538459019282634988872350469, 13705801162117899970864518389004, 188); _liquidationERC20PoolHandler.transferLps(199759799107781350114343349550991, 497, 2180743764590318425656, 1000000062292734136, 4775947491736807511419322719843); _liquidationERC20PoolHandler.addCollateral(90744, 525420393141, 13985932354134354271752913286674319943, 49); _liquidationERC20PoolHandler.addCollateral(89249969659991605923694813706082678377263611985494587790767111859484643291755, 1000000000471187496, 5954, 11497); @@ -1327,19 +1327,19 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 142473239743399856055953016341427638793608549581658096); _liquidationERC20PoolHandler.takeAuction(10164797307683022350292999643351, 1594998868621216919235672938595, 5466587391368983124271191287369, 999999999999999114913558998715712986066532245); _liquidationERC20PoolHandler.pledgeCollateral(12271, 598829960386834718049609671651, 23287601731289146173260296604367); - _liquidationERC20PoolHandler.kickWithDeposit(3423765579545985681718084563836, 1203, 2356); + _liquidationERC20PoolHandler.lenderKickAuction(3423765579545985681718084563836, 1203, 2356); _liquidationERC20PoolHandler.pledgeCollateral(1344422293760301170083345887289294474808301534241783452, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.removeCollateral(44105702191588859150444052120328786055106305661457404005935479, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 2); _liquidationERC20PoolHandler.pledgeCollateral(203203367572274835957733290346992544162096087314851781664922016869, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 67789474081035347390348212228351941294482423953364726); _liquidationERC20PoolHandler.removeQuoteToken(2375332150709034511636897578194, 28664, 999999973399713977919705906092735768746264563, 34135654361264256252701021532069); - _liquidationERC20PoolHandler.kickWithDeposit(358297536181, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _liquidationERC20PoolHandler.lenderKickAuction(358297536181, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); _liquidationERC20PoolHandler.transferLps(44409565376463276744081435, 4418800529180, 5348576788646765515249057402989391594182, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.drawDebt(8351887612886545010336801399996, 1095616791464198812, 1000000003435309771); _liquidationERC20PoolHandler.takeAuction(2884221716, 3381, 35183124670560284298, 239190486492171935028231528866706); _liquidationERC20PoolHandler.removeCollateral(1829671378, 4865, 5258020892788885610064, 1328045011803835495034210039154058); _liquidationERC20PoolHandler.removeQuoteToken(41622459487914234861809080177147801129399821144262705761453694, 120255639969594074499869481328516718520974977740520320340819, 6702, 2); _liquidationERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _liquidationERC20PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); + _liquidationERC20PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); _liquidationERC20PoolHandler.withdrawBonds(3, 302738754397921363243386545024786386562370050354572296947328, 1); _liquidationERC20PoolHandler.addCollateral(566, 147388629533982715799454882285, 1181, 38898951037670015657714387875373877); _liquidationERC20PoolHandler.transferLps(1739278404896739062117647266909495932002826184886509935637827101260214055915, 5014738683364887829145006157342901477569, 916292897988, 1735694572, 3048700831887468626861956910207078464776143763356461795303803632837239); @@ -1353,7 +1353,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 201927815544798661697879429115821); _liquidationERC20PoolHandler.pledgeCollateral(49728769014918020074107076829698150002820348, 0, 1); _liquidationERC20PoolHandler.transferLps(1, 12465391437082, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 41363834680148697565176, 486800528434649375955484894044054285360403); - _liquidationERC20PoolHandler.kickWithDeposit(3785069641788993626789, 109330805999, 50038612454053116969877049); + _liquidationERC20PoolHandler.lenderKickAuction(3785069641788993626789, 109330805999, 50038612454053116969877049); _liquidationERC20PoolHandler.addCollateral(999999999999988796866327107833122277440856297, 20768, 6058, 7097001367403385503391183525474); _liquidationERC20PoolHandler.pledgeCollateral(5145236774307090396291047403146279424981705981838663326149, 1, 9075171507393423864803017354790483100309652724152); _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 62483145107); @@ -1366,7 +1366,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 253660479074, 6731420358097119659540491209319848613212796352029622, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(2, 628777872113511537381959028588270983590728574019621706247604506812262318171, 27050, 184); _liquidationERC20PoolHandler.pledgeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); - _liquidationERC20PoolHandler.kickWithDeposit(22015999008879062046723881651819174, 1138, 1000000006219674974); + _liquidationERC20PoolHandler.lenderKickAuction(22015999008879062046723881651819174, 1138, 1000000006219674974); _liquidationERC20PoolHandler.takeAuction(2812031190, 695166040737547674982300741392335527415554823899681066725033317311525899, 1611, 7057); _liquidationERC20PoolHandler.transferLps(857018152996784203040720372919447, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 305785053105657825360276749453847498388219088372580, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 679889639857881346288747929882897114897713944258, 3); @@ -1380,7 +1380,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(55515512608714882415652436156902123460968115290593670668440928097027815698, 495672, 1, 368447089773014272098238172065868334498500411); _liquidationERC20PoolHandler.drawDebt(1303152927138053846852458471464502225362113941548109, 438275440179849640835715223563410419987781376, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.transferLps(46797485890831874496286837207750357863574219474243819193962580281300157, 9861245156917629136158284020767850078284342, 46685610691555226904208861618103392441104355760555, 767579327507826548862025260445684196, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _liquidationERC20PoolHandler.kickWithDeposit(3072, 1489729693876548796265058468152, 472251444439949757); + _liquidationERC20PoolHandler.lenderKickAuction(3072, 1489729693876548796265058468152, 472251444439949757); _liquidationERC20PoolHandler.addCollateral(12537, 1220438274832401859343209819529, 2884220620, 1282593070917697887228658390216); _liquidationERC20PoolHandler.settleAuction(40110469233557260070664986862396, 1140524109538014396939922358286, 1000000000000000000063174278260, 665644430377522712479606394300011); _liquidationERC20PoolHandler.settleAuction(361323087192222911182861485850113, 272438757495276040624077804162, 173294915118139854461962934230431069372, 2122801349683577065); @@ -1396,7 +1396,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 569509492554612460292777994015941474912396612167922916132, 2); _liquidationERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 0); _liquidationERC20PoolHandler.kickAuction(1, 154847171504745652218948395451928780, 1, 3204659520887422793725626293868618233163); - _liquidationERC20PoolHandler.kickWithDeposit(581426116297367949177490772388110065666231448547, 106806140652134112102119138348000331415465234417803582355804326198, 353847788057370323920); + _liquidationERC20PoolHandler.lenderKickAuction(581426116297367949177490772388110065666231448547, 106806140652134112102119138348000331415465234417803582355804326198, 353847788057370323920); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 94, 2); _liquidationERC20PoolHandler.takeAuction(3, 1, 2, 12739282614363141031963450271792816777206682429745753778); _liquidationERC20PoolHandler.pullCollateral(470547463474708982397073434279589766146333, 1376560957954934104441689943701, 2478670353995886447139); @@ -1408,7 +1408,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.bucketTake(0, 1, false, 43180116, 1); _liquidationERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1744081308282520815206053425738, 0); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 40072203014835130622567994476, 170901910265610063052721595228766197159454452324195378823590515422974478069); - _liquidationERC20PoolHandler.kickWithDeposit(1, 1, 124265850592); + _liquidationERC20PoolHandler.lenderKickAuction(1, 1, 124265850592); _liquidationERC20PoolHandler.moveQuoteToken(16424, 2048795040952848143094424, 6193, 795807197892999360388503914721993140561530428675743459372171053850157347, 506661131830768797566926993722319); _liquidationERC20PoolHandler.pullCollateral(8059388733287833478312059653454483, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4868607135928629337656760824432737); _liquidationERC20PoolHandler.bucketTake(1903, 240295282008300134527202, false, 62907110681430603126560957185071844669359509208468529789208444216516007871140, 1017751926272850884); @@ -1419,7 +1419,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(1000569148559146780, 4712072026853408146594777902412, 1000000002619763523, 857049037515447784681833158156); _liquidationERC20PoolHandler.settleAuction(480975773619305672057899823739944550137, 837030131754995806100950591507667304263680010537638580711949887020609003693, 711013363971491878612455659051638402117437351, 3937933083693263782805627135182305152009260668887754732422604236162359); _liquidationERC20PoolHandler.pullCollateral(18218801660651406863683942007478865, 27150, 14254); - _liquidationERC20PoolHandler.kickWithDeposit(617210846496167409, 2960408220527634975079850052449, 24165067446840582842562511042503); + _liquidationERC20PoolHandler.lenderKickAuction(617210846496167409, 2960408220527634975079850052449, 24165067446840582842562511042503); _liquidationERC20PoolHandler.moveQuoteToken(1980679149563492697429195588328800076156, 74631198164672431692233275, 276, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _liquidationERC20PoolHandler.withdrawBonds(11849875040490189671675065917, 16071840925426171693165122, 308953464849); _liquidationERC20PoolHandler.transferLps(346080940829431752246297948398, 775515401937420502891403847347, 26693575983786517061431816971868152, 1023388832322527316, 3431); @@ -1442,7 +1442,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(2, 251221947758397001759404963854460773562345897637744172689725102656767487, 371655216055405920271011128116461249926889511436058929153481054776263456744, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(1999999999999984402185041545398780858441995400, 29822277423554624721599017170825029, 11469228734589030332277623017463, 3493874968556389439770868409740); _liquidationERC20PoolHandler.moveQuoteToken(1999999873708802142794052084369350875458287833, 18683070550441764782465002083807911, 1120, 37116969210268546124240867858825884, 2206366497060103377190223418409); - _liquidationERC20PoolHandler.kickWithDeposit(693252046, 1186387964848049631843379883260040520297275386319220176874865863501964913, 3586817019671345946); + _liquidationERC20PoolHandler.lenderKickAuction(693252046, 1186387964848049631843379883260040520297275386319220176874865863501964913, 3586817019671345946); _liquidationERC20PoolHandler.repayDebt(0, 11672, 136116504129171438417179151802523124831851468428); _liquidationERC20PoolHandler.pullCollateral(941224665390967157923458106385, 1999999999999999821014436651233957875759839298, 36368890031928520500001401896875283); _liquidationERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 29080221519867550101138055591534159080014668690513050993032329576488, 1, 201894135); @@ -1461,7 +1461,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pullCollateral(998551275450083045349393434965, 145635949179492897156627679173, 4748); _liquidationERC20PoolHandler.drawDebt(11518462302484418438700029811661350394170543926419426, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 12686442343234974589465875772667932832192664239951972621182337423928); _liquidationERC20PoolHandler.withdrawBonds(14408069958874258986761915308262, 6938540205872947284870492230576, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(6452, 7207, 3063952857); + _liquidationERC20PoolHandler.lenderKickAuction(6452, 7207, 3063952857); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 278119927929777745730788853053465559221409428016, 3315577004833190258413813685920114); _liquidationERC20PoolHandler.pledgeCollateral(1163185120772270409699470239764649619319682521, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 24911143841770681140273); _liquidationERC20PoolHandler.takeAuction(366930303770441006095487490824229977968638883789112612219181973102162168, 118851701727313618970061282485588, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -1486,7 +1486,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addCollateral(71473454203084169944419030779, 5009, 17409969645782489014433698896164551, 106697031467647014); _liquidationERC20PoolHandler.removeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 92936551543567118059880150063304129785958126647971412469799); _liquidationERC20PoolHandler.removeCollateral(4324464572425276889, 1068066838173663521, 360408436815529843134072079434, 1825); - _liquidationERC20PoolHandler.kickWithDeposit(10446040800629857585100976701203904724694, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.lenderKickAuction(10446040800629857585100976701203904724694, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.pullCollateral(5885447653761, 1246631610736, 1); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _liquidationERC20PoolHandler.moveQuoteToken(73006729492899523822133084389193639372544730237, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 567733422126081405128282338026963233, 1, 3); @@ -1497,11 +1497,11 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.transferLps(128573687331607193913139781683995458954198690993746533091, 1021977, 2, 6099752586636998, 1); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _liquidationERC20PoolHandler.withdrawBonds(2, 2151101568907306679205434, 1265028491997928498413903427249161940450036731190822483149); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 1636073162859546153612516165941308812427587714800574013076154420928); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 1636073162859546153612516165941308812427587714800574013076154420928); _liquidationERC20PoolHandler.withdrawBonds(3, 3426953581463307277404, 43075760049603874478682092440148793290972120); _liquidationERC20PoolHandler.withdrawBonds(1999999968332058715836803090913186520966751299, 1109487411714326643841066363013, 12836); _liquidationERC20PoolHandler.settleAuction(324146295062760379543629653, 1, 4460371167012301658964, 1); - _liquidationERC20PoolHandler.kickWithDeposit(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.lenderKickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.removeCollateral(510091443484612973284763166110370, 4029698143568110476131286773668181, 54326281663751643614594215930353259785855622952369683943604427315917105, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.drawDebt(41654925488727137808063568272197163, 7408, 1699890490819583593); _liquidationERC20PoolHandler.takeAuction(3933826739250660100144171594440880, 29208, 233874931537431526444130539775511, 2948134745909242610166804820890); @@ -1516,7 +1516,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.settleAuction(42025284371424084865352938120740, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 38875, 3); _liquidationERC20PoolHandler.removeQuoteToken(144258767699235322297666376413390, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.moveQuoteToken(999999999999997960243923689508590358793238152, 86281706796073995434388480242829278277721838458597503574114465309750919575780, 6226487098215611883147609631810344, 57094920783582695530840800828108, 43046721000000000); - _liquidationERC20PoolHandler.kickWithDeposit(66798973287937706259784413104315513006902123786418083366322678458347714091514, 239872411695577437097866895113, 22376); + _liquidationERC20PoolHandler.lenderKickAuction(66798973287937706259784413104315513006902123786418083366322678458347714091514, 239872411695577437097866895113, 22376); _liquidationERC20PoolHandler.addQuoteToken(7321549002997100270643898706910813930537081278849447, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3092483999818575265201969609646767635505530261333742683489653548149442742609); _liquidationERC20PoolHandler.transferLps(70064598548696301127, 566322293988871541754362467626340367327536269790153181937807187877408325466, 1154536071240718701947104725639244439916999731673496475754137745023603880, 22486424957868062443382486271184751015791645541274196404200532122550, 115792089237316195423570985008687907853269984665640564039457584007913129639934); @@ -1547,20 +1547,20 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 62364391695486267000576489180656829778036876666646993634211029, 3184738113690091, 2); _liquidationERC20PoolHandler.drawDebt(10468705148701143657072475145051101265963755, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 302936063297177892532772016769279032525853349410085689826348); - _liquidationERC20PoolHandler.kickWithDeposit(35070498359691, 23432, 6696); + _liquidationERC20PoolHandler.lenderKickAuction(35070498359691, 23432, 6696); _liquidationERC20PoolHandler.drawDebt(75406678607603651626832431655941680, 1747781291706057775184, 1010489354880451557412201205687); _liquidationERC20PoolHandler.withdrawBonds(1704488981166274825108413781455323173845147234699301246184631808172, 32873131229305894056981450790423035358359700418, 12875918643472791649623351087773895937); _liquidationERC20PoolHandler.transferLps(1, 55727620448, 92, 292787373241541737756463518477956988335078866585429791274309008007282, 21459549980754364600974578132749321310809); _liquidationERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1751923892059930264356053309909363942711057610171855368984381, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 1); - _liquidationERC20PoolHandler.kickWithDeposit(14435656529482196070963425478517165267231, 29960, 999903800603536116560017499841655446840683475); + _liquidationERC20PoolHandler.lenderKickAuction(14435656529482196070963425478517165267231, 29960, 999903800603536116560017499841655446840683475); _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 39630588809978718334137474802424715472632607777984600809308286570510691, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.kickAuction(34599140821721004872146293788607579, 2079094606631248939573265, 75547074675952753431022387033607839, 1037704452964084398); _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6334089054211995, 70954223961299852304884929224633); _liquidationERC20PoolHandler.pullCollateral(12814334915570895588093880471138, 20481784895010570144901687555267, 7299121079913046718600); - _liquidationERC20PoolHandler.kickWithDeposit(324656462129661673085551374955014058409, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.lenderKickAuction(324656462129661673085551374955014058409, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.removeQuoteToken(1337979035741660779103317692497953654459231, 29643885804379431674936266388143284380073894825487093, 5141070170065179, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.takeAuction(1236441125787264625649453408991, 607, 2306897834405321530470647634899375, 22497); - _liquidationERC20PoolHandler.kickWithDeposit(182923339824695377225165347654229, 10118351144707016169251106519057, 14760); + _liquidationERC20PoolHandler.lenderKickAuction(182923339824695377225165347654229, 10118351144707016169251106519057, 14760); _liquidationERC20PoolHandler.moveQuoteToken(3, 257096285020638136544775003156470892447678672145863994929224516616420905, 1259047666226954746333986662507670683941798984775111291133, 2, 130082810654749235603204422110); _liquidationERC20PoolHandler.removeQuoteToken(23670, 0, 809584435791512814684433974742480398677502583498291, 1); _liquidationERC20PoolHandler.kickAuction(9948335530185888455199886979473, 5196754986324574723, 1000000038009125451, 183815587865270587917205605010912); @@ -1570,15 +1570,15 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(85495680025, 33066438403539243050205147767, 2); _liquidationERC20PoolHandler.removeQuoteToken(33423122566106219564880651462831726, 29821992027185497256804521752640691, 26926297201797448308282348078989619, 18683071668887553831903493343544604); _liquidationERC20PoolHandler.moveQuoteToken(3218, 5755, 111338239158506438317142529200, 59395200056630812322390070242235379, 12744); - _liquidationERC20PoolHandler.kickWithDeposit(1059113621149848822, 1000061409582393212, 5029022274314959645335499479244); + _liquidationERC20PoolHandler.lenderKickAuction(1059113621149848822, 1000061409582393212, 5029022274314959645335499479244); _liquidationERC20PoolHandler.addQuoteToken(3, 72833915696960411947652415399351158928689922830, 476394131428309245856224602680476380100716843147078073230613107060496, 12573733045543350381601238947566304); _liquidationERC20PoolHandler.moveQuoteToken(736589894126, 6191622570718449220129930903764060486761475087945631380783118, 55823, 3, 6628324997298962385098190278465773572776571086374); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19117935095018769281353862325873, 235064, 167238871596327640582); _liquidationERC20PoolHandler.bucketTake(7075, 1133365525801942245, false, 6712, 4064422259990117805156626958909704); - _liquidationERC20PoolHandler.kickWithDeposit(14182757781668611274455656334326, 11449376913590974402386983079462592, 221260959124963460594604460369); + _liquidationERC20PoolHandler.lenderKickAuction(14182757781668611274455656334326, 11449376913590974402386983079462592, 221260959124963460594604460369); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.bucketTake(3556311203, 16342471872591808574461572770734592, false, 1041753664546387465165938280824302176852546210498102365531219852414166552, 1000008105346646203); - _liquidationERC20PoolHandler.kickWithDeposit(2, 37382081939594744606266700402843541827079229107135053, 233324202040370028371806391440947031893954424422); + _liquidationERC20PoolHandler.lenderKickAuction(2, 37382081939594744606266700402843541827079229107135053, 233324202040370028371806391440947031893954424422); _liquidationERC20PoolHandler.settleAuction(406340599513339470631426885749, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 555431229104702340522); _liquidationERC20PoolHandler.addQuoteToken(75407551750008902572126553545811806, 4702, 90608535124274706322401261491318647, 75222379577151499743273104654); _liquidationERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); @@ -1593,7 +1593,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pledgeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _liquidationERC20PoolHandler.pledgeCollateral(30291935847004061215630590273256620, 638613783494526764459484995366386, 948011831205408124039909083144); _liquidationERC20PoolHandler.settleAuction(26376, 71597609871358614278553126563579611205594244307006467, 1226191867790291912023009953355, 109413548234219834742); - _liquidationERC20PoolHandler.kickWithDeposit(33513844677624561186, 8541, 1037498618972871011); + _liquidationERC20PoolHandler.lenderKickAuction(33513844677624561186, 8541, 1037498618972871011); _liquidationERC20PoolHandler.removeQuoteToken(12349834, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 2); _liquidationERC20PoolHandler.kickAuction(21036, 1476019353954887964797392099574618582645943544195042103646685919181645239, 8627488212148956216967, 1037435872627089435264827); _liquidationERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 87701183770184883123099579906270975083392346635069182640414861063073210, 382516332383047920359907855039676741459451, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1604,7 +1604,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(346216889575493455500534772690, 6292, 822, 346223992857487998675810095580); _liquidationERC20PoolHandler.addCollateral(6220991522311278791356, 6333425167894330313650319429309, 2878705437013655346318496586882, 1259391345044787663); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 972351475228534632409, 18597657358899405795226526574991022197, 778929497536277498040045853897722419771309295480661286148763); - _liquidationERC20PoolHandler.kickWithDeposit(84715834552883270549, 1737, 552922486650437896336228337919); + _liquidationERC20PoolHandler.lenderKickAuction(84715834552883270549, 1737, 552922486650437896336228337919); _liquidationERC20PoolHandler.repayDebt(564282758101329098032237788401310812468106591259792424102, 497896864420392950697207018724749, 438751821688025265176713401457165273528542410714381150420083); _liquidationERC20PoolHandler.drawDebt(1, 738968925434039882367248856443119273812713882817611000427338705093388824260, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.moveQuoteToken(6904, 999999999999999999375924560773900965537169217, 58347508761915812413420944357190209, 112763819644670319893230237063298837, 3235183385310977709817); @@ -1616,7 +1616,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pledgeCollateral(1, 26553861614590984287499687418045258262632345, 1); _liquidationERC20PoolHandler.bucketTake(6400913498579748927, 115792089237316195423570985008687907853269984665640564039457584007913129639932, false, 536428316683650309186112716849019189591410136073237, 9475833273503883576388613451861611312401496682); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 14846835018, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(25578, 168438337473479248982207602433519182986110361412261842, 16167365174050713927287752); + _liquidationERC20PoolHandler.lenderKickAuction(25578, 168438337473479248982207602433519182986110361412261842, 16167365174050713927287752); _liquidationERC20PoolHandler.transferLps(11923, 2770205520102603824108954439438, 1394343900389548287, 5523, 560064669103939699050930870511); _liquidationERC20PoolHandler.transferLps(10337567286437701281284, 2, 114285565130887391, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 45329184097210580468982056349637855045174179, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -1636,7 +1636,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(75961902188997306998533519433974507755, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3671503261819, 1465718828122672794206396979164659502010473574, 86356669430903039473500256147764168305569873); _liquidationERC20PoolHandler.removeCollateral(55179595826612934513494354121242108, 68777794606202006183486888368430, 8517629759961877688460710463220, 46440512678648109551); _liquidationERC20PoolHandler.kickAuction(3, 18653796555954574270094020, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _liquidationERC20PoolHandler.kickWithDeposit(22721878533902109127887238302730760775033832349145988484428736101050217, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 237515184182272316329479583509008948691017945883); + _liquidationERC20PoolHandler.lenderKickAuction(22721878533902109127887238302730760775033832349145988484428736101050217, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 237515184182272316329479583509008948691017945883); _liquidationERC20PoolHandler.removeCollateral(625463959184073847612222320347, 2776824937, 1010489354880451557418665888951, 1002005571852725942); _liquidationERC20PoolHandler.takeAuction(11900351467945498441960762786346155643418644006729824888638663140390, 2798100, 16529319796640, 15459741712945939594201192716738); _liquidationERC20PoolHandler.settleAuction(465863883603546192492578423226665928534328768417130974410938937103171068830, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -1654,13 +1654,13 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.moveQuoteToken(10113092, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5478655427356259200410250, 1366861404090354644036054253345780100432834152665581347790414, 272241339920643255102129260469398870546331956398); _liquidationERC20PoolHandler.pullCollateral(452833827682988208281189882481702285, 1237716375242328830088212380657960, 29451083107119663123497528485797155); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _liquidationERC20PoolHandler.kickWithDeposit(1999793747059384695388435910206114926896175776, 550917265766066076976816523690282, 5304); + _liquidationERC20PoolHandler.lenderKickAuction(1999793747059384695388435910206114926896175776, 550917265766066076976816523690282, 5304); _liquidationERC20PoolHandler.moveQuoteToken(3685116822206421791473, 24353856812664804974700830719755276, 29602553456699505411924168351382, 112050403619541126438168436919693753, 52998408067983295591322199620178278298944); _liquidationERC20PoolHandler.moveQuoteToken(1006342773421085205, 999999973399715185001714725013192832550951273, 26926277186799335767684060230996648, 5490510354746911849, 177057445719536967259167058903030); _liquidationERC20PoolHandler.settleAuction(43431391919629208679047588936064984904390681914275147832, 1237728409656374876477104614, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); _liquidationERC20PoolHandler.withdrawBonds(12701566195212600669849214552124, 6112, 1000000008440797709); - _liquidationERC20PoolHandler.kickWithDeposit(389133999214186838797283216836044915381148267223589240179984278867118, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _liquidationERC20PoolHandler.kickWithDeposit(400673016434456444851283089633727682508127156545361200670, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1255414616903228473357162937324895385619629612838); + _liquidationERC20PoolHandler.lenderKickAuction(389133999214186838797283216836044915381148267223589240179984278867118, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.lenderKickAuction(400673016434456444851283089633727682508127156545361200670, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1255414616903228473357162937324895385619629612838); _liquidationERC20PoolHandler.pledgeCollateral(11621527874499, 2, 4); _liquidationERC20PoolHandler.drawDebt(163396412114000526113870010043020304946477247761866701, 439122172384354016614786284693363639, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(6233824456207077101056, 1, 7500484386839401124976356291274528888393406112900152330955480, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1689,7 +1689,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.pullCollateral(42218807178469388699840183376961417712938657585022, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 16697583952570988805935521007638913894122292507827692354540); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 159263956406795075170682558899607326023267877780376432377448503921, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 191044914719050599883530605363160297954399095222302576803707823837223279580); _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 779861723686610486554746940881328356991654693, 2); - _liquidationERC20PoolHandler.kickWithDeposit(1761971072, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.lenderKickAuction(1761971072, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.removeQuoteToken(2, 71052234025600570285655539577973314912065539792432297412131, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _liquidationERC20PoolHandler.moveQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 3, 3); _liquidationERC20PoolHandler.drawDebt(43055055497078855912661933570638726197320, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 11629); @@ -1742,7 +1742,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.settleAuction(52883729304257928841947896275703016, 7022, 9647949837937828210857853843996, 45134708444041344661664272362725); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 744175154376942590097644900898, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.takeAuction(715344796060044574719876401510139, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 11450, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 259526482, 2498500718040673799020949881012880972620753809); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 259526482, 2498500718040673799020949881012880972620753809); _liquidationERC20PoolHandler.withdrawBonds(159793, 2, 39770049432); _liquidationERC20PoolHandler.moveQuoteToken(482188048673918269357385923249, 1, 2740413169371537690231352527915934388158355509175111587973521272376610, 0, 2133234199048826256152445); _liquidationERC20PoolHandler.addQuoteToken(109081365567409467883151996406121923917777738142278042885843639492808331822, 625473182516265521302572857984288072363470, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 9920152182630); @@ -1751,7 +1751,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addQuoteToken(3, 364063155450052428274049048977248061235470913, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 51259613659940421804776608437336616326276877171342759598939); _liquidationERC20PoolHandler.kickAuction(2937649563032, 19889410814636091694259082765303011653545788318933922258070863, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.settleAuction(105738998354076669014529504607577402519233853760889, 695051975067623438958018668135059130626846780187103126161076, 6098839995954425291140613589330718286610473748475292770956593570, 0); - _liquidationERC20PoolHandler.kickWithDeposit(1377020139107469590759663794401, 728187939245212499551669322729, 3151027794); + _liquidationERC20PoolHandler.lenderKickAuction(1377020139107469590759663794401, 728187939245212499551669322729, 3151027794); _liquidationERC20PoolHandler.repayDebt(3333337496447651396, 5552, 264359551083264964); _liquidationERC20PoolHandler.withdrawBonds(3, 128, 47660593244118533241986180151788214552001673394592659); _liquidationERC20PoolHandler.takeAuction(1004085663791407235988875, 690479920665055094984550244192672, 61563674451, 1699900755054682712); @@ -1762,7 +1762,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.moveQuoteToken(5075269675518593362639986360469428295396041727710168860592632448587056712436, 702784453692, 999999943167493398182179306100501451553896446, 30906617125206254229305336841557740, 553752298382825683162256016390); _liquidationERC20PoolHandler.withdrawBonds(311231544918208086377034898833088310037363204813931456306047677, 78396912902201798639984981376807244853734212078750989390688144, 4999452372067653198009011148974588); - _liquidationERC20PoolHandler.kickWithDeposit(2, 305164825078467294185296460657298, 3); + _liquidationERC20PoolHandler.lenderKickAuction(2, 305164825078467294185296460657298, 3); _liquidationERC20PoolHandler.addCollateral(881, 6562938912595, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); _liquidationERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 51572491232394571, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.transferLps(54347710771407376387384228333461468511773, 2468143957056893191664499963201904420386258758480778939227317, 3, 2, 854857108184454389760531427040733558049003188426253756500179820439105223); @@ -1778,7 +1778,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.kickAuction(3, 102173475751, 747306448698006792466831528355416102072241468015101543256975569854156047420, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.moveQuoteToken(32673503115026229007012228867575850786962, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 774637722732682731733865327175530656497860236470915191703865164473239, 16228, 2722498449793140893469625985349827808830707269683494745); _liquidationERC20PoolHandler.removeQuoteToken(5280938911639540329966971340193, 268435456, 1004326448215893873, 830630872742174951966); - _liquidationERC20PoolHandler.kickWithDeposit(113322756159296272089552060401766, 7693883461382628449781981224508, 55826311177308569971079026071813230965080332731738038533925925351740026105452); + _liquidationERC20PoolHandler.lenderKickAuction(113322756159296272089552060401766, 7693883461382628449781981224508, 55826311177308569971079026071813230965080332731738038533925925351740026105452); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 22, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.transferLps(1000000304087238923, 352548414157449007297080867, 31940120107675296125660783586888, 284088993229034528164530931046028529, 203738398150652679792915800254); _liquidationERC20PoolHandler.kickAuction(272686980222126771524004334864663449, 68618962530160834094116820679695404130, 52575915, 159791869966848971); @@ -1790,7 +1790,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.repayDebt(28002057643899221176957912260601, 56550383691, 78659726225135404531); _liquidationERC20PoolHandler.repayDebt(38539756690756796931790840301174943, 1771663078151615315791295399897351892564952218735339216762230220256997663, 1419123693977062392446636); _liquidationERC20PoolHandler.settleAuction(31472523588705767332769, 2523411106853673669090426890242091109356, 2543948551852472557143941253061378419563077816424744490795, 0); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 3); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 3); _liquidationERC20PoolHandler.moveQuoteToken(1502403412175627230671593061912264576255150032527179415953282154268725720, 5838089081482949247865865735286750771505116248626788087, 12030855090098148374903888315183329897081, 520543561859, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 879060697817461137093177980019305389209049220129227, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.moveQuoteToken(3960246407173827617592555605533943118895106628561143115415, 778464786473868381, 1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -1799,15 +1799,15 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.repayDebt(159508734139392219081789103179823, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.kickAuction(4211879175073153538739905785, 380872949540923206886810902738091483345872797681539477340823437099545131644, 2895485801390578740943420947507720627086043220858500325252032018075695, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3653580693620688861251785, 1019652, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(357335290571458261706036706266466, 214795226283050742943674919780, 1000000002110199420); + _liquidationERC20PoolHandler.lenderKickAuction(357335290571458261706036706266466, 214795226283050742943674919780, 1000000002110199420); _liquidationERC20PoolHandler.addQuoteToken(5937, 160110466834061262, 6083, 132828088170404013173500033453); _liquidationERC20PoolHandler.takeAuction(2640171742678673466703340239040435022268150966113, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 622318701107049701984792792065932144040996, 0); - _liquidationERC20PoolHandler.kickWithDeposit(3869108004, 7568783627582864987963534764328, 393384402887125527268); + _liquidationERC20PoolHandler.lenderKickAuction(3869108004, 7568783627582864987963534764328, 393384402887125527268); _liquidationERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 505608); _liquidationERC20PoolHandler.addCollateral(7125, 948093537714687520, 27864, 246733393078443419588502886197590214); _liquidationERC20PoolHandler.pledgeCollateral(21803, 1127057905270367289699390, 2492126816140724393230141238192); _liquidationERC20PoolHandler.moveQuoteToken(170204712183129708604837582783197851, 10191, 99, 17415439345103888656048988238979146, 18446744073715366156); - _liquidationERC20PoolHandler.kickWithDeposit(107776584810667930167225708797, 11704, 394668164584996324563775691764036475); + _liquidationERC20PoolHandler.lenderKickAuction(107776584810667930167225708797, 11704, 394668164584996324563775691764036475); _liquidationERC20PoolHandler.bucketTake(0, 0, false, 8742205789170289715820748717063696935225771814, 14035489045628360448351284992302868749198007924659284322138261929482946); _liquidationERC20PoolHandler.kickAuction(1011925749339051153847572297981, 1019428557574749764, 838052307148078519, 29495816993527168670450925020587184); _liquidationERC20PoolHandler.withdrawBonds(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1820,19 +1820,19 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.settleAuction(1101629296614662274662722635181, 92795903950988179674048653308512683978462977909601659621874403302093297935, 664669127499086830, 28956706259731049); _liquidationERC20PoolHandler.withdrawBonds(7124, 14540, 2215385759); _liquidationERC20PoolHandler.pullCollateral(1414, 1951971412255540628, 164255122525129458376782433340483820); - _liquidationERC20PoolHandler.kickWithDeposit(356327678940018434658542448470398875180191532648669734, 20412550162199423199882, 10809); + _liquidationERC20PoolHandler.lenderKickAuction(356327678940018434658542448470398875180191532648669734, 20412550162199423199882, 10809); _liquidationERC20PoolHandler.takeAuction(234336795343058464243609662754022468, 15463, 25716, 46206459611232821710258966060242408); _liquidationERC20PoolHandler.drawDebt(7873845088622976382864429600001128253687192020931398, 2, 8875676957570945843517907569551935914305763304169671652932804); - _liquidationERC20PoolHandler.kickWithDeposit(3, 1494178453681296527100665418616174904485965936224747493689940388810928764584, 3); + _liquidationERC20PoolHandler.lenderKickAuction(3, 1494178453681296527100665418616174904485965936224747493689940388810928764584, 3); _liquidationERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 287043031073330581196049, 295891219986495515320557023271924965); _liquidationERC20PoolHandler.takeAuction(84430392959149898762155227582559886578618480696467788375730645923931822, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 16286509035942226662129850199339691083479561221752414811375568331735365921488, 731570984948369); - _liquidationERC20PoolHandler.kickWithDeposit(264225165305995668154469327355667786009512273494080394, 17532647541435990172, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.lenderKickAuction(264225165305995668154469327355667786009512273494080394, 17532647541435990172, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 423040411043143502477739460332936550252280075411268349867839542470, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.withdrawBonds(1999931571521984707948560157925509455448271850, 3073703905231324223966753683073875, 14149061408420627095229906200648); _liquidationERC20PoolHandler.transferLps(264918756289709693938799472490449514, 121407494485422920563211880228057746826551608642309037419273, 24822713823435980987, 115820998811797072468166598824744, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.addQuoteToken(3, 353383926466098469443889776227790614543688678846757582928719841550736174213, 17624519611274981053378908426418747754, 137432397021); _liquidationERC20PoolHandler.takeAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 31694543940719395374506433041712953663080529113489394, 2958493606573960057494374684126463430339635595735220427814565824548968795); - _liquidationERC20PoolHandler.kickWithDeposit(2, 2, 541094728244368102780655737260392501280835458812349); + _liquidationERC20PoolHandler.lenderKickAuction(2, 2, 541094728244368102780655737260392501280835458812349); _liquidationERC20PoolHandler.kickAuction(3337245626355878237684, 964012250792881996062280, 1822098056114239452376311950137803894718753870255670995104295114173601828, 31820934401561817875369535576114061253045602576635224244662716790187225140341); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 143835898498818826096962815306178617640669462132734995323861672126522018, 313018756420431364571557973528208397); _liquidationERC20PoolHandler.takeAuction(19584394209793400378831995857995615043037487044468048783758029261222475077, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 3213299790888611685911958464977456049598939230571372803111334101883965353975); @@ -1858,12 +1858,12 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeQuoteToken(39363554788185861962223976477738656621231164536767995141994486935405, 2, 3, 1323); _liquidationERC20PoolHandler.kickAuction(190444099949730904760092788907730724, 1276866741914019905, 56087026497945952033, 5819); _liquidationERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 673388295068344528421294071590279766180561827169839479193734010414151121, 2, 1701239605775795477412735143176603536861171); - _liquidationERC20PoolHandler.kickWithDeposit(0, 5435962809425969510815611614354304183958157, 0); + _liquidationERC20PoolHandler.lenderKickAuction(0, 5435962809425969510815611614354304183958157, 0); _liquidationERC20PoolHandler.removeQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 249273291579961360759140348316764088092671611587113344849); _liquidationERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 232598899371115558349554260015, false, 1, 363313225633); _liquidationERC20PoolHandler.withdrawBonds(1378687179382561571822058789198, 135984964984744701267176709, 1013388490871478097248684806450); _liquidationERC20PoolHandler.removeCollateral(1, 4694105535632500327348330233753347897049529475107197642657043221, 3, 13804220465526865653693); - _liquidationERC20PoolHandler.kickWithDeposit(29999507412727580438182881173299, 999999999999993291936522890114629559158078741, 1999958864753689105057735436299182823286429295); + _liquidationERC20PoolHandler.lenderKickAuction(29999507412727580438182881173299, 999999999999993291936522890114629559158078741, 1999958864753689105057735436299182823286429295); _liquidationERC20PoolHandler.bucketTake(664370163947035568313334244662826118431164209505591, 990054720316834, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.pullCollateral(3673174657967049984084414096033363889392482583674851856291, 1123727254784339187558203469890656692341196814297184062, 32701600906047405717879151118293508827173268524728958394544223118226935172); _liquidationERC20PoolHandler.transferLps(1, 1, 20840568773720593554904249488649891225643022489015, 2, 102168994424133231876030901538094171625200040851661649462452002141); @@ -1877,7 +1877,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.kickAuction(2775319957605459681562889020, 86520762849966484302389472082432785997889911078203689, 8615260252262140977596, 22125228135317473296); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 106, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2927002734189982693624); _liquidationERC20PoolHandler.drawDebt(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 197072438144042418106658174650); - _liquidationERC20PoolHandler.kickWithDeposit(703112020307201707515539940782159042677550917872584429757, 4227698939291748248595176491594386, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.lenderKickAuction(703112020307201707515539940782159042677550917872584429757, 4227698939291748248595176491594386, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.withdrawBonds(75584255977265532327, 342987066832602679771080893583, 91074713056013678658053978983434734); _liquidationERC20PoolHandler.removeQuoteToken(38017129912091268560612011723399045921368284473729360394085035933572237765118, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 634604059189397771357166866742, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.addQuoteToken(2606800230111140876446024783333, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -1914,13 +1914,13 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(996, 834242890361989544, 34886847077215667900407501893857696839634778071075293191425257382422012185439); _liquidationERC20PoolHandler.kickAuction(616285736217966104906544438861896923, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 9832785311554901394529856510023940494961209161159844225877846261965260, 13041358); _liquidationERC20PoolHandler.pullCollateral(2608953068828953702, 2544505546497361851799809688138, 5284); - _liquidationERC20PoolHandler.kickWithDeposit(511862917281461237426893721616247989281119199388920708790903456208001030472, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _liquidationERC20PoolHandler.lenderKickAuction(511862917281461237426893721616247989281119199388920708790903456208001030472, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _liquidationERC20PoolHandler.pledgeCollateral(538377768954517685, 2645806779815680374977348265761886097239, 1); _liquidationERC20PoolHandler.pledgeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.removeQuoteToken(171689953570941913381116205320043801, 49329307818581629973470704358109005, 11860872310313877801310669035911, 1562183713296714933696785064346); _liquidationERC20PoolHandler.pullCollateral(14540347077258789855750390143456488980522126191554782074, 31038911724749177389262039993, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.removeCollateral(3840568699456614479162960612528539, 115109919145062482317792171020775, 1852, 1361184627788890955327091836684608898953094160286809083011398981392818283); - _liquidationERC20PoolHandler.kickWithDeposit(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.lenderKickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.pledgeCollateral(2, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.repayDebt(4385191414843958107195413109934, 75407449409141005143205751534101710, 457773474269147366762597334509); _liquidationERC20PoolHandler.takeAuction(1254255936521993216569300145736857052787520323444984819690064043429421, 1, 1, 948001628019808628444612340681870481338701755); @@ -1929,7 +1929,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.removeQuoteToken(1356038261863046207754816647066, 11780, 491434909205858855432359822169, 3781875797709437685289888962433); _liquidationERC20PoolHandler.settleAuction(60402310132212550772836693756224982, 7102419632328095885413, 5728, 3111698218224072256713521930705); _liquidationERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5011423438896381, false, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _liquidationERC20PoolHandler.kickWithDeposit(1000000065537899408, 4866031170, 9511); + _liquidationERC20PoolHandler.lenderKickAuction(1000000065537899408, 4866031170, 9511); _liquidationERC20PoolHandler.addQuoteToken(166, 952716922757582465306372728974, 179725728638278564232518892957387143000572184450, 2225189056882436016646523321259159346885657443086349263); _liquidationERC20PoolHandler.repayDebt(106996773742211988165620120149742160787, 0, 2); _liquidationERC20PoolHandler.pledgeCollateral(28709538333622503415521317243799156933779885564188221324993649, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); @@ -1942,7 +1942,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(1216608765936077493961031325824419897254198941347138292885315050589535442, 909, 553860876945323010174467765, 2116); _liquidationERC20PoolHandler.removeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3959749509882121235418060248741634113864740709); _liquidationERC20PoolHandler.removeCollateral(140554894239494641060584544971659, 46368659938093125110717300123805379897280069272566430836850435568576, 0, 396788035169726789845183365995902688915805630922630533788331485); - _liquidationERC20PoolHandler.kickWithDeposit(6836721363443, 1967577180213, 1186497541432845364964401573531567797080585865); + _liquidationERC20PoolHandler.lenderKickAuction(6836721363443, 1967577180213, 1186497541432845364964401573531567797080585865); _liquidationERC20PoolHandler.repayDebt(1153, 28380215237074380749564568152532625, 11089); _liquidationERC20PoolHandler.settleAuction(12528282612534910084849985973, 3072329877435329996373764, 0, 3); _liquidationERC20PoolHandler.pullCollateral(93678781365955858652849018209900, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1957,11 +1957,11 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 47638263707723829724392753); _liquidationERC20PoolHandler.pledgeCollateral(2, 1492255181948291, 7919); _liquidationERC20PoolHandler.removeQuoteToken(999855925089057994976611694893046553074415446, 69665900642876717262449349300311641, 4533716895551853677802443, 445400550358798594); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.withdrawBonds(396538032021238355075541735913150654851375340282947791328730774712, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.pullCollateral(29738904041258873880018149685184483511092077354819390709272711231569055072810, 20744591268115466683208, 37920605645293449013987397220802314); _liquidationERC20PoolHandler.repayDebt(20146452451913501602523867804973, 1775, 255735536265989907098292830282708182); - _liquidationERC20PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 75622244035312465703511160290270031386539135081069970988778264); + _liquidationERC20PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 75622244035312465703511160290270031386539135081069970988778264); _liquidationERC20PoolHandler.settleAuction(309231309640205094847891209341281675401761564514531, 155293241401893114503152605113721190553053724076832749091383010725538, 418507167090026732, 82); _liquidationERC20PoolHandler.bucketTake(44954933993361862701218733411127939207671659608645298393768924093973356677, 24211091801864942449126485809011254495460180, false, 28655603304326239005333600737600164621638009741339692773573433031544537, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.moveQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -1973,7 +1973,7 @@ contract RegressionTestLiquidationWith20BucketsERC20Pool is LiquidationERC20Pool _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 1, 2); _liquidationERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14819900235970556627031895677682500562266515385536408823, 352088884439205197489822554918442576809020, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.settleAuction(2978216434672118087, 999500318161101295995752831493603837641592507, 27496301577559382942782256802753, 11860872217491657657774671354343); - _liquidationERC20PoolHandler.kickWithDeposit(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.lenderKickAuction(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.bucketTake(3530, 2985325127, false, 2773713294270349755687100442010, 11966678993985930819698310868227); _liquidationERC20PoolHandler.repayDebt(1620134971, 1510034900360754554840774, 3227); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 32146832743173123956824573971387, 16670311354329445004227754302338528251225840696194644363935, 2); @@ -2028,7 +2028,7 @@ contract RegressionTestReserveEvmRevertERC720Pool is LiquidationERC20PoolInvaria _liquidationERC20PoolHandler.bucketTake(22765324419526727572603601977900698325264802588, 7533929630559522736121398142063238102045629830, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 244214723782593976865616866798803); _liquidationERC20PoolHandler.withdrawBonds(1128228894618696303584964046455212952744233345903252711986057862490511, 3652098029031134911608867443042718748103259829347769588484425681660064545593, 3); _liquidationERC20PoolHandler.drawDebt(28713, 7737, 12707); - _liquidationERC20PoolHandler.kickWithDeposit(18056, 5435, 2860); + _liquidationERC20PoolHandler.lenderKickAuction(18056, 5435, 2860); _liquidationERC20PoolHandler.addQuoteToken(27112000, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); _liquidationERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 798265474509252397436472217, 12447110935); _liquidationERC20PoolHandler.settleAuction(4137627460448967178018548476500114887655556666197, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 168558123165843084105619138874476609213253, 3123126809); @@ -2039,7 +2039,7 @@ contract RegressionTestReserveEvmRevertERC720Pool is LiquidationERC20PoolInvaria _liquidationERC20PoolHandler.pullCollateral(62096022603261910391915529699612025965090365927877467, 233329356247989315499380880613332782326468622531907280482238497197007122, 13); _liquidationERC20PoolHandler.removeQuoteToken(10175619617937467555654632294044665887894864601726296094761316834435937680, 889974652827764069853464043941089390137377, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _liquidationERC20PoolHandler.removeCollateral(639, 13260, 1520, 10564); - _liquidationERC20PoolHandler.kickWithDeposit(4997, 9332, 11088); + _liquidationERC20PoolHandler.lenderKickAuction(4997, 9332, 11088); _liquidationERC20PoolHandler.addCollateral(440100009998, 2435270231063538, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.addCollateral(3590525101177806600273026, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1126906423986601743, 12106990512766854325058603917294727674929227916650928146244248512412948059); _liquidationERC20PoolHandler.settleAuction(13377, 17259, 2482, 4447); @@ -2084,7 +2084,7 @@ contract RegressionTestReserveEvmRevertERC720Pool is LiquidationERC20PoolInvaria _liquidationERC20PoolHandler.addQuoteToken(5425, 7676, 16514, 3555); _liquidationERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC20PoolHandler.takeAuction(1676994081, 1493, 23704, 17824); - _liquidationERC20PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _liquidationERC20PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _liquidationERC20PoolHandler.moveQuoteToken(181237287132711354399, 4637845448874433765629, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3514341427711996191277073773683861093716635506552698744241787834695306380768, 3); _liquidationERC20PoolHandler.moveQuoteToken(5282, 21884, 5925, 1002474608431867682, 23640); _liquidationERC20PoolHandler.removeQuoteToken(1900, 3010, 12081, 3085); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestRWERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestRWERC20Pool.t.sol index 5d6f52dcb..fd3b88d86 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestRWERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestRWERC20Pool.t.sol @@ -33,14 +33,14 @@ contract RealWorldRegressionTestReserveWithQuotePrecision4 is RealWorldScenarioI _reserveERC20PoolHandler.removeCollateral(1002580094500313390, 4349918351284402115944745, 15883378519233197999993482, 20131171169937622184259233583); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1971276126515618090809269981755202625621, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC20PoolHandler.kickWithDeposit(445111249236231050, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1478); + _reserveERC20PoolHandler.lenderKickAuction(445111249236231050, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1478); _reserveERC20PoolHandler.moveQuoteToken(58576, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 33098097); _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 260702590952862450913576644866280910051133308320, 67722548236883655728327240241521288280348, 9201465619164779947691674263609372601606463329); _reserveERC20PoolHandler.moveQuoteToken(29999999999999999999999999999999999999999900050000000000000000, 1751021327260965438140078474, 9090596393695245040902366017867282, 12176, 186176); _reserveERC20PoolHandler.removeCollateral(91104, 2950251536058311779672, 2013045480121387317266085984, 4846); _reserveERC20PoolHandler.pullCollateral(0, 0, 932826914200829216833488894128047256686607562109149515); _reserveERC20PoolHandler.settleAuction(16956974056639888415703243270106258861027432719340291487789, 838253015765304, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _reserveERC20PoolHandler.kickWithDeposit(214714674051826133189, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.lenderKickAuction(214714674051826133189, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _reserveERC20PoolHandler.pledgeCollateral(1597, 1193183683178164662693349, 11385); _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1551378768118532558604594588559, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.kickAuction(155920, 6346024412533292418122715, 165436, 108800); @@ -49,7 +49,7 @@ contract RealWorldRegressionTestReserveWithQuotePrecision4 is RealWorldScenarioI _reserveERC20PoolHandler.repayDebt(158288, 1000139695383059594700678, 28855713437726691455957594488); _reserveERC20PoolHandler.bucketTake(1106091987343555638750929, 1686892875, false, 1679267730, 108092); _reserveERC20PoolHandler.removeQuoteToken(1, 8146489593381014177684143965379792440238763, 3, 11); - _reserveERC20PoolHandler.kickWithDeposit(21435, 641975060134140426, 7607); + _reserveERC20PoolHandler.lenderKickAuction(21435, 641975060134140426, 7607); _reserveERC20PoolHandler.kickReserveAuction(144284, 119979095118923778894466); _reserveERC20PoolHandler.kickAuction(6820959702894797920460492, 2524492372289063576522568, 25934875004694140332937460761, 19480); _reserveERC20PoolHandler.removeCollateral(214694620246634467819157, 11911052875786719171772749940, 12991, 184012); @@ -120,14 +120,14 @@ contract RealWorldRegressionTestReserveWithColPrecision2 is RealWorldScenarioInv _reserveERC20PoolHandler.removeCollateral(1002580094500313390, 4349918351284402115944745, 15883378519233197999993482, 20131171169937622184259233583); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1971276126515618090809269981755202625621, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC20PoolHandler.kickWithDeposit(445111249236231050, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1478); + _reserveERC20PoolHandler.lenderKickAuction(445111249236231050, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1478); _reserveERC20PoolHandler.moveQuoteToken(58576, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 33098097); _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 260702590952862450913576644866280910051133308320, 67722548236883655728327240241521288280348, 9201465619164779947691674263609372601606463329); _reserveERC20PoolHandler.moveQuoteToken(29999999999999999999999999999999999999999900050000000000000000, 1751021327260965438140078474, 9090596393695245040902366017867282, 12176, 186176); _reserveERC20PoolHandler.removeCollateral(91104, 2950251536058311779672, 2013045480121387317266085984, 4846); _reserveERC20PoolHandler.pullCollateral(0, 0, 932826914200829216833488894128047256686607562109149515); _reserveERC20PoolHandler.settleAuction(16956974056639888415703243270106258861027432719340291487789, 838253015765304, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _reserveERC20PoolHandler.kickWithDeposit(214714674051826133189, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); + _reserveERC20PoolHandler.lenderKickAuction(214714674051826133189, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _reserveERC20PoolHandler.pledgeCollateral(1597, 1193183683178164662693349, 11385); _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1551378768118532558604594588559, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.kickAuction(155920, 6346024412533292418122715, 165436, 108800); @@ -136,7 +136,7 @@ contract RealWorldRegressionTestReserveWithColPrecision2 is RealWorldScenarioInv _reserveERC20PoolHandler.repayDebt(158288, 1000139695383059594700678, 28855713437726691455957594488); _reserveERC20PoolHandler.bucketTake(1106091987343555638750929, 1686892875, false, 1679267730, 108092); _reserveERC20PoolHandler.removeQuoteToken(1, 8146489593381014177684143965379792440238763, 3, 11); - _reserveERC20PoolHandler.kickWithDeposit(21435, 641975060134140426, 7607); + _reserveERC20PoolHandler.lenderKickAuction(21435, 641975060134140426, 7607); _reserveERC20PoolHandler.kickReserveAuction(144284, 119979095118923778894466); _reserveERC20PoolHandler.kickAuction(6820959702894797920460492, 2524492372289063576522568, 25934875004694140332937460761, 19480); _reserveERC20PoolHandler.removeCollateral(214694620246634467819157, 11911052875786719171772749940, 12991, 184012); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol index b466d1fce..c8cd030c8 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -131,7 +131,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { } function test_regression_reserve_16() external { - _reserveERC20PoolHandler.kickWithDeposit(24364934041550678417946191455, 52607039466540426076659653665991, 0); + _reserveERC20PoolHandler.lenderKickAuction(24364934041550678417946191455, 52607039466540426076659653665991, 0); _reserveERC20PoolHandler.moveQuoteToken(12701858085177571414571267592, 42692775850651681314985098497603, 999999999999999997089137720115121650200233243, 110756792431977317946585133, 0); _reserveERC20PoolHandler.takeReserves(1000000005297961791, 4169814726576748738687746199368099036929520400874217254297794929654231, 0); _reserveERC20PoolHandler.takeReserves(3052809529665022333893308239466671666604242469878272137069, 2, 0); @@ -146,7 +146,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 0); _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 175006273713916823228319530732179, 3, 0); _reserveERC20PoolHandler.kickAuction(999999999999999989948035804259829580593704779, 2999999999999999995605838724439103323477035837, 567178035339127142779327214, 0); - _reserveERC20PoolHandler.kickWithDeposit(17028734043909648834002499445, 9578925065330517200577552073309, 0); + _reserveERC20PoolHandler.lenderKickAuction(17028734043909648834002499445, 9578925065330517200577552073309, 0); _reserveERC20PoolHandler.addQuoteToken(6672165, 3776221923932077947607417775990788567, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); invariant_reserves(); @@ -256,7 +256,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.addQuoteToken(2, 2, 306147942052277777154794038508061442, 0); _reserveERC20PoolHandler.takeReserves(999999997592778230040335721194842507878613188, 617767166532412476599141189, 0); _reserveERC20PoolHandler.kickReserveAuction(103210968180742388081044815736108888392928341723424194324988612249639, 0); - _reserveERC20PoolHandler.kickWithDeposit(571331675273077569870268525690, 3000000000000000153070529032047742375224439804, 0); + _reserveERC20PoolHandler.lenderKickAuction(571331675273077569870268525690, 3000000000000000153070529032047742375224439804, 0); _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 2345974107770202992, 596944268880651135381308885897365469741047535828013376978854456255492067, 0); _reserveERC20PoolHandler.kickAuction(249542131817080594576330466916380605939068941221926774088755, 1792443579171442237436215, 2, 0); _reserveERC20PoolHandler.settleAuction(2475430586786710276861336070835, 2600907908657087816392951766665339, 618867463233346276220185869, 0); @@ -277,7 +277,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _reserveERC20PoolHandler.repayDebt(123785744463475277851, 431477, 0); _reserveERC20PoolHandler.transferLps(8349868629210939854344368826901611192, 2050523511941068426657597285533, 482178822629563486190079445656644, 113294184847064316812952522804, 0); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0); _reserveERC20PoolHandler.settleAuction(2, 60232917818899277216367937385395389606, 109871490879953029603376159938904259489696033217506136, 0); _reserveERC20PoolHandler.repayDebt(11000946587948121111587595267746251370302202324589596297423219199459160, 1640564753028103680512592653747, 0); _reserveERC20PoolHandler.kickAuction(3981871706795545560915874060150150667177950440617972926122855684987, 198277768150818655020367, 2892877132676919180494078569276042, 0); @@ -373,7 +373,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.settleAuction(2913861884801667469428509650, 17685440748964982730500143988068465999241920952718023027278539889735696458314, 744860398079104642573120377479575543713282684535849403581932752660396046, 0); _reserveERC20PoolHandler.takeReserves(9546428924610247071820016, 1, 0); _reserveERC20PoolHandler.kickAuction(1021712469506287128291988, 470273052888220, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); - _reserveERC20PoolHandler.kickWithDeposit(21372131561480654576901520848, 583255095299263976575486908, 0); + _reserveERC20PoolHandler.lenderKickAuction(21372131561480654576901520848, 583255095299263976575486908, 0); _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 219682941, 6398456408984021365251851328837461998816613070677747503909692892499751257833, 0); _reserveERC20PoolHandler.moveQuoteToken(8413969458442105899430554342773, 42973831423907508485458560352, 14483994975746621772566970294, 27693669185946254354714892761, 0); _reserveERC20PoolHandler.bucketTake(0, 1, false, 1, 0); @@ -400,7 +400,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.takeAuction(1000000000147122258, 3919731510820678131056801, 158441107709132461742605107, 0); _reserveERC20PoolHandler.repayDebt(15097247704276523502490912, 5821681489746654725611665637, 0); _reserveERC20PoolHandler.addQuoteToken(409278183265946161107935122, 13459778251101474251175765782, 17131651646875762675637482511491680925564181440856864512, 0); - _reserveERC20PoolHandler.kickWithDeposit(3000000000000000000003060052276861736589117902, 10971651541557993591476169, 0); + _reserveERC20PoolHandler.lenderKickAuction(3000000000000000000003060052276861736589117902, 10971651541557993591476169, 0); _reserveERC20PoolHandler.drawDebt(99176811231448450752542388131222351, 4756085816094695387473840, 0); _reserveERC20PoolHandler.transferLps(345464481275697722, 1, 1571, 636770839146216364947817981246144824780203402016795537219680499840300283500, 0); _reserveERC20PoolHandler.takeReserves(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); @@ -450,7 +450,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.addCollateral(942680573168415959, 1199548961510475789275654540025108262785374840317057516601691579134979, 2999999999999999999695465971169782999351812188, 0); _reserveERC20PoolHandler.takeReserves(1471, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _reserveERC20PoolHandler.kickReserveAuction(32594801409066350134162972068, 0); - _reserveERC20PoolHandler.kickWithDeposit(2999999999999999574088451549152362060347655934, 48090144344287028180951883593, 0); + _reserveERC20PoolHandler.lenderKickAuction(2999999999999999574088451549152362060347655934, 48090144344287028180951883593, 0); } /* @@ -528,16 +528,16 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { function test_regression_bucket_take_F1_F2() external { _reserveERC20PoolHandler.settleAuction(1510914784515760699173187165544, 56781153476701101508130985112, 738818868447359631695629380008183363630282764181000585867138796869876478, 826729014323244190827572488053); _reserveERC20PoolHandler.pullCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 81950073367662209514774267517191923671913258); - _reserveERC20PoolHandler.kickWithDeposit(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC20PoolHandler.lenderKickAuction(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, true, 16564, 1); _reserveERC20PoolHandler.pullCollateral(2, 11181577647630232495296346954387708896679284248835926583085255351494229, 4615339307365404773083); _reserveERC20PoolHandler.pullCollateral(1007164428353398281573211, 964159427775903864473526777760, 261230209900412451745100526475); _reserveERC20PoolHandler.kickAuction(0, 554539983014618013651520598582291624736058825092179787664, 607065087, 2); _reserveERC20PoolHandler.pullCollateral(8677988786893516887084947060, 10701983022987536454745187554, 2320584222753413054555955504763); - _reserveERC20PoolHandler.kickWithDeposit(1486776298593531042, 2020603011457936715090930810854, 1402064626949378737); + _reserveERC20PoolHandler.lenderKickAuction(1486776298593531042, 2020603011457936715090930810854, 1402064626949378737); _reserveERC20PoolHandler.pledgeCollateral(65582376469670144960045063897640986143586634210322834458, 245005754869224, 2); _reserveERC20PoolHandler.withdrawBonds(2523139806230558464349567550, 1188425283706188004221953654058, 6393771947719760203082952454725); - _reserveERC20PoolHandler.kickWithDeposit(1, 2691769591875735361793461264703373146895996368, 0); + _reserveERC20PoolHandler.lenderKickAuction(1, 2691769591875735361793461264703373146895996368, 0); _reserveERC20PoolHandler.takeReserves(5737, 2688407785637229852497751501094273, 1004385089582049768428212223255); _reserveERC20PoolHandler.takeAuction(554219272498135606970798166790315003, 3, 2, 0); _reserveERC20PoolHandler.repayDebt(29687620020, 3369242366170335995970777, 225603670502873549001365942057667084788237); @@ -561,7 +561,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.kickReserveAuction(3, 111350983922696397771656120829290070270862146672613); _reserveERC20PoolHandler.repayDebt(537837957907582525859501126027241, 1066815515628580409796241599143, 1001156513580077724); _reserveERC20PoolHandler.moveQuoteToken(150994705072980195816644977482, 1728676792823377569756944287120, 3749400490566836004015771809290, 166858, 1509516514751735973985835075499); - _reserveERC20PoolHandler.kickWithDeposit(193413806405457706345786708852661811545178, 1047704970, 2995221756746166151759690152622550418495787241369904977564155482144830696); + _reserveERC20PoolHandler.lenderKickAuction(193413806405457706345786708852661811545178, 1047704970, 2995221756746166151759690152622550418495787241369904977564155482144830696); _reserveERC20PoolHandler.addQuoteToken(3023841269839124425804122589061027, 2058019688463725681621910836029, 891046488727245859377654469131, 1249210750552821373482); _reserveERC20PoolHandler.pledgeCollateral(3, 0, 98322504996953992046749321771); _reserveERC20PoolHandler.pullCollateral(92794261541957113617256800038346816759944975908266533925455372278785, 1230582320792434706053835371, 1276471416813335613); @@ -584,7 +584,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.settleAuction(1793755319666702586223721636112, 1062058871163086566, 2413232366548259005446, 1796325987279351495770187048297); _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 143381296286622596217261690020938346499350019625300111739, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.kickAuction(746337189990642222625, 24840873603345398151212671885145398406615143472203234339196049246556, 0, 1514976639337558233422658496899394592); - _reserveERC20PoolHandler.kickWithDeposit(8405289450785532590816548320, 1029707615502801074, 4520920790726583536432399129470); + _reserveERC20PoolHandler.lenderKickAuction(8405289450785532590816548320, 1029707615502801074, 4520920790726583536432399129470); _reserveERC20PoolHandler.transferLps(2996563606833486714118058094564, 702408244445504832281666423610937442523512618396554838397742202654139648, 762810992474851803555903948575531786509, 11084174673435631351973324677604, 61235761931845916270908237816); _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 275227317920633202208830403173255314144728374, 2, 0, 688725045170235338428585609807); _reserveERC20PoolHandler.kickAuction(1, 2, 95173045790157393433334185544083261266161112921995634013255737145082976, 2); @@ -600,16 +600,16 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.kickAuction(201, 21631479461464263959768, 78123176120365843894150397741, 9300800067863236721553303813027179802975904016109787695236273); _reserveERC20PoolHandler.takeAuction(2736062665407603508654, 2060027413022391924621910998607, 1889598418819244308794543271766, 3085151436892150503789441382075834); _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _reserveERC20PoolHandler.kickWithDeposit(16534523299591874273106448500135778, 71859113478704890667760930617275, 157063302890337049783087968502017451800257526563959); + _reserveERC20PoolHandler.lenderKickAuction(16534523299591874273106448500135778, 71859113478704890667760930617275, 157063302890337049783087968502017451800257526563959); _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC20PoolHandler.pledgeCollateral(7463182009321059015374227047840412, 101831081341642573274301689378412876012422960796588974807649751, 0); - _reserveERC20PoolHandler.kickWithDeposit(6057082585985160611374338873092, 9037036310590101965162407201532, 1757181752773554121418819873463); + _reserveERC20PoolHandler.lenderKickAuction(6057082585985160611374338873092, 9037036310590101965162407201532, 1757181752773554121418819873463); _reserveERC20PoolHandler.repayDebt(3, 1, 1); _reserveERC20PoolHandler.pullCollateral(860890364359, 357071378403476971353854511534324768381739279063271933897303445465789815353, 6593344128314924384710528432227744612333514602846854245); _reserveERC20PoolHandler.transferLps(2151741125651550001598260859423, 1000000000000, 7738815365523781817313950916289, 769770164544161186766097336122909859786947698826792914214697337544273867, 843462236981741829082334556003); _reserveERC20PoolHandler.moveQuoteToken(1, 946799222988, 1, 813535, 3); - _reserveERC20PoolHandler.kickWithDeposit(6117630415543116221029359681, 1436615297827490227261541667418, 660419568619948531310455586057838); - _reserveERC20PoolHandler.kickWithDeposit(1, 2, 1); + _reserveERC20PoolHandler.lenderKickAuction(6117630415543116221029359681, 1436615297827490227261541667418, 660419568619948531310455586057838); + _reserveERC20PoolHandler.lenderKickAuction(1, 2, 1); _reserveERC20PoolHandler.takeReserves(42317498246148578995135345225498459937438, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 75242355315450165939025760776986335913274750311380); _reserveERC20PoolHandler.takeAuction(0, 737682015658631343232102398874034548752313741661360229665602145052, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2); _reserveERC20PoolHandler.addQuoteToken(267101460469660557, 21691712974319419159980592740542096318021321414207, 774819884029991515642353812484, 1); @@ -690,7 +690,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.pullCollateral(2107184968682540637222168402402260, 6976945233474060516949541924, 10666089550012015382626455302014); _reserveERC20PoolHandler.takeAuction(2, 10001569229914546588403446781361564495361, 45867941843605449875930196882942691023106069575773335329017753223, 15827094); _reserveERC20PoolHandler.settleAuction(4459787066864056137922416868599, 1043836262122498138, 5293003766838764380279676973542, 824026457496951518112890267558); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1722842605532975337834938114152151019578165536286804239); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1722842605532975337834938114152151019578165536286804239); _reserveERC20PoolHandler.removeQuoteToken(3236621837, 44183766947594404, 2974124552001687, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC20PoolHandler.kickAuction(105185097275328730025037262046113899775376496820745273956304586546, 1589078415473592047181994985685135, 1, 3217485339); _reserveERC20PoolHandler.withdrawBonds(321128742051564402669457978517, 3, 11597933248424411); @@ -702,7 +702,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.drawDebt(1059512, 1, 909477225258871115986346185885701353249075126); _reserveERC20PoolHandler.repayDebt(1027379846155197184, 5021429792761646149436322671963, 761108618539002443286025569073624232820788258138497851866096066064141603); _reserveERC20PoolHandler.repayDebt(1, 1891088270259771, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _reserveERC20PoolHandler.kickWithDeposit(300390279396872823639244057100825569615, 0, 3); + _reserveERC20PoolHandler.lenderKickAuction(300390279396872823639244057100825569615, 0, 3); _reserveERC20PoolHandler.withdrawBonds(4196906598583494376186279932398, 4497241908239658040573381740008, 1046112866272332596); _reserveERC20PoolHandler.transferLps(45001641534605145137523002218999291861378873673372208251415919733, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 0, 3434873428102678042182782); _reserveERC20PoolHandler.repayDebt(3303634669327189965378726651570, 1406376839519270869072044219653090, 380296556529511098221); @@ -717,7 +717,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 12377615235980434330469749220, 54289616930265498272273182179664228091804062500140130319397233, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC20PoolHandler.withdrawBonds(1000117305548843410, 73849868392851742413150409706, 4346276117046344791695503030483); _reserveERC20PoolHandler.settleAuction(9547521812214451840653486389726, 794441229233281486, 4511497902694814377922862924051, 1000000007626253540); - _reserveERC20PoolHandler.kickWithDeposit(1039853791313702979, 1002386832397769812553370, 24519218157573415); + _reserveERC20PoolHandler.lenderKickAuction(1039853791313702979, 1002386832397769812553370, 24519218157573415); _reserveERC20PoolHandler.addQuoteToken(1005767073092496690, 11343481630748420758999004408570, 3225912566227729574375973110, 2349178470758192740760600733698030); _reserveERC20PoolHandler.repayDebt(126172940855594324020583670142245989043194002832582726, 614364996266979362934279134515, 175241477724685331709233230552259521288362115444301425763618382220169154); _reserveERC20PoolHandler.removeCollateral(2069362329751901762, 0, 3601637614991925341243, 409012071510846939820280682934901873417767627622444842446); @@ -730,7 +730,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.bucketTake(3223823237354686313918759360797465471784188352102860652348606665897890, 1754353286614602592, false, 2185014526, 3860770289842261099567160893419805); _reserveERC20PoolHandler.repayDebt(7517685404433611986094250342214, 7940901081625241886337696262142937, 1097380875386845652); _reserveERC20PoolHandler.settleAuction(466828746892708685166031060246, 7700884483698536245874645220943, 24755120684682887675851958558, 13022015566438663971362971400004); - _reserveERC20PoolHandler.kickWithDeposit(13171130573439383597216480715235988594211573475731394375016373802717212, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 914024113882843531397); + _reserveERC20PoolHandler.lenderKickAuction(13171130573439383597216480715235988594211573475731394375016373802717212, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 914024113882843531397); _reserveERC20PoolHandler.removeQuoteToken(695447900447299642356165997679842662901566195463157340836308600901538944, 26338, 2750085291079463313654375774119, 1009983518963444847128355032656); _reserveERC20PoolHandler.repayDebt(2, 720009914530612268728781952715289187456556291113063227723, 1); _reserveERC20PoolHandler.removeQuoteToken(186798158006677995439829616916, 1669048312912208536158674351746, 1331790117327389005457408891555, 1009210456843097238); @@ -741,7 +741,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.drawDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 23962313511619198832612632); _reserveERC20PoolHandler.settleAuction(3539333218283803558221379703441729486607923717130701980907774963194645577, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 122417852564842231348); _reserveERC20PoolHandler.repayDebt(1036157435152920871, 296432208332564, 1041275378574753707); - _reserveERC20PoolHandler.kickWithDeposit(221918906303210725917652444807610588787540333206884, 2, 2); + _reserveERC20PoolHandler.lenderKickAuction(221918906303210725917652444807610588787540333206884, 2, 2); _reserveERC20PoolHandler.removeCollateral(10147684103334539502918396075581113, 3841078953660488375366583614786, 5676616818976646660864850730552, 477776147858243698); _reserveERC20PoolHandler.takeReserves(1113050647784922130, 142473471658488519340713962054, 2478598952576055565665905); _reserveERC20PoolHandler.withdrawBonds(2, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -763,7 +763,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.removeQuoteToken(1207029624308850304685657760952501453282297619043072791255821747487419643922, 1, 219115292265915811623890717117285699021873530422413, 1284055940502576843747109289578849); _reserveERC20PoolHandler.kickReserveAuction(1, 3); _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 81879577845458796722163030797080833476139568975206586970647380742, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _reserveERC20PoolHandler.kickWithDeposit(1188022138207972484, 811819938423221709910746519451171960025020447862340415313819696144610399, 116756059283900633269555696670); + _reserveERC20PoolHandler.lenderKickAuction(1188022138207972484, 811819938423221709910746519451171960025020447862340415313819696144610399, 116756059283900633269555696670); _reserveERC20PoolHandler.addCollateral(278745405706241433205866274723856692911353790542553123896139586, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 0); _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14398994507642219, 387176001736981316845899134170473924828818, 391032112785994464285277564833775366165); _reserveERC20PoolHandler.kickAuction(61041404087, 291935695912440421090686268850060008895187650347757099923166, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); @@ -773,7 +773,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.transferLps(1931854544556192231849350062994774, 2044637794174221820726854298843, 2099054531044613733088458086519, 146401084693287768820340001895, 7984503452821327002253); _reserveERC20PoolHandler.takeReserves(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _reserveERC20PoolHandler.drawDebt(81475957283104500803441729085, 3612778198882533119778837270530, 9922714459144784603057264887419); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25104328799466); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 25104328799466); _reserveERC20PoolHandler.pullCollateral(90676237759214414885900829290828179209609353668805, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC20PoolHandler.drawDebt(90117714255547081923244102774281723, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); @@ -833,7 +833,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.addQuoteToken(14036311948084606882143641577, 6114726890383846519464348356, 27440, 124577843671240731663191476069661363485564336329605232166988892654002); _reserveERC20PoolHandler.transferLps(9872990784377414306547041, 999999999999999999999989641217604218267494373, 1672536439, 10027, 2533); _reserveERC20PoolHandler.drawDebt(3, 14972137663886333686802900321, 523892674); - _reserveERC20PoolHandler.kickWithDeposit(1000130943059863910, 6131, 1017224451143915959); + _reserveERC20PoolHandler.lenderKickAuction(1000130943059863910, 6131, 1017224451143915959); _reserveERC20PoolHandler.kickAuction(16612, 9052172837629344905112030283, 149277958556264141173760145, 16812); _reserveERC20PoolHandler.takeReserves(3, 101612373222750572528253027191156910463885519243511875272520449979009, 266614003985374887564348479277741231124260919310742954767943555991); _reserveERC20PoolHandler.takeReserves(607548627652618511385002408008383549076778857, 1, 429966741527392416); @@ -849,7 +849,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { function test_regression_failure_A1_repaydebt_t0_rounding() external { _reserveERC20PoolHandler.transferLps(883172166925196014153612741, 1011874887306145524, 1560280797611982634762545, 2999999999999999999999999999999999999999988581, 166067911958117829389897753); _reserveERC20PoolHandler.drawDebt(109748618821205351803014988731482981932, 1, 1946224850931); - _reserveERC20PoolHandler.kickWithDeposit(23120646526972050226088733811, 114506716413332403306176469, 85883); + _reserveERC20PoolHandler.lenderKickAuction(23120646526972050226088733811, 114506716413332403306176469, 85883); _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.removeQuoteToken(16015765038220222984273010530, 1020363514639207733373983, 1014737335754083714, 673321911366647590987964); _reserveERC20PoolHandler.repayDebt(266183799725795118552059050547, 999999999999998990000017889368360594282917314, 25104380621850820); @@ -875,7 +875,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { Fixed by making invariant logic inline with pool logic (applying penalty take to t0 debt). */ function test_regression_rw_reserves_failure() external { - _reserveERC20PoolHandler.kickWithDeposit(2745, 24455, 13722); + _reserveERC20PoolHandler.lenderKickAuction(2745, 24455, 13722); _reserveERC20PoolHandler.pledgeCollateral(123337267943716142615242382731926630930323989357616310, 831733227434971474, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC20PoolHandler.withdrawBonds(15840, 11617, 226); _reserveERC20PoolHandler.bucketTake(1365, 2902, false, 18724, 939); @@ -890,7 +890,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.pledgeCollateral(2, 76961268213505018630059906018712883113465719035691941927061520, 0); _reserveERC20PoolHandler.takeReserves(3097519512, 94653314286117312, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _reserveERC20PoolHandler.kickWithDeposit(3417, 5313, 1065); + _reserveERC20PoolHandler.lenderKickAuction(3417, 5313, 1065); _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 262723374, 3); _reserveERC20PoolHandler.settleAuction(18592, 23024, 59620, 1130); _reserveERC20PoolHandler.transferLps(17904054251994466560905859484014215462564, 15888216163148783188069980097884298806041869, 2, 79507040, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -900,7 +900,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.takeAuction(6470269723793827696552427938265598607645887801758057431297364941052293, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2866630568615781311922993476096073, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.bucketTake(68664, 7326, false, 4233, 5677); _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3); - _reserveERC20PoolHandler.kickWithDeposit(0, 1218898441896362378535137262535177203, 21798664731976227158610477457991755208543783402036139286216); + _reserveERC20PoolHandler.lenderKickAuction(0, 1218898441896362378535137262535177203, 21798664731976227158610477457991755208543783402036139286216); _reserveERC20PoolHandler.failed(); _reserveERC20PoolHandler.bucketTake(13445613122200147477792608151727, 270565483187498024573987287835057900370441980356809225245307134, false, 172971071584471702836978258371210100661094308, 0); _reserveERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3168, 69361987003667393973146886443285869929, 151854736120); @@ -911,13 +911,13 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 4136243925327015826551896052210933199888246316718789990226072929761635355, 17017692613008421741158348905143822); _reserveERC20PoolHandler.pullCollateral(576878529233854490611652048799820558153187703902, 23345238424267457, 678151723892535345234384954426157441012880665738860910379295890697763880); _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 8022761294074727038680587196911881844164552093948646494354); - _reserveERC20PoolHandler.kickWithDeposit(22192, 33876, 1849); + _reserveERC20PoolHandler.lenderKickAuction(22192, 33876, 1849); _reserveERC20PoolHandler.kickAuction(3, 54344449090570270030575794, 41331735998982754712822, 413913523436635659969293009110325); _reserveERC20PoolHandler.pullCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 590921270504087763943624823522978007950936); _reserveERC20PoolHandler.failed(); _reserveERC20PoolHandler.takeAuction(2147, 4584, 3843, 5018); _reserveERC20PoolHandler.failed(); - _reserveERC20PoolHandler.kickWithDeposit(14340, 48434856810956849965736021604069675576075951470372408084823421939858231806374, 3299); + _reserveERC20PoolHandler.lenderKickAuction(14340, 48434856810956849965736021604069675576075951470372408084823421939858231806374, 3299); _reserveERC20PoolHandler.moveQuoteToken(68852, 7424, 1038525076100356668671255, 492568651, 13139); _reserveERC20PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 505628); _reserveERC20PoolHandler.failed(); @@ -945,7 +945,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.kickReserveAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.kickAuction(42696, 53948, 4098, 80208); - _reserveERC20PoolHandler.kickWithDeposit(11168, 4687, 46203667883211236176009300351222888745161251164121910689922122206957300538260); + _reserveERC20PoolHandler.lenderKickAuction(11168, 4687, 46203667883211236176009300351222888745161251164121910689922122206957300538260); _reserveERC20PoolHandler.bucketTake(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 52717956413245182495690438857638203602407222750947906512913358177748309461, 1830655722053423400022802920473021837); _reserveERC20PoolHandler.transferLps(8648942085539954219328447003223809341519, 950885841320713403982849019036607701793496635, 1864492050351847862134365417027951703327712, 0, 12365193093817834339793997848323656585885308060548800349); _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 441041722731880847112545726224); @@ -976,11 +976,11 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.kickReserveAuction(1000236603027803172, 21754741055016307934840204006); _reserveERC20PoolHandler.withdrawBonds(373702251020986977207790889868085050901394374965, 4140, 53424); _reserveERC20PoolHandler.transferLps(58808, 53864, 35788, 74796, 55652); - _reserveERC20PoolHandler.kickWithDeposit(1764, 5382, 31700); + _reserveERC20PoolHandler.lenderKickAuction(1764, 5382, 31700); _reserveERC20PoolHandler.pledgeCollateral(1058781579682788238311, 3595163542440, 1174127066216041681081057); _reserveERC20PoolHandler.withdrawBonds(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); _reserveERC20PoolHandler.repayDebt(3, 577096421800264625310269861, 6069872263612439813277667159763490263920271842304881717238); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 19, 2); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 19, 2); _reserveERC20PoolHandler.kickReserveAuction(4210960525909156020704, 150717425581035467460005734401755); _reserveERC20PoolHandler.transferLps(19525089915530989, 200896599144468014944428982, 31856939995214172578550674772713104925855484, 1, 15450231414793903579649709108337); _reserveERC20PoolHandler.transferLps(9999999999999999999999998904, 51624, 9971, 1342211067070467, 16700); @@ -1017,7 +1017,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.pullCollateral(1000251480639075482, 1694, 2861); _reserveERC20PoolHandler.drawDebt(43388, 15271340786116372574138093141534396687613031025591758746939347758077531181799, 44324); _reserveERC20PoolHandler.withdrawBonds(2, 1, 0); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.bucketTake(11273382872855962494616156929227174104394223152675369,563071629684930228962, true, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.settleAuction(120876873422711933, 13123, 1202025693345828720, 86474506389175276555789104803); _reserveERC20PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 2153576920718485934032590649534232750065468526); @@ -1033,7 +1033,7 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { _reserveERC20PoolHandler.transferLps(386809077963557983132, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 148380917210836178473325853580934307774647345526133, 1471892031300499403); _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1198429820689537065749, 243483583504501197526845158753139835924066659); _reserveERC20PoolHandler.takeAuction(1199779041428331153, 71740, 29306, 212074468834203469445731314306); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.withdrawBonds(5886, 6118, 31095594184158051362419323440); _reserveERC20PoolHandler.settleAuction(73104, 19886, 67842558439608731261142755949781586203409010660475186688055685950916002409738, 252057734655093500419854976371); _reserveERC20PoolHandler.takeAuction(7196998050564854545778916884105598407810383237719695, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7255413239007126458982904756151267359533146366352519669325613874036, 2047248371259122735965487218913991798927990); @@ -1088,7 +1088,7 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 29425834998902062728, 2815561902903892364700367145997869863083581937863, 0); _reserveERC20PoolHandler.takeAuction(1002082639411802781, 1000000141393972450, 2062329569865819338652496, 3639518374983970385625641369267); _reserveERC20PoolHandler.pullCollateral(716928335861873075224326450171091915803141636754600547146763478924688677, 6017014239243671152668202570617, 811528433232365724170352835761); - _reserveERC20PoolHandler.kickWithDeposit(1006966022689012113631510, 2839423961165, 1012610096869894613); + _reserveERC20PoolHandler.lenderKickAuction(1006966022689012113631510, 2839423961165, 1012610096869894613); _reserveERC20PoolHandler.repayDebt(59697, 4218268651349607331917838812219315, 4198061940385182860329527760110561); _reserveERC20PoolHandler.addQuoteToken(9102590, 10619990735779382463268300515514058022851111, 1670387541301, 10508691425622217157731331015369006567594519374645329314842933480452519); _reserveERC20PoolHandler.settleAuction(0, 59960806476012009153510156995088168122, 2, 238483732749493419311882771922463500070384363806126829); @@ -1134,7 +1134,7 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 42019400363510559466713945056402714606538140568246384014480110914328265163403); _reserveERC20PoolHandler.settleAuction(1057279804021938190, 246687658464793724986455352391, 5925827996077694552730400457343, 2084381812461048011473064757225); _reserveERC20PoolHandler.kickReserveAuction(214359998882822941400036836759, 772237151693507486089823656752); - _reserveERC20PoolHandler.kickWithDeposit(580502608968719507145237660113965916868063012, 1, 2); + _reserveERC20PoolHandler.lenderKickAuction(580502608968719507145237660113965916868063012, 1, 2); _reserveERC20PoolHandler.withdrawBonds(1, 1, 869697374638745867981687493872400658574867528089570078229036174); _reserveERC20PoolHandler.addCollateral(2835013280595323711754, 1379747638539802930158795366740, 2999260289280542828859825661600, 1111505902930696308); _reserveERC20PoolHandler.transferLps(101318005368562086532090860441, 727691276523922201026494539, 999999999999998209545201949951385339923831640, 2625186857895955159432498610976, 1008568104827895584797314); @@ -1154,7 +1154,7 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian _reserveERC20PoolHandler.drawDebt(3672889067541591, 17, 83856721931010423002279627799971306025841049042329947); _reserveERC20PoolHandler.bucketTake(1000197316935676153, 3096097749449943758920050453756, false, 2824023740736482172369426325793, 1777694503); _reserveERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 64603456943647345, 22726223561335484363204986876705771); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.settleAuction(5448707427889081580045157214016, 898517806662526225, 57255705446025176430893986032941, 1798503358); _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 338902, 24895432670362520003757781937901496507349044); _reserveERC20PoolHandler.takeAuction(253339908492728, 17277739980789095840457279982793255431547403624057861740152922, 2, 47882133371720379988628201061591263125271753131194); @@ -1165,7 +1165,7 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian _reserveERC20PoolHandler.takeReserves(1, 0, 2); _reserveERC20PoolHandler.removeQuoteToken(14730140957608857, 99, 1, 1386705920515328814743931560931167479097551832850008218878487983494150); _reserveERC20PoolHandler.kickReserveAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _reserveERC20PoolHandler.kickWithDeposit(893008286811460788553031904481952573606214832422259596085940570283982304, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(893008286811460788553031904481952573606214832422259596085940570283982304, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.takeReserves(3, 170439307069053886557145191896703842826953837742170479, 20466465501556948674803401059840117427266555527646887); _reserveERC20PoolHandler.moveQuoteToken(24576850282145403341840304023303746575460022097947982029320014455, 199259095182280921249849, 3, 263081299123519591374903422280598171358315911105268634044959571252407, 107705715799261820459195895645732878612286692246405740446896247929123014); _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5504186113825436176758787846084168342878, 41473922375020639787670112003); @@ -1195,7 +1195,7 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian _reserveERC20PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 639402091975833721492394191878388806085281852328); _reserveERC20PoolHandler.takeAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _reserveERC20PoolHandler.kickReserveAuction(1192029264782433734511278767050585798022919741840914701707701, 9838660868733061321749714698638583897632565681053207160200164948032353326111); - _reserveERC20PoolHandler.kickWithDeposit(848911323651847292018922493625, 475461101841015439785306204553, 5038495789764551021097736053014); + _reserveERC20PoolHandler.lenderKickAuction(848911323651847292018922493625, 475461101841015439785306204553, 5038495789764551021097736053014); invariant_reserves(); } @@ -1204,12 +1204,12 @@ contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvarian Test was failing because replicated invariant logic didn't cap lender factor at 10x the interest factor for borrowers. Fixed by getting invariants logic inline with pool logic. */ - function test_regression_10_buckets_kickWithDeposit_F1_F2() external { + function test_regression_10_buckets_lenderKickAuction_F1_F2() external { _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 872511381148049007720, 539489537953478369108753171886182489172581205791027954527); _reserveERC20PoolHandler.transferLps(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 15030691, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _reserveERC20PoolHandler.settleAuction(3311151379956769964767988508503575272954757, 75267398466877804280028379007551879365458802899983, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 282706799353988314281438019223518391928165574); _reserveERC20PoolHandler.removeQuoteToken(11174, 2673, 7678, 1606); - _reserveERC20PoolHandler.kickWithDeposit(16859, 23442, 2222); + _reserveERC20PoolHandler.lenderKickAuction(16859, 23442, 2222); invariant_fenwick(); } diff --git a/tests/forge/regression/ERC20Pool/prototech/PrototechRegression.t.sol b/tests/forge/regression/ERC20Pool/prototech/PrototechRegression.t.sol index 0faafcbfc..e5df2986a 100644 --- a/tests/forge/regression/ERC20Pool/prototech/PrototechRegression.t.sol +++ b/tests/forge/regression/ERC20Pool/prototech/PrototechRegression.t.sol @@ -216,7 +216,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsERC20Pool is Liquidation _liquidationERC20PoolHandler.removeQuoteToken(847108075881, 42162244106064982390, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC20PoolHandler.pledgeCollateral(1139872047305319828329319702900629531630147801503024602238950376239270491, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 661230912199721); _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 372744813196399714519399926917647299094014976270437803, 2820097493008818092337602368055496904404410450846957902300803247165784, 173467464882758185083557, 11482305045332324833614739919808727240718678); - _liquidationERC20PoolHandler.kickWithDeposit(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC20PoolHandler.lenderKickAuction(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.removeQuoteToken(44196108561, 959859487311170472139557427, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.drawDebt(1312093315543461913781047720589269967180454, 221271430054517801486904020700382587418626242738, 14016013892798531558012100646932474885842079882403824111180458899503053382); } @@ -248,7 +248,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsERC20Pool is Liquidation _liquidationERC20PoolHandler.takeAuction(1000000000006003053, 2156019376206333175397003792224, 13525679699098751385619866801462, 5883059969726926208070021166571); _liquidationERC20PoolHandler.addCollateral(38106769140065340496445941148921, 914446861396065494494774492712, 132105158784728224915354076868436, 26484264067426313892760182056); _liquidationERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1532903294790092742021906905570144870578284156105342441629016165274228947, 3, 2); - _liquidationERC20PoolHandler.kickWithDeposit(2117094175447831677576620378161, 8452721478740162, 10302392823801389709309931842264); + _liquidationERC20PoolHandler.lenderKickAuction(2117094175447831677576620378161, 8452721478740162, 10302392823801389709309931842264); _liquidationERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 9681449122811687478019129425564610008133337660494); _liquidationERC20PoolHandler.settleAuction(1, 3, 13084269823973179053980426994278720150378474483498343876526136951, 1098273546995278229442622620282361570906); _liquidationERC20PoolHandler.takeAuction(1969381645399570394974017447775, 4744897916139589403209196971356, 1000021968166020712, 5185393015585021259329084663473); @@ -323,8 +323,8 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 681002066038338357923623733806); _liquidationERC20PoolHandler.addQuoteToken(3323733645828764244783800401948, 1025246565380062903799492448802, 5504962058656769867822798034, 4601370545578631412322935527072); _liquidationERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 6532731000244171849848344848723915, 34480671929303814720, 44248794276583082784954806503925522851829741440166, 750188936923231745218533301001262200166527749923536547908073497523578773); - _liquidationERC20PoolHandler.kickWithDeposit(2004579093724976231508186677767, 10999812472107451, 2008170300); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 924656886714369235845431724622202358995089, 1241197474375783649486568362713407); + _liquidationERC20PoolHandler.lenderKickAuction(2004579093724976231508186677767, 10999812472107451, 2008170300); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 924656886714369235845431724622202358995089, 1241197474375783649486568362713407); _liquidationERC20PoolHandler.repayDebt(3, 1429272782580961788459421912268911305779790482389159, 3601089186740122417890035855513892236234856106231629744244671436287276039218); _liquidationERC20PoolHandler.addQuoteToken(2, 837936031553845712866764572567, 7444859491, 9554871296787595280431542930104391508161683437167829377); _liquidationERC20PoolHandler.settleAuction(11288350957475559598229201068, 9235370281345232721947056843407, 13766347507771284991127856221265468791, 11423013003238370); @@ -342,7 +342,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.pledgeCollateral(1787007805467465227923718735991, 5393120746062957904527097649141, 1912703283384720471225931413726); _liquidationERC20PoolHandler.takeAuction(192604336920797431114934624890, 6101578548568682359333222351973996246816, 105730532527, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC20PoolHandler.transferLps(1000105959518389446, 2044727637238278861994725788899, 5826800130471596549929629281119, 1000003028083545390, 1000007928853885115); - _liquidationERC20PoolHandler.kickWithDeposit(3228023325993422277288130539062, 39505413210895824789729350063, 6248449210465815409795990278848258783); + _liquidationERC20PoolHandler.lenderKickAuction(3228023325993422277288130539062, 39505413210895824789729350063, 6248449210465815409795990278848258783); _liquidationERC20PoolHandler.takeAuction(6191101619230344581079117178723, 4720814275041204535087465527278, 1000005163387036068255354, 1089919911498364436636276791); _liquidationERC20PoolHandler.settleAuction(1, 391834874104811301350332136523278679938043797003744848419865685493, 2655150871419339452091087802566556763831966253311897196651839700615, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC20PoolHandler.settleAuction(384198234746339048, 8983453236928890625815972000289386481374054419, 1, 2); @@ -356,7 +356,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.takeAuction(635285680275723692289448379180119809691822929284021639331816463, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 21756043279069684263673812); _liquidationERC20PoolHandler.moveQuoteToken(1831266681, 1000146604043416963, 1002174561478012908323019664, 1707591886, 102661865136966498821878628); _liquidationERC20PoolHandler.kickAuction(1082996175271372137833467946, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6508444497989592201503937927833829371286945005924618342859658355737); - _liquidationERC20PoolHandler.kickWithDeposit(1230353598539171369624843805065, 1007971129190814463, 1002908373963252229); + _liquidationERC20PoolHandler.lenderKickAuction(1230353598539171369624843805065, 1007971129190814463, 1002908373963252229); _liquidationERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 136437801288778798184008585174211646445246862016565292176, 172763808072301); _liquidationERC20PoolHandler.takeAuction(593644314923590037002843454552688531686186697552207486412073918222, 534505298241021630045631723960787270860482313902491037942617, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _liquidationERC20PoolHandler.settleAuction(3, 42774741220449, 642089743490606640491580457089160539049478812410205761603, 0); @@ -367,7 +367,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.settleAuction(2460989443290938169170344407550648131, 999997014290027250383268796817, 12947087505965474262773861205294358443, 13959052182721488072138021584677); _liquidationERC20PoolHandler.pullCollateral(1601366803286368357832451593484, 9520302142806509186086342113039, 1025638029347460318); _liquidationERC20PoolHandler.removeQuoteToken(255281350766042539272854584, 949655629175075470884773602122519860145529, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 99955760662301602045685); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 23803730325876271598225398589164165071391238917086398440672206534088, 13773175627480392170176677304581555977912896463); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 23803730325876271598225398589164165071391238917086398440672206534088, 13773175627480392170176677304581555977912896463); _liquidationERC20PoolHandler.pledgeCollateral(6220309756903282813565519525679, 1074271152139548387, 2088373590283817852620400777692); _liquidationERC20PoolHandler.bucketTake(3, 2019110, false, 99047382297, 3647); _liquidationERC20PoolHandler.repayDebt(42270049297035793075830006273990793285158130811655226089, 13244551272304785459570982429077356278479, 78731490663129812696186448231062); @@ -393,7 +393,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.transferLps(22608024113365095905584131452586028419270976193494306118281696290898985, 4461392298422715704774948, 2, 7846121570888180, 331392658758838563647203297249878207); _liquidationERC20PoolHandler.repayDebt(11698528811210192396351422646626, 2280035964984916837444558076982, 946922613349713677617598738003); _liquidationERC20PoolHandler.settleAuction(721541049170869524534845911477519041194899408936855489382846493028286662695, 92565402695990540562562919637, 1004806469796271346446984441011, 412399875357809146503163133); - _liquidationERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 656300418695953408530813878943170659, 1); + _liquidationERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 656300418695953408530813878943170659, 1); _liquidationERC20PoolHandler.takeAuction(23167766422813360944322594861698583030, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 18371215130007, 154042139961746405); _liquidationERC20PoolHandler.removeQuoteToken(16581130443054062792053099565786, 82006613552073764251704758982666586639757573675137319445886509306574244670174, 399503514902688198786683762902, 1584974834931813176157302188001); _liquidationERC20PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 756289706172057271129663005793149327528967350131125151435120252, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3034979985391077148518907493258006498774414125002734091810702534231056276); @@ -405,7 +405,7 @@ contract PrototechRegressionTestLiquidationWith50BucketsIndex1ERC20Pool is Liqui _liquidationERC20PoolHandler.bucketTake(97345306443579698471872863296731644454017981112310798743, 5097744324262305618803451333516871213204886788557904266905027885950348, false, 15976607071872348505532550924741413111663206793776080940491903785, 0); _liquidationERC20PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 36117836052233398260956981148387392517, 158089829806239236878783692384690887729226316917813242, 3); _liquidationERC20PoolHandler.bucketTake(439745608561618692346292483450499249047450803078311, 10547674864087612574890602963119232697, true, 306357957930947756827036148861840, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _liquidationERC20PoolHandler.kickWithDeposit(10495414043, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); + _liquidationERC20PoolHandler.lenderKickAuction(10495414043, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); _liquidationERC20PoolHandler.removeCollateral(2028613, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 577661336610046132410646096489019863); _liquidationERC20PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 514110685473872, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); _liquidationERC20PoolHandler.takeAuction(20673646728439025426136023323770124885, 675549037640195962340401361, 4219316359517260616958832563315, 5361358460803438); @@ -533,7 +533,7 @@ contract PrototechRegressionTestReserveWith50BucketsERC20Pool is ReserveERC20Poo _reserveERC20PoolHandler.addCollateral(0, 2, 1232641734641, 31343380291915790650373266756963988847); _reserveERC20PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _reserveERC20PoolHandler.kickWithDeposit(788004982292849387186182063285, 1940790819808691432528086343550, 731272264496848181811731492195469346809758718359079122899716176283941283); + _reserveERC20PoolHandler.lenderKickAuction(788004982292849387186182063285, 1940790819808691432528086343550, 731272264496848181811731492195469346809758718359079122899716176283941283); _reserveERC20PoolHandler.addQuoteToken(2, 14624, 617249058149064089429428, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC20PoolHandler.moveQuoteToken(1088872909900745236189950617, 15890612102926550116, 4582399149352835659555995253711, 13387122748009058461180259144937, 861762172514412847328248827402360937406130776600887962454677836216335656); _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 26346071745620654135109826889565369349143698978199503472136502685355, false, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 153558817743023308082175787142765072463488294348201227240); @@ -546,7 +546,7 @@ contract PrototechRegressionTestReserveWith50BucketsERC20Pool is ReserveERC20Poo function test_regression_prototech_R12() external { _reserveERC20PoolHandler.takeAuction(111503320743527282123336088690786562111577764908, 2, 0, 3); _reserveERC20PoolHandler.transferLps(3884277863890184536548790232, 1000226692427973497, 362994476962284067579436395, 2066937044638233220791038649593, 1000718160321343602459955); - _reserveERC20PoolHandler.kickWithDeposit(3, 9667900678314907513590203324738, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.lenderKickAuction(3, 9667900678314907513590203324738, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 12902846031691147340, 164594771213835727638288874641553370090658299, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); _reserveERC20PoolHandler.kickAuction(3843665, 25230739321792218739005704, 119030224870754091764872, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC20PoolHandler.bucketTake(11315247177110042886106595681008, 8983849823197858095975364450901, false, 2323824412855204507962581562067, 975533577556622775069616347005); @@ -578,14 +578,14 @@ contract PrototechRegressionTestReserveWith50BucketsIndex1ERC20Pool is ReserveER } function test_regression_prototech_R10() external { - _reserveERC20PoolHandler.kickWithDeposit(9433627986933283125646888807064008232, 221118523365400131, 2465980960817735242955065701468); + _reserveERC20PoolHandler.lenderKickAuction(9433627986933283125646888807064008232, 221118523365400131, 2465980960817735242955065701468); _reserveERC20PoolHandler.settleAuction(2, 1465566755990294261551, 5446397116094743378510145168778507713319320588457, 1528994712721440933750048600830501692959831074023837696043986057926859); _reserveERC20PoolHandler.removeQuoteToken(2000454123866580850167634, 18691527695339216532215675622, 2279, 816); _reserveERC20PoolHandler.repayDebt(2016357865827986953341016567272966202336117189931, 1, 2849421575152156960123738830798059105666358364513420127963486); _reserveERC20PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 50295); _reserveERC20PoolHandler.repayDebt(0, 109490491610, 12885272574892044); _reserveERC20PoolHandler.bucketTake(5735945213, 21744658176442223517969005828038137972068113864460088, false, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 405985353121972162110815290234023925555); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 405985353121972162110815290234023925555); _reserveERC20PoolHandler.takeAuction(5603471022574005901436218588047, 1095565616863252189, 3772604393288482751689957579532, 846289097042058312098640953448); _reserveERC20PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 187660066730418, 14515486327980056496462485304382041505225); _reserveERC20PoolHandler.pullCollateral(4045826300537223, 10970319889760213101329999562, 3107111484864040608557343630211); @@ -633,7 +633,7 @@ contract PrototechRegressionTestReserveWith50BucketsIndex500ERC20Pool is Reserve _reserveERC20PoolHandler.takeAuction(4604772779040364692966482996, 1018719297903985859204238589365, 6435463, 12936658684489119113561977309306); _reserveERC20PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 3137717894415033604438675247628414126129278320964911519270210382962); _reserveERC20PoolHandler.repayDebt(4377929121944, 4074033843091774413737392892238607292609159924582735309689579134, 73373299140376457406029691325274109293508305634464); - _reserveERC20PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 78381888898559226074023822312301457536253423426); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 78381888898559226074023822312301457536253423426); _reserveERC20PoolHandler.repayDebt(1, 63177319003775515959478, 8930233654559205122776043352670093340626596133); _reserveERC20PoolHandler.transferLps(1813082927800051699848948074492, 6673145729685370939756153985086, 1013414194637543961, 1982, 66809); _reserveERC20PoolHandler.moveQuoteToken(781486194288092748029626811087512234868929543911, 676294221029944352850660106242863124963677, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); diff --git a/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol b/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol index 02620271e..aeb17e536 100644 --- a/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol +++ b/tests/forge/regression/ERC721Pool/RegressionTestLiquidationERC721Pool.t.sol @@ -85,7 +85,7 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants function test_regression_invariant_B5_3() external { _liquidationERC721PoolHandler.moveQuoteToken(898761346601995332968440, 1, 281290971280478301822821494347217658505029428037879054325, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); _liquidationERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 2, 9813692387192478769130999425125066055); - _liquidationERC721PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _liquidationERC721PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _liquidationERC721PoolHandler.settleAuction(140569786344478, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 761335476707022719857597); invariant_bucket(); @@ -97,7 +97,7 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants */ function test_regression_invariant_B5_4() external { _liquidationERC721PoolHandler.bucketTake(3, 37625625304, true, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _liquidationERC721PoolHandler.kickWithDeposit(3, 3, 2); + _liquidationERC721PoolHandler.lenderKickAuction(3, 3, 2); _liquidationERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 51633399605532141251772874775295477365945157734353620); invariant_bucket(); @@ -109,8 +109,8 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants */ function test_regression_liquidation_CT2_3() external { _liquidationERC721PoolHandler.pullCollateral(54505878282630621336327288518119032809649402198240989711348043195888862303, 6425192232404400726345611481226777529322694577339980527764654089807135, 6069097751382701056451900914776322223900273807977361688596777846059535); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _liquidationERC721PoolHandler.kickWithDeposit(40634111685881491540685038935075868009461471090313, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 794065631491126295075683045712740549307641208240422976574); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC721PoolHandler.lenderKickAuction(40634111685881491540685038935075868009461471090313, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 794065631491126295075683045712740549307641208240422976574); _liquidationERC721PoolHandler.removeQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 316968315, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.addQuoteToken(3, 853851203028462651768, 1, 198496430460941314962462441789669119480667961292532319857094939); _liquidationERC721PoolHandler.transferLps(123534659549619259016658721662490016547975255328, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 95841980982668727695631410563963, 2775913420849760488284925839916); @@ -120,7 +120,7 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants } /* - Test was failing because invariant logic for kickWithDeposit didn't accounted kicker claimable bonds. + Test was failing because invariant logic for lenderKickAuction didn't accounted kicker claimable bonds. Fixed by using pre and post kicker bonds when calculating new bonds accumulator. */ function test_regression_failure_A7_2() external { @@ -143,7 +143,7 @@ contract RegressionTestLiquidationERC721Pool is LiquidationERC721PoolInvariants _liquidationERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, true, 122391791823515205739915477639339999027699445717632722485958, 1); _liquidationERC721PoolHandler.mergeCollateral(7137415919637491141881, 1025411825); _liquidationERC721PoolHandler.bucketTake(2074255567, 62930419783609851358322950084447067504714907123847879176349713897770248274790, false, 30898680600184438890868737570792388570065267524078030025687460257800451485100, 14079292358154521351); - _liquidationERC721PoolHandler.kickWithDeposit(91387242540804, 1000002606711604178, 85946383966053781430487237900937953007849640831813517263628662558720153363601); + _liquidationERC721PoolHandler.lenderKickAuction(91387242540804, 1000002606711604178, 85946383966053781430487237900937953007849640831813517263628662558720153363601); invariant_auction(); } @@ -163,7 +163,7 @@ contract RegressionTestLiquidationWith10BucketsERC721Pool is LiquidationERC721Po Fixed by extracting min and max index from `getBuckets()` buckets inside `fenwickIndexForSum`. */ function test_regression_10_buckets_erc721_F1_F2() external { - _liquidationERC721PoolHandler.kickWithDeposit(2, 0, 119623984614); + _liquidationERC721PoolHandler.lenderKickAuction(2, 0, 119623984614); _liquidationERC721PoolHandler.kickAuction(2, 1156683884353192742341767421, 459270, 3); _liquidationERC721PoolHandler.transferLps(29013806206364598365, 1427168328567585510116210033014146583028839301025725954083, 1, 0, 18572119254493611002099); _liquidationERC721PoolHandler.kickAuction(16695879118143227003041354410, 20257574621205291951103843117, 1000003697188716997, 26779825480547342678627084615); @@ -182,7 +182,7 @@ contract RegressionTestLiquidationWith10BucketsERC721Pool is LiquidationERC721Po _liquidationERC721PoolHandler.settleAuction(970340745519190785737461702432489766136265250, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC721PoolHandler.kickAuction(21153289945874099718636115846686023780707539150855083580438348991810009707592, 231833300790627422, 2430778200610757092748730249372285, 13040999445181237637293392234); _liquidationERC721PoolHandler.settleAuction(28829603314846949380261872, 112191708732827586266077754, 22638900296959380506195308927, 1000335038342628591); - _liquidationERC721PoolHandler.kickWithDeposit(14160215155867284847068871, 3066449405235676217230027, 1000005659521776292); + _liquidationERC721PoolHandler.lenderKickAuction(14160215155867284847068871, 3066449405235676217230027, 1000005659521776292); _liquidationERC721PoolHandler.takeAuction(2, 3, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC721PoolHandler.repayDebt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 158201561385950295129615012177899108288175); _liquidationERC721PoolHandler.mergeCollateral(15443, 3967798534471471250975814546); @@ -205,7 +205,7 @@ contract RegressionTestLiquidationWith10BucketsERC721Pool is LiquidationERC721Po _liquidationERC721PoolHandler.drawDebt(3860251784759441355850425654, 10022160373994742100540867773, 86926429185491158163971785); _liquidationERC721PoolHandler.kickAuction(1000023404955489823332134, 25365911766656173122139859337, 20012742395166753493977469175, 9333154884192050595923467164); _liquidationERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 573593659528923718, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3); - _liquidationERC721PoolHandler.kickWithDeposit(32882475918305935415526014479, 71712963014369177599807221, 702536441180428194811094101333785233668641934645322721111759648519780728); + _liquidationERC721PoolHandler.lenderKickAuction(32882475918305935415526014479, 71712963014369177599807221, 702536441180428194811094101333785233668641934645322721111759648519780728); _liquidationERC721PoolHandler.removeQuoteToken(32684121703749567918313030113529773051, 244784655, 3, 25487161); _liquidationERC721PoolHandler.pledgeCollateral(288999079921244931741500695891, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.takeAuction(33410008093666158498951519, 481975152400521717024558009967316, 1005864628141771195, 1000004180567372692); @@ -213,12 +213,12 @@ contract RegressionTestLiquidationWith10BucketsERC721Pool is LiquidationERC721Po _liquidationERC721PoolHandler.settleAuction(3253385564908967779436236718, 28276713074860098780254266272, 5837230669964347830868836887, 6252323640064169991251338021); _liquidationERC721PoolHandler.addQuoteToken(3, 5158865936150580623717254521873401546277661243070599862, 0, 3); _liquidationERC721PoolHandler.addCollateral(33020828092900921632894247715, 10504880927923291577237829931, 12492310190457093324544966547, 818639664676614552485166588); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 10300652091, 1032463552968); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 10300652091, 1032463552968); _liquidationERC721PoolHandler.settleAuction(14989907985802722133727358, 1000081351959314238, 7993376402219492844516656910, 16388963991550774779688403792); _liquidationERC721PoolHandler.drawDebt(5464118811185766229700296775734451, 57514763379348766299186557, 15058213631944735895160588); _liquidationERC721PoolHandler.pledgeCollateral(0, 574270603285831642985387182167035891353834349631418692, 1184504645755354943030405957751217066414186144); _liquidationERC721PoolHandler.withdrawBonds(2, 0, 2); - _liquidationERC721PoolHandler.kickWithDeposit(2, 8747239138299630922320054146639159820141434760146080, 167002917966202206884); + _liquidationERC721PoolHandler.lenderKickAuction(2, 8747239138299630922320054146639159820141434760146080, 167002917966202206884); _liquidationERC721PoolHandler.takeAuction(566195741605537888263397312246837580262190272351822333745934353086, 3948248540667634345713024497862548201881780252187246019937162277, 27810772533350621789874295209691369393366591925132656, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 717180990621304163923299428654137326974164894424239886804322771768); _liquidationERC721PoolHandler.addCollateral(69350434094149412981208550, 41760775104065152001952235, 10121285650495161460634668771, 56273450916713270865378253); @@ -252,9 +252,9 @@ contract RegressionTestLiquidationERC721PoolWith12QuotePrecision is LiquidationE _liquidationERC721PoolHandler.mergeCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC721PoolHandler.drawDebt(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2374972450283557865290600746428019329015146759); _liquidationERC721PoolHandler.transferLps(9282292895534554771871563832084952, 2, 2, 12796052825748083917802579705752036449484, 0); - _liquidationERC721PoolHandler.kickWithDeposit(441788552983044798549384408236400377766093, 28953621624085806682, 2); + _liquidationERC721PoolHandler.lenderKickAuction(441788552983044798549384408236400377766093, 28953621624085806682, 2); _liquidationERC721PoolHandler.addQuoteToken(147352750606922587857705029, 790350990648198541341376, 3, 197430356083443459140104403322030286015166410); - _liquidationERC721PoolHandler.kickWithDeposit(15979, 8840, 7103); + _liquidationERC721PoolHandler.lenderKickAuction(15979, 8840, 7103); _liquidationERC721PoolHandler.pledgeCollateral(137966369042325511615, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 18282785); _liquidationERC721PoolHandler.kickAuction(3414, 7293, 1269551700153446102879003155429082957619641411999, 2986); _liquidationERC721PoolHandler.removeCollateral(3518258747735211683867322437163037864218, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 66499887, 43684831053633976295457348049); @@ -269,7 +269,7 @@ contract RegressionTestLiquidationERC721PoolWith12QuotePrecision is LiquidationE _liquidationERC721PoolHandler.mergeCollateral(67803600884805679278480851170236427019931833943757240605119119301814655914107, 688055298445555605485150372355439597236128231399532592754958298807271424); _liquidationERC721PoolHandler.pledgeCollateral(20844046108832218789395248987757532785974407123849648366760256817948055046510, 35276, 4825); _liquidationERC721PoolHandler.removeCollateral(3843, 98952450680579533410181254112209333238157149659402663450290741057725986281846, 76000000000000000000, 110349606679412691172957834289542550319383271247755660854362242977991410020132); - _liquidationERC721PoolHandler.kickWithDeposit(88827291404079698668721230880260160559290269665158672048614475775631968918112, 6552338875626040099058182821311906768274833679008314103495576099267966881764, 77119255649644092519274403514471579745954075144891191719705841129989684133973); + _liquidationERC721PoolHandler.lenderKickAuction(88827291404079698668721230880260160559290269665158672048614475775631968918112, 6552338875626040099058182821311906768274833679008314103495576099267966881764, 77119255649644092519274403514471579745954075144891191719705841129989684133973); _liquidationERC721PoolHandler.bucketTake(1, 34605058975690051, true, 2, 162365376961783756423495395536037671729173545628152); _liquidationERC721PoolHandler.settleAuction(858414386677148102, 3, 110125680049117402515387055, 9750530446); _liquidationERC721PoolHandler.bucketTake(54305081175207239589309070700754052606921126123420008658817903528168167, 99670677855487908376110090150330923332944566031630517476, false, 1, 311450586165688818653022787627230584015326821787505688683607129); diff --git a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol index 3bd926c3d..9aaa9abd1 100644 --- a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol +++ b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol @@ -50,7 +50,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.drawDebt(0, 5711299, 0); _reserveERC721PoolHandler.takeReserves(52580967332816855446614075396003761174408900540583074540513, 3066371283933430634405115377931952568434121552, 0); _reserveERC721PoolHandler.moveQuoteToken(187, 10746658534810329994020169146, 26326378734592892198504991, 3678, 0); - _reserveERC721PoolHandler.kickWithDeposit(9347, 1019767997450901378, 0); + _reserveERC721PoolHandler.lenderKickAuction(9347, 1019767997450901378, 0); _reserveERC721PoolHandler.pullCollateral(0, 1727508752834082423180670412007678522620836706739773785431403804, 0); _reserveERC721PoolHandler.addQuoteToken(10272927241872097800945271290053605104341355430184682823901929, 133408017309487439448075733, 17099185418125710911451484450376088, 0); _reserveERC721PoolHandler.drawDebt(448053659500389508982384470106829047, 1400284447444730491147774097, 0); @@ -100,7 +100,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { function test_regression_erc721_evm_revert_1() external { _reserveERC721PoolHandler.settleAuction(9989243900619820637977810558874905516372668734956884150787421704623, 18550308766242836156918, 185813535265204352484610945242967379275287026502359577631531764507799333257, 0); _reserveERC721PoolHandler.settleAuction(3978325917508522510207263223865211237976, 7790053814939864208425264498, 999999999999999996743786245260429581471869387, 0); - _reserveERC721PoolHandler.kickWithDeposit(46026209085391641194310671609, 3130043694548050944738567, 0); + _reserveERC721PoolHandler.lenderKickAuction(46026209085391641194310671609, 3130043694548050944738567, 0); _reserveERC721PoolHandler.bucketTake(321403975624759, 1, true, 33704310988122856275082007990402091273248356, 0); _reserveERC721PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0); _reserveERC721PoolHandler.drawDebt(18035929394751812384297714732077328967746743, 119690523270955711756656740687855244882128084589819921547953371161511980, 0); @@ -112,7 +112,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.kickReserveAuction(0, 0); _reserveERC721PoolHandler.moveQuoteToken(1292329311184978054029223707608815228366442482359118197, 245731237234102963770011164221044194699962572289589, 2, 499131904050126199254174184464801061408, 0); _reserveERC721PoolHandler.kickAuction(12878604154240405292071458, 1000077974370365988, 5250731775066900335970481825, 0); - _reserveERC721PoolHandler.kickWithDeposit(30005857229801396387000562790, 262188009448718993801623229194350476, 0); + _reserveERC721PoolHandler.lenderKickAuction(30005857229801396387000562790, 262188009448718993801623229194350476, 0); _reserveERC721PoolHandler.transferLps(85517991264671346765943178766299956200222191839647589428775263346038301370940, 1001528530588111108, 5892088159565189714123454118, 81450625910729021997682284682898584896063448663928167861202354603723895077022, 0); _reserveERC721PoolHandler.takeReserves(1, 1, 0); _reserveERC721PoolHandler.moveQuoteToken(141666662243202853679, 56777880157945535810, 3, 1065279319875431430205, 0); @@ -124,23 +124,23 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.removeCollateral(363349503122708, 1116100944119057116, 106039457316425099783017640, 0); _reserveERC721PoolHandler.pullCollateral(105543882139698869110686, 73433708449377181858755380995, 0); _reserveERC721PoolHandler.pledgeCollateral(0, 193805990262767737979667904191845569153058129047262518417094401922845726, 0); - _reserveERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 16910632010742109640505760601383025605, 0); + _reserveERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 16910632010742109640505760601383025605, 0); _reserveERC721PoolHandler.drawDebt(115102, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); _reserveERC721PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 502278298364, 15623406760877121471307769380791966990279994, 25804227618345963384523584277775608274901137376896553430212216675747581362, 0); _reserveERC721PoolHandler.kickReserveAuction(706553361502694834509668636, 0); _reserveERC721PoolHandler.takeAuction(1008933132135642147, 63849767418381441757665327769, 3000000000000000000009545218614793863981329058, 0); _reserveERC721PoolHandler.kickAuction(1897933710841310333005368598886, 1000867455304781533, 50027874221493313760260247, 0); - _reserveERC721PoolHandler.kickWithDeposit(532262591863, 1001203767205043464, 0); + _reserveERC721PoolHandler.lenderKickAuction(532262591863, 1001203767205043464, 0); _reserveERC721PoolHandler.pullCollateral(20627776779876037812477066019170418743803603627426329204, 15621817480121736319934257078370317632228890568374574704147371391628169050220, 0); _reserveERC721PoolHandler.transferLps(2964971320695470084755812518644439501, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2418436671989139908121468417555958956713, 3, 0); _reserveERC721PoolHandler.kickAuction(4353115105586914085762881497, 1029709442025500487720749904677337277025353438765212074, 3839837154162449238408405046265155159774, 0); - _reserveERC721PoolHandler.kickWithDeposit(3, 36307900544, 0); + _reserveERC721PoolHandler.lenderKickAuction(3, 36307900544, 0); _reserveERC721PoolHandler.settleAuction(36222422140461077799644694858694814901204980637473820481182588, 4294499838797823, 3, 0); _reserveERC721PoolHandler.addQuoteToken(12243, 1, 0, 0); _reserveERC721PoolHandler.takeAuction(0, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); _reserveERC721PoolHandler.addCollateral(43036656387401835818710642809, 102292442512853022585172627047482697338758087389118360669301779723744169241429, 74381750930592072482138046563, 0); _reserveERC721PoolHandler.repayDebt(24937488734288345893346053564, 17186699442063728778426820146, 0); - _reserveERC721PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); + _reserveERC721PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _reserveERC721PoolHandler.settleAuction(72429479998190670655551465151, 9240337923752307137120083262, 22687272470234089804757129661, 0); _reserveERC721PoolHandler.pullCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); _reserveERC721PoolHandler.pledgeCollateral(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); @@ -223,7 +223,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.moveQuoteToken(2913970992235361986540207480498, 1, 3910345503097307393855, 278786698370971243898520651552401338675291759134438373, 0); _reserveERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 0); _reserveERC721PoolHandler.addQuoteToken(3, 2036364831458569, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); - _reserveERC721PoolHandler.kickWithDeposit(1457413383332496534674315845, 37509813785472017970525636662, 0); + _reserveERC721PoolHandler.lenderKickAuction(1457413383332496534674315845, 37509813785472017970525636662, 0); _reserveERC721PoolHandler.transferLps(44188279104373937481999858181, 39286859172421825465539369065, 44628425590202646236523866533, 51555673326592954378962902209, 0); _reserveERC721PoolHandler.addQuoteToken(1072136986589800395035805, 22904335154524190434559120, 1030801052100464518, 0); _reserveERC721PoolHandler.addQuoteToken(97677075084166305679836442, 1000008452124308451, 15249165865336324622600068551, 0); @@ -240,7 +240,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { function test_regression_CT2_3() external { _reserveERC721PoolHandler.settleAuction(13652854, 3, 22274361584262295180502534344873136686717874240, 77611568702503302987473072664549443425918559); _reserveERC721PoolHandler.withdrawBonds(707, 12156087, 19174970663707445513928200315780515094988880044); - _reserveERC721PoolHandler.kickWithDeposit(3, 3, 672444647); + _reserveERC721PoolHandler.lenderKickAuction(3, 3, 672444647); _reserveERC721PoolHandler.kickAuction(56848152111578191493999238385381542863095352, 58529940235731531982925635292876828548122574070883324158957672865569214, 899039491413, 107401523435280391282671144); _reserveERC721PoolHandler.settleAuction(19634294495748734616428837200, 4937, 77655590346650144951112602856523781688846543008934920669778106922357739827346, 994969230863047393940054601942); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 71512, 2, 3); @@ -304,15 +304,15 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.kickAuction(593125189929653888262651091513034101288176061637, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 39771257494928994772443159489388667828120255974663414059829667, 112512069512306494727303008885128122363137); _reserveERC721PoolHandler.mergeCollateral(57942411214135331116344019086, 50966166168829018646951094181); _reserveERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 9976727188958565820940949504880740882251161670606412); - _reserveERC721PoolHandler.kickWithDeposit(46499906238498902586911772110, 243585206007404659308061323622196762, 72952765246592935010907664); + _reserveERC721PoolHandler.lenderKickAuction(46499906238498902586911772110, 243585206007404659308061323622196762, 72952765246592935010907664); _reserveERC721PoolHandler.kickAuction(55028537595944270770553211257, 1001516670443746139, 82763479476530761653416180818770120221606073479896485216701663210067343855733, 87173954989810140824386757692098008); _reserveERC721PoolHandler.addCollateral(1001024179421838751, 1000001188819721496, 1000002344506367095, 6530134921782189394752696377); _reserveERC721PoolHandler.mergeCollateral(19828356041079785921978483412, 464424117899390679322680785); - _reserveERC721PoolHandler.kickWithDeposit(1146129138812820279512275742406899006346258348802902797, 4219718424788489909768119100775277245934850981691811631036534783842816329, 0); + _reserveERC721PoolHandler.lenderKickAuction(1146129138812820279512275742406899006346258348802902797, 4219718424788489909768119100775277245934850981691811631036534783842816329, 0); _reserveERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1050087191221791082398932662990324766651316, 3); _reserveERC721PoolHandler.mergeCollateral(0, 386168673403894210328116890716853946723469); _reserveERC721PoolHandler.repayDebt(1015864060585021484623052152563094131418012206877374489310749142251489, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC721PoolHandler.kickWithDeposit(19408939535910672758664488407938897092273679997782010200857723087644923896, 1057414462466256286, 13289084132804322739065722933); + _reserveERC721PoolHandler.lenderKickAuction(19408939535910672758664488407938897092273679997782010200857723087644923896, 1057414462466256286, 13289084132804322739065722933); _reserveERC721PoolHandler.bucketTake(3151017896386031827413516875, 2540768948197827014424192592, false, 761140598920073980925454850899687234927852597610046440423563685117132715, 100113745313246552520935757834280383100238762714184955603720473801765591344919); _reserveERC721PoolHandler.kickAuction(1027920, 0, 254879170573312258270793799360370693954580536471439396, 97286380385190384847571593446602726303888375224589706116); _reserveERC721PoolHandler.settleAuction(6178626592817349057786143551, 49577215984102992731321444262, 85049865577681057730992856830535, 53241092962274802353717679741); @@ -321,13 +321,13 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.removeCollateral(129740094499015661734020744, 11188961989447144928224461839, 36473640492253790055690961099, 18659652953490960603283370445); _reserveERC721PoolHandler.kickReserveAuction(1, 1); _reserveERC721PoolHandler.moveQuoteToken(9, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 544781490063735185438746830928607, 0, 2); - _reserveERC721PoolHandler.kickWithDeposit(107394140960, 46678630708744656096834836008492873180013869100869966463468687812771350549746, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC721PoolHandler.lenderKickAuction(107394140960, 46678630708744656096834836008492873180013869100869966463468687812771350549746, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.moveQuoteToken(682467056624483736247668823913521291271521942309410690, 13297056714637176297680690285357850443056031002605095196048, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 905, 90586972155252299764626426031637260); _reserveERC721PoolHandler.removeCollateral(820397375784401341, 2289851227553302238346804, 366291680291620320873389755930105761, 1036401623765599425); _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 12360422984728090763174972381336997720414891, 6551786103746359696774); _reserveERC721PoolHandler.removeCollateral(1, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 52919477132483414642703365492331309794304054278629913950497511394333677413997); _reserveERC721PoolHandler.addQuoteToken(1010757079117454502, 1742910830, 14318576517254284592091915, 13885739647634851069262128); - _reserveERC721PoolHandler.kickWithDeposit(237, 1327412166737802466004533203335178272754780546877479845176496458676010, 116999066456574005838751437815033); + _reserveERC721PoolHandler.lenderKickAuction(237, 1327412166737802466004533203335178272754780546877479845176496458676010, 116999066456574005838751437815033); _reserveERC721PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 838605009491023757396180747491021195288915834986478797881597476991101, 0, 12185655371963123202426292852633631246491940546961645574398702828); _reserveERC721PoolHandler.bucketTake(29880206871970, 1, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2514168214202568818637700798335620356, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); @@ -370,7 +370,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.withdrawBonds(12359640723606534757209152717, 102935434505351343912280215325917315062167825230686093278816538829689024068015, 34810599451682367962123147026); _reserveERC721PoolHandler.kickAuction(58485213306022382326189166039000286440128823013881931783701007845436636653839, 56606995915681684154395560059456928878992630945401931569697046893374843925100, 3452271214393100, 43243114592860114229589354); _reserveERC721PoolHandler.kickAuction(183003886826191747798880165681, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 291234521932052682362882015007, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC721PoolHandler.kickWithDeposit(1, 31233606660941926768869028632460306972481382008, 106765844095672375477199495769622555985798999265655424237241669); + _reserveERC721PoolHandler.lenderKickAuction(1, 31233606660941926768869028632460306972481382008, 106765844095672375477199495769622555985798999265655424237241669); _reserveERC721PoolHandler.withdrawBonds(391055528107383309760, 58466282460279340254555320596944, 1950784552175522082992529617963956806452196403342914318832231945664043); _reserveERC721PoolHandler.takeAuction(498139115547681239562291, 6289687308174905562829207209464121448122091926916226574718854, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 12229950103649157091400); _reserveERC721PoolHandler.takeReserves(865225, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); @@ -405,7 +405,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.drawDebt(19326596503819015122434076483248832001, 0, 3); _reserveERC721PoolHandler.takeReserves(1, 69549065499190809, 14560248220041165357); _reserveERC721PoolHandler.settleAuction(1, 333956958563755226022233863388209592786685540557382138570, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1658); - _reserveERC721PoolHandler.kickWithDeposit(31963677911186726812936292557952954764313493121955298534633510702615665376692, 447986841978, 177508954925347945049604278975979722437516018170581303253274132261); + _reserveERC721PoolHandler.lenderKickAuction(31963677911186726812936292557952954764313493121955298534633510702615665376692, 447986841978, 177508954925347945049604278975979722437516018170581303253274132261); _reserveERC721PoolHandler.pledgeCollateral(472718701078051043, 2, 1); _reserveERC721PoolHandler.addQuoteToken(1982293065154827338663610945109, 39918920720200831999879075808139079, 11809030164816699035634512342, 103834669188655825147339496110968394100595725587777685550942448920228256060866); _reserveERC721PoolHandler.moveQuoteToken(61254389549281892933238407562, 8987658565873430091702403327, 1000001442416058038, 29197004059567091447142350617, 6606313173691139960356513108); @@ -415,7 +415,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.kickAuction(106448808771037447301803820926416226252394847235491597014603888747398433953283, 98930505109154940965382144224046356529341303497473852076125450676446123485610, 57420795107228920750120741, 14343513994235904689950452); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 18398671003660997328489361733181380059771194151374720940100774309490); _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 10056492706478328827467723138987722201051013349277071, 5863659101796899072148019909975931); - _reserveERC721PoolHandler.kickWithDeposit(40088073782493770845962553207132495163225, 0, 1); + _reserveERC721PoolHandler.lenderKickAuction(40088073782493770845962553207132495163225, 0, 1); _reserveERC721PoolHandler.transferLps(2146935195669, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 253876435052301745166, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.bucketTake(8978705110297794447193521314, 110349606679412691172957834289542550319383271247755660854362242977991410025713, false, 1212036, 21995663469672571506523191137); _reserveERC721PoolHandler.takeReserves(13983215926481194279332364949173675554014444060943088056978847257560416393754, 11328152995191119345390530785, 11111110231647937598087699472); @@ -429,7 +429,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.drawDebt(1520472492222614822, 23804313838152813827948900122, 14507380694644109624196145); _reserveERC721PoolHandler.transferLps(6816294063633881901715353594, 47834447104972204440426812770, 666433214817705272498932756, 115040648028213763271245853549043880494636874452181292758191479633142775385877, 102417322237688655); _reserveERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 4551881259667522805609387966388, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _reserveERC721PoolHandler.kickWithDeposit(1, 7989672918233794, 40726242568900785035707173794); + _reserveERC721PoolHandler.lenderKickAuction(1, 7989672918233794, 40726242568900785035707173794); _reserveERC721PoolHandler.mergeCollateral(270147720067271986, 2); _reserveERC721PoolHandler.removeQuoteToken(710119199745696966903848707590636104955123834893999917692890399162669538, 11228333960250406280414063234409665807588369059982824974040511115339182010055, 22240360080774618842439937678, 84504225004904376369791573563284249542408850021887527687604654240424532542007); _reserveERC721PoolHandler.moveQuoteToken(3, 43053076695891353188678443447462499759824775, 374510291702722721486842413850256458482381280611070981918593987, 349319539515366013914185404929464950865423385119063071887464, 1); @@ -465,7 +465,7 @@ contract RegressionTestReserveERC721Pool is ReserveERC721PoolInvariants { _reserveERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.removeQuoteToken(1, 117506215362711008534467107982071294667273969293791, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.kickAuction(2, 115035799109830221, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 9150273853555630333); - _reserveERC721PoolHandler.kickWithDeposit(1, 2380963819538393125633366019791981, 0); + _reserveERC721PoolHandler.lenderKickAuction(1, 2380963819538393125633366019791981, 0); } } @@ -497,13 +497,13 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.pledgeCollateral(2973, 12980, 12575); _reserveERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 5836897713694909458961143219087657265859396202386, 418994944943089462509828792605480090787194735707899603341331861); _reserveERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, true, 166295466119333049767188, 0); - _reserveERC721PoolHandler.kickWithDeposit(216865859185051050490395844374682464336597720750158643011958868, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); + _reserveERC721PoolHandler.lenderKickAuction(216865859185051050490395844374682464336597720750158643011958868, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.withdrawBonds(1858090718805359669499377281512607, 557139523703671539785912454157825729, 2); _reserveERC721PoolHandler.withdrawBonds(7305, 2817, 27548); _reserveERC721PoolHandler.withdrawBonds(577, 35236, 1810); _reserveERC721PoolHandler.repayDebt(9882, 5933, 5257653714629391278209); - _reserveERC721PoolHandler.kickWithDeposit(425890864274089673370439398318040, 8124420662388080388625483997786480234652167205683345976961316664729343626, 212292); + _reserveERC721PoolHandler.lenderKickAuction(425890864274089673370439398318040, 8124420662388080388625483997786480234652167205683345976961316664729343626, 212292); _reserveERC721PoolHandler.bucketTake(10001, 10917840686393747753248013573387435474019080871649447935005320552478637850401, false, 6818, 7225); _reserveERC721PoolHandler.settleAuction(20003, 14874, 13726, 191); _reserveERC721PoolHandler.pledgeCollateral(2, 3, 83398553782781505302811573551993282445); @@ -588,7 +588,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1722371354839680683988766610329203277858181788470460488233666996333852018, 1); _reserveERC721PoolHandler.drawDebt(0, 30333357180428676788451188588686278894229468869212795776, 101); _reserveERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 73274262195612324714235063617462285603377716151565431360143491268980618269199); - _reserveERC721PoolHandler.kickWithDeposit(91221039842142260878471427, 2115110545210901948621409148599, 42155231413531253709163242634000659484778704909444546167257722348302126445308); + _reserveERC721PoolHandler.lenderKickAuction(91221039842142260878471427, 2115110545210901948621409148599, 42155231413531253709163242634000659484778704909444546167257722348302126445308); _reserveERC721PoolHandler.moveQuoteToken(1348435468469406527294724725910300993538, 14, 252868175, 2406010387359192497786851723918820385417682024241156835709, 33344372068804643151373724385031701660242792259102); _reserveERC721PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _reserveERC721PoolHandler.removeCollateral(75334916421908342715821991360314406659986243367584363431282435806482422434649, 84254812764063300473689406001366385055532468438486031564463701344309344971928, 691214260344610523417893990369819322900782727280106288200780356407044406, 6957); @@ -606,7 +606,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.withdrawBonds(3, 10252948217684358277690585924402315339730759158, 676); _reserveERC721PoolHandler.bucketTake(4091, 440, false, 3811, 18446744076686596088); _reserveERC721PoolHandler.removeQuoteToken(24679, 1833814778071575358614168217504482460080985797979610045719303973958300874008, 7641263304278166328613719, 12133); - _reserveERC721PoolHandler.kickWithDeposit(218617107916019362312548502476912579017035322382094, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 20636530197409440120925006135347157704837349); + _reserveERC721PoolHandler.lenderKickAuction(218617107916019362312548502476912579017035322382094, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 20636530197409440120925006135347157704837349); _reserveERC721PoolHandler.moveQuoteToken(25249348, 128730544, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 24824); _reserveERC721PoolHandler.kickReserveAuction(17049140588647704682779728141221654120232565469773188747816293913628437447779, 6976); _reserveERC721PoolHandler.pledgeCollateral(8312, 1066718972345429572, 18439263935650869961584999358742717378985964498324261726170680900373130139839); @@ -618,21 +618,21 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.moveQuoteToken(54506191507188327675542136885154930492711596315175730396964335963889829055712, 11930, 2817, 128730544, 83129991832086412493188006332287529671990339939278588866947563818932066088328); _reserveERC721PoolHandler.removeQuoteToken(4334, 17049140588647704682779728141221654120232565469773188747816293913628437447587, 7104521089183411911525122572776830420034201370300760705799357985154591952548, 20862791592217206631760600618160127950195753045737699209602687643923944467016); _reserveERC721PoolHandler.takeAuction(13189060067774031245623722836087800382947130520846912515080407936430043802648, 77, 87356276492659184466935582729932072437428114345322608718701023753572010646773, 1005325872708055929); - _reserveERC721PoolHandler.kickWithDeposit(13391, 5079476237624530602997235662015064, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC721PoolHandler.lenderKickAuction(13391, 5079476237624530602997235662015064, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.removeCollateral(544866250621213342646, 346985111684322310601641158045149412247149858342, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.removeCollateral(110349606679412691172957834289542550319383271247755660854362242977991410020308, 7000, 41000000000000000000, 17049140588647704682779728141221654120232565469773188747816293913628437447569); _reserveERC721PoolHandler.mergeCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 5978817446, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.pullCollateral(1002015662, 28, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.mergeCollateral(101084969685458490664033183559026968439053133011961092589565110571441453784516, 1000000017882055678); - _reserveERC721PoolHandler.kickWithDeposit(174251395529662625240909133004120507808196529121131490357885215415540815025, 3141080455, 3); + _reserveERC721PoolHandler.lenderKickAuction(174251395529662625240909133004120507808196529121131490357885215415540815025, 3141080455, 3); _reserveERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2297627921383370558416925689180900206628, 3496027494511808625436010596328839324698811471663105306779442805387875230745, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.pledgeCollateral(15739059877204073566117270814380188000214131303904218179175805497, 2, 3); _reserveERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 0); _reserveERC721PoolHandler.removeCollateral(2800634200846942493380842859424168854937074958681190467784858903, 78016991579, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.takeReserves(22580, 5147, 94460421841806538645057264132452793505262781441760895576901872079175127626500); _reserveERC721PoolHandler.drawDebt(17617, 12757, 5732); - _reserveERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6089060, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 6089060, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.takeReserves(1005710137141791512, 6904, 18139232371044103294278230912249567520145553997619280823194857001192733261051); _reserveERC721PoolHandler.mergeCollateral(9631171420675049043490255810798743819031189355044434603, 92198069096804414219442026698185040); _reserveERC721PoolHandler.kickReserveAuction(15623, 31410); @@ -642,7 +642,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.takeReserves(81482726478655780606519880836922780817194345611961531020561271497223861065456, 23922, 4358); _reserveERC721PoolHandler.withdrawBonds(3, 311, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.drawDebt(12460, 5634734609024883542269019750290, 27052); - _reserveERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.addQuoteToken(1230829525782142910842009636962430353068385216042726, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 243426103071929, 25253278677111562214999540485425277174875830375592711212450572647289657333); _reserveERC721PoolHandler.pledgeCollateral(231262758102498965, 2, 8431004467895649538221); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 18880593406428743687513214464228284805455136622115593315733172694013019, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -660,13 +660,13 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.withdrawBonds(89144452124699093633634021, 75568418754544239747000991790958882781347547485625682732390856727550926414041, 53421120790691520000000000); _reserveERC721PoolHandler.repayDebt(6745670486422665958801904, 18156, 110349606679412691172957834289542550319383271247755660854362242977991410021182); _reserveERC721PoolHandler.takeReserves(4223709321876209335800977, 6779403723488191555452736, 6649); - _reserveERC721PoolHandler.kickWithDeposit(126793640627116164, 93425562755246744301947722467021262725348593741, 113906932254024505677867947038104172278325388159025836551499890064497372393631); + _reserveERC721PoolHandler.lenderKickAuction(126793640627116164, 93425562755246744301947722467021262725348593741, 113906932254024505677867947038104172278325388159025836551499890064497372393631); _reserveERC721PoolHandler.transferLps(61059273622, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 686409889119102776553402514367887304409027821603525887599132, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.kickAuction(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.moveQuoteToken(6888031490875856383505624, 1000004251641650119, 17766, 521107689842149420099566856, 3116); _reserveERC721PoolHandler.bucketTake(9147, 110909611012307929921258558443111924434269890558053490118774409200516705425069, false, 848, 24516); _reserveERC721PoolHandler.addCollateral(66808358008877058555786202321428473300565051210245825630345, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); - _reserveERC721PoolHandler.kickWithDeposit(0, 572276761840333371835230514415, 1); + _reserveERC721PoolHandler.lenderKickAuction(0, 572276761840333371835230514415, 1); _reserveERC721PoolHandler.settleAuction(204908, 2, 312393663946591687019965590847811856924255613481018783417, 0); _reserveERC721PoolHandler.moveQuoteToken(12831, 7227, 6996, 18824, 1737066738165192954454524880601); _reserveERC721PoolHandler.pullCollateral(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 205074143153835252310169402383223127381796088790882058178720299255983); @@ -683,7 +683,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 36944037160284334633642150968736548, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.kickAuction(1664, 2687, 61844819425205955611780822297214949030390319935644088197958760795480037037004, 5684); _reserveERC721PoolHandler.kickAuction(2, 334821833427659408884044192205358189297953705210827333055625, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 114714946632198761448); - _reserveERC721PoolHandler.kickWithDeposit(9079766756264585028704744204349811692132311072893370, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 5019779030599366583537235537338422951452870132667490870496286144); + _reserveERC721PoolHandler.lenderKickAuction(9079766756264585028704744204349811692132311072893370, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 5019779030599366583537235537338422951452870132667490870496286144); _reserveERC721PoolHandler.mergeCollateral(4984, 229608465785188673438805); _reserveERC721PoolHandler.removeQuoteToken(93642312574415333353871715021716883034632464017331388812198771399808496942989, 1699741820, 18672, 8929); _reserveERC721PoolHandler.drawDebt(1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -699,7 +699,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.kickReserveAuction(3, 86280961761976730134953952439501336168); _reserveERC721PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3); _reserveERC721PoolHandler.addCollateral(699448245850365432665399399924070569419804726303386463502570993919918954, 1029868820922250736, 15410, 5639); - _reserveERC721PoolHandler.kickWithDeposit(118140301563251387374179768635068379059, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); + _reserveERC721PoolHandler.lenderKickAuction(118140301563251387374179768635068379059, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _reserveERC721PoolHandler.takeReserves(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.kickReserveAuction(411472, 52800516909296046030868598048611712208610813746399253775709698); _reserveERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 57777546185757217018044169352187208027407203882449808764607468958391167045673, 0, 1115145735128719535068773); @@ -731,7 +731,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.removeCollateral(13527654971365554136875240, 1024469854532947873, 82277264767608023807376655911526894242468349787505827700381501112786587951270, 6989657689877239829075539); _reserveERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 887625685042184418077998675336162167234696325914066889, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.addQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC721PoolHandler.kickWithDeposit(6975871988748397977595519851525984100494284301448125658986775, 35002418308494006878517694729319844164245816106307775350474987542895265049, 2); + _reserveERC721PoolHandler.lenderKickAuction(6975871988748397977595519851525984100494284301448125658986775, 35002418308494006878517694729319844164245816106307775350474987542895265049, 2); _reserveERC721PoolHandler.drawDebt(6957, 110349606679412691172957834289542550319383271247755660854362242977991410020390, 77807111595342673118281562); _reserveERC721PoolHandler.withdrawBonds(9223372036854775808, 6510, 1020249773700191477); _reserveERC721PoolHandler.transferLps(95868018266807660364567840688052268807368341235311662355325559728435081724210, 59343197987575902026200461, 50385582252721282543332560173666025362019029665057323749608221748241939337217, 986892103542755949328285, 702609569733041430000000000); @@ -740,7 +740,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.kickAuction(984, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 22692365548170576, 3769721194498056682809150739); _reserveERC721PoolHandler.repayDebt(54893429065585558013, 219002552, 1); _reserveERC721PoolHandler.addQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 112591795913981702405803017248976489615008255088860004648579385468454, 3); - _reserveERC721PoolHandler.kickWithDeposit(37186343836485239697177495355142346443133796930131714211502, 40, 952473014788157191696532820958); + _reserveERC721PoolHandler.lenderKickAuction(37186343836485239697177495355142346443133796930131714211502, 40, 952473014788157191696532820958); _reserveERC721PoolHandler.takeReserves(109275629822051245282711948884584740116225058749358267158936571, 1, 0); _reserveERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 71065286603072338); _reserveERC721PoolHandler.drawDebt(0, 765907, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -773,7 +773,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.kickReserveAuction(9202317719259999575111364254567, 2); _reserveERC721PoolHandler.removeQuoteToken(802456967614351751426469, 13035906296026882271389283, 9696, 8831); _reserveERC721PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 42557142512854052976639966906, 51261204, 244931333613551306317296101839267523016033074); - _reserveERC721PoolHandler.kickWithDeposit(110349606679412691172957834289542550319383271247755660854362242977991410020299, 21669769847638224766044984, 15188); + _reserveERC721PoolHandler.lenderKickAuction(110349606679412691172957834289542550319383271247755660854362242977991410020299, 21669769847638224766044984, 15188); _reserveERC721PoolHandler.bucketTake(17049140588647704682779728141221654120232565469773188747816293913628437447832, 10508, false, 82870141131114123210747106, 20173); _reserveERC721PoolHandler.moveQuoteToken(2361, 516861593, 12931, 863442823903604990000000000, 110349606679412691172957834289542550319383271247755660854362242977991410020812); _reserveERC721PoolHandler.takeAuction(3, 953723, 538201916876175337548, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -787,10 +787,10 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.mergeCollateral(615931907849527636407007999, 3409); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1615339971172289919, 9561813463648725830553079493511206240, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.settleAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 330390241802924149901913414865502270241491269533229827, 192238039574901627359751114691678109119545817036982599588138245250474); - _reserveERC721PoolHandler.kickWithDeposit(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 294477524364238597200667591233569460950782622978725); + _reserveERC721PoolHandler.lenderKickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 294477524364238597200667591233569460950782622978725); _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 125083948280992804673111007919998321, 178726166247461946684); _reserveERC721PoolHandler.bucketTake(6023645728103390554922799558529861901413439451833373750434366586930036878094, 85127295370114431, false, 47085614128393308692141, 110349606679412691172957834289542550319383271247755660854362242977991410020881); - _reserveERC721PoolHandler.kickWithDeposit(8674, 110349606679412691172957834289542550319383271247755660854362242977991410021562, 8739); + _reserveERC721PoolHandler.lenderKickAuction(8674, 110349606679412691172957834289542550319383271247755660854362242977991410021562, 8739); _reserveERC721PoolHandler.addQuoteToken(21416496157382734703023454, 16461, 14679, 2434225653257542523); _reserveERC721PoolHandler.pullCollateral(11877692222422748602206535, 8276, 4969317385555680448399656681204); _reserveERC721PoolHandler.kickAuction(24759795978403238641007088, 706310547396036310492496148481330216983963267868437781470258272885792074, 1026893218716441175, 6436); @@ -851,7 +851,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 0); _reserveERC721PoolHandler.settleAuction(110349606679412691172957834289542550319383271247755660854362242977991410021341, 3180, 111870582307655644804278828607808171435461142419445233568639003286225185770073, 22392291288828474616555843); _reserveERC721PoolHandler.drawDebt(16414, 6759734260545935184506684, 1004625717575739868); - _reserveERC721PoolHandler.kickWithDeposit(67272724708963954958722409033233844188807710838825258598180929318320993125796, 89592051342142976988730232, 2021); + _reserveERC721PoolHandler.lenderKickAuction(67272724708963954958722409033233844188807710838825258598180929318320993125796, 89592051342142976988730232, 2021); _reserveERC721PoolHandler.withdrawBonds(12853882064148404568563416224684410761047212014008428559323666130956821324947, 1997, 90307154178509584558366781); _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 339005774714724073, 435659783314771702598395272185016109632489664884291924026); _reserveERC721PoolHandler.repayDebt(17049140588647704682779728141221654120232565469773188747816293913628437447769, 471592098562661897234358387, 8215); @@ -879,7 +879,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 1, 10081834886462023113594973965133743137605743725729452456222271818182158670); _reserveERC721PoolHandler.withdrawBonds(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 135030087901748510114); _reserveERC721PoolHandler.transferLps(0, 0, 4914570263677369223966356991492381213239779752914081580131772, 4132607545180483, 5058329695630319188021807198857650546138436643272740407529685366236716); - _reserveERC721PoolHandler.kickWithDeposit(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _reserveERC721PoolHandler.lenderKickAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); _reserveERC721PoolHandler.kickAuction(30324730254955386193178254028518, 1184, 33469470521903697003104591057581529958054288659353468664277554984825714320942, 914); _reserveERC721PoolHandler.kickAuction(47204, 91454058164531467765695516, 3282, 8791); _reserveERC721PoolHandler.repayDebt(9673, 947056426666112419832299590, 54367033323784375538660337); @@ -890,7 +890,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.addCollateral(6944177584966, 9072112672431403459055763513432629494975616493727, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.kickAuction(0, 20821899840959197750506560073187538309066818017162195144801387057829, 121, 2341475908609198032495219723783565707251558345296631); _reserveERC721PoolHandler.removeQuoteToken(314173728045723915231099672, 3, 430596206249116637817, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC721PoolHandler.kickWithDeposit(2, 5594889650233664392475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.lenderKickAuction(2, 5594889650233664392475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.removeCollateral(16992453233292721045360115722858090495726253356619, 2, 3, 297712174142663301838675895090570646663526975); _reserveERC721PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 11687554619744686479680690400440483003931125041755561310164463248); _reserveERC721PoolHandler.takeAuction(110349606679412691172957834289542550319383271247755660854362242977991410022209, 57912509746078764575672674048543543886962344334129484298661037744834795902531, 2596356766803498599352523836033032873847346775640057640754715266346091938488, 18426); @@ -899,9 +899,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.addQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 455409650, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 40750954507732731557620667893283939431424265051722441797397943680380025); _reserveERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, false, 181173649846957613966723096162270025337961577415873802305, 0); _reserveERC721PoolHandler.takeReserves(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 11455); - _reserveERC721PoolHandler.kickWithDeposit(3, 0, 1); + _reserveERC721PoolHandler.lenderKickAuction(3, 0, 1); _reserveERC721PoolHandler.moveQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 134293144796577627031089975043705452310458619816434131237); - _reserveERC721PoolHandler.kickWithDeposit(75278511664418889852128284, 3370, 39515879849448015247209746562162317016925577386745453204546963263924533360060); + _reserveERC721PoolHandler.lenderKickAuction(75278511664418889852128284, 3370, 39515879849448015247209746562162317016925577386745453204546963263924533360060); _reserveERC721PoolHandler.mergeCollateral(156929519241970745164342457619482957567855215604596369181877473770284, 5602821767846275921723012186393534663762664926921032986654981305137887990532); _reserveERC721PoolHandler.addQuoteToken(51197342469581565833816208135546238056538197856526153611960954478051294384724, 109037503291001032522139932, 8050621528750408574545769, 9781); _reserveERC721PoolHandler.takeReserves(3, 4778669456713440690922420432805013255822874244476295494108286177804305817350, 14181666862969); @@ -914,7 +914,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.removeCollateral(48292332661984842675, 2, 160708667844241, 2958909860); _reserveERC721PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); _reserveERC721PoolHandler.kickAuction(221877832173424279, 282633423412468648220118, 0, 1); - _reserveERC721PoolHandler.kickWithDeposit(1872, 89242611905605994413275182985444538558391394499455186634383858074937530098533, 56257948443220192871595000345796007955542145382848696895724028479796611741124); + _reserveERC721PoolHandler.lenderKickAuction(1872, 89242611905605994413275182985444538558391394499455186634383858074937530098533, 56257948443220192871595000345796007955542145382848696895724028479796611741124); _reserveERC721PoolHandler.addCollateral(3752886672815641846548, 2, 60264689855906637685422747148170807601294022662395394912, 0); _reserveERC721PoolHandler.settleAuction(6840089205084041494789025947142738405664443669335373, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.bucketTake(9515, 1000000000, false, 93367352816879321, 42701881846504780434713886); @@ -972,14 +972,14 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 969869145845371529948775369615319097344406, false, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 144585881710344968462546184715943765156662183711); _reserveERC721PoolHandler.takeReserves(461559833565898122988327400325974789199294034703796939674278840982298596037, 2568374042366821377977901084825338916022232516802683512435, 0); _reserveERC721PoolHandler.moveQuoteToken(3982902995217437798968062519106020512474874211683, 36701680406848004143, 14287815798972665852353621839112627533584381937, 132005, 2); - _reserveERC721PoolHandler.kickWithDeposit(50310705142968539584273299129510444522871522397269627054556058594119858500216, 45978599603359075781444831263900707496437331655382222738127705004512629605810, 1083198430236618964); + _reserveERC721PoolHandler.lenderKickAuction(50310705142968539584273299129510444522871522397269627054556058594119858500216, 45978599603359075781444831263900707496437331655382222738127705004512629605810, 1083198430236618964); _reserveERC721PoolHandler.moveQuoteToken(2, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 434773218942245113129549207366355118696046828427451, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1379026254093475227745727); _reserveERC721PoolHandler.mergeCollateral(82101080172765201046315741214838494490540879089751250512904667457846639610730, 69870915829807863617934990); _reserveERC721PoolHandler.takeReserves(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); _reserveERC721PoolHandler.removeQuoteToken(94460421841806538645057264132452793505262781441760895576901872079175127626471, 22497985564735546931841875695435363017, 1042212097404729943, 110349606679412691172957834289542550319383271247755660854362242977991410021076); _reserveERC721PoolHandler.addQuoteToken(108295737856151253918775797758912873100941255803949027045716415973253423671047, 68397328269062983959241185268980190637364, 1004751202289701972, 132712777142965696718176194491516311627011792390393719489504691657348230); _reserveERC721PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 186439148264861203449391027618480408120000176731369, 3, 40023200504718086734416971094252194987436721, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _reserveERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639933, 197410721677371430362045723888975033742, 2181043900806628); + _reserveERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 197410721677371430362045723888975033742, 2181043900806628); _reserveERC721PoolHandler.kickAuction(1, 1142116748440938946689513224971022590947627121488051443735284418919, 14393668195164112, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.takeAuction(59989254010533297890765253686752098, 58761484768111130545009473750017209089064138985343535332182563, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.kickReserveAuction(1017857843580423432, 4956716931018294068994338); @@ -992,7 +992,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1, 873397330870953111425361349319149236689979258273918571901005458830862924); _reserveERC721PoolHandler.pledgeCollateral(3, 1902787282165869087646595753269357088079447600687337, 0); _reserveERC721PoolHandler.repayDebt(45436660615262588692406296738278171087799280242, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0); - _reserveERC721PoolHandler.kickWithDeposit(77408115217590017978412719720799857196157310231777211402042333694085318668374, 90799109809447300000000000, 16297560196350174330026106688466836917060202468177493882877709479403984047470); + _reserveERC721PoolHandler.lenderKickAuction(77408115217590017978412719720799857196157310231777211402042333694085318668374, 90799109809447300000000000, 16297560196350174330026106688466836917060202468177493882877709479403984047470); _reserveERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 47112383542945504303658628846045126630882131596942368276296039422525110569693, 166927988668618715657330314393630305044615392965526); _reserveERC721PoolHandler.settleAuction(47610241856056731132742760325409739314543349064959445967807639708702674265148, 4493, 168, 128796501156618976); _reserveERC721PoolHandler.pullCollateral(74236091829800111029172567704161886557379617844271211623618640907146314911232, 1343581646697625520000000000, 13824); @@ -1011,7 +1011,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.takeReserves(17049140588647704682779728141221654120232565469773188747816293913628437447807, 7651, 1045811184292014869); _reserveERC721PoolHandler.drawDebt(3279560014298887494766, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.kickReserveAuction(270121923656824, 112321331586198069083100950849665749980518728164696403424496311980048631369556); - _reserveERC721PoolHandler.kickWithDeposit(3284443624301598106206960818650371215777330987730575080725486939254173, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _reserveERC721PoolHandler.lenderKickAuction(3284443624301598106206960818650371215777330987730575080725486939254173, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); _reserveERC721PoolHandler.addCollateral(10616216246530184234966311866334, 56256556235935072677102942323001967, 0, 12021163246520400743589185965628); _reserveERC721PoolHandler.kickReserveAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.kickReserveAuction(0, 19979657596357888692279813663846429612); @@ -1022,7 +1022,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.removeQuoteToken(9227, 13941320904240752555833919, 165240148976787116493188160, 34025277266869118749817860524810612156321736119786881869803197160053520329500); _reserveERC721PoolHandler.transferLps(106317399761513305970663681108985732067607582319266680615621593700366731717573, 1242416601454437126614364945, 17049140588647704682779728141221654120232565469773188747816293913628437447948, 84810456870879655, 40059634669114966542286785); _reserveERC721PoolHandler.pullCollateral(6319, 88358780817628065037099743872475289622616338613170834220557273924276165656272, 891635191903999660000000000); - _reserveERC721PoolHandler.kickWithDeposit(3, 1696888859136447871286455510021308487813514819905612, 22970); + _reserveERC721PoolHandler.lenderKickAuction(3, 1696888859136447871286455510021308487813514819905612, 22970); _reserveERC721PoolHandler.takeAuction(1001249331476812266, 1710646628, 105234822610892977279892258887404823221551214624745795922260573953900744545483, 6634559779732654171925568496645381369799143368335138943959763091379284544487); _reserveERC721PoolHandler.takeReserves(1137528028818895737, 97325466505697806021261515, 2393402404848776433277228); _reserveERC721PoolHandler.addQuoteToken(110349606679412691172957834289542550319383271247755660854362242977991410022919, 2321603669961633289175053777547488671064392392667703119488740678865967925260, 1310877560468336622, 33425116473689933427778545378122799752138984264507361135403282302171137192662); @@ -1038,7 +1038,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.transferLps(4290010903603450, 9423131765552259003679275460906470114844928635643560164058, 0, 0, 3); _reserveERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 14900237193158208449918878169379000398734725501611631, 3, 0); _reserveERC721PoolHandler.transferLps(161927995494663611566910077810017873360098650670769758806477554306, 2079778, 3, 0, 0); - _reserveERC721PoolHandler.kickWithDeposit(153862296776603492, 18440327452859058366960038679320021856510555458866072605820371279232851664580, 33784521288333558174310189); + _reserveERC721PoolHandler.lenderKickAuction(153862296776603492, 18440327452859058366960038679320021856510555458866072605820371279232851664580, 33784521288333558174310189); _reserveERC721PoolHandler.pledgeCollateral(72464101745278774506085047583302803010683905799293165068016069564041376518621, 1036949351348937430, 15271568507320603061404794); _reserveERC721PoolHandler.transferLps(177, 83319296884457194672060749, 3001189307209841484693233558848, 13731025689741413542173372594331327371720961386378534776172193655990112775392, 2369); _reserveERC721PoolHandler.kickAuction(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 19905551914344144, 115792089237316195423570985008687907853269984665640564039457584007913129639935); @@ -1054,7 +1054,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.takeAuction(1000000000000000000000000000000015279322571684, 114395535064915329783163924249182617957175991588872769406986526168220147248067, 670268987378007584653171, 528); _reserveERC721PoolHandler.removeCollateral(1869047007922666106782535527626441838951792721731, 3, 1826074316662029411031795015663282588799344377344919699205, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.withdrawBonds(680015565322977171146463750, 98952051484438470000000000, 34877897525259221302315900469558307295618759709653541674579116172375681370859); - _reserveERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639935, 12945782878025864415238253647749476744412392107088451195, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _reserveERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 12945782878025864415238253647749476744412392107088451195, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _reserveERC721PoolHandler.takeReserves(68394675939489581409814016805464823205387222476203922322008671053529744970887, 24471, 33828831002529280172585159183693347152531726433832746369635034296542821809298); _reserveERC721PoolHandler.withdrawBonds(1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _reserveERC721PoolHandler.addCollateral(25877995643433930364689114808607575553506140477339421465986892750669606077092, 41507183200840372924289362900233965605661253666099041636741327107669552970807, 33008387469947294101638137830679038095581347948628262525173485428716211, 6157709115687037075520926); @@ -1128,7 +1128,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 70173488031339811521078882726077494784085213607, 2080973060562700953073211966813542122522167712807430431329393703366145659, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.takeAuction(5233, 22301295712931858060141247190645982492898341495690436621125192782373229254274, 43764952978556299336569611165192937702867819082178243241851041746706074827130, 1230345865539008060417316501); _reserveERC721PoolHandler.withdrawBonds(1032748245255268, 78098042508423659719689436517309882407037339874817938146060979015, 3); - _reserveERC721PoolHandler.kickWithDeposit(0, 2, 5819240836839086400119214410503549102547033159651); + _reserveERC721PoolHandler.lenderKickAuction(0, 2, 5819240836839086400119214410503549102547033159651); _reserveERC721PoolHandler.kickReserveAuction(30148168545918263388103443210121104667836967188570267, 714786213957829735714537276811750778591810307820350208595641709); _reserveERC721PoolHandler.kickReserveAuction(3325843666295109104252728306, 37402186049731323923490597749464496633517964215791656722808930228659640718045); _reserveERC721PoolHandler.takeReserves(7439, 12706802713463190655343114869961889945437903289201159203494939967350544042375, 24440); @@ -1158,13 +1158,13 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.kickReserveAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.removeQuoteToken(4165, 110349606679412691172957834289542550319383271247755660854362242977991410025896, 44813789050917922843525695584181139281561682682789553891976103352616696676450, 37216166979974404180437872468027626145507614596804510895271718567280663890868); _reserveERC721PoolHandler.settleAuction(4670291814652310463712962818849011898860531353858873104880504582424582199480, 11291243930342946428052099600678, 22834926146751784003678754368935153319379126427922833815118091286945438881622, 4661); - _reserveERC721PoolHandler.kickWithDeposit(1060419740155953531, 76581305006666593050435605109884251471184511907860295180804797363183009172518, 17049140588647704682779728141221654120232565469773188747816293913628437448129); + _reserveERC721PoolHandler.lenderKickAuction(1060419740155953531, 76581305006666593050435605109884251471184511907860295180804797363183009172518, 17049140588647704682779728141221654120232565469773188747816293913628437448129); _reserveERC721PoolHandler.takeAuction(79051682376884988638840106792513757374989259508589586478025506023083974624107, 1023617642909507627, 10277909286762186173502977204, 110349606679412691172957834289542550319383271247755660854362242977991410031843); _reserveERC721PoolHandler.kickAuction(8853630667992750553638900487147028447849014217765012674296299195, 79935532779679873389045009319833325992883356818427703497499484278, 3893685858321079645, 140956999); _reserveERC721PoolHandler.settleAuction(6555356995414220666845377, 73646370981667934963733961753964965171961420011398047284402033418662623341800, 17049140588647704682779728141221654120232565469773188747816293913628437448365, 1678955710); _reserveERC721PoolHandler.settleAuction(195474934582959082666777108384475412535734991087, 0, 81707858379237322755113001664779701923578139757776342960626124024582792, 0); _reserveERC721PoolHandler.mergeCollateral(110349606679412691172957834289542550319383271247755660854362242977991410028018, 52035096966165069098678334399629139194257647153255930448520122205110845044490); - _reserveERC721PoolHandler.kickWithDeposit(123355078383615564701961123, 28332019758714482594428958, 103677654654093669796670520570660480161406907628706079697559073573022600261148); + _reserveERC721PoolHandler.lenderKickAuction(123355078383615564701961123, 28332019758714482594428958, 103677654654093669796670520570660480161406907628706079697559073573022600261148); _reserveERC721PoolHandler.drawDebt(4707470850799779342815163658547135, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 7539410644177589385057680971088); _reserveERC721PoolHandler.removeQuoteToken(10912375542018741604, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 300141089550676539097042491696555481937216134279146, 100929563396520016); _reserveERC721PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1391094481635148746087409007027295443683845760, 883092727263262498347775353359806478044799967593820); @@ -1200,7 +1200,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.addQuoteToken(45202668247587175655414, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); _reserveERC721PoolHandler.addCollateral(23093636503402966125428604840327186808172411233516979464260686697517634748827, 44676663231643890771274199878184307567903206893351431065390676400931697176499, 110349606679412691172957834289542550319383271247755660854362242977991410027176, 8548); _reserveERC721PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 1); - _reserveERC721PoolHandler.kickWithDeposit(0, 20563275643991229091232812911994390736022472582033200362613925, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC721PoolHandler.lenderKickAuction(0, 20563275643991229091232812911994390736022472582033200362613925, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639932, 43869818970719934002938479268368400562196426152437423, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.removeCollateral(78643449810765483440740999096441639950965454112506271686626475895043904496705, 1068721548252481074, 143608068364623628824780733, 49745121764463264922188111015692250481049496450111852169418987803124756520863); _reserveERC721PoolHandler.mergeCollateral(4510160366019958217656155039, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1213,13 +1213,13 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _reserveERC721PoolHandler.addCollateral(0, 3589932432086166330, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.addCollateral(0, 1, 1071943670325492601427650078797113571576721606677458099651331210227, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _reserveERC721PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 595910480626364957921262774435578495415796367642062443426, 30263794382233212393747, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _reserveERC721PoolHandler.kickWithDeposit(47096058033881415827, 101902921203138351021721659257728797620279649645382963308753958694537917948552, 6996989738119660531345330); + _reserveERC721PoolHandler.lenderKickAuction(47096058033881415827, 101902921203138351021721659257728797620279649645382963308753958694537917948552, 6996989738119660531345330); _reserveERC721PoolHandler.removeQuoteToken(1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 24082702607785241512945810732039061875681498); _reserveERC721PoolHandler.transferLps(8785, 5517, 248392406223906035987413321, 1291, 25063); _reserveERC721PoolHandler.takeReserves(102749287001790714687712150586513920909198774391301806880685052811496504109486, 110349606679412691172957834289542550319383271247755660854362242977991410028473, 110349606679412691172957834289542550319383271247755660854362242977991410029924); _reserveERC721PoolHandler.repayDebt(30285096121830403947134558644956487841, 1048297510208744571088310896650231298276893636915828208122110, 436973193969840851145429852); _reserveERC721PoolHandler.repayDebt(18, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); - _reserveERC721PoolHandler.kickWithDeposit(34134860810911474290416650290686076222926739487106938311237949421690653716981, 4032, 1333501642771490000000000); + _reserveERC721PoolHandler.lenderKickAuction(34134860810911474290416650290686076222926739487106938311237949421690653716981, 4032, 1333501642771490000000000); _reserveERC721PoolHandler.bucketTake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, false, 2839186653002568784777085022448404483404726694806, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _reserveERC721PoolHandler.withdrawBonds(110349606679412691172957834289542550319383271247755660854362242977991410021628, 76529475526451187491982575966313403485592038333197826787817219431583701987401, 1310077841665241169856764); _reserveERC721PoolHandler.kickAuction(3539, 1525, 47573102242519063645838019693949691266732320757640444506346417447743805834703, 1794623067530945372406223994625738705986999348129378022947241895172413198578); @@ -1273,7 +1273,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants bond factor 10000000000000000 neutral price 2192531875681761460142783972780 */ - function test_regression_kickWithDeposit_neutralPrice_cast() external { + function test_regression_lenderKickAuction_neutralPrice_cast() external { _liquidationERC721PoolHandler.moveQuoteToken(16240720125467661606, 28507061386252532506012948324212153588801236092794769231606167085831814924268, 0, 40358324135316113531931393405372229766, 2); _liquidationERC721PoolHandler.kickAuction(228874383014542695468217087622403, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC721PoolHandler.addCollateral(23121, 6166, 7000, 1896); @@ -1284,7 +1284,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 68); _liquidationERC721PoolHandler.addQuoteToken(2644, 13836, 16410, 7178); _liquidationERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 672088878607963814997927668757064124069753982839736236050670749746712986, 1, 729013072206232519134783948761); - _liquidationERC721PoolHandler.kickWithDeposit(28262719802168522, 48848998002172574296720863399512897605460326389131400261938845100050735686, 52452577); + _liquidationERC721PoolHandler.lenderKickAuction(28262719802168522, 48848998002172574296720863399512897605460326389131400261938845100050735686, 52452577); _liquidationERC721PoolHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 0, 30396071636327539549111261300842373583312078816387575); _liquidationERC721PoolHandler.withdrawBonds(1, 90312535873102305736385108980270515816485, 45541159251580637509308611116687744487081722353859931413158); _liquidationERC721PoolHandler.bucketTake(87658210016255932887119830170416025175286252107146, 5715789760161648995455320028011320801218565075278926585576347024319432, true, 1193179031134196798442157080499159509, 11164505394125949813560325953834487291711336901424348); @@ -1292,12 +1292,12 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.withdrawBonds(9648252531436976565219102860600044562536694518719750729, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _liquidationERC721PoolHandler.addQuoteToken(6534, 2317, 4024, 10784); _liquidationERC721PoolHandler.withdrawBonds(107763320087340106734965987981723753909383158103508851802652077516623430392698, 7323, 5151534821115945192353164396480956473511573634899664160920884112447096424265); - _liquidationERC721PoolHandler.kickWithDeposit(3076, 12764, 6282); - _liquidationERC721PoolHandler.kickWithDeposit(0, 16408400898734062116577460012912667012287455, 65773776258373433131580603717471270601328100625959658898845346732102); + _liquidationERC721PoolHandler.lenderKickAuction(3076, 12764, 6282); + _liquidationERC721PoolHandler.lenderKickAuction(0, 16408400898734062116577460012912667012287455, 65773776258373433131580603717471270601328100625959658898845346732102); _liquidationERC721PoolHandler.settleAuction(34081948563130815749, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 159708144379349862281566665546635594716393854617244825653429126); _liquidationERC721PoolHandler.transferLps(1641, 5327, 1063, 4711834399694008773535387, 2854); _liquidationERC721PoolHandler.takeAuction(7426, 110349606679412691172957834289542550319383271247755660854362242977991410020068, 13173, 4638); - _liquidationERC721PoolHandler.kickWithDeposit(510077028605139511112517527060037280036458218992385377000111081662770, 4394380182120472288567827043655915277073451283544574935855972185841, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.lenderKickAuction(510077028605139511112517527060037280036458218992385377000111081662770, 4394380182120472288567827043655915277073451283544574935855972185841, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.kickAuction(5734, 17049140588647704682779728141221654120232565469773188747816293913628437447586, 12828, 3193); _liquidationERC721PoolHandler.pledgeCollateral(35940, 454, 1200); _liquidationERC721PoolHandler.withdrawBonds(101864022921265762660121874185712211490556967677588053835031063478670167772461, 532796735559386331821278202904716106660777401312, 1297172601950155808557573782108709228397367180241338836020); @@ -1309,11 +1309,11 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.bucketTake(9360378859599753115882287584886950847045, 269568137942861, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 858334960022945668261399707730752300983984534389179760179200); _liquidationERC721PoolHandler.repayDebt(5665, 16081, 10598); _liquidationERC721PoolHandler.takeAuction(2206649220961061, 3, 2558822529498055607535538082, 2); - _liquidationERC721PoolHandler.kickWithDeposit(5135, 252, 3052); + _liquidationERC721PoolHandler.lenderKickAuction(5135, 252, 3052); _liquidationERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 84778326809, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.pledgeCollateral(26704702559225324, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 123813966528466488405289534290869974834); - _liquidationERC721PoolHandler.kickWithDeposit(28676584055155371127339424197743556014228397271881303299274209337718138573272, 715142653053347066044245, 7764); + _liquidationERC721PoolHandler.lenderKickAuction(28676584055155371127339424197743556014228397271881303299274209337718138573272, 715142653053347066044245, 7764); _liquidationERC721PoolHandler.mergeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1444530191740898608263564613786346598409258687973983894817157141569827954309); _liquidationERC721PoolHandler.takeAuction(2683262963772906007726, 61794922595012971575345748309835264049466828340715, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 209274824015567095928261875669007463838); _liquidationERC721PoolHandler.pullCollateral(84262887215945421474490051181846080073302855398141535126932442358224078654327, 131581210063195547982169, 3158); @@ -1343,7 +1343,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.addCollateral(8603, 99900944915474782579496377896170946505554788190103848378839838164881858335657, 11500, 20589113602286618350728304985651065486495845821975021544070012297585943335517); _liquidationERC721PoolHandler.addCollateral(6525, 8832, 190203349757305774448838, 17485); _liquidationERC721PoolHandler.settleAuction(8159, 25332102553001194559703975696286123841168307023495310180416066017865639681243, 6991, 8750); - _liquidationERC721PoolHandler.kickWithDeposit(46900152567531912949534061275304527366300540659433162198397801645114849134502, 3207, 1818); + _liquidationERC721PoolHandler.lenderKickAuction(46900152567531912949534061275304527366300540659433162198397801645114849134502, 3207, 1818); _liquidationERC721PoolHandler.removeCollateral(868, 2, 52947173568469315358037569797, 3); _liquidationERC721PoolHandler.takeAuction(65130234722589130134667348576240687075912788594912757212031393701891742536326, 5172, 1000569036523119027, 2404); _liquidationERC721PoolHandler.settleAuction(1042968834923118153195776299849785937895168284462048925006461231628559495, 77972472601089264004437114811616471376430027220227157483188978538519931, 361887418009158311401517964660103544015, 2); @@ -1362,7 +1362,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.addQuoteToken(0, 726815, 1, 2932779668528103355949814079583301488156544243528675404174344755142098183355); _liquidationERC721PoolHandler.repayDebt(471233093929416296889588572257815098049, 960418, 80472346698); _liquidationERC721PoolHandler.moveQuoteToken(2, 364787773548331092026913292245437703, 2, 73557271271396621183, 579840063845373025411980956025717190624608903746429385196235273); - _liquidationERC721PoolHandler.kickWithDeposit(327802103882017109659626094313563460720823034734717686279625350780584039572, 4076676164188590, 5501239074574528461247508019230244165677304875827); + _liquidationERC721PoolHandler.lenderKickAuction(327802103882017109659626094313563460720823034734717686279625350780584039572, 4076676164188590, 5501239074574528461247508019230244165677304875827); _liquidationERC721PoolHandler.drawDebt(111442906621817668651212151270134672993260463626380605189870313919033323376070, 8713, 3013); _liquidationERC721PoolHandler.pullCollateral(282970807149668576085559389854100165846143234005, 5086256282164499150802733031891060245556845029309915122, 2065566568421007343783918655139823137473073669947466); _liquidationERC721PoolHandler.takeAuction(690091934088262250909605940709040986644756222386535711266170666980698177, 97435855000000000, 7407, 10297); @@ -1380,7 +1380,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.addQuoteToken(44676197319765223275607159424012724449281318024444720250279869, 261, 10635780417911034776477404764589105344639527920838396372, 7777324989604283658203600733633057299); _liquidationERC721PoolHandler.removeQuoteToken(4494, 10152, 45226879256681936737340727417792716656816496690696108158359702646866264337356, 4974); _liquidationERC721PoolHandler.transferLps(785944483884, 2, 41501069480420576790835849922556679957811554270390476143573385, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 0); - _liquidationERC721PoolHandler.kickWithDeposit(26928750472841041879932565, 26123068860409804723282978927412742528582918552906671535319571778159961538927, 5307); + _liquidationERC721PoolHandler.lenderKickAuction(26928750472841041879932565, 26123068860409804723282978927412742528582918552906671535319571778159961538927, 5307); _liquidationERC721PoolHandler.kickAuction(7148270798289634, 123562683855770113788739689413771780533379978027139387891106852861, 14341530288208615034173978545726, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.mergeCollateral(57825258216, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.pledgeCollateral(22613168825581155780081618742485829082070464489342, 321153929447946244959967246053193, 158606461995372470821572301357887135842991432754469395); @@ -1405,15 +1405,15 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.repayDebt(3075, 16888, 6876); _liquidationERC721PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 124, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.withdrawBonds(58546073979273980447760663203870717, 1823256, 271464071142188304031325); - _liquidationERC721PoolHandler.kickWithDeposit(2260916007981296474281749923465809825, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 97362456469653076435370247); + _liquidationERC721PoolHandler.lenderKickAuction(2260916007981296474281749923465809825, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 97362456469653076435370247); _liquidationERC721PoolHandler.bucketTake(533197809248651243864742703816031487998685828685647599040445, 248811279902, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 26924611628387715685528592868359459082424142193334471443103857000044912); _liquidationERC721PoolHandler.repayDebt(2030357616756168135545217, 9951113, 46707708790923503680867700847191422768762729160465524312543250020115642189229); _liquidationERC721PoolHandler.addCollateral(13092, 6848, 4884229086628787517232069, 14937371903851846029272014701216634099173805304477119181385826964981754437309); _liquidationERC721PoolHandler.withdrawBonds(297510898748, 3, 91441202004527443837329575926313542797762831680048047009069890555360586017); - _liquidationERC721PoolHandler.kickWithDeposit(3235345220622657242076698379841500723529023160420386459, 71923315062412716384354187275681257339148927062139082134682, 1); + _liquidationERC721PoolHandler.lenderKickAuction(3235345220622657242076698379841500723529023160420386459, 71923315062412716384354187275681257339148927062139082134682, 1); _liquidationERC721PoolHandler.removeQuoteToken(853100609798508055519363847765040142977645174, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC721PoolHandler.pledgeCollateral(3475949935082590421075665820010611521808345452135639357597414408209558444665, 0, 2); - _liquidationERC721PoolHandler.kickWithDeposit(70472678854313457065762927493398315609051607091850141997672973647552880689367, 30048146413441522972941930824870448374317907361655623488066608546737241009974, 104622675119319866199166284355409847693399235199913438416992461195623902903974); + _liquidationERC721PoolHandler.lenderKickAuction(70472678854313457065762927493398315609051607091850141997672973647552880689367, 30048146413441522972941930824870448374317907361655623488066608546737241009974, 104622675119319866199166284355409847693399235199913438416992461195623902903974); _liquidationERC721PoolHandler.kickAuction(44750535322323097886232700953711533167432706667447769787857330682761671954159, 2772, 11409, 36836); _liquidationERC721PoolHandler.pullCollateral(7233978972438828602958474502487290630446597822236, 0, 21985327600407612206550360385); _liquidationERC721PoolHandler.moveQuoteToken(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 2, 2); @@ -1421,7 +1421,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.pullCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 239940201348644233208); _liquidationERC721PoolHandler.settleAuction(15503, 19100, 1000000000000000000000000000000103950766006382, 17049140588647704682779728141221654120232565469773188747816293913628437447681); _liquidationERC721PoolHandler.pledgeCollateral(33048543792124048621731808725621184491027490904574222759119253950220, 134515436679508803290748978690145, 9017960981718934214761476028315749251765937262015411712549083527151122); - _liquidationERC721PoolHandler.kickWithDeposit(3402484140704840714852165222466421319277196115904276688808989949209863148382, 332356037529979757136141110688988763423733251104366226107422465, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC721PoolHandler.lenderKickAuction(3402484140704840714852165222466421319277196115904276688808989949209863148382, 332356037529979757136141110688988763423733251104366226107422465, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 109244865661167951376579660840052128629362683365553988031104, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 434616476881531912650597121373353757879323799369633890624606998680799955); _liquidationERC721PoolHandler.drawDebt(17049140588647704682779728141221654120232565469773188747816293913628437447792, 14327268022221408372437138, 6980); _liquidationERC721PoolHandler.takeAuction(37714057305872612089428949748275078505078436571074044799028069429283585400881, 22257493475249211941276288306153969376780678014335618615538805067256729832007, 1004678346925653953, 328008362368927965420329); @@ -1463,7 +1463,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.kickAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _liquidationERC721PoolHandler.bucketTake(971006664332363873, 0, true, 0, 15986); _liquidationERC721PoolHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 2); - _liquidationERC721PoolHandler.kickWithDeposit(12720, 675, 110349606679412691172957834289542550319383271247755660854362242977991410021149); + _liquidationERC721PoolHandler.lenderKickAuction(12720, 675, 110349606679412691172957834289542550319383271247755660854362242977991410021149); _liquidationERC721PoolHandler.addCollateral(133974925741102977860155184598397, 11137, 36117560019477733219984400, 84600044717556314155614986115330154363062300820583133957863761299521521289897); _liquidationERC721PoolHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 98546356536658849434258099672833233, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); _liquidationERC721PoolHandler.drawDebt(786252340239316354007821985565908446632227539806265549140047894110155501, 90435141303855032427308077630435649302048, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1475,7 +1475,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.moveQuoteToken(3244720808165042587255585340035, 34244, 8531, 22738, 9764); _liquidationERC721PoolHandler.takeAuction(1, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); _liquidationERC721PoolHandler.pullCollateral(2836923789, 11084, 1066392982825872485); - _liquidationERC721PoolHandler.kickWithDeposit(6726038676156020517974971996445795098715274405869621537902270417586368871589, 111621529414873316662263978727041793952079363677428237052890850838439717965894, 29346036003018903669490809856255450358643342149088887164960525732294055280172); + _liquidationERC721PoolHandler.lenderKickAuction(6726038676156020517974971996445795098715274405869621537902270417586368871589, 111621529414873316662263978727041793952079363677428237052890850838439717965894, 29346036003018903669490809856255450358643342149088887164960525732294055280172); _liquidationERC721PoolHandler.addQuoteToken(1495348749258069363646141008368109600700429591964583523318646824667430, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 9260791534798, 102588914508724528896946077198999); _liquidationERC721PoolHandler.bucketTake(2913523189356960662022182, 179086652739514922685883, false, 1006826676733707632, 5865627197071135484993339); _liquidationERC721PoolHandler.addCollateral(1203066715617402811784887572423578628224922261386350219308978576, 1485342683932701325295496949083592841, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); @@ -1494,7 +1494,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.takeAuction(84302279592249174798926704353019458379571723129910786803533086889172, 2, 837652390361928323840720, 26788062095621267426630304881576854); _liquidationERC721PoolHandler.removeCollateral(58853586268803237264344882998102064023655331370610767150059205485351029577131, 5740, 109527266517559640736816627879259638736773192273923970585403470519999261876730, 6412); _liquidationERC721PoolHandler.repayDebt(40193996907637574310407453, 64650572443540791510409588286068283072289743976179099823953728804096581861294, 16890633210740139386951272290667807876990721461707025530636606677393584905517); - _liquidationERC721PoolHandler.kickWithDeposit(1339591516706836065215627775081, 949188112003023642838930314, 279833028916452901398); + _liquidationERC721PoolHandler.lenderKickAuction(1339591516706836065215627775081, 949188112003023642838930314, 279833028916452901398); _liquidationERC721PoolHandler.addCollateral(2, 2551757117317376983515589071170863073624587318883214268791, 0, 3); _liquidationERC721PoolHandler.settleAuction(204977, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 1038771564945455498); _liquidationERC721PoolHandler.drawDebt(94516436976342041022181862897390, 8392, 110349606679412691172957834289542550319383271247755660854362242977991410020143); @@ -1507,7 +1507,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.takeAuction(19211121209242582398386599977204988, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2, 3); _liquidationERC721PoolHandler.removeCollateral(6255286185929723510878268310824, 8058911585528, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 0); _liquidationERC721PoolHandler.addCollateral(3, 657286326299620656036667163073688742535367, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _liquidationERC721PoolHandler.kickWithDeposit(1001576293879273832, 7440, 91897966198308029099749099432594203431250943500715406530266036837761694360819); + _liquidationERC721PoolHandler.lenderKickAuction(1001576293879273832, 7440, 91897966198308029099749099432594203431250943500715406530266036837761694360819); _liquidationERC721PoolHandler.drawDebt(623040457374668789552664552, 4463, 23580); _liquidationERC721PoolHandler.addQuoteToken(3462, 21859, 1000700898679174503, 50180923402297581999245996); _liquidationERC721PoolHandler.removeCollateral(1, 16609356725239214801, 126335242522206457, 0); @@ -1519,9 +1519,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.bucketTake(10419, 6795, false, 59987649140957074847083443, 7523893329470187777887047); _liquidationERC721PoolHandler.drawDebt(450404442910448967918615, 9932, 60586922367620731354092885749685043727393054330159083751520216651782316342842); _liquidationERC721PoolHandler.transferLps(4846920300852404488893299713430, 1010852265552264464, 14205428207821613918369767845326207321907546584446368443040789737204775621288, 46703193022488893432537917, 1007995947975429839); - _liquidationERC721PoolHandler.kickWithDeposit(929761818956829310540095, 443664109553693451404905562764133947055696194307766936097083521, 1); + _liquidationERC721PoolHandler.lenderKickAuction(929761818956829310540095, 443664109553693451404905562764133947055696194307766936097083521, 1); _liquidationERC721PoolHandler.removeCollateral(6311986398556722439055, 275398883033435592, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _liquidationERC721PoolHandler.kickWithDeposit(11435515741491807582, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14432); + _liquidationERC721PoolHandler.lenderKickAuction(11435515741491807582, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 14432); _liquidationERC721PoolHandler.repayDebt(1027, 1008912661361014875, 13224); _liquidationERC721PoolHandler.mergeCollateral(805305, 8127200515022134005149926609156100); _liquidationERC721PoolHandler.moveQuoteToken(1631521105165549537949, 232, 0, 128606664821950649350713, 242); @@ -1532,9 +1532,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1840696318, 102312901600206290880360615947324549881113719182773013349784047141667145726); _liquidationERC721PoolHandler.moveQuoteToken(3, 0, 46113304395105894089110143856952326502430862928759922087243424851487, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.withdrawBonds(13941, 110349606679412691172957834289542550319383271247755660854362242977991410021375, 30463873253431034776515342835293484334263321734472479990455382576262218042543); - _liquidationERC721PoolHandler.kickWithDeposit(49074042615676915551958149, 1468, 1007661362084909794); - _liquidationERC721PoolHandler.kickWithDeposit(1811, 4066, 108318443171002616228104398874619056615117313976461947562227768695549714877254); - _liquidationERC721PoolHandler.kickWithDeposit(1069, 13439, 20862791592217206631760600618160127950195753045737699209602687643923944467016); + _liquidationERC721PoolHandler.lenderKickAuction(49074042615676915551958149, 1468, 1007661362084909794); + _liquidationERC721PoolHandler.lenderKickAuction(1811, 4066, 108318443171002616228104398874619056615117313976461947562227768695549714877254); + _liquidationERC721PoolHandler.lenderKickAuction(1069, 13439, 20862791592217206631760600618160127950195753045737699209602687643923944467016); _liquidationERC721PoolHandler.addCollateral(1, 1300169104369671206067267908015106943211100708245287342805334865131025166, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.removeQuoteToken(0, 28789883343432221516648160, 4974021750582169791155661954188529352131864855347552795737706, 1625895491409739616551); _liquidationERC721PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 64305946219419228989022186501722238439370517030024195895476202983674999190, 1); @@ -1603,7 +1603,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.withdrawBonds(2, 52, 724387624658214309608251485961735439829653428194716170); _liquidationERC721PoolHandler.drawDebt(0, 3858447779762080653816365896079345016041622432254426317183930819833, 149); _liquidationERC721PoolHandler.bucketTake(53338690798596230725348246, 36128973989335300935693608708275125207782580628723764850443810872656511067035, false, 105143166600035659332100729, 9028868735235007752207762291531958134037876655441065118461092885234818515216); - _liquidationERC721PoolHandler.kickWithDeposit(39930100953879792539593688863973383275333610122673307672344661503807581837650, 11607, 62192763172083093979225128161737601021732751528553725513069671410129050216903); + _liquidationERC721PoolHandler.lenderKickAuction(39930100953879792539593688863973383275333610122673307672344661503807581837650, 11607, 62192763172083093979225128161737601021732751528553725513069671410129050216903); _liquidationERC721PoolHandler.moveQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 1088485852, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC721PoolHandler.removeCollateral(1000942982521085505, 2556844871796884110114088674353771150081258696833713082771707413985807095183, 83758998523500311315278142524802672453545534911746182170876662449750940954764, 10143); _liquidationERC721PoolHandler.withdrawBonds(3, 8099201282925391169299173541218079856803945731942657926804, 115792089237316195423570985008687907853269984665640564039457584007913129639933); @@ -1623,14 +1623,14 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.drawDebt(3552075814921319194, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _liquidationERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639934, 164864555048179990311970604734448197, 15420592838661726962082605, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.settleAuction(929016762125416, 20845168657858206178238546904, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); - _liquidationERC721PoolHandler.kickWithDeposit(3272938804282660973234057223977964015724684957938897047851197371, 7842256739816746735458513198632145, 77001858116697620655815838640622429409348153165823774097207586575709); + _liquidationERC721PoolHandler.lenderKickAuction(3272938804282660973234057223977964015724684957938897047851197371, 7842256739816746735458513198632145, 77001858116697620655815838640622429409348153165823774097207586575709); _liquidationERC721PoolHandler.removeQuoteToken(17049140588647704682779728141221654120232565469773188747816293913628437447862, 3494179161174218391884967215088, 88, 693797957386013129147009190); _liquidationERC721PoolHandler.pledgeCollateral(3862959377535358657059390, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.kickAuction(1482983055714318893230009562469454706561179266, 1181674545297622455574678822368075, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5680893814); _liquidationERC721PoolHandler.withdrawBonds(27871036043547613289037948447264456077258330226313561240112694887716707509764, 45251464397734712283721560876609641629228966779126597206822675987627239632669, 6535); _liquidationERC721PoolHandler.mergeCollateral(1000303584718335188, 701304960790646159430301212331024251206205026213789307317829821435004627); _liquidationERC721PoolHandler.moveQuoteToken(1991, 39315386250298687722012312849799166165024762804902841571644826106239197769092, 1000976457351982855, 41740568139652812265713570158854588029242418548921997608771244687820831484709, 1000749514706140419); - _liquidationERC721PoolHandler.kickWithDeposit(11590, 1000594832446657912, 108619783081057594119823178391603371593291574816044833327231515917599557510311); + _liquidationERC721PoolHandler.lenderKickAuction(11590, 1000594832446657912, 108619783081057594119823178391603371593291574816044833327231515917599557510311); _liquidationERC721PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3131383840361801052, 38156551050827); _liquidationERC721PoolHandler.kickAuction(9339407672176553502475955360754402621447223885472419359186845062999655633872, 1000000171232891372, 42023569335758151611923679009928412781978635216285001913354316696562919603983, 486259868442788130341682685); _liquidationERC721PoolHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4838667295947331327808852126178022161298989, 313866516706, 234336607984965590078750310808627624045385952338027408852495204694832661); @@ -1661,9 +1661,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.bucketTake(220698198824874, 22912336831387277920118340306103530652873736914853967235916390447481802484, false, 2087509, 120657398064822419654681659945); _liquidationERC721PoolHandler.bucketTake(11882162897381061915914368118927279, 2369464245, true, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 891423204979062300914856830623932291719346879124506015303170); _liquidationERC721PoolHandler.moveQuoteToken(4870, 75139167725859269052588878783608654723767566346442396602765121063516320276470, 75745732999416079946172157226330835535039545217897544881256358721177802752282, 12154, 13189); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 82024813097633140486145849608933639793889539544958167); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 82024813097633140486145849608933639793889539544958167); _liquidationERC721PoolHandler.kickAuction(13040, 46979238150872800799677652319383860715234582820074203552677064985602401692866, 76876699529364196847806544444508040664462721441447668877111153141084241089631, 88827291404079698668721230880260160559290269665158672048614475775631968917528); - _liquidationERC721PoolHandler.kickWithDeposit(22515282003491352267766796555879540130444098522562176146641059522444209406510, 110349606679412691172957834289542550319383271247755660854362242977991410022738, 12875); + _liquidationERC721PoolHandler.lenderKickAuction(22515282003491352267766796555879540130444098522562176146641059522444209406510, 110349606679412691172957834289542550319383271247755660854362242977991410022738, 12875); _liquidationERC721PoolHandler.drawDebt(17049140588647704682779728141221654120232565469773188747816293913628437448260, 12152906238448552859162820908699006070246911942373333871442047880174647862641, 128914047382956099930069731); _liquidationERC721PoolHandler.drawDebt(70818418263444074802805077456993826488653329112634690485258715786118067870591, 999999999999999999999999999994685213120433153, 97359066871955009383519005718429085730671047821017916040850359963420740167195); _liquidationERC721PoolHandler.mergeCollateral(702260409025065980488427136869638125039443959440914587963609598558523387, 13121); @@ -1689,10 +1689,10 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.repayDebt(1053500510982562855, 15449313866170848067809345, 28886699956745812721018619); _liquidationERC721PoolHandler.pullCollateral(11607, 82337020098216480598936885108271102760982967827978209270083192726780427189003, 108934572480757764126831522880230246649905370467789769919197856937856352397464); _liquidationERC721PoolHandler.kickAuction(1589698656450841943972190062114692603548395637107441146632349543218634, 1846761758019327443658768653746925776215839331615895, 2441485959612141241971328824318, 1151017430788110759664333421592762525624606499834512056551759404164206402); - _liquidationERC721PoolHandler.kickWithDeposit(3, 3, 39080649500123704176852982839260749850168212118872468290534777943457335750629); + _liquidationERC721PoolHandler.lenderKickAuction(3, 3, 39080649500123704176852982839260749850168212118872468290534777943457335750629); _liquidationERC721PoolHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 9050855355037177236409447425769679247384941625043365893296519253085222747, 2, 661731986682810277669866764989769119278791029359089847029); _liquidationERC721PoolHandler.bucketTake(17396, 22868, false, 110349606679412691172957834289542550319383271247755660854362242977991410022741, 1013966522844326608); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.drawDebt(115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 10145887837140397115308588262409803182801586947198); _liquidationERC721PoolHandler.repayDebt(3, 0, 3466145420673306); _liquidationERC721PoolHandler.withdrawBonds(88976846131701973203464847889240634953744059683515071426517197989999902287287, 81711260915330388557713443409365790730322413897464281875806144685918588147870, 12627); @@ -1726,9 +1726,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639932, 247759, 8149083335054920124, 3); _liquidationERC721PoolHandler.transferLps(1010727915902755028, 46709127050683844462971973, 58996967478444929459096314502986330757151975535848024561708514705427261350565, 1613, 3924); _liquidationERC721PoolHandler.bucketTake(45097996286159061000777982656200126192362835154770412753890452098137252216294, 4901256940930011353728267, false, 20644833354292720259901919217291400962019423843079428609785861849859766008759, 1242); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 726831511452094871132536235534677298700294881401542959633799040215247, 105185431052497444548); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 726831511452094871132536235534677298700294881401542959633799040215247, 105185431052497444548); _liquidationERC721PoolHandler.repayDebt(2083429395054835353025108880276707867688264905432612969222256279842300, 1, 1); - _liquidationERC721PoolHandler.kickWithDeposit(354220292, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC721PoolHandler.lenderKickAuction(354220292, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _liquidationERC721PoolHandler.settleAuction(86112566729419227477071178644138637354057110534321357651744229818629511674760, 17049140588647704682779728141221654120232565469773188747816293913628437448866, 5981, 28888352188525039460552474); _liquidationERC721PoolHandler.addCollateral(2, 446073356368431317153228593588947194502494349120678116636996067, 2, 32284963417825787413521396587679113940555099195991559040289881); _liquidationERC721PoolHandler.addQuoteToken(28709839346827896499122244886561383646499418165788351559176733379002249023187, 7989, 25349388164294716870427081099832502884063096710969845333511673768933393245448, 3474); @@ -1765,7 +1765,7 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.removeQuoteToken(8394, 78188974470091329107016171351111071676479036950455695646225660077594219135253, 96954927241560491011074081894738304157772754973830579620496704770531265577378, 1002245079619685801); _liquidationERC721PoolHandler.repayDebt(0, 84971388368541071, 2); _liquidationERC721PoolHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 18840967029851926228253170878); - _liquidationERC721PoolHandler.kickWithDeposit(106359770259408433381029324728461236255034435109123120442764489653700211640789, 5724, 1107089454340020068); + _liquidationERC721PoolHandler.lenderKickAuction(106359770259408433381029324728461236255034435109123120442764489653700211640789, 5724, 1107089454340020068); _liquidationERC721PoolHandler.takeAuction(0, 31657, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); _liquidationERC721PoolHandler.repayDebt(15744, 876898945649343067601783, 32644); _liquidationERC721PoolHandler.removeCollateral(7991104529544995195934644930838046025028624408206, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 10265830497254481887870763746502746886004067632292036342619859997972140); @@ -1790,6 +1790,6 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants _liquidationERC721PoolHandler.repayDebt(1000172216496567793, 31621, 22702); _liquidationERC721PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 8427499, 48301780641613791628015445563826447871620428181731854); _liquidationERC721PoolHandler.withdrawBonds(6162407927856572007525601797448903049478809668711157, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 107488441665597113470438432006472595205433191723889867333936566853); - _liquidationERC721PoolHandler.kickWithDeposit(115792089237316195423570985008687907853269984665640564039457584007913129639934, 101660650320013120840863364686996498168471542781622903660015386008, 26551745986563838800685120771903690269972431445); + _liquidationERC721PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 101660650320013120840863364686996498168471542781622903660015386008, 26551745986563838800685120771903690269972431445); } } \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol index 523753786..d77ecafd4 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol @@ -77,7 +77,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { function test_regression_evm_revert_2() public { _rewardsHandler.redeemPositions(535, 10526, 16402, 90638196); _rewardsHandler.moveQuoteToken(3, 3, 3665933105380066469, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 35609320936341689682324970775); - _rewardsHandler.kickWithDeposit(65195123838887638071598468995195715179071041842210505440218069543269527898574, 1428, 1550); + _rewardsHandler.lenderKickAuction(65195123838887638071598468995195715179071041842210505440218069543269527898574, 1428, 1550); _rewardsHandler.updateExchangeRate(3324, 3433, 385); _rewardsHandler.removeQuoteToken(487993211956248337274085963929265840000354071708865988088685578811819, 8714694397591072960002001972219030782403253520, 0, 0); _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 3, 0); @@ -132,8 +132,8 @@ contract RegressionTestRewardsManager is RewardsInvariants { function test_regression_moveliquidity_below_lup() external { _rewardsHandler.unstake(4735, 7947, 99648028073174186569406251043082614463523861559444314198794141049070931765266, 165); _rewardsHandler.memorializePositions(1017586779835017595, 2000093450358386131913319801132, 999999999999999994705800289221, 5936); - _rewardsHandler.kickWithDeposit(0, 552702177486359210209998874773373639789414577510403177176780671, 1); - _rewardsHandler.kickWithDeposit(5408465446957, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1244705446892222810789723108370662428040158); + _rewardsHandler.lenderKickAuction(0, 552702177486359210209998874773373639789414577510403177176780671, 1); + _rewardsHandler.lenderKickAuction(5408465446957, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1244705446892222810789723108370662428040158); _rewardsHandler.pledgeCollateral(17006067685850655253277243263894458277559455, 365821919836536381007791134, 3); _rewardsHandler.transferLps(1020398235799939978, 8615, 10094997325303278, 6365, 16905); _rewardsHandler.moveQuoteToken(31568984050285372419235475362633334556373463, 2459831956710974374263868230506844670431779539018807045, 5569725293573705060280053370462598629680698918, 3, 0); @@ -152,7 +152,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.withdrawBonds(408448193972491682247856759691, 6725156476034981825430803209361659548467896941475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _rewardsHandler.burn(207659258550486295439876272535780992392904995291122705229127151, 747338929, 1252191612369811194685436, 1); _rewardsHandler.settleAuction(40898023934445005959403090083409155881516500501072076223, 14829255767842040071, 22556694249976650341045163634875596221258685026085348004092232963852919995373, 0); - _rewardsHandler.kickWithDeposit(3, 1763503097380079097391449321238134748267573906097584829633224009446989852620, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _rewardsHandler.lenderKickAuction(3, 1763503097380079097391449321238134748267573906097584829633224009446989852620, 115792089237316195423570985008687907853269984665640564039457584007913129639933); _rewardsHandler.failed(); _rewardsHandler.pledgeCollateral(992967362603883335031186827777494890596884348, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); _rewardsHandler.moveLiquidity(1439924512892792038061585821476, 12312838412972807476774254, 1386973529615993967509458441, 3153442172782088538684911, 25874047955237976217666127598767369999822558723350386077928985570803529547776); @@ -177,7 +177,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.unstake(1008040767152967082, 2705590298374864519261, 2711436202524373179865882211354132, 1058992097359326876866506180); _rewardsHandler.drawDebt(0, 2, 2); _rewardsHandler.settleAuction(3, 109119248607504264825921197422518323470603, 2736316384792465597, 12368015967168137); - _rewardsHandler.kickWithDeposit(1, 34593728349238363, 2); + _rewardsHandler.lenderKickAuction(1, 34593728349238363, 2); _rewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); _rewardsHandler.takeReserves(37288205583577963230409441522973702491285105267336919446, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); _rewardsHandler.redeemPositions(46789, 6151865526048672236676594, 9043006728606892937350259542, 93268112651994959075836677); @@ -234,7 +234,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.drawDebt(7803620494871325091384326, 1000000000005890305, 808187899175442127626759093647); _rewardsHandler.stake(1881897373701350, 1, 384457493842895898324057, 2); _rewardsHandler.kickAuction(1801888015, 36313972, 14589, 68230236911552087964619588008895983939113692817643498711581573912769382961420); - _rewardsHandler.kickWithDeposit(3409291658389088656420401948375478879628336006312790484, 256489454668391, 264957533719095533849934255388); + _rewardsHandler.lenderKickAuction(3409291658389088656420401948375478879628336006312790484, 256489454668391, 264957533719095533849934255388); } @@ -305,7 +305,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { // fixed by adding a greater than with diff check function test_regression_rounding_on_moveliquidity() external { _rewardsHandler.bucketTake(29456557203126366201854827466482433206831494327361303, 19307664601998129837361, false, 3492651658979151995106448, 0); - _rewardsHandler.kickWithDeposit(4429580015302257459201655018526, 2770867242698718418626, 9388); + _rewardsHandler.lenderKickAuction(4429580015302257459201655018526, 2770867242698718418626, 9388); _rewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); _rewardsHandler.moveLiquidity(41132919728951221583605488, 1102564553356549573347, 3410238307441803358653636, 52534, 4545656474572434187813557497); } @@ -348,7 +348,7 @@ contract RegressionTestRewardsManager is RewardsInvariants { _rewardsHandler.bucketTake(4645898402004950106563597036, 1, true, 3, 2); _rewardsHandler.kickReserveAuction(3, 144); _rewardsHandler.claimRewards(44705418907931161819765043998797583827, 151688058596538037321153972615358552, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5828173); - _rewardsHandler.kickWithDeposit(1, 0, 58846077910505664190879804); + _rewardsHandler.lenderKickAuction(1, 0, 58846077910505664190879804); _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); _rewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); _rewardsHandler.moveLiquidity(7886, 1223, 249959471556478, 8036, 957); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol index fbc57ae54..9b44ebb24 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol @@ -355,7 +355,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { vm.stopPrank(); } - function testLoadERC20PoolGasKickWithDepositAndSettleHighestTP() public { + function testLoadERC20PoolGasLenderKickAuctionAndSettleHighestTP() public { address kicker = makeAddr("kicker"); _mintQuoteAndApproveTokens(kicker, type(uint256).max); // mint enough to cover bonds @@ -364,7 +364,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { _pool.addQuoteToken(500_000_000_000_000 * 1e18, 3_000, block.timestamp + 2 minutes); vm.warp(100_000 days); - _pool.kickWithDeposit(3_000, MAX_FENWICK_INDEX); // worst case scenario, pool interest accrues + _pool.lenderKick(3_000, MAX_FENWICK_INDEX); // worst case scenario, pool interest accrues skip(80 hours); @@ -372,7 +372,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { // kick remaining loans with deposit to get average gas cost for (uint256 i; i < LOANS_COUNT - 1; i ++) { - _pool.kickWithDeposit(3_000, MAX_FENWICK_INDEX); + _pool.lenderKick(3_000, MAX_FENWICK_INDEX); } vm.stopPrank(); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKickWithDeposit.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol similarity index 85% rename from tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKickWithDeposit.t.sol rename to tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol index 16f0a8f75..d8c7b1d14 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKickWithDeposit.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol @@ -5,7 +5,7 @@ import { ERC20HelperContract } from './ERC20DSTestPlus.sol'; import 'src/libraries/helpers/PoolHelper.sol'; -contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { +contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { address internal _borrower1; address internal _borrower2; @@ -151,7 +151,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { }); } - function testKickWithDepositAmountHigherThanAuctionBond() external tearDown { + function testLenderKickAuctionAmountHigherThanAuctionBond() external tearDown { /** - kick with deposit amount lower than deposit available (lender can redeem less LP from bucket than deposit) @@ -168,21 +168,18 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { }); // should revert if NP goes below limit - _assertKickWithDepositNpUnderLimitRevert({ + _assertLenderKickAuctionNpUnderLimitRevert({ from: _lender1, index: 2500 }); - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 3_844.432207828138682757 * 1e18 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower1, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); /******************************/ @@ -193,7 +190,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { PoolParams({ htp: 20.019230769230769240 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 104_994.230769230769228000 * 1e18, + poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, encumberedCollateral: 26.101746319376146305 * 1e18, poolDebt: 100_346.394230769230815500 * 1e18, @@ -208,8 +205,8 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - assertEq(_quote.balanceOf(address(_pool)), 11_000 * 1e18); - assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 17_005.769230769230772000 * 1e18); + assertEq(_quote.balanceOf(_lender1), 42_994.230769230769228000 * 1e18); assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -221,7 +218,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 43_994.230769230769228 * 1e18, // reduced by amount used to cover auction bond + lpBalance: 50_000 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -233,9 +230,9 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 53_994.230769230769228 * 1e18, // reduced by amount used to cover auction bond + lpBalance: 60_000 * 1e18, collateral: 0, - deposit: 53_994.230769230769228000 * 1e18, // reduced by amount used to cover auction bond + deposit: 60_000 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender1 as a kicker @@ -264,7 +261,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { } - function testKickWithDepositAmountLowerThanAuctionBond() external tearDown { + function testLenderKickAuctionAmountLowerThanAuctionBond() external tearDown { /** - kick with deposit amount lower than deposit available (lender can redeem less LP from bucket than deposit) - bond auction is not covered entirely by removed deposit (bucket still contains LP), difference to cover bond is sent by lender @@ -301,21 +298,18 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { // should revert if NP goes below limit - _assertKickWithDepositNpUnderLimitRevert({ + _assertLenderKickAuctionNpUnderLimitRevert({ from: _lender3, index: 2500 }); - _kickWithDeposit({ - from: _lender3, - index: 2500, - borrower: _borrower1, - debt: 29_390.733173076923090475 * 1e18, - collateral: 1_000 * 1e18, - bond: 8_708.365384615384619400 * 1e18, - removedFromDeposit: 3_863.654368867279344664 * 1e18, - transferAmount: 4_844.711015748105274736 * 1e18, - lup: 99836282890 + _lenderKick({ + from: _lender3, + index: 2500, + borrower: _borrower1, + debt: 29_390.733173076923090475 * 1e18, + collateral: 1_000 * 1e18, + bond: 8_708.365384615384619400 * 1e18 }); /******************************/ @@ -325,10 +319,10 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertPool( PoolParams({ htp: 20.019230769230769240 * 1e18, - lup: 99836282890, - poolSize: 107_136.345631132720655336 * 1e18, + lup: 3_844.432207828138682757 * 1e18, + poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 1096471674237.029479718793645083 * 1e18, + encumberedCollateral: 28.474336477334401997 * 1e18, poolDebt: 109_467.656250000000050475 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -341,10 +335,10 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 6_844.711015748105274736 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 10_708.365384615384619400 * 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), 145_155.288984251894725264 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender3), 141_291.634615384615380600 * 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); @@ -361,15 +355,15 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender3, index: 2500, - lpBalance: 0, + lpBalance: 3_863.654368867279344664 * 1e18, depositTime: _startTime }); // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 60_000 * 1e18, + lpBalance: 63_863.654368867279344664 * 1e18, collateral: 1 * 1e18, - deposit: 56_136.345631132720655336 * 1e18, + deposit: 60_000 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender3 as a kicker @@ -397,7 +391,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); } - function testKickWithDepositUsingAllLpsWithinBucket() external tearDown { + function testLenderKickAuctionUsingAllLpsWithinBucket() external tearDown { /** - kick using entire deposit / LP from bucket - bond auction is not covered entirely by deposit, deposit is obliterated and difference to cover bond is sent by lender @@ -434,22 +428,19 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(_quote.balanceOf(_borrower5), 20_000 * 1e18); // should revert if NP goes below limit - _assertKickWithDepositNpUnderLimitRevert({ + _assertLenderKickAuctionNpUnderLimitRevert({ from: _lender2, index: 2500 }); - // lender 2 kicks using all LP from bucket 2499 (10_000) and sending additional quote tokens to cover auction bond (510.096153846153851000) - _kickWithDeposit({ - from: _lender2, - index: 2499, - borrower: _borrower1, - debt: 35_471.574519230769247125 * 1e18, - collateral: 1_000 * 1e18, - bond: 10_510.096153846153851000 * 1e18, - removedFromDeposit: 10_000 * 1e18, - transferAmount: 510.096153846153851000 * 1e18, - lup: 99836282890 + // lender 2 kicks using bucket 2499 + _lenderKick({ + from: _lender2, + index: 2499, + borrower: _borrower1, + debt: 35_471.574519230769247125 * 1e18, + collateral: 1_000 * 1e18, + bond: 10_510.096153846153851000 * 1e18 }); /******************************/ @@ -459,10 +450,10 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertPool( PoolParams({ htp: 20.019230769230769240 * 1e18, - lup: 99836282890, - poolSize: 111_000 * 1e18, + lup: 3_844.432207828138682757 * 1e18, + poolSize: 121_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 1157379804729.565349777467060503 * 1e18, + encumberedCollateral: 30.056063249306572459 * 1e18, poolDebt: 115_548.497596153846207125 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -475,9 +466,9 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 6_510.096153846153851000 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 16_510.096153846153851000 * 1e18); // increased with the amount sent to cover bond assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); - assertEq(_quote.balanceOf(_lender2), 129_489.903846153846149000 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender2), 119_489.903846153846149000 * 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); @@ -489,15 +480,15 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender2, index: 2499, - lpBalance: 0, + lpBalance: 10_000 * 1e18, depositTime: _startTime }); // assert bucket - LP and deposit obliterated _assertBucket({ index: 2499, - lpBalance: 0, + lpBalance: 10_000 * 1e18, collateral: 0, - deposit: 0, + deposit: 10_000 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender2 as a kicker @@ -525,7 +516,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); } - function testKickWithDepositAmountHigherThanAvailableDeposit() external tearDown { + function testLenderKickAuctionAmountHigherThanAvailableDeposit() external tearDown { /** - kick with deposit amount higher than deposit available (lender can redeem more LP from bucket than deposit) @@ -556,21 +547,18 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { }); // should revert if NP goes below limit - _assertKickWithDepositNpUnderLimitRevert({ + _assertLenderKickAuctionNpUnderLimitRevert({ from: _lender1, index: 2500 }); - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 3_844.432207828138682757 * 1e18 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower1, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); /******************************/ @@ -581,7 +569,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { PoolParams({ htp: 20.019230769230769240 * 1e18, lup: 3_844.432207828138682757 * 1e18, - poolSize: 104_994.230769230769228000 * 1e18, + poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, encumberedCollateral: 26.101746319376146305 * 1e18, poolDebt: 100_346.394230769230815500 * 1e18, @@ -596,8 +584,8 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - assertEq(_quote.balanceOf(address(_pool)), 11_000 * 1e18); - assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 17_005.769230769230772000 * 1e18); // increased by amount used to cover auction bond + assertEq(_quote.balanceOf(_lender1), 42_994.230769230769228000 * 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); @@ -609,7 +597,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 82_630.77445790356267464 * 1e18, // reduced by amount used to cover auction bond + lpBalance: 88_636.543688672793446640 * 1e18, depositTime: _startTime }); _assertLenderLpBalance({ @@ -621,9 +609,9 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { // assert bucket LP _assertBucket({ index: 2500, - lpBalance: 92_630.77445790356267464 * 1e18, // reduced by amount used to cover auction bond + lpBalance: 98_636.543688672793446640 * 1e18, collateral: 10 * 1e18, - deposit: 53_994.230769230769228000 * 1e18, // reduced by amount used to cover auction bond + deposit: 60_000 * 1e18, exchangeRate: 1 * 1e18 }); // assert lender1 as a kicker @@ -652,7 +640,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { } - function testKickWithDepositAllBorrowersAndSettle() external tearDown { + function testLenderKickAuctionAllBorrowersAndSettle() external tearDown { // assert loans positions in heap address borrower; uint256 thresholdPrice; @@ -673,16 +661,13 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(thresholdPrice, 20.019230769230769240 * 1e18); // kick borrower 1 - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 3_844.432207828138682757 * 1e18 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower1, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -712,16 +697,13 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(prev, address(0)); // kick borrower 5 - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower5, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 99836282890 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower5, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -750,16 +732,13 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(prev, _borrower1); // kick borrower 4 - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower4, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 99836282890 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower4, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -792,16 +771,13 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(prev, _borrower5); // kick borrower 3 - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower3, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 99836282890 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower3, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -838,16 +814,13 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { assertEq(prev, _borrower4); // kick borrower 2 - _kickWithDeposit({ - from: _lender1, - index: 2500, - borrower: _borrower2, - debt: 20_269.471153846153855500 * 1e18, - collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18, - removedFromDeposit: 6_005.769230769230772000 * 1e18, - transferAmount: 0, - lup: 99836282890 + _lenderKick({ + from: _lender1, + index: 2500, + borrower: _borrower2, + debt: 20_269.471153846153855500 * 1e18, + collateral: 1_000 * 1e18, + bond: 6_005.769230769230772000 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -891,10 +864,10 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertPool( PoolParams({ htp: 0, - lup: 99836282890, - poolSize: 80_971.153846153846140000 * 1e18, + lup: 3_844.432207828138682757 * 1e18, + poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 1015135508208.931167644556923668 * 1e18, + encumberedCollateral: 26.362112866202841031 * 1e18, poolDebt: 101_347.355769230769277500 * 1e18, actualUtilization: 0, targetUtilization: 1e18, @@ -1180,11 +1153,12 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { ); // add more liquidity to settle auction + _mintQuoteAndApproveTokens(_lender1, 40_000 * 1e18); _addLiquidity({ from: _lender1, amount: 40_000 * 1e18, index: 2500, - lpAward: 39_980.573029659913832943 * 1e18, + lpAward: 39_985.826748556412134387 * 1e18, newLup: 3_863.654368867279344664 * 1e18 }); @@ -1238,8 +1212,8 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 19_721.271266431727390767 * 1e18, - pledgedCollateral: 3_978.965725315792902718 * 1e18, + poolSize: 49_645.701045977641587831 * 1e18, + pledgedCollateral: 4_973.729764048432419297 * 1e18, encumberedCollateral: 0, poolDebt: 0, actualUtilization: 0, @@ -1255,7 +1229,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 59_951.726875813759972943 * 1e18, + lpBalance: 89_985.826748556412134387 * 1e18, depositTime: _startTime + 80 hours }); // assert lender1 as a kicker @@ -1268,7 +1242,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower1, borrowerDebt: 0, - borrowerCollateral: 994.725169378126588635 * 1e18, + borrowerCollateral: 994.750357720674222924 * 1e18, borrowert0Np: 21.020192307692307702 * 1e18, borrowerCollateralization: 1 * 1e18 }); @@ -1289,24 +1263,24 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower4, borrowerDebt: 0, - borrowerCollateral: 994.737731304578575591 * 1e18, + borrowerCollateral: 994.751412316543869246 * 1e18, borrowert0Np: 21.125293269230769068 * 1e18, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower5, borrowerDebt: 0, - borrowerCollateral: 0, + borrowerCollateral: 994.725169378126588635 * 1e18, borrowert0Np: 21.230919735576922742 * 1e18, borrowerCollateralization: 1 * 1e18 }); } - function testKickWithDepositReverts() external tearDown { + function testLenderKickAuctionReverts() external tearDown { // assert lender cannot kick with a bucket without deposit _assertKickWithInsufficientLiquidityRevert({ - from: _lender1, - index: 2_503 + from: _lender3, + index: 2_500 }); // assert lender cannot kick a loan if the proposed LUP doesn't render borrower uncollateralized @@ -1325,7 +1299,7 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { newLup: 3_844.432207828138682757 * 1e18 }); - _assertKickPriceBelowProposedLupRevert({ + _assertKickPriceBelowLupRevert({ from: _lender3, index: 7000 }); @@ -1351,6 +1325,6 @@ contract ERC20PoolLiquidationsKickWithDepositTest is ERC20HelperContract { changePrank(_lender4); vm.expectRevert("ERC20: transfer amount exceeds balance"); - _pool.kickWithDeposit(2499, MAX_FENWICK_INDEX); + _pool.lenderKick(2499, MAX_FENWICK_INDEX); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index 056fa0ade..0ca99665d 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -446,13 +446,13 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { // kick borrower 2 changePrank(_lender); - _pool.kickWithDeposit(_i9_52, MAX_FENWICK_INDEX); + _pool.lenderKick(_i9_52, MAX_FENWICK_INDEX); _assertPool( PoolParams({ htp: 0, lup: 0.000000099836282890 * 1e18, - poolSize: 8_002.290256823112434920 * 1e18, + poolSize: 8_083.134379679494060567 * 1e18, pledgedCollateral: 1_001.742368450520005091 * 1e18, encumberedCollateral: 81_714_595_700.439346767851204401 * 1e18, poolDebt: 8_158.081492591040321202 * 1e18, @@ -512,7 +512,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 0, lup: 0.000000099836282890 * 1e18, - poolSize: 8_002.657492380122502335 * 1e18, + poolSize: 8_083.501615236504132602 * 1e18, pledgedCollateral: 1.742368450520005091 * 1e18, encumberedCollateral: 82_124_923_660.837160770168974387 * 1e18, poolDebt: 8_199.047110922993196875 * 1e18, @@ -550,7 +550,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 470.467834275489987588 * 1e18, + poolSize: 551.311957051027493010 * 1e18, pledgedCollateral: 1.742368450520005091 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -593,10 +593,10 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { }); _assertBucket({ index: _i9_52, - lpBalance: 7_920.016453607292031745 * 1e18, + lpBalance: 8_000.033211272270098596 * 1e18, collateral: 0, - deposit: 470.467834275489987599 * 1e18, - exchangeRate: 0.059402380920712388 * 1e18 + deposit: 551.311957051027493215 * 1e18, + exchangeRate: 0.068913708542386244 * 1e18 }); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol index 4767154f1..093c90a3c 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol @@ -47,7 +47,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { _lender = makeAddr("lender"); _bidder = makeAddr("bidder"); - uint256 lenderDepositDenormalized = 200_000 * _quoteTokenPrecision; + uint256 lenderDepositDenormalized = 300_000 * _quoteTokenPrecision; // give bidder quote token to cover liquidation bond vm.startPrank(_bidder); @@ -175,8 +175,8 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { function testSettleAuctionWithoutTakes( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_, - uint16 startBucketId_) external tearDown - { + uint16 startBucketId_ + ) external tearDown { uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 6, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 6, 18); uint256 startBucketId = bound(uint256(startBucketId_), 1000, 6388); @@ -193,10 +193,10 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { assertLt(_borrowerCollateralization(_borrower), 1e18); // Kick an auction and wait for a meaningful price - assertEq(_quote.balanceOf(_bidder), 200_000 * _quoteTokenPrecision); + assertEq(_quote.balanceOf(_bidder), 300_000 * _quoteTokenPrecision); _kick(_borrower, _bidder); // assert bidder locked balance in auction bond - assertLt(_quote.balanceOf(_bidder), 200_000 * _quoteTokenPrecision); + assertLt(_quote.balanceOf(_bidder), 300_000 * _quoteTokenPrecision); (uint256 auctionPrice, uint256 auctionDebt, uint256 auctionCollateral) = _advanceAuction(9 hours); assertGt(auctionPrice, 0); @@ -227,13 +227,13 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { if ( bondTransferAmount * _pool.quoteTokenScale() < claimableBond ) roundingDiff = 1; // ensure bidders can still withdraw their bonds - assertLt(_quote.balanceOf(_bidder), 200_000 * _quoteTokenPrecision); + assertLt(_quote.balanceOf(_bidder), 300_000 * _quoteTokenPrecision); changePrank(_bidder); _pool.withdrawBonds(_bidder, type(uint256).max); - assertEq(_quote.balanceOf(_bidder), 200_000 * _quoteTokenPrecision - roundingDiff); + assertEq(_quote.balanceOf(_bidder), 300_000 * _quoteTokenPrecision - roundingDiff); } - function testLiquidationKickWithDeposit( + function testLiquidationLenderKickAuction( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_, uint16 startBucketId_ @@ -254,7 +254,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { assertLt(_borrowerCollateralization(_borrower), 1e18); // Kick off an auction and wait the grace period - _kickWithDeposit(_lender, _startBucketId); + _lenderKick(_lender, _startBucketId); skip(1 hours); // Wait until price drops below utilized portion of book @@ -291,22 +291,22 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { _checkAuctionStateUponKick(kicker); } - function _kickWithDeposit(address lender, uint256 bucketId) internal { + function _lenderKick(address lender, uint256 bucketId) internal { (uint256 lastLenderLP, ) = _pool.lenderInfo(bucketId, lender); (, uint256 lastBucketDeposit, , uint256 lastBucketLP, , ) = _poolUtils.bucketInfo(address(_pool), bucketId); changePrank(lender); - _pool.kickWithDeposit(bucketId, MAX_FENWICK_INDEX); + _pool.lenderKick(bucketId, MAX_FENWICK_INDEX); _checkAuctionStateUponKick(lender); - // confirm user has redeemed some of their LP to post liquidation bond + // confirm user doesn't redeemed any of their LP to post liquidation bond (uint256 lenderLP, ) = _pool.lenderInfo(bucketId, lender); - assertLt(lenderLP, lastLenderLP); + assertEq(lenderLP, lastLenderLP); - // confirm deposit has been removed from bucket + // confirm deposit wasn't removed from bucket (, uint256 bucketDeposit, , uint256 bucketLP, , ) = _poolUtils.bucketInfo(address(_pool), bucketId); - assertLt(bucketDeposit, lastBucketDeposit); - assertLt(bucketLP, lastBucketLP); + assertTrue(bucketDeposit >= lastBucketDeposit); + assertEq(bucketLP, lastBucketLP); } function _checkAuctionStateUponKick(address kicker) internal { diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol index 3501b1d18..c9bcd5b5b 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol @@ -120,28 +120,22 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { /*** Kick both loans ***/ /***********************/ - _kickWithDeposit({ - from: _lender, - index: 2500, - borrower: _borrower, - debt: 5_067.367788461538463875 * 1e18, - collateral: 2 * 1e18, - bond: 1_501.442307692307693000 * 1e18, - removedFromDeposit: 1_501.442307692307693000 * 1e18, - transferAmount: 0, - lup: 3_863.654368867279344664 * 1e18 + _lenderKick({ + from: _lender, + index: 2500, + borrower: _borrower, + debt: 5_067.367788461538463875 * 1e18, + collateral: 2 * 1e18, + bond: 1_501.442307692307693000 * 1e18 }); - _kickWithDeposit({ - from: _lender, - index: 2500, - borrower: _borrower2, - debt: 5_067.367788461538463875 * 1e18, - collateral: 3 * 1e18, - bond: 1_501.442307692307693000 * 1e18, - removedFromDeposit: 1_501.442307692307693000 * 1e18, - transferAmount: 0, - lup: 3_863.654368867279344664 * 1e18 + _lenderKick({ + from: _lender, + index: 2500, + borrower: _borrower2, + debt: 5_067.367788461538463875 * 1e18, + collateral: 3 * 1e18, + bond: 1_501.442307692307693000 * 1e18 }); // skip to make loans clearable @@ -150,7 +144,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 3_863.654368867279344664 * 1e18, - poolSize: 12_997.115384615384614000 * 1e18, + poolSize: 16_000 * 1e18, pledgedCollateral: 5 * 1e18, encumberedCollateral: 2.624293841728065377 * 1e18, poolDebt: 10_139.364366784136304617 * 1e18, @@ -178,8 +172,8 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrowerCollateralization: 2.286329337285291739 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 6_000 * 1e18); - assertEq(_quote.balanceOf(_lender), 104_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 9_002.884615384615386000 * 1e18); // increased by bonds size + assertEq(_quote.balanceOf(_lender), 100_997.115384615384614000 * 1e18); // decreased by bonds size assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); } @@ -255,7 +249,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 2_861.685489213148775844 * 1e18, + poolSize: 5_864.570104597764159383 * 1e18, pledgedCollateral: 1 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -307,8 +301,8 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { exchangeRate: 1.000000000005475091 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 6_000 * 1e18); - assertEq(_quote.balanceOf(_lender), 104_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 9_002.884615384615386000 * 1e18); + assertEq(_quote.balanceOf(_lender), 100_997.115384615384614000 * 1e18); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); @@ -371,10 +365,10 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 1_860.819465331537769873 * 1e18, + lpBalance: 4_863.128335182565063307 * 1e18, collateral: 0, - deposit: 1_861.382770397052268844 * 1e18, - exchangeRate: 1.000302718816096508 * 1e18 + deposit: 4_864.324200136395380383 * 1e18, + exchangeRate: 1.000245904461368780 * 1e18 }); } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 5452ceed2..993be7abe 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -89,28 +89,25 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { tokenIds: tokenIdsToAdd }); + // skip time to accumulate interest + skip(5100 days); + // kick both loans - _kickWithDeposit({ - from: _lender, - index: 2500, - borrower: _borrower, - debt: 5_067.367788461538463875 * 1e18, - collateral: 2 * 1e18, - bond: 1_501.442307692307693000 * 1e18, - removedFromDeposit: 1_501.442307692307693000 * 1e18, - transferAmount: 0, - lup: 3_825.305679430983794766 * 1e18 - }); - _kickWithDeposit({ - from: _lender, - index: 2500, - borrower: _borrower2, - debt: 5_067.367788461538463875 * 1e18, - collateral: 3 * 1e18, - bond: 1_501.442307692307693000 * 1e18, - removedFromDeposit: 1_501.442307692307693000 * 1e18, - transferAmount: 0, - lup: 99836282890 + _lenderKick({ + from: _lender, + index: 2500, + borrower: _borrower, + debt: 10_190.456508610307854461 * 1e18, + collateral: 2 * 1e18, + bond: 100.646484035657361526 * 1e18 + }); + _lenderKick({ + from: _lender, + index: 2500, + borrower: _borrower2, + debt: 10_203.037319114765024653 * 1e18, + collateral: 3 * 1e18, + bond: 1_325.327386341314188042 * 1e18 }); } @@ -122,19 +119,18 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // skip to make loans clearable skip(80 hours); - _assertBucket({ - index: 2500, - lpBalance: 4_997.115384615384614 * 1e18, - collateral: 0, - deposit: 4_997.115384615384614 * 1e18, - exchangeRate: 1 * 1e18 - }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_069.682183392068152309 * 1e18, + borrowerDebt: 10_195.576288428866513838 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039385618 * 1e18 + borrowerCollateralization: 0.750385377189985519 * 1e18 + }); + + _addLiquidityNoEventCheck({ + from: _lender, + amount: 5_000 * 1e18, + index: 2499 }); // first settle call settles partial borrower debt @@ -142,24 +138,24 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 4_996.799887883802392935 * 1e18 + settledDebt: 2_485.081590832967738263 * 1e18 }); // collateral in bucket used to settle auction increased with the amount used to settle debt _assertBucket({ - index: 2500, - lpBalance: 4_997.115384615384614 * 1e18, - collateral: 1.293874031008720308 * 1e18, + index: 2499, + lpBalance: 5_000 * 1e18, + collateral: 1.287673250019003865 * 1e18, deposit: 0, - exchangeRate: 1.000393560665305039 * 1e18 + exchangeRate: 1.000000000000000001 * 1e18 }); // partial borrower debt is settled, borrower collateral decreased with the amount used to settle debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 70.600130721308266688 * 1e18, - borrowerCollateral: 0.706125968991279692 * 1e18, + borrowerDebt: 5_195.576288428866513840 * 1e18, + borrowerCollateral: 0.712326749980996135 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000998539114 * 1e18 + borrowerCollateralization: 0.527081453163032823 * 1e18 }); _assertCollateralInvariants(); @@ -181,22 +177,14 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _addLiquidityNoEventCheck({ from: _lender, amount: 20_000 * 1e18, - index: 2500 - }); - - _assertBucket({ - index: 2500, - lpBalance: 24_989.247267890536782149 * 1e18, - collateral: 1.293874031008720308 * 1e18, - deposit: 20_000 * 1e18, - exchangeRate: 1.000393560665305039 * 1e18 + index: 2000 }); _settle({ from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 70.567900577736070940 * 1e18 + settledDebt: 2_582.286197628570725612 * 1e18 }); // no token id left in borrower token ids array @@ -207,11 +195,11 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); _assertBucket({ - index: 2500, - lpBalance: 24_989.247267890536782149 * 1e18, - collateral: 1.312146920864032689 * 1e18, - deposit: 19_929.399869278691733312 * 1e18, - exchangeRate: 1.000393560665305039 * 1e18 + index: 2000, + lpBalance: 20_000 * 1e18, + collateral: 0.111071996695171075 * 1e18, + deposit: 14_804.423711571133486162 * 1e18, + exchangeRate: 1.000000000000000002 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -227,28 +215,35 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 5_067.367788461538463875 * 1e18 + settledDebt: 5_073.623798076923079263 * 1e18 }); _assertBucket({ - index: 2500, - lpBalance: 24_989.247267890536782149 * 1e18, - collateral: 2.624293841728065378 * 1e18, - deposit: 14_859.717685886623581004 * 1e18, - exchangeRate: 1.000393560665305039 * 1e18 + index: 2000, + lpBalance: 20_000 * 1e18, + collateral: 0.329304013831793309 * 1e18, + deposit: 4_596.260291921984421072 * 1e18, + exchangeRate: 1.000000000000000003 * 1e18 + }); + _assertBucket({ + index: 2499, + lpBalance: 5_000 * 1e18, + collateral: 1.287673250019003865 * 1e18, + deposit: 0, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBucket({ index: 7388, - lpBalance: 0.000000137345389190 * 1e18, - collateral: 1.375706158271934622 * 1e18, + lpBalance: 0.000000138075849129 * 1e18, + collateral: 1.383022736149202826 * 1e18, deposit: 0, - exchangeRate: 1.000000000005475091 * 1e18 + exchangeRate: 1.000000000003575156 * 1e18 }); - // borrower 2 can claim 1 NFT token (id 51) after settle + // borrower 2 can claim 2 NFT tokens (id 51 and 53) after settle _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 1 * 1e18, + borrowerCollateral: 2 * 1e18, borrowert0Np: 1_769.243311298076895206 * 1e18, borrowerCollateralization: 1 * 1e18 }); @@ -256,29 +251,28 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertCollateralInvariants(); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower2, 0), 51); + assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower2, 1), 53); // tokens used to 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)).bucketTokenIds(2), 73); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(3), 53); - // lender can claim 2 NFTs from bucket 2500 + // lender can claim 1 NFTs from bucket 2499 changePrank(_lender); - _pool.removeCollateral(2, 2500); + _pool.removeCollateral(1, 2499); - // lender adds liquidity in min bucket and merge / removes the other 2 NFTs - _addLiquidity({ + // lender adds liquidity in min bucket and merge / removes the other NFTs + _addLiquidityNoEventCheck({ from: _lender, amount: 100 * 1e18, - index: MAX_FENWICK_INDEX, - lpAward: 99.999999999452490925 * 1e18, - newLup: MAX_PRICE + index: MAX_FENWICK_INDEX }); - uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2500; - removalIndexes[1] = MAX_FENWICK_INDEX; + uint256[] memory removalIndexes = new uint256[](3); + removalIndexes[0] = 2000; + removalIndexes[1] = 2499; + removalIndexes[2] = MAX_FENWICK_INDEX; _mergeOrRemoveCollateral({ from: _lender, toIndex: MAX_FENWICK_INDEX, @@ -288,42 +282,49 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { toIndexLps: 0 }); - // the 4 NFTs claimed from pool are owned by lender + // the 3 NFTs claimed from pool are owned by lender assertEq(_collateral.ownerOf(1), _lender); assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(53), _lender); assertEq(_collateral.ownerOf(73), _lender); assertEq(_collateral.ownerOf(51), address(_pool)); + assertEq(_collateral.ownerOf(53), address(_pool)); - // borrower 2 can pull 1 NFT from pool + // borrower 2 can pull 2 NFTs from pool _repayDebtNoLupCheck({ from: _borrower2, borrower: _borrower2, amountToRepay: 0, amountRepaid: 0, - collateralToPull: 1 + collateralToPull: 2 }); assertEq(_collateral.ownerOf(1), _lender); assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(53), _lender); assertEq(_collateral.ownerOf(73), _lender); - // the NFT pulled from pool is owned by lender + // the NFTs pulled from pool are owned by borrower assertEq(_collateral.ownerOf(51), _borrower2); + assertEq(_collateral.ownerOf(53), _borrower2); _assertBucket({ - index: 2500, - lpBalance: 14_853.871786224081495216 * 1e18, + index: 2000, + lpBalance: 4_596.260291921984408543 * 1e18, + collateral: 0, + deposit: 4_596.260291921984421072 * 1e18, + exchangeRate: 1.000000000000000003 * 1e18 + }); + _assertBucket({ + index: 2499, + lpBalance: 0, collateral: 0, - deposit: 14_859.717685886623581004 * 1e18, - exchangeRate: 1.000393560665305039 * 1e18 + deposit: 0, + exchangeRate: 1 * 1e18 }); _assertBucket({ index: MAX_FENWICK_INDEX, - lpBalance: 99.999999999452490925 * 1e18, + lpBalance: 99.999999999642484483 * 1e18, collateral: 0, deposit: 100 * 1e18, - exchangeRate: 1.000000000005475091 * 1e18 + exchangeRate: 1.000000000003575156 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -350,41 +351,46 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); _assertBucket({ - index: 2500, - lpBalance: 4997.115384615384614 * 1e18, + index: 2502, + lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 4_997.115384615384614 * 1e18, - exchangeRate: 1 * 1e18 + deposit: 3_433.621534856445752000 * 1e18, + exchangeRate: 1.716810767428222876 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(32 hours); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 3_000 * 1e18, + index: 2502 + }); _depositTake({ from: _lender, borrower: _borrower, - index: 2500 + index: 2502 }); _assertBucket({ - index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 425.172014916344732952 * 1e18, - borrowerCollateral: 0.152044867770467010 * 1e18, + borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000035702243 * 1e18 + borrowerCollateralization: 0.258770970502146036 * 1e18 }); _assertCollateralInvariants(); @@ -403,30 +409,23 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _settle({ from: _lender, borrower: _borrower, - maxDepth: 1, - settledDebt: 425.094365018849626168 * 1e18 + maxDepth: 2, + settledDebt: 2_223.210773740853089765 * 1e18 }); _assertBucket({ index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, - deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 - }); - _assertBucket({ - index: 2501, - lpBalance: 2_000 * 1e18, - collateral: 0.110639687749865566 * 1e18, - deposit: 1_575.596009456533555165 * 1e18, - exchangeRate: 1.000471394253082552 * 1e18 + lpBalance: 8_000 * 1e18, + collateral: 0.300997199476505990 * 1e18, + deposit: 11_773.847757000624330192 * 1e18, + exchangeRate: 1.617099612721855334 * 1e18 }); _assertBucket({ - index: MAX_FENWICK_INDEX, - lpBalance: 4133739266, - collateral: 0.041405180020601444 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 0.999999999914881374 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -436,29 +435,19 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerCollateralization: 1 * 1e18 }); - _assertCollateralInvariants(); + // _assertCollateralInvariants(); // tokens used to settle auction are moved to pool claimable array assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); - // lender adds liquidity in min bucket and merge / removes the other 2 NFTs - _addLiquidityWithPenalty({ - from: _lender, - amount: 100 * 1e18, - amountAdded: 99.986438356164383600 * 1e18, - index: MAX_FENWICK_INDEX, - lpAward: 99.986438364675091908 * 1e18, - newLup: 3_806.274307891526195092 * 1e18 - }); - - uint256[] memory removalIndexes = new uint256[](3); + // lender merge / removes the other 2 NFTs + uint256[] memory removalIndexes = new uint256[](2); removalIndexes[0] = 2500; - removalIndexes[1] = 2501; - removalIndexes[2] = MAX_FENWICK_INDEX; + removalIndexes[1] = 2502; _mergeOrRemoveCollateral({ from: _lender, - toIndex: MAX_FENWICK_INDEX, + toIndex: 2502, noOfNFTsToRemove: 2, collateralMerged: 2 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -474,40 +463,38 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { function testDepositTakeAndSettleByPledgeSubsetPool() external tearDown { - // the 2 token ids are owned by borrower before settle + // the 2 token ids are owned by borrower before bucket take assertEq(ERC721Pool(address(_pool)).totalBorrowerTokens(_borrower), 2); assertEq(ERC721Pool(address(_pool)).totalBucketTokens(), 0); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); - _assertBucket({ - index: 2500, - lpBalance: 4_997.115384615384614000 * 1e18, - collateral: 0, - deposit: 4_997.115384615384614000 * 1e18, - exchangeRate: 1 * 1e18 - }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(32 hours); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 3_000 * 1e18, + index: 2502 + }); _depositTake({ from: _lender, borrower: _borrower, kicker: _lender, - index: 2500, - collateralArbed: 1.847955132229532990 * 1e18, - quoteTokenAmount: 7_139.859920109346031462 * 1e18, - bondChange: 2_141.957976032803809439 * 1e18, + index: 2502, + collateralArbed: 1.699002800523494010 * 1e18, + quoteTokenAmount: 6_499.205062211668483663 * 1e18, + bondChange: 64.992050622116684837 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 2_141.620879120879119905 * 1e18 + lpAwardKicker: 37.849749216362450585 * 1e18 }); // after bucket take, token id 3 is moved to pool claimable array (the most recent pledged) @@ -517,18 +504,18 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); _assertBucket({ - index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 425.172014916344732952 * 1e18, - borrowerCollateral: 0.152044867770467010 * 1e18, + borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000035702243 * 1e18 + borrowerCollateralization: 0.258770970502146036 * 1e18 }); _assertCollateralInvariants(); @@ -537,10 +524,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _repayDebt({ from: _borrower2, borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 5_068.293419619520519499 * 1e18, + amountToRepay: 11_000 * 1e18, + amountRepaid: 10_205.087450363250041380 * 1e18, collateralToPull: 3, - newLup: 3_844.432207828138682757 * 1e18 + newLup: 3_863.654368867279344664 * 1e18 }); // borrower exits from auction by pledging more collateral @@ -558,10 +545,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 425.172014916344732952 * 1e18, + borrowerDebt: 4_471.766388200619360129 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 148.074537148232619781 * 1e18, - borrowerCollateralization: 27.126189445355815944 * 1e18 + borrowert0Np: 781.829122098866669900 * 1e18, + borrowerCollateralization: 2.592032342562933134 * 1e18 }); _assertAuction( AuctionParams({ @@ -572,10 +559,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 141.724004972114910984 * 1e18, + thresholdPrice: 1_490.588796066873120043 * 1e18, neutralPrice: 0 }) ); @@ -593,35 +580,32 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 5); _assertBucket({ - index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBucket({ - index: 6113, - lpBalance: 0.000008769784221045 * 1e18, - collateral: 0.152044867770467010 * 1e18, + index: 6051, + lpBalance: 0.000023652411506879 * 1e18, + collateral: 0.300997199476505990 * 1e18, deposit: 0, - exchangeRate: 0.999999999999946239 * 1e18 + exchangeRate: 0.999999999999991497 * 1e18 }); - // lender adds liquidity in bucket 6113 and merge / removes the other 2 NFTs - _addLiquidityWithPenalty({ - from: _lender, - amount: 1_000 * 1e18, - amountAdded: 999.876712328767123000 * 1e18, - index: 6113, - lpAward: 999.876712328820878239 * 1e18, - newLup: 3_844.432207828138682757 * 1e18 + // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs + _addLiquidityNoEventCheck({ + from: _lender, + amount: 1_000 * 1e18, + index: 6051 }); uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2500; - removalIndexes[1] = 6113; + removalIndexes[0] = 2502; + removalIndexes[1] = 6051; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 6113, + toIndex: 6051, noOfNFTsToRemove: 2, collateralMerged: 2 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -632,18 +616,18 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _repayDebt({ from: _borrower, borrower: _borrower, - amountToRepay: 500 * 1e18, - amountRepaid: 425.172014916344732952 * 1e18, + amountToRepay: 5_000 * 1e18, + amountRepaid: 4_471.766388200619360129 * 1e18, collateralToPull: 3, newLup: MAX_PRICE }); // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000008769784221044 * 1e18, - index: 6113, + amount: 0.000023652411506878 * 1e18, + index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000008769784221045 * 1e18 + lpRedeem: 0.000023652411506879 * 1e18 }); // the 3 NFTs pulled from pool are owned by borrower @@ -659,53 +643,51 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { function testDepositTakeAndSettleByRepaySubsetPool() external tearDown { - // the 2 token ids are owned by borrower before settle + // the 2 token ids are owned by borrower before bucket take assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); - _assertBucket({ - index: 2500, - lpBalance: 4997.115384615384614 * 1e18, - collateral: 0, - deposit: 4_997.115384615384614000 * 1e18, - exchangeRate: 1 * 1e18 - }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(32 hours); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 3_000 * 1e18, + index: 2502 + }); _depositTake({ from: _lender, borrower: _borrower, kicker: _lender, - index: 2500, - collateralArbed: 1.847955132229532990 * 1e18, - quoteTokenAmount: 7_139.859920109346031462 * 1e18, - bondChange: 2_141.957976032803809439 * 1e18, + index: 2502, + collateralArbed: 1.699002800523494010 * 1e18, + quoteTokenAmount: 6_499.205062211668483663 * 1e18, + bondChange: 64.992050622116684837 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 2_141.620879120879119905 * 1e18 + lpAwardKicker: 37.849749216362450585 * 1e18 }); _assertBucket({ - index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 425.172014916344732952 * 1e18, - borrowerCollateral: 0.152044867770467010 * 1e18, + borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000035702243 * 1e18 + borrowerCollateralization: 0.258770970502146036 * 1e18 }); _assertCollateralInvariants(); @@ -714,17 +696,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _repayDebt({ from: _borrower2, borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 5_068.293419619520519499 * 1e18, + amountToRepay: 11_000 * 1e18, + amountRepaid: 10_205.087450363250041380 * 1e18, collateralToPull: 3, - newLup: 3_844.432207828138682757 * 1e18 + newLup: 3_863.654368867279344664 * 1e18 }); // borrower exits from auction by repaying the debt _repayDebt({ from: _borrower, borrower: _borrower, - amountToRepay: 500 * 1e18, - amountRepaid: 425.172014916344732952 * 1e18, + amountToRepay: 5_000 * 1e18, + amountRepaid: 4_471.766388200619360129 * 1e18, collateralToPull: 0, newLup: MAX_PRICE }); @@ -745,7 +727,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -760,34 +742,32 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); _assertBucket({ - index: 2500, - lpBalance: 7_138.736263736263733905 * 1e18, - collateral: 1.847955132229532990 * 1e18, + index: 2502, + lpBalance: 3_784.974921636245059251 * 1e18, + collateral: 1.699002800523494010 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775900 * 1e18 }); _assertBucket({ - index: 6113, - lpBalance: 0.000008769784221045 * 1e18, - collateral: 0.152044867770467010 * 1e18, + index: 6051, + lpBalance: 0.000023652411506879 * 1e18, + collateral: 0.300997199476505990 * 1e18, deposit: 0, - exchangeRate: 0.999999999999946239 * 1e18 + exchangeRate: 0.999999999999991497 * 1e18 }); - // lender adds liquidity in bucket 6113 and merge / removes the other 2 NFTs - _addLiquidity({ + // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs + _addLiquidityNoEventCheck({ from: _lender, amount: 1_000 * 1e18, - index: 6113, - lpAward: 1_000.000000000053761867 * 1e18, - newLup: MAX_PRICE + index: 6051 }); uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2500; - removalIndexes[1] = 6113; + removalIndexes[0] = 2502; + removalIndexes[1] = 6051; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 6113, + toIndex: 6051, noOfNFTsToRemove: 2, collateralMerged: 2 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -803,17 +783,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000008769784221044 * 1e18, - index: 6113, + amount: 0.000023652411506878 * 1e18, + index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000008769784221045 * 1e18 + lpRedeem: 0.000023652411506879 * 1e18 }); } function testDepositTakeAndSettleByRegularTakeSubsetPool() external tearDown { - // the 2 token ids are owned by borrower before settle + // the 2 token ids are owned by borrower before bucket take assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); @@ -821,25 +801,22 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_000 * 1e18, - exchangeRate: 1 * 1e18 + deposit: 3_433.621534856445752000 * 1e18, + exchangeRate: 1.716810767428222876 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(4 hours); - - _addLiquidity({ + _addLiquidityNoEventCheck({ from: _lender, amount: 1_000 * 1e18, - index: 2000, - lpAward: 1_000 * 1e18, - newLup: 3_806.274307891526195092 * 1e18 + index: 2000 }); _depositTake({ @@ -849,7 +826,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, collateralArbed: 0.021378186081598093 * 1e18, quoteTokenAmount: 999.9999999999999908 * 1e18, - bondChange: 299.99999999999999724 * 1e18, + bondChange: 9.999999999999999908 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -864,37 +841,37 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_422.207326928504959735 * 1e18, + borrowerDebt: 9_904.062307087997095630 * 1e18, borrowerCollateral: 1.978621813918401907 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 1.703035796058482710 * 1e18 + borrowerCollateralization: 0.764215028898934136 * 1e18 }); _assertCollateralInvariants(); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 4_000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 5_425.973870376971549568 * 1e18); // borrower exits from auction by regular take _take({ from: _lender, borrower: _borrower, maxCollateral: 1, - bondChange: 1_201.442307692307695760 * 1e18, - givenAmount: 4_422.207326928504959735 * 1e18, - collateralTaken: 0.286141493566424944 * 1e18, + bondChange: 90.646484035657361618 * 1e18, + givenAmount: 9_904.062307087997095630 * 1e18, + collateralTaken: 0.468592638026133318 * 1e18, isReward: false }); - assertEq(_quote.balanceOf(_borrower), 16_132.410148540612418451 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 8_422.207326928504959735 * 1e18); + assertEq(_quote.balanceOf(_borrower), 16_331.699340400048828763 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 15_330.036177464968645198 * 1e18); // borrower 2 repays entire debt and pulls collateral _repayDebt({ from: _borrower2, borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 5_067.483483110752298818 * 1e18, + amountToRepay: 11_000 * 1e18, + amountRepaid: 10_203.293562995691294053 * 1e18, collateralToPull: 3, newLup: MAX_PRICE }); @@ -915,7 +892,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, kickMomp: 0, - totalBondEscrowed: 1_501.442307692307693000 * 1e18, + totalBondEscrowed: 1_325.327386341314188042 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -936,34 +913,30 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { exchangeRate: 0.999999999999999991 * 1e18 }); _assertBucket({ - index: 2222, - lpBalance: 15_127.888999922350308085 * 1e18, + index: 2159, + lpBalance: 20_712.867160884608174886 * 1e18, collateral: 0.978621813918401907 * 1e18, deposit: 0, exchangeRate: 1.000000000000000001 * 1e18 }); - // lender adds liquidity in bucket 2222 and merge / removes remaining NFTs - _addLiquidity({ + // lender adds liquidity in bucket 2159 and merge / removes remaining NFTs + _addLiquidityNoEventCheck({ from: _lender, - amount: 20_000 * 1e18, - index: 2222, - lpAward: 19_999.999999999999999999 * 1e18, - newLup: MAX_PRICE + amount: 40_000 * 1e18, + index: 2159 }); - _addLiquidity({ + _addLiquidityNoEventCheck({ from: _lender, - amount: 10_000 * 1e18, - index: 2000, - lpAward: 10_000.000000000000092004 * 1e18, - newLup: MAX_PRICE + amount: 40_000 * 1e18, + index: 2000 }); uint256[] memory removalIndexes = new uint256[](2); removalIndexes[0] = 2000; - removalIndexes[1] = 2222; + removalIndexes[1] = 2159; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 2222, + toIndex: 2159, noOfNFTsToRemove: 1, collateralMerged: 1 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -979,15 +952,14 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 15_127.888999922350308085 * 1e18, - index: 2222, + amount: 20_712.867160884608174886 * 1e18, + index: 2159, newLup: MAX_PRICE, - lpRedeem: 15_127.888999922350308085 * 1e18 + lpRedeem: 20_712.867160884608174886 * 1e18 }); } function testDepositTakeAndSettleByBucketTakeSubsetPool() external tearDown { - // the 2 token ids are owned by borrower before settle assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); @@ -996,16 +968,16 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_000 * 1e18, - exchangeRate: 1 * 1e18 + deposit: 3_433.621534856445752000 * 1e18, + exchangeRate: 1.716810767428222876 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(32 hours); @@ -1015,27 +987,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.747023327968958780 * 1e18, - quoteTokenAmount: 2_857.592579147092505518 * 1e18, - bondChange: 857.277773744127751655 * 1e18, + collateralArbed: 0.906830021600950636 * 1e18, + quoteTokenAmount: 3_468.902031908638183607 * 1e18, + bondChange: 34.689020319086381836 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 857.142857142857142797 * 1e18 + lpAwardKicker: 20.202020202020202030 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_857.142857142857142797 * 1e18, - collateral: 0.747023327968958780 * 1e18, + lpBalance: 2_020.202020202020202030 * 1e18, + collateral: 0.906830021600950636 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 3_422.759153589922201864 * 1e18, - borrowerCollateral: 1.252976672031041220 * 1e18, + borrowerDebt: 7_471.766388200619360126 * 1e18, + borrowerCollateral: 1.093169978399049364 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000036547279 * 1e18 + borrowerCollateralization: 0.556883685430732796 * 1e18 }); _assertCollateralInvariants(); @@ -1044,32 +1016,30 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _repayDebt({ from: _borrower2, borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 5_068.293419619520519499 * 1e18, + amountToRepay: 11_000 * 1e18, + amountRepaid: 10_205.087450363250041380 * 1e18, collateralToPull: 3, newLup: 3_863.654368867279344664 * 1e18 }); // borrower exits from auction by bucket take: lender adds quote token at a higher priced bucket and calls deposit take - _addLiquidity({ + _addLiquidityNoEventCheck({ from: _lender, - amount: 10_000 * 1e18, - index: 2400, - lpAward: 10_000 * 1e18, - newLup: 6_362.157913642177655049 * 1e18 + amount: 40_000 * 1e18, + index: 2000 }); _depositTake({ from: _lender, borrower: _borrower, kicker: _lender, - index: 2400, - collateralArbed: 0.768553060151988915 * 1e18, - quoteTokenAmount: 4_889.655933699888859806 * 1e18, - bondChange: 1_466.896780109966657942 * 1e18, + index: 2000, + collateralArbed: 0.161346274954730238 * 1e18, + quoteTokenAmount: 7_547.238775960221575885 * 1e18, + bondChange: 75.472387759602215759 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 1_466.896780109966657942 * 1e18 + lpAwardKicker: 75.472387759602215759 * 1e18 }); _assertBorrower({ @@ -1088,7 +1058,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1103,35 +1073,33 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); _assertBucket({ - index: 2400, - lpBalance: 11_466.896780109966657942 * 1e18, - collateral: 0.768553060151988915 * 1e18, - deposit: 6_577.240846410077798136 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 + index: 2000, + lpBalance: 40_075.472387759602215759 * 1e18, + collateral: 0.161346274954730238 * 1e18, + deposit: 32_528.233611799380639874 * 1e18, + exchangeRate: 1 * 1e18 }); _assertBucket({ - index: 6113, - lpBalance: 0.000027941032210122 * 1e18, - collateral: 0.484423611879052305 * 1e18, + index: 6051, + lpBalance: 0.000073222866272711 * 1e18, + collateral: 0.931823703444319126 * 1e18, deposit: 0, - exchangeRate: 0.999999999999988853 * 1e18 + exchangeRate: 1.000000000000005246 * 1e18 }); - // lender adds liquidity in bucket 6113 and merge / removes the other 2 NFTs - _addLiquidity({ + // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs + _addLiquidityNoEventCheck({ from: _lender, amount: 1_000 * 1e18, - index: 6113, - lpAward: 1_000.000000000011147000 * 1e18, - newLup: MAX_PRICE + index: 6051 }); uint256[] memory removalIndexes = new uint256[](3); - removalIndexes[0] = 2400; + removalIndexes[0] = 2000; removalIndexes[1] = 2502; - removalIndexes[2] = 6113; + removalIndexes[2] = 6051; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 6113, + toIndex: 6051, noOfNFTsToRemove: 2, collateralMerged: 2 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -1147,10 +1115,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000027941032210121 * 1e18, - index: 6113, + amount: 0.000073222866272711 * 1e18, + index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000027941032210122 * 1e18 + lpRedeem: 0.000073222866272711 * 1e18 }); } @@ -1164,16 +1132,16 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_000 * 1e18, - exchangeRate: 1 * 1e18 + deposit: 3_433.621534856445752000 * 1e18, + exchangeRate: 1.716810767428222876 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_067.367788461538463875 * 1e18, + borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000039403606 * 1e18 + borrowerCollateralization: 0.750762377759786560 * 1e18 }); skip(32 hours); @@ -1183,27 +1151,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.747023327968958780 * 1e18, - quoteTokenAmount: 2_857.592579147092505518 * 1e18, - bondChange: 857.277773744127751655 * 1e18, + collateralArbed: 0.906830021600950636 * 1e18, + quoteTokenAmount: 3_468.902031908638183607 * 1e18, + bondChange: 34.689020319086381836 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 857.142857142857142797 * 1e18 + lpAwardKicker: 20.202020202020202030 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_857.142857142857142797 * 1e18, - collateral: 0.747023327968958780 * 1e18, + lpBalance: 2_020.202020202020202030 * 1e18, + collateral: 0.906830021600950636 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 3_422.759153589922201864 * 1e18, - borrowerCollateral: 1.252976672031041220 * 1e18, + borrowerDebt: 7_471.766388200619360126 * 1e18, + borrowerCollateral: 1.093169978399049364 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.000000000036547279 * 1e18 + borrowerCollateralization: 0.556883685430732796 * 1e18 }); _assertCollateralInvariants(); @@ -1212,8 +1180,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _repayDebt({ from: _borrower2, borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 5_068.293419619520519499 * 1e18, + amountToRepay: 11_000 * 1e18, + amountRepaid: 10_205.087450363250041380 * 1e18, collateralToPull: 3, newLup: 3_863.654368867279344664 * 1e18 }); @@ -1225,7 +1193,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 3_422.134049189579697687 * 1e18 + settledDebt: 3_714.709153177962410149 * 1e18 }); _assertBorrower({ @@ -1244,7 +1212,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondFactor: 0, kickTime: 0, kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1260,41 +1228,26 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 4_997.115384615384614000 * 1e18, - collateral: 0.886214193313763368 * 1e18, - deposit: 1_574.549120144393919177 * 1e18, - exchangeRate: 1.000291983507608181 * 1e18 + lpBalance: 8_000 * 1e18, + collateral: 1.093169978399049364 * 1e18, + deposit: 8_769.974931189662198177 * 1e18, + exchangeRate: 1.624200736768212333 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_857.142857142857142797 * 1e18, - collateral: 0.747023327968958780 * 1e18, + lpBalance: 2_020.202020202020202030 * 1e18, + collateral: 0.906830021600950636 * 1e18, deposit: 0, - exchangeRate: 1.000157402701482377 * 1e18 - }); - _assertBucket({ - index: 7388, - lpBalance: 0.000000036616202579 * 1e18, - collateral: 0.366762478717277852 * 1e18, - deposit: 0, - exchangeRate: 0.999999999990598588 * 1e18 + exchangeRate: 1.717106505794775901 * 1e18 }); - // lender adds liquidity in bucket 7388 and merge / removes the other 2 NFTs - _addLiquidity({ - from: _lender, - amount: 1_000 * 1e18, - index: 7388, - lpAward: 1_000.000000009401412837 * 1e18, - newLup: MAX_PRICE - }); - uint256[] memory removalIndexes = new uint256[](3); + // lender merge / removes the other 2 NFTs + uint256[] memory removalIndexes = new uint256[](2); removalIndexes[0] = 2500; removalIndexes[1] = 2502; - removalIndexes[2] = 7388; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 7388, + toIndex: 2502, noOfNFTsToRemove: 2, collateralMerged: 2 * 1e18, removeCollateralAtIndex: removalIndexes, diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index d97415854..bf0bed1b6 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -257,24 +257,19 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.kick(borrower, MAX_FENWICK_INDEX); } - function _kickWithDeposit( + function _lenderKick( address from, uint256 index, address borrower, uint256 debt, uint256 collateral, - uint256 bond, - uint256 removedFromDeposit, - uint256 transferAmount, - uint256 lup + uint256 bond ) internal { changePrank(from); vm.expectEmit(true, true, false, true); emit Kick(borrower, debt, collateral, bond); - vm.expectEmit(true, true, false, true); - emit RemoveQuoteToken(from, index, removedFromDeposit, removedFromDeposit, lup); - if (transferAmount != 0) _assertQuoteTokenTransferEvent(from, address(_pool), transferAmount); - _pool.kickWithDeposit(index, MAX_FENWICK_INDEX); + _assertQuoteTokenTransferEvent(from, address(_pool), bond); + _pool.lenderKick(index, MAX_FENWICK_INDEX); } function _moveLiquidity( @@ -1089,13 +1084,13 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.kick(borrower, 0); } - function _assertKickWithDepositNpUnderLimitRevert( + function _assertLenderKickAuctionNpUnderLimitRevert( address from, uint256 index ) internal { changePrank(from); vm.expectRevert(IPoolErrors.LimitIndexExceeded.selector); - _pool.kickWithDeposit(index, 0); + _pool.lenderKick(index, 0); } function _assertKickWithInsufficientLiquidityRevert( @@ -1104,7 +1099,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('InsufficientLiquidity()')); - _pool.kickWithDeposit(index, MAX_FENWICK_INDEX); + _pool.lenderKick(index, MAX_FENWICK_INDEX); } function _assertKickWithBadProposedLupRevert( @@ -1113,16 +1108,16 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('BorrowerOk()')); - _pool.kickWithDeposit(index, MAX_FENWICK_INDEX); + _pool.lenderKick(index, MAX_FENWICK_INDEX); } - function _assertKickPriceBelowProposedLupRevert( + function _assertKickPriceBelowLupRevert( address from, uint256 index ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('PriceBelowLUP()')); - _pool.kickWithDeposit(index, MAX_FENWICK_INDEX); + _pool.lenderKick(index, MAX_FENWICK_INDEX); } function _assertRemoveCollateralAuctionNotClearedRevert( From 1692046f755a71d34df505e3eb3420a53e6e8aa8 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Sun, 18 Jun 2023 10:47:28 +0300 Subject: [PATCH 10/32] Invariants improvements: Adapt rate invariant for ERC20 pool with collateral precision lower than quote precision (#895) * Adapt rate invariant for ERC20 pool with collateral precision lower than quote precision * Use pending inflator to calculate bucket take penalty * Fix compile error --- Makefile | 2 +- .../invariants/base/BasicInvariants.t.sol | 17 +++-- .../base/handlers/unbounded/BaseHandler.sol | 6 +- .../UnboundedLiquidationPoolHandler.sol | 3 +- .../RegressionTestReservesERC20Pool.t.sol | 65 +++++++++++++++++++ 5 files changed, 83 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index add7a8466..6bb1dde2d 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # (-include to ignore error if it does not exist) -include .env && source ./tests/forge/invariants/scenarios/scenario-${SCENARIO}.sh -CONTRACT_EXCLUDES="RegressionTest|Panic|RealWorld|Trading" +CONTRACT_EXCLUDES="RegressionTest|Panic|RealWorld|Trading|Position|Rewards" TEST_EXCLUDES="testLoad|invariant|test_regression" all: clean install build diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index 8c92219f8..4dd0672fc 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -5,8 +5,9 @@ pragma solidity 0.8.18; import "@std/console.sol"; import '../../utils/DSTestPlus.sol'; -import { IERC20Pool } from 'src/interfaces/pool/erc20/IERC20Pool.sol'; -import { Maths } from 'src/libraries/internal/Maths.sol'; +import { IERC20Token } from 'src/interfaces/pool/IPool.sol'; +import { IERC20Pool } from 'src/interfaces/pool/erc20/IERC20Pool.sol'; +import { Maths } from 'src/libraries/internal/Maths.sol'; import { IBaseHandler } from '../interfaces/IBaseHandler.sol'; import { BaseInvariants } from '../base/BaseInvariants.sol'; @@ -223,13 +224,21 @@ abstract contract BasicInvariants is BaseInvariants { "Exchange Rate Invariant R1, R2, R3, R4, R5, R6, R7 or R8" ); } else { + uint256 deviation = 1e13; + + // if ERC20 pool and collateral precision lower than quote precision then require exchange rate to be within collateral scale + // this could happen in a take / bucket take situation when we round to collateral scale in order to be claimed + if (_pool.poolType() == 0 && _quote.decimals() > IERC20Token(_pool.collateralAddress()).decimals()) { + deviation = Maths.max(deviation, IERC20Pool(address(_pool)).collateralScale()); + } + // Common case, 1 one millionth (0.000_001) of a quote token or greater is inserted into a single bucket requireWithinDiff( currentExchangeRate, previousExchangeRate, - 1e8, // otherwise require exchange rates to be within 1e-10 + deviation, "Exchange Rate Invariant R1, R2, R3, R4, R5, R6, R7 or R8" - ); + ); } } } diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 1e9691175..2c8a7c957 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -461,16 +461,14 @@ abstract contract BaseHandler is Test { bond_ = claimableBond + lockedBond; } - function _updateCurrentTakeState(address borrower_, uint256 borrowert0Debt_) internal { + function _updateCurrentTakeState(address borrower_, uint256 borrowert0Debt_, uint256 inflator_) internal { if (!alreadyTaken[borrower_]) { alreadyTaken[borrower_] = true; - (uint256 inflator, ) = _pool.inflatorInfo(); - // **RE7**: Reserves increase by 7% of the loan quantity upon the first take. increaseInReserves += Maths.wmul( Maths.wmul(borrowert0Debt_, 0.07 * 1e18), - inflator + inflator_ ); firstTake = true; diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index 897851dff..2f5c135b5 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -213,6 +213,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { (address kicker, , , , , , , , , ) = _pool.auctionInfo(borrower_); ( , , , , uint256 auctionPrice, ) = _poolInfo.auctionStatus(address(_pool), borrower_); uint256 auctionBucketIndex = auctionPrice < MIN_PRICE ? 7388 : (auctionPrice > MAX_PRICE ? 0 : _indexOf(auctionPrice)); + ( , , , uint256 pendingInflator, ) = _poolInfo.poolLoansInfo(address(_pool)); LocalBucketTakeVars memory beforeBucketTakeVars = getBucketTakeInfo(bucketIndex_, kicker, _actor, auctionBucketIndex, borrower_); @@ -252,7 +253,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // assign value to fenwick tree to mitigate rounding error that could be created in a _fenwickRemove call fenwickDeposits[bucketIndex_] = afterBucketTakeVars.deposit; - _updateCurrentTakeState(borrower_, borrowerT0Debt); + _updateCurrentTakeState(borrower_, borrowerT0Debt, pendingInflator); } catch (bytes memory err) { _ensurePoolError(err); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol index c8cd030c8..826fadb89 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -1256,3 +1256,68 @@ contract RegressionTestReserveWith12CollateralPrecisionERC20Pool is ReserveERC20 invariant_quote(); } } + +contract RegressionTestReserveRateFailureERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "2"); + + super.setUp(); + } + + function test_regression_failure_rate_rw_1() external { + _reserveERC20PoolHandler.moveQuoteToken(2713745082854240244061, 15659150431173520656126, 11627790492018001678103538003719, 702302526125586756087377603844607976064956618811079445222892931689959409, 2999999999999999999999999932305381158509265807); + _reserveERC20PoolHandler.kickAuction(1, 6809446559826261847258010878078267653625372887206796015056396925681, 3, 108777762057340874954184791481296119581); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4818032864823826134704772955529733, true, 486355303824498230104826569186, 101231418301489137629); + + _invariant_R1_R2_R3_R4_R5_R6_R7_R8(); + } +} + +contract RegressionTestReserveWith8CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "8"); + super.setUp(); + } + + function test_regression_failure_rate_with_col_precision_8() external { + _reserveERC20PoolHandler.moveQuoteToken(7065465912395301546653771299344157923107747921279658981452834151342496639, 250541874700065836620, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 339193523082930124569760269504805082869260003, 8148628492079059521271069954244976097); + _reserveERC20PoolHandler.withdrawBonds(23709619545376531780606275884917745024902333684128986776737387593908743, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.pledgeCollateral(42666532108011595784308924152350052531383375335, 5809118760125432997676654732, 965904341458225551777795352986886956188290554326089); + _reserveERC20PoolHandler.removeCollateral(702351282836996322752708166120229445999756883520462134558879235029860352, 7094792829913997357504516282, 1000090299392130745372174632914, 1012057857228338770); + _reserveERC20PoolHandler.removeQuoteToken(11988599652599805756463937657, 18221051085757115699515976785494, 1915424620773394265921779, 5149377894786633179300473); + _reserveERC20PoolHandler.lenderKickAuction(2899957802674216732984, 1000216196714744597, 4008287359660140746236758059); + _reserveERC20PoolHandler.bucketTake(3, 607525307198026895012163441032845762821611030339, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2344477780612242655930676572341759663622902686070567495); + _reserveERC20PoolHandler.lenderKickAuction(2, 0, 2302565122490673838968099194821778180394707183828480120102840951454827); + _reserveERC20PoolHandler.removeQuoteToken(29999999999999999999999999999993955717018273660000000000, 100000074400781173509, 1690078137, 7746566126667503662259919454813345813464); + _reserveERC20PoolHandler.pledgeCollateral(73702245772623658491340224, 16504816212303219314310736480896, 23854977676725639332395733208692944486349876972253503634401400543441081192917); + _reserveERC20PoolHandler.bucketTake(32507579561616385, 3, true, 1, 24); + + invariant_exchange_rate(); + } + + function test_regression_failure_reserves_with_col_precision_8() external { + _reserveERC20PoolHandler.addCollateral(114238260062574182853, 10369772791768212489561568, 695188329508152730048443240988655562367482441302665039944603718446743552, 18583369093672742703093239386); + _reserveERC20PoolHandler.pullCollateral(10147, 2343322363531191320713183406, 1707574665); + _reserveERC20PoolHandler.removeCollateral(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3606477932718685137709236900053470943, 23385415607402486572668); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, false, 679194464007709242765248157037212202199214448722523641028299465752719992, 24137506329721); + _reserveERC20PoolHandler.addCollateral(3258448918269729152175438140803564738674280, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _reserveERC20PoolHandler.repayDebt(4240954761491, 506382, 46295193839352600139383379009183528168231424499253797364809851); + _reserveERC20PoolHandler.withdrawBonds(529674970946337695788247196445527494449474476473211190416, 12633126596755336114408498859733373487282942486261382963393306387, 2427707355658); + _reserveERC20PoolHandler.repayDebt(219913722554346459171121996440783221556597, 1580045853267856820361525499065414598, 2); + _reserveERC20PoolHandler.addCollateral(3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4924795240935312983096353741083393641419906095740467126627640723723085666); + _reserveERC20PoolHandler.lenderKickAuction(115792089237316195423570985008687907853269984665505241123434172405395527169317, 1419490228827145537718746, 412671412358632982503555579); + _reserveERC20PoolHandler.bucketTake(1027935897138128431, 77846035770509710261666, false, 354405506725417003060000000000, 31404802804047717331727); + _reserveERC20PoolHandler.lenderKickAuction(12083827091688561989797789, 5036169582603030000000000, 840998853324115664088420098255182867602843310728); + _reserveERC20PoolHandler.removeQuoteToken(2580054854117444202133186, 3, 1885976439479270141074119744163442391561113698071923440810698322709539, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.bucketTake(96085151998096, 5845075940198927177680538279496604459032449306087006808901507782891, true, 0, 21522202620166094191862172737223123435968299034261665131133830075); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 150179944416354305931107238750987364354, true, 23361419, 1); + + invariant_reserves(); + } +} \ No newline at end of file From 0a7b4bb7dbff1a96ba90b9ed512a8558222ce374 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Wed, 21 Jun 2023 08:04:00 +0300 Subject: [PATCH 11/32] Bug fix: use better precision when calculating quote tokens in `_calculateTakeFlowsAndBondChange` (#898) * Add failing tests * Proposed increase in accuracy for calculateTakeFlows * improved accuracy of rounding in debt limited case * Fix baseline, code style, put back lower exchange rate invariant deviation * Tests comment * Changes after review: fix t0RepayAmount calculation, use borrowerPrice instead vars.auctionPrice Fix unit tests --------- Co-authored-by: mwc --- src/libraries/external/TakerActions.sol | 12 +-- .../invariants/base/BasicInvariants.t.sol | 10 +-- .../RegressionTestLiquidationERC20Pool.t.sol | 29 +++++++ .../RegressionTestReservesERC20Pool.t.sol | 28 +++++++ .../ERC20PoolLiquidationsArbTake.t.sol | 10 +-- .../ERC20PoolLiquidationsDepositTake.t.sol | 20 ++--- .../ERC20PoolLiquidationsSettle.t.sol | 16 ++-- .../ERC20Pool/ERC20PoolLiquidationsTake.t.sol | 26 +++---- .../ERC721Pool/ERC721PoolCollateral.t.sol | 18 ++--- .../ERC721PoolLiquidationsDepositTake.t.sol | 10 +-- .../ERC721PoolLiquidationsSettleAuction.t.sol | 78 +++++++++---------- .../ERC721PoolLiquidationsTake.t.sol | 10 +-- 12 files changed, 159 insertions(+), 108 deletions(-) diff --git a/src/libraries/external/TakerActions.sol b/src/libraries/external/TakerActions.sol index 2b2655fa4..f7131b744 100644 --- a/src/libraries/external/TakerActions.sol +++ b/src/libraries/external/TakerActions.sol @@ -753,10 +753,12 @@ library TakerActions { if (vars.quoteTokenAmount <= vars.borrowerDebt && vars.quoteTokenAmount <= borrowerCollateralValue) { // quote token used to purchase is constraining factor vars.collateralAmount = _roundToScale(Maths.wdiv(vars.quoteTokenAmount, borrowerPrice), collateralScale_); - vars.t0RepayAmount = Maths.wdiv(vars.quoteTokenAmount, inflator_); - vars.unscaledQuoteTokenAmount = vars.unscaledDeposit; - vars.quoteTokenAmount = Maths.wmul(vars.collateralAmount, vars.auctionPrice); + vars.t0RepayAmount = Math.mulDiv(vars.collateralAmount, borrowerPrice, inflator_); + vars.unscaledQuoteTokenAmount = Maths.min( + vars.unscaledDeposit, + Math.mulDiv(vars.collateralAmount, borrowerPrice, vars.bucketScale) + ); } else if (vars.borrowerDebt <= borrowerCollateralValue) { // borrower debt is constraining factor @@ -769,8 +771,8 @@ library TakerActions { } else { // collateral available is constraint vars.collateralAmount = totalCollateral_; - vars.t0RepayAmount = Maths.wdiv(borrowerCollateralValue, inflator_); - vars.unscaledQuoteTokenAmount = Maths.wdiv(borrowerCollateralValue, vars.bucketScale); + vars.t0RepayAmount = Math.mulDiv(totalCollateral_, borrowerPrice, inflator_); + vars.unscaledQuoteTokenAmount = Math.mulDiv(totalCollateral_, borrowerPrice, vars.bucketScale); vars.quoteTokenAmount = Maths.wmul(vars.collateralAmount, vars.auctionPrice); } diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index 4dd0672fc..1867a192d 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -224,19 +224,11 @@ abstract contract BasicInvariants is BaseInvariants { "Exchange Rate Invariant R1, R2, R3, R4, R5, R6, R7 or R8" ); } else { - uint256 deviation = 1e13; - - // if ERC20 pool and collateral precision lower than quote precision then require exchange rate to be within collateral scale - // this could happen in a take / bucket take situation when we round to collateral scale in order to be claimed - if (_pool.poolType() == 0 && _quote.decimals() > IERC20Token(_pool.collateralAddress()).decimals()) { - deviation = Maths.max(deviation, IERC20Pool(address(_pool)).collateralScale()); - } - // Common case, 1 one millionth (0.000_001) of a quote token or greater is inserted into a single bucket requireWithinDiff( currentExchangeRate, previousExchangeRate, - deviation, + 1e8, // otherwise require exchange rates to be within 1e-10, "Exchange Rate Invariant R1, R2, R3, R4, R5, R6, R7 or R8" ); } diff --git a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol index f3d5514f2..1e9db81d5 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol @@ -2093,4 +2093,33 @@ contract RegressionTestReserveEvmRevertERC720Pool is LiquidationERC20PoolInvaria invariant_auction(); } +} +contract RegressionTestLiquidationWith18QuotePrecision4CollateralPrecisionERC20Pool is LiquidationERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "4"); + super.setUp(); + } + + /** + Test was failing due to precision lost when calculating quote token amount / repaid debt in _calculateTakeFlowsAndBondChange function. + Fixed by using Math.mulDiv to preserve precision. + */ + function test_regression_rate_token_precision_failure_1() external { + _liquidationERC20PoolHandler.moveQuoteToken(175392022767193814475874741962393251106628328261315429178972, 1797327127263818960, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1644988175134, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.repayDebt(2901144704650608259897936167503, 1009953125564359729, 8655010762301333632174703); + _liquidationERC20PoolHandler.addCollateral(2294881370148, 20036810979990508388781820623, 55222771518408080817454805, 2383437524486764676091662); + _liquidationERC20PoolHandler.pledgeCollateral(9537484863810905098467296279802705017627, 56938426356851360122988248749867665850, 51383472145726921198541); + _liquidationERC20PoolHandler.moveQuoteToken(8113486005935801158342845527, 999999999999999998617712392378071841007479784, 1677040111146948110025, 723879823343174623088606487519303876125332616357885239396937077266114809, 32813280521190660407318457183186); + _liquidationERC20PoolHandler.settleAuction(3030330973006860175747595472187110259994329124939584837008550716405647885216, 438723833154373485390315041294, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0); + _liquidationERC20PoolHandler.addQuoteToken(1259872590692064398485886435, 5751, 501139121213931580, 1672408341); + _liquidationERC20PoolHandler.bucketTake(402464741, 115792089237316195423570985008687907853269984665640564039457584007913129639932, true, 596804051989417298867293967, 4263459484279997743180736624973236997004790747955740959160048356852365887525); + _liquidationERC20PoolHandler.repayDebt(3268559648765402077441832, 571873621400257, 22720331790746250902065302734414); + _liquidationERC20PoolHandler.removeQuoteToken(2, 1, 6410479082320500083885018107446985425406358959644188734992944292238950812208, 24112255150711148497418360422332205020941643); + _liquidationERC20PoolHandler.bucketTake(10938447166695146361346492482578582432642009558632194844027301822, 115792089237316195423570985008687907853269984665640564039457584007913129639933, true, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + + invariant_exchange_rate(); + } + } \ 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 826fadb89..10c0cf95e 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -1320,4 +1320,32 @@ contract RegressionTestReserveWith8CollateralPrecisionERC20Pool is ReserveERC20P invariant_reserves(); } +} + +contract RegressionTestReservesWith18QuotePrecision4CollateralPrecisionERC20Pool is ReserveERC20PoolInvariants { + + function setUp() public override { + vm.setEnv("QUOTE_PRECISION", "18"); + vm.setEnv("COLLATERAL_PRECISION", "4"); + super.setUp(); + } + + /** + Test was failing due to precision lost when calculating quote token amount / repaid debt in _calculateTakeFlowsAndBondChange function. + Fixed by using Math.mulDiv to preserve precision. + */ + function test_regression_rate_token_precision_failure_2() external { + _reserveERC20PoolHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 89552631, 27353130995490170987078007); + _reserveERC20PoolHandler.takeAuction(1000006698792936000000000000000, 1013696853399, 11864972053525826488457833767, 20272629953825623093168169460); + _reserveERC20PoolHandler.bucketTake(101217938655794611879794153, 115792089237316195423570985008687907853269984665640564039457584007913129639935, true, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 109434987841691942673859961998); + _reserveERC20PoolHandler.takeAuction(2, 1, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _reserveERC20PoolHandler.repayDebt(709587692312031012755297910153597281037249007558669044012478487199113024, 324034365691376028489096823787371897298145, 691167229021501979791794056627); + _reserveERC20PoolHandler.drawDebt(8819683027554036158806221339871426233668492926100027683713695687747, 2, 611155566926195158593401676); + _reserveERC20PoolHandler.removeQuoteToken(10831, 2999999999999999999999999999999999999998188685, 16413, 1630905596080266311331453901); + _reserveERC20PoolHandler.drawDebt(19656673249166279044881856997468, 17698, 15782530613322326845); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 3359951965909399193842356284157491036179701263876178043669343533768515993, true, 199361393407780895490, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + + invariant_exchange_rate(); + } + } \ No newline at end of file diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol index ea533ebac..9df8a42bb 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol @@ -496,7 +496,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { totalBondEscrowed: 0.045342779771472726 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 4.858174346779663272 * 1e18, + thresholdPrice: 4.858174346779663281 * 1e18, neutralPrice: 0 }) ); @@ -504,15 +504,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { index: _i1505_26, lpBalance: 1_100.822235391290531090 * 1e18, collateral: 0.731315193857015473 * 1e18, - deposit: 0, + deposit: 10, exchangeRate: 1 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6.163491979352977585 * 1e18, + borrowerDebt: 6.163491979352977596 * 1e18, borrowerCollateral: 1.268684806142984527 * 1e18, - borrowert0Np: 5.057793757429320956 * 1e18, - borrowerCollateralization: 2.001018319047304752 * 1e18 + borrowert0Np: 5.057793757429320966 * 1e18, + borrowerCollateralization: 2.001018319047304749 * 1e18 }); _assertLenderLpBalance({ lender: _taker, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol index d728026a5..209be726c 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol @@ -309,8 +309,8 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { }); // reserves should remain the same after deposit take _assertReserveAuction({ - reserves: 51.238131288298142182 * 1e18, - claimableReserves : 9.897035340857769727 * 1e18, + reserves: 51.238131288298142183 * 1e18, + claimableReserves : 9.897035340857769728 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -326,14 +326,14 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { kickMomp: 9.818751856078723036 * 1e18, totalBondEscrowed: 0.199398195043779403 * 1e18, auctionPrice: 7.402280333270247968 * 1e18, - debtInAuction: 1.966997287334847888 * 1e18, + debtInAuction: 1.966997287334847889 * 1e18, thresholdPrice: 0, neutralPrice: 10.468405239798418677 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 1.966997287334847888 * 1e18, + borrowerDebt: 1.966997287334847889 * 1e18, borrowerCollateral: 0, borrowert0Np: 10.115967548076923081 * 1e18, borrowerCollateralization: 0 @@ -503,7 +503,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { totalBondEscrowed: 0.049398195043779403 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 3.317960196583009904 * 1e18, + thresholdPrice: 3.317960196583009907 * 1e18, neutralPrice: 0 }) ); @@ -511,15 +511,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { index: _i1505_26, lpBalance: 15 * 1e18, collateral: 0.009965031187761219 * 1e18, - deposit: 0, - exchangeRate: 1 * 1e18 + deposit: 5, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6.602856816327319771 * 1e18, + borrowerDebt: 6.602856816327319776 * 1e18, borrowerCollateral: 1.990034968812238781 * 1e18, - borrowert0Np: 3.384038787324199948 * 1e18, - borrowerCollateralization: 2.929901291475173000 * 1e18 + borrowert0Np: 3.384038787324199951 * 1e18, + borrowerCollateralization: 2.929901291475172996 * 1e18 }); _assertLenderLpBalance({ lender: _taker, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 242ef954d..bbb509694 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -746,7 +746,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { // 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: 10_028.889031920233428708 * 1e18, + borrowerDebt: 10_028.889031920233428709 * 1e18, borrowerCollateral: 0, borrowert0Np: 10.307611531622595991 * 1e18, borrowerCollateralization: 0 @@ -763,7 +763,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are resetted @@ -1012,13 +1012,13 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender1, amount: 2_884.311069344372084707 * 1e18 + 10 - reserves, index: _i9_81, - lpAward: 2_020.307252493359351054 * 1e18, + lpAward: 2_020.307252493359351053 * 1e18, newLup: 9.721295865031779605 * 1e18 }); uint256 bucket1Deposit = 2_112.736560735960384000 * 1e18; - uint256 bucket2Deposit = 7_065.014537346601772214 * 1e18; - uint256 debtToSettle = 10_028.889031920233428708 * 1e18; + uint256 bucket2Deposit = 7_065.014537346601772213 * 1e18; + uint256 debtToSettle = 10_028.889031920233428709 * 1e18; _assertBorrower({ borrower: _borrower2, @@ -1038,7 +1038,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertBucket({ index: _i9_81, - lpBalance: 7_020.307252493359351054 * 1e18, + lpBalance: 7_020.307252493359351053 * 1e18, collateral: 0, deposit: bucket2Deposit, exchangeRate: 1.006368280367980193 * 1e18 @@ -1048,12 +1048,12 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { vm.expectEmit(true, true, false, true); emit BucketBankruptcy(_i9_91, 2_099.367201799558744044 * 1e18); vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_81, 7_020.307252493359351054 * 1e18); + emit BucketBankruptcy(_i9_81, 7_020.307252493359351053 * 1e18); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are resetted diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol index 1e58e3d76..14a0d5b27 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol @@ -649,14 +649,14 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { kickMomp: 1_505.263728469068226832 * 1e18, totalBondEscrowed: 3_023.936406503595156885 * 1e18, auctionPrice: 25.933649477033750336 * 1e18, - debtInAuction: 10_460.307309872275586822 * 1e18, + debtInAuction: 10_460.307309872275586823 * 1e18, thresholdPrice: 10.565966979668965239 * 1e18, neutralPrice: 1_597.054445085392479852 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_460.307309872275586822 * 1e18, + borrowerDebt: 10_460.307309872275586823 * 1e18, borrowerCollateral: 990 * 1e18, borrowert0Np: 1_575.326150647652569911 * 1e18, borrowerCollateralization: 0.920057377023560467 * 1e18 @@ -1014,7 +1014,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { poolSize: 73_113.913417169507608000 * 1e18, pledgedCollateral: 992.0 * 1e18, encumberedCollateral: 925.265940856763249328 * 1e18, - poolDebt: 8_994.783964905591719092 * 1e18, + poolDebt: 8_994.783964905591719093 * 1e18, actualUtilization: 0.539426554958980321 * 1e18, targetUtilization: 0.996698499658312393 * 1e18, minDebtAmount: 449.739198245279585955 * 1e18, @@ -1043,7 +1043,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_975.249486232776725894 * 1e18, + borrowerDebt: 8_975.249486232776725895 * 1e18, borrowerCollateral: 990.000000000000000000 * 1e18, borrowert0Np: 9.438566662973887791 * 1e18, borrowerCollateralization: 1.072291407736791833 * 1e18 @@ -1492,14 +1492,14 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { kickMomp: 9.818751856078723036 * 1e18, totalBondEscrowed: 105.065056948053351817 * 1e18, auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 10_028.889031920233428708 * 1e18, + debtInAuction: 10_028.889031920233428709 * 1e18, thresholdPrice: 0, neutralPrice: 10.449783245217816340 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_028.889031920233428708 * 1e18, + borrowerDebt: 10_028.889031920233428709 * 1e18, borrowerCollateral: 0, borrowert0Np: 10.307611531622595991 * 1e18, borrowerCollateralization: 0 @@ -1511,8 +1511,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); // reserves should increase after take action _assertReserveAuction({ - reserves: 851.125605070547984803 * 1e18, - claimableReserves : 800.883410388937242978 * 1e18, + reserves: 851.125605070547984804 * 1e18, + claimableReserves : 800.883410388937242979 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1540,7 +1540,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); _assertAuction( @@ -1640,8 +1640,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { vm.revertTo(postTakeSnapshot); _assertReserveAuction({ - reserves: 851.125605070547984803 * 1e18, - claimableReserves : 800.883410388937242978 * 1e18, + reserves: 851.125605070547984804 * 1e18, + claimableReserves : 800.883410388937242979 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1651,7 +1651,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 0, - settledDebt: 839.502646350469647165 * 1e18 + settledDebt: 839.502646350469647166 * 1e18 }); _assertReserveAuction({ reserves: 0.000073114629046626 * 1e18, @@ -1917,7 +1917,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 2_824.753476813975806663 * 1e18 + settledDebt: 2_824.753476813975806664 * 1e18 }); // Borrower draws more debt diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol index 630c330d5..05b00308f 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol @@ -874,8 +874,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { kickMomp: 0.000000099836282890 * 1e18, totalBondEscrowed: 5.907892673985352325 * 1e18, auctionPrice: 0.000004621809202112 * 1e18, - debtInAuction: 439.681348088864224701 * 1e18, - thresholdPrice: 385.774399985858744600 * 1e18, + debtInAuction: 439.681348088864224563 * 1e18, + thresholdPrice: 385.774399985858744479 * 1e18, neutralPrice: 310.164365384230997074 * 1e18 }) ); @@ -886,8 +886,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { lup: 99836282890, poolSize: 374.163546520999771310 * 1e18, pledgedCollateral: 1.139736976079754220 * 1e18, - encumberedCollateral: 4404023621.084799631616172644 * 1e18, - poolDebt: 439.681348088864224701 * 1e18, + encumberedCollateral: 4_404_023_621.084799630233909643 * 1e18, + poolDebt: 439.681348088864224563 * 1e18, actualUtilization: 0.750721153846153847 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, @@ -904,7 +904,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 439.681348088864224701 * 1e18, + borrowerDebt: 439.681348088864224563 * 1e18, borrowerCollateral: 1.139736976079754220 * 1e18, borrowert0Np: 78.825721153846153882 * 1e18, borrowerCollateralization: 0.000000000258794474 * 1e18, @@ -930,7 +930,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 439.681343513273114610 * 1e18, + borrowerDebt: 439.681343513273114473 * 1e18, borrowerCollateral: 0.139736976079754220 * 1e18, borrowert0Np: 78.825721153846153882 * 1e18, borrowerCollateralization: 0.000000000031729389 * 1e18, @@ -962,8 +962,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { kickMomp: 0.000000099836282890 * 1e18, totalBondEscrowed: 5.907892720203444346 * 1e18, auctionPrice: 0, - debtInAuction: 439.681343513273114610 * 1e18, - thresholdPrice: 3_148.017628779219832340 * 1e18, + debtInAuction: 439.681343513273114473 * 1e18, + thresholdPrice: 3_148.017628779219831352 * 1e18, neutralPrice: 310.164365384230997074 * 1e18 }) ); @@ -972,7 +972,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 111.718947293453085984 * 1e18 + settledDebt: 111.718947293453085949 * 1e18 }); _assertBorrower({ diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol index 81180a3ac..0d31ea0b4 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol @@ -257,7 +257,7 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { totalBondEscrowed: 0.077287198298417188 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 9.624359312514645329 * 1e18, + thresholdPrice: 9.624359312514645335 * 1e18, neutralPrice: 0 }) ); @@ -272,14 +272,14 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { index: _i1505_26, lpBalance: 15 * 1e18, collateral: 0.009965031187761219 * 1e18, - deposit: 0, - exchangeRate: 1 * 1e18 + deposit: 5, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9.624359312514645329 * 1e18, + borrowerDebt: 9.624359312514645335 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 8.769696613728507377 * 1e18, + borrowert0Np: 8.769696613728507382 * 1e18, borrowerCollateralization: 1.030425457052554443 * 1e18 }); _assertLenderLpBalance({ diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 993be7abe..f262f1a17 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -382,12 +382,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerDebt: 4_471.766388200619361301 * 1e18, borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.258770970502146036 * 1e18 @@ -410,22 +410,22 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 2, - settledDebt: 2_223.210773740853089765 * 1e18 + settledDebt: 2_223.210773740853090348 * 1e18 }); _assertBucket({ index: 2500, lpBalance: 8_000 * 1e18, collateral: 0.300997199476505990 * 1e18, - deposit: 11_773.847757000624330192 * 1e18, + deposit: 11_773.847757000624329017 * 1e18, exchangeRate: 1.617099612721855334 * 1e18 }); _assertBucket({ index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -507,12 +507,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerDebt: 4_471.766388200619361301 * 1e18, borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.258770970502146036 * 1e18 @@ -545,9 +545,9 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerDebt: 4_471.766388200619361301 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 781.829122098866669900 * 1e18, + borrowert0Np: 781.829122098866670106 * 1e18, borrowerCollateralization: 2.592032342562933134 * 1e18 }); _assertAuction( @@ -562,7 +562,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 1_490.588796066873120043 * 1e18, + thresholdPrice: 1_490.588796066873120433 * 1e18, neutralPrice: 0 }) ); @@ -583,8 +583,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBucket({ index: 6051, @@ -617,7 +617,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _borrower, borrower: _borrower, amountToRepay: 5_000 * 1e18, - amountRepaid: 4_471.766388200619360129 * 1e18, + amountRepaid: 4_471.766388200619361301 * 1e18, collateralToPull: 3, newLup: MAX_PRICE }); @@ -679,12 +679,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619360129 * 1e18, + borrowerDebt: 4_471.766388200619361301 * 1e18, borrowerCollateral: 0.300997199476505990 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.258770970502146036 * 1e18 @@ -706,7 +706,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _borrower, borrower: _borrower, amountToRepay: 5_000 * 1e18, - amountRepaid: 4_471.766388200619360129 * 1e18, + amountRepaid: 4_471.766388200619361301 * 1e18, collateralToPull: 0, newLup: MAX_PRICE }); @@ -745,8 +745,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 3_784.974921636245059251 * 1e18, collateral: 1.699002800523494010 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775900 * 1e18 + deposit: 1175, + exchangeRate: 1.717106505794775901 * 1e18 }); _assertBucket({ index: 6051, @@ -836,12 +836,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 0, - exchangeRate: 0.999999999999999991 * 1e18 + deposit: 9201, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9_904.062307087997095630 * 1e18, + borrowerDebt: 9_904.062307087997104829 * 1e18, borrowerCollateral: 1.978621813918401907 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.764215028898934136 * 1e18 @@ -858,13 +858,13 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, maxCollateral: 1, bondChange: 90.646484035657361618 * 1e18, - givenAmount: 9_904.062307087997095630 * 1e18, - collateralTaken: 0.468592638026133318 * 1e18, + givenAmount: 9_904.062307087997104828 * 1e18, + collateralTaken: 0.468592638026133319 * 1e18, isReward: false }); - assertEq(_quote.balanceOf(_borrower), 16_331.699340400048828763 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 15_330.036177464968645198 * 1e18); + assertEq(_quote.balanceOf(_borrower), 16_331.699340400048807627 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 15_330.036177464968654396 * 1e18); // borrower 2 repays entire debt and pulls collateral _repayDebt({ @@ -909,8 +909,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 0, - exchangeRate: 0.999999999999999991 * 1e18 + deposit: 9201, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBucket({ index: 2159, @@ -1004,7 +1004,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7_471.766388200619360126 * 1e18, + borrowerDebt: 7_471.766388200619358358 * 1e18, borrowerCollateral: 1.093169978399049364 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.556883685430732796 * 1e18 @@ -1035,11 +1035,11 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { kicker: _lender, index: 2000, collateralArbed: 0.161346274954730238 * 1e18, - quoteTokenAmount: 7_547.238775960221575885 * 1e18, - bondChange: 75.472387759602215759 * 1e18, + quoteTokenAmount: 7_547.238775960221574099 * 1e18, + bondChange: 75.472387759602215741 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 75.472387759602215759 * 1e18 + lpAwardKicker: 75.472387759602215741 * 1e18 }); _assertBorrower({ @@ -1074,9 +1074,9 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, - lpBalance: 40_075.472387759602215759 * 1e18, + lpBalance: 40_075.472387759602215741 * 1e18, collateral: 0.161346274954730238 * 1e18, - deposit: 32_528.233611799380639874 * 1e18, + deposit: 32_528.233611799380641641 * 1e18, exchangeRate: 1 * 1e18 }); _assertBucket({ @@ -1168,7 +1168,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7_471.766388200619360126 * 1e18, + borrowerDebt: 7_471.766388200619358358 * 1e18, borrowerCollateral: 1.093169978399049364 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.556883685430732796 * 1e18 @@ -1193,7 +1193,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 3_714.709153177962410149 * 1e18 + settledDebt: 3_714.709153177962409270 * 1e18 }); _assertBorrower({ diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol index da92f9550..2ad9744f3 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol @@ -292,12 +292,12 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertPool( PoolParams({ - htp: 7.749209044755361552 * 1e18, + htp: 7.749209044755361553 * 1e18, lup: 9.917184843435912074 * 1e18, poolSize: 73_004.347853838043123634 * 1e18, pledgedCollateral: 4 * 1e18, encumberedCollateral: 2.517692578855560848 * 1e18, - poolDebt: 24.968422683457442924 * 1e18, + poolDebt: 24.968422683457442926 * 1e18, actualUtilization: 0.000411524519658268 * 1e18, targetUtilization: 0.781984313351887130 * 1e18, minDebtAmount: 1.248421134172872146 * 1e18, @@ -310,9 +310,9 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 7.749209044755361553 * 1e18, + borrowerDebt: 7.749209044755361554 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 7.061045370627448273 * 1e18, + borrowert0Np: 7.061045370627448275 * 1e18, borrowerCollateralization: 1.279767365438131935 * 1e18 }); @@ -328,7 +328,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { totalBondEscrowed: 0.058535063145029754 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 7.749209044755361553 * 1e18, + thresholdPrice: 7.749209044755361554 * 1e18, neutralPrice: 0 }) ); From c4c857644efdccd11669f1f9422a54208e884ab4 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Wed, 21 Jun 2023 11:00:47 +0300 Subject: [PATCH 12/32] Set GH actions to use older foundry build, fix failing test (#900) --- .github/workflows/forge-test.yml | 2 +- tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/forge-test.yml b/.github/workflows/forge-test.yml index 3994b614b..6c0b7e391 100644 --- a/.github/workflows/forge-test.yml +++ b/.github/workflows/forge-test.yml @@ -21,7 +21,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly + version: nightly-cc5637a979050c39b3d06bc4cc6134f0591ee8d0 - name: Run Forge build run: | diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol index 3f39aa778..71bd2776b 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol @@ -1048,7 +1048,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _pool.addQuoteToken(913597152782868931694946846442, 2572, block.timestamp + 100); ERC20Pool(address(_pool)).drawDebt(actor, 456798576391434465847473423221, 7388, 170152459663184217402759609); - vm.warp(1689742127); + 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); From b14c243ba5b59de3167fe6ed0242d538991ba796 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 22 Jun 2023 08:35:15 +0300 Subject: [PATCH 13/32] Remove forge build dependency, add back Position and Rewards manager tests (#905) --- .github/workflows/forge-test.yml | 2 +- Makefile | 2 +- tests/forge/unit/Positions/CodearenaReports.t.sol | 2 +- tests/forge/unit/Positions/PositionManager.t.sol | 4 ++-- tests/forge/unit/Rewards/RewardsManager.t.sol | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/forge-test.yml b/.github/workflows/forge-test.yml index 6c0b7e391..3994b614b 100644 --- a/.github/workflows/forge-test.yml +++ b/.github/workflows/forge-test.yml @@ -21,7 +21,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 with: - version: nightly-cc5637a979050c39b3d06bc4cc6134f0591ee8d0 + version: nightly - name: Run Forge build run: | diff --git a/Makefile b/Makefile index 6bb1dde2d..add7a8466 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # (-include to ignore error if it does not exist) -include .env && source ./tests/forge/invariants/scenarios/scenario-${SCENARIO}.sh -CONTRACT_EXCLUDES="RegressionTest|Panic|RealWorld|Trading|Position|Rewards" +CONTRACT_EXCLUDES="RegressionTest|Panic|RealWorld|Trading" TEST_EXCLUDES="testLoad|invariant|test_regression" all: clean install build diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/Positions/CodearenaReports.t.sol index a6146bbbe..df64e5948 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/Positions/CodearenaReports.t.sol @@ -163,7 +163,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are reset diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol index 6591e0e68..cdd89f42d 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -942,7 +942,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are reset @@ -2831,7 +2831,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are reset diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index c4442d9e9..96da7b8bc 100644 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ b/tests/forge/unit/Rewards/RewardsManager.t.sol @@ -710,7 +710,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterTwo, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346922 * 1e18 + settledDebt: 9_891.935520844277346923 * 1e18 }); // bucket is insolvent, balances are reset From c64d47e1bbcbb55b492cfb98b8a400edf4262e5c Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Thu, 22 Jun 2023 11:06:24 +0530 Subject: [PATCH 14/32] Add stampLoan handler (#881) --- tests/forge/invariants/base/BasicInvariants.t.sol | 3 +++ tests/forge/invariants/base/LiquidationInvariants.t.sol | 3 +++ tests/forge/invariants/base/ReserveInvariants.t.sol | 3 +++ tests/forge/invariants/base/handlers/BasicPoolHandler.sol | 8 ++++++++ .../base/handlers/unbounded/UnboundedBasicPoolHandler.sol | 8 ++++++++ 5 files changed, 25 insertions(+) diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index 1867a192d..cacc1baba 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -458,6 +458,8 @@ abstract contract BasicInvariants is BaseInvariants { console.log("UBBasicHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); console.log("BBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); console.log("UBBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); + console.log("BBasicHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan")); + console.log("UBBasicHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.stampLoan")); console.log("--Liquidation--------"); console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); @@ -506,6 +508,7 @@ abstract contract BasicInvariants is BaseInvariants { IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + + IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.lenderKickAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction") + diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index b6206e521..19db71e26 100644 --- a/tests/forge/invariants/base/LiquidationInvariants.t.sol +++ b/tests/forge/invariants/base/LiquidationInvariants.t.sol @@ -169,6 +169,8 @@ abstract contract LiquidationInvariants is BasicInvariants { console.log("UBLiquidationHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); console.log("BLiquidationHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); console.log("UBLiquidationHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); + console.log("BLiquidationHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan")); + console.log("UBLiquidationHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.stampLoan")); console.log("--Kicker/Taker----"); console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); @@ -194,6 +196,7 @@ abstract contract LiquidationInvariants is BasicInvariants { IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + + IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction") + diff --git a/tests/forge/invariants/base/ReserveInvariants.t.sol b/tests/forge/invariants/base/ReserveInvariants.t.sol index ab9ed8bb8..f1314e013 100644 --- a/tests/forge/invariants/base/ReserveInvariants.t.sol +++ b/tests/forge/invariants/base/ReserveInvariants.t.sol @@ -57,6 +57,8 @@ abstract contract ReserveInvariants is LiquidationInvariants { console.log("UBBasicHandler.pledgeCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pledgeCollateral")); console.log("BBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral")); console.log("UBBasicHandler.pullCollateral ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.pullCollateral")); + console.log("BBasicHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan")); + console.log("UBBasicHandler.stampLoan ", IBaseHandler(_handler).numberOfCalls("UBBasicHandler.stampLoan")); console.log("--Kicker/Taker----"); console.log("BLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction")); console.log("UBLiquidationHandler.kickAuction ", IBaseHandler(_handler).numberOfCalls("UBLiquidationHandler.kickAuction")); @@ -86,6 +88,7 @@ abstract contract ReserveInvariants is LiquidationInvariants { IBaseHandler(_handler).numberOfCalls("BBasicHandler.pullCollateral") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.drawDebt") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.repayDebt") + + IBaseHandler(_handler).numberOfCalls("BBasicHandler.stampLoan") + IBaseHandler(_handler).numberOfCalls("BBasicHandler.transferLps") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.kickAuction") + IBaseHandler(_handler).numberOfCalls("BLiquidationHandler.takeAuction") + diff --git a/tests/forge/invariants/base/handlers/BasicPoolHandler.sol b/tests/forge/invariants/base/handlers/BasicPoolHandler.sol index f691f038b..82c7db254 100644 --- a/tests/forge/invariants/base/handlers/BasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/BasicPoolHandler.sol @@ -84,6 +84,14 @@ abstract contract BasicPoolHandler is UnboundedBasicPoolHandler { _transferLps(_actor, receiver, _lenderBucketIndex); } + function stampLoan( + uint256 actorIndex_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BBasicHandler.stampLoan']++; + _stampLoan(); + } + /*******************************/ /*** Prepare Tests Functions ***/ /*******************************/ diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol index b41d813ab..927747d5b 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol @@ -176,6 +176,14 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { } } + function _stampLoan() internal updateLocalStateAndPoolInterest { + numberOfCalls['UBBasicHandler.stampLoan']++; + try _pool.stampLoan() { + } catch (bytes memory err) { + _ensurePoolError(err); + } + } + function _drawDebt( uint256 amount_ ) internal virtual; From 29e34dca033955d2063579c31713185e6c0b3c48 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:59:56 +0300 Subject: [PATCH 15/32] Sherlock-106: Settle should account the 72 hour when reverting with AuctionNotClearable (#902) https://github.com/sherlock-audit/2023-04-ajna-judging/blob/main/106.md --- src/libraries/external/SettlerActions.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/external/SettlerActions.sol b/src/libraries/external/SettlerActions.sol index 3a1585ba4..b42888023 100644 --- a/src/libraries/external/SettlerActions.sol +++ b/src/libraries/external/SettlerActions.sol @@ -110,7 +110,7 @@ library SettlerActions { if (kickTime == 0) revert NoAuction(); Borrower memory borrower = loans_.borrowers[params_.borrower]; - if ((block.timestamp - kickTime < 72 hours) && (borrower.collateral != 0)) revert AuctionNotClearable(); + if ((block.timestamp - kickTime <= 72 hours) && (borrower.collateral != 0)) revert AuctionNotClearable(); result_.debtPreAction = borrower.t0Debt; result_.collateralPreAction = borrower.collateral; From a8db4608ea3bb8fb1ebb4f0293fce48e0f5a3430 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Tue, 27 Jun 2023 11:38:41 +0300 Subject: [PATCH 16/32] Sherlock-44: assert owners of position NFT in unstake / emergencyUnstake before and after action taken (#912) --- tests/forge/unit/Rewards/RewardsDSTestPlus.sol | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol b/tests/forge/unit/Rewards/RewardsDSTestPlus.sol index c67482f11..e14c360be 100644 --- a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol +++ b/tests/forge/unit/Rewards/RewardsDSTestPlus.sol @@ -7,8 +7,8 @@ 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'; @@ -98,6 +98,8 @@ abstract contract RewardsDSTestPlus is IRewardsManagerEvents, ERC20HelperContrac uint256[] memory indexes, uint256 updateExchangeRatesReward ) internal { + // token owner is Rewards manager + assertEq(ERC721(address(_positionManager)).ownerOf(tokenId), address(_rewardsManager)); // when the token is unstaked updateExchangeRates emits vm.expectEmit(true, true, true, true); @@ -114,6 +116,9 @@ abstract contract RewardsDSTestPlus is IRewardsManagerEvents, ERC20HelperContrac 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); @@ -124,10 +129,16 @@ abstract contract RewardsDSTestPlus is IRewardsManagerEvents, ERC20HelperContrac address pool, uint256 tokenId ) internal { - // when the token is unstaked in emergency mode then no cliam event is emitted + // 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( From a667027e333025c67e2eafdc415438ada92e327b Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Tue, 27 Jun 2023 21:28:11 -0400 Subject: [PATCH 17/32] Proof unable to claim rightful rewards post bucket bankruptcy (#911) * proof that calling memorialize on the same tokenID doesn't work * minter one gets no rewards when they should receive rewards * removed invariant check * cleaned up comments and removed fixme * removed console.sol --------- Co-authored-by: Ian Harvey --- tests/forge/unit/Rewards/RewardsManager.t.sol | 375 ++++++++++++++++++ 1 file changed, 375 insertions(+) diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index 96da7b8bc..84b202d30 100644 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ b/tests/forge/unit/Rewards/RewardsManager.t.sol @@ -9,6 +9,7 @@ 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'; @@ -786,6 +787,380 @@ contract RewardsManagerTest is RewardsHelperContract { 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.007075096372721386 * 1e18 + }); + assertEq(_ajnaToken.balanceOf(_updater), 0.007075096372721386 * 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.283003854923906684 * 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.021225289119669282 * 1e18 + }); + assertEq(_ajnaToken.balanceOf(_updater2), .021225289119669282 * 1e18); + + // assert minterOne has rewards to be claimed + uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); + assertEq(rewardsEarned, 0.226403083939125347 * 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.511985000906831402 * 1e18 + }); + + assertEq(_ajnaToken.balanceOf(_updater), 3.519060097279552788 * 1e18); + + _assertBurn({ + pool: address(_pool), + epoch: 2, + timestamp: block.timestamp - 24 hours, + burned: 140.762403891199659050 * 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.160572158484729706 * 1e18 + }); + assertEq(_ajnaToken.balanceOf(_updater2), 3.181797447604398988 * 1e18); + + // assert minterOne has more rewards to be claimed + rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); + assertEq(rewardsEarned, 66.951974677854736430 * 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); + (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); + + // 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_004.264567230919901856 * 1e18, + borrowerCollateralization: 0.990376081445383032 * 1e18 + }); + + _kick({ + from: _minterTwo, + borrower: _borrower, + debt: 25_945.020148443326455492 * 1e18, + collateral: 25.921751033498703620 * 1e18, + bond: 256.563858081021769646 * 1e18, + transferAmount: 256.563858081021769646 * 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: 0 * 1e18, + givenAmount: 0 * 1e18, + collateralTaken: 25.921751033498703620 * 1e18, + isReward: true + }); + + _settle({ + from: _minterTwo, + borrower: _borrower, + maxDepth: 10, + settledDebt: 26_954.947917202244023854 * 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 + }); + } function testClaimRewardsCap() external { skip(10); From bc4ae5553338a3acda4578301f3d16da27d66929 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Wed, 28 Jun 2023 20:23:20 +0300 Subject: [PATCH 18/32] Sherlock-88: In `moveQuoteToken` ensure pool debt is less than deposits (if deposit fee applied) (#901) * In moveQuoteToken ensure pool debt is not less than deposits (if deposit fee applied) * added test (#910) * added test * cleanup --------- Co-authored-by: Ian Harvey --------- Co-authored-by: Ian Harvey Co-authored-by: Ian Harvey --- src/libraries/external/LenderActions.sol | 13 +- .../forge/unit/ERC20Pool/ERC20DSTestPlus.sol | 11 ++ .../unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 148 +++++++++++++++++- 3 files changed, 169 insertions(+), 3 deletions(-) diff --git a/src/libraries/external/LenderActions.sol b/src/libraries/external/LenderActions.sol index 7d384da5c..5f92bcba5 100644 --- a/src/libraries/external/LenderActions.sol +++ b/src/libraries/external/LenderActions.sol @@ -311,7 +311,18 @@ library LenderActions { vars.htp = Maths.wmul(params_.thresholdPrice, poolState_.inflator); // check loan book's htp against new lup, revert if move drives LUP below HTP - if (params_.fromIndex < params_.toIndex && vars.htp > lup_) revert LUPBelowHTP(); + if ( + params_.fromIndex < params_.toIndex + && + ( + // check loan book's htp doesn't exceed new lup + vars.htp > lup_ + || + // ensure that pool debt < deposits after move + // this can happen if deposit fee is applied when moving amount + (poolState_.debt != 0 && poolState_.debt > Deposits.treeSum(deposits_)) + ) + ) revert LUPBelowHTP(); // update lender and bucket LP balance in from bucket vars.fromBucketRemainingLP = vars.fromBucketLP - fromBucketRedeemedLP_; diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index c81d81c49..ea10a15de 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -722,6 +722,17 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { ERC20Pool(address(_pool)).drawDebt(from, amount, indexLimit, 0); } + function _assertLupBelowHTPRevert( + address from, + uint256 amount, + uint256 fromIndex, + uint256 toIndex + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.LUPBelowHTP.selector); + ERC20Pool(address(_pool)).moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + } + } abstract contract ERC20HelperContract is ERC20DSTestPlus { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index f3da70f0d..7b059758c 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -21,8 +21,8 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { _lender = makeAddr("lender"); _lender1 = makeAddr("bidder"); - _mintCollateralAndApproveTokens(_borrower, 100 * 1e18); - _mintCollateralAndApproveTokens(_borrower2, 200 * 1e18); + _mintCollateralAndApproveTokens(_borrower, 5_000 * 1e18); + _mintCollateralAndApproveTokens(_borrower2, 5_000 * 1e18); _mintQuoteAndApproveTokens(_lender, 200_000 * 1e18); _mintQuoteAndApproveTokens(_lender1, 200_000 * 1e18); @@ -913,6 +913,150 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { }); } + function testPoolMoveQuoteTokenRevertOnHTPLUP() external { + + _addLiquidity({ + from: _lender, + amount: 40_000 * 1e18, + index: 2549, + lpAward: 40_000 * 1e18, + newLup: MAX_PRICE + }); + _addLiquidity({ + from: _lender, + amount: 10_000 * 1e18, + index: 2550, + lpAward: 10_000 * 1e18, + newLup: MAX_PRICE + }); + _addLiquidity({ + from: _lender, + amount: 20_000 * 1e18, + index: 2551, + lpAward: 20_000 * 1e18, + newLup: MAX_PRICE + }); + + _addLiquidity({ + from: _lender, + amount: 20_000 * 1e18, + index: 2540, + lpAward: 20_000 * 1e18, + newLup: MAX_PRICE + }); + _assertLenderLpBalance({ + lender: _lender, + index: 2549, + lpBalance: 40_000 * 1e18, + depositTime: _startTime + }); + _assertLenderLpBalance({ + lender: _lender, + index: 2540, + lpBalance: 20_000 * 1e18, + depositTime: _startTime + }); + _assertLenderLpBalance({ + lender: _lender, + index: 2552, + lpBalance: 0, + depositTime: 0 + }); + + uint256 snapshot = vm.snapshot(); + + _drawDebt({ + from: _borrower, + borrower: _borrower, + amountToBorrow: 89_000 * 1e18, + limitIndex: 7_388, + collateralToPledge: 30 * 1e18, + newLup: 2_995.912459898389633881 * 1e18 + }); + + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 89_085.576923076923118000 * 1e18, + borrowerCollateral: 30.0 * 1e18, + borrowert0Np: 3_117.995192307692309130 * 1e18, + borrowerCollateralization: 1.008888047888587643 * 1e18 + }); + + _drawDebt({ + from: _borrower2, + borrower: _borrower2, + amountToBorrow: 900 * 1e18, + limitIndex: 7_388, + collateralToPledge: 5_000 * 1e18, + newLup: 2_995.912459898389633881 * 1e18 + }); + + _assertPool( + PoolParams({ + htp: 2_969.519230769230770600 * 1e18, + lup: 2_995.912459898389633881 * 1e18, + poolSize: 90_000.000000000000000000 * 1e18, + pledgedCollateral: 5_030.0 * 1e18, + encumberedCollateral: 30.036405773600046352 * 1e18, + poolDebt: 89_986.442307692307733800 * 1e18, + actualUtilization: 0 * 1e18, + targetUtilization: 1.0 * 1e18, + minDebtAmount: 4_499.322115384615386690 * 1e18, + loans: 2, + maxBorrower: _borrower, + interestRate: 0.050000000000000000 * 1e18, + interestRateUpdate: _startTime + }) + ); + + // ensure htp > lup to fire error + _assertLupBelowHTPRevert({ + from: _lender, + fromIndex: 2549, + toIndex: 3000, + amount: 40_000 * 1e18 + }); + + vm.revertTo(snapshot); + + _drawDebt({ + from: _borrower, + borrower: _borrower, + amountToBorrow: 89_913 * 1e18, + limitIndex: 7_388, + collateralToPledge: 5_000 * 1e18, + newLup: 2_995.912459898389633881 * 1e18 + }); + + _assertPool( + PoolParams({ + htp: 17.999890961538461547 * 1e18, + lup: 2_995.912459898389633881 * 1e18, + poolSize: 90_000.000000000000000000 * 1e18, + pledgedCollateral: 5000.0 * 1e18, + encumberedCollateral: 30.040749191565083066 * 1e18, + poolDebt: 89_999.454807692307733806 * 1e18, + actualUtilization: 0 * 1e18, + targetUtilization: 1.0 * 1e18, + minDebtAmount: 8_999.945480769230773381 * 1e18, + loans: 1, + maxBorrower: _borrower, + interestRate: 0.050000000000000000 * 1e18, + interestRateUpdate: _startTime + }) + ); + + skip(50 days); + + // htp > lup && debt > deposit + _assertLupBelowHTPRevert({ + from: _lender, + fromIndex: 2549, + toIndex: 3000, + amount: 40_000 * 1e18 + }); + } + function testPoolMoveQuoteTokenWithDifferentTime() external tearDown { _addLiquidity({ from: _lender, From 7228f92f98f3c959f8e1486923e1e6189b63484a Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Wed, 28 Jun 2023 20:23:34 +0300 Subject: [PATCH 19/32] Make decrease rate condition inline with increase (#903) --- src/libraries/external/PoolCommons.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index f9c89f954..020f331d9 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -294,7 +294,7 @@ library PoolCommons { if (4 * (tu - mau102) < (((tu + mau102 - 1e18) / 1e9) ** 2) - 1e18) { newInterestRate_ = Maths.wmul(poolState_.rate, INCREASE_COEFFICIENT); // decrease rates if 4*(tu-mau) > 1-(tu+mau-1)^2 - } else if (4 * (tu - mau) > 1e18 - ((tu + mau - 1e18) ** 2) / 1e18) { + } else if (4 * (tu - mau) > 1e18 - ((tu + mau - 1e18) / 1e9) ** 2) { newInterestRate_ = Maths.wmul(poolState_.rate, DECREASE_COEFFICIENT); } From d4c9ad2687c6f0ef23aae47bfef29bdd978bd164 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Wed, 28 Jun 2023 22:53:46 +0530 Subject: [PATCH 20/32] Increment nonce on approve to avoid signature replay (#906) --- src/base/PermitERC721.sol | 15 +++++++++++ .../unit/Positions/PositionManager.t.sol | 26 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/base/PermitERC721.sol b/src/base/PermitERC721.sol index 91ec8ee04..188df1f3f 100644 --- a/src/base/PermitERC721.sol +++ b/src/base/PermitERC721.sol @@ -256,6 +256,21 @@ abstract contract PermitERC721 is ERC721, IPermit { _nonces[tokenId]++; } + /** + * @notice _approve override to be able to increment the permit nonce + * @inheritdoc ERC721 + */ + function _approve( + address to, + uint256 tokenId + ) internal virtual override { + // increment the permit nonce of this tokenId to ensure it can't be reused + _incrementNonce(tokenId); + + // Approve the NFT to the to address + super._approve(to, tokenId); + } + /** * @notice _transfer override to be able to increment the permit nonce * @inheritdoc ERC721 diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol index cdd89f42d..7dd06eae5 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -1330,7 +1330,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract spenderContract.transferFromWithPermit(address(recipientContract), tokenId, deadline, signature); // check nonces increment with transfer - assertEq(_positionManager.nonces(tokenId), 1); + assertEq(_positionManager.nonces(tokenId), 2); // check retrieving token nonces for non existent tokens will revert vm.expectRevert(IPermit.NonExistentToken.selector); @@ -1379,6 +1379,28 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.nonces(tokenId), 0); } + function testPermitSignatureReplayReverts() external { + // generate addresses and set test params + (address testMinter, uint256 minterPrivateKey) = makeAddrAndKey("testMinter"); + address testSpender = makeAddr("spender"); + + changePrank(testMinter); + uint256 tokenId = _mintNFT(testMinter, testMinter, address(_pool)); + assertEq(_positionManager.ownerOf(tokenId), testMinter); + + uint256 deadline = block.timestamp + 1 days; + bytes memory signature = _getPermitSig(testSpender, tokenId, 0, deadline, minterPrivateKey); + + _positionManager.permit(testSpender, tokenId, deadline, signature); + + // minter revokes approval + _positionManager.approve(address(0), tokenId); + + // spender tries to get approval with the same signature + vm.expectRevert(IPermit.NotAuthorized.selector); + _positionManager.permit(testSpender, tokenId, deadline, signature); + } + /** * @notice Tests permit signatures are invalid after each transfer due to incremented nonce. */ @@ -1442,7 +1464,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.ownerOf(tokenId), testMinter); // check nonces after transfer - assertEq(_positionManager.nonces(tokenId), 2); + assertEq(_positionManager.nonces(tokenId), 3); } /** From 2f18a936c9ca09933f13e7cf4879303b7d6f228d Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Wed, 28 Jun 2023 23:07:46 +0530 Subject: [PATCH 21/32] Add test to check multiple unstake in same epoch has no effect on staking rewards (#913) --- tests/forge/unit/Rewards/RewardsManager.t.sol | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index 84b202d30..0bed3241a 100644 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ b/tests/forge/unit/Rewards/RewardsManager.t.sol @@ -2344,6 +2344,180 @@ contract RewardsManagerTest is RewardsHelperContract { } + 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: 408.996298826179924310 * 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.449814941308995996 * 1e18 + }); + assertEq(_ajnaToken.balanceOf(_updater), 20.449814941308995996 * 1e18); + + uint256 rewardsEarnedFirstEpoch = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); + assertEq(rewardsEarnedFirstEpoch, 204.498149413089959965 * 1e18); + + uint256 totalRewardEarned = 374.969146539701943260 * 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: 749.938293079403940202 * 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.047099712661198328 * 1e18 + }); + + uint256 newRewardsEarned = totalRewardEarned - rewardsEarnedFirstEpoch; + + // 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: 749.938293079403940202 * 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.047099712661198328 * 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 ***/ /********************/ From 61470bf5e23cb621b2f890674534a757661c4b29 Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Thu, 29 Jun 2023 00:24:57 +0530 Subject: [PATCH 22/32] Sherlock-31: Add supportsInterface for EIP-4494 compliance (#907) --- src/base/PermitERC721.sol | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/base/PermitERC721.sol b/src/base/PermitERC721.sol index 188df1f3f..7a7401a51 100644 --- a/src/base/PermitERC721.sol +++ b/src/base/PermitERC721.sol @@ -34,6 +34,15 @@ interface IPermit { /*** External Functions ***/ /**************************/ + function DOMAIN_SEPARATOR() external view returns (bytes32); + + /** + * @notice Allows to retrieve current nonce for token. + * @param tokenId token id + * @return current token nonce + */ + function nonces(uint256 tokenId) external view returns (uint256); + /** * @notice `EIP-4494` permit to approve by way of owner signature. */ @@ -156,6 +165,19 @@ abstract contract PermitERC721 is ERC721, IPermit { _approve(spender_, tokenId_); } + /** + * @notice Query if a contract implements an interface. + * @param interfaceId The interface identifier. + * @return `true` if the contract implements `interfaceId` and `interfaceId` is not 0xffffffff, `false` otherwise + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override returns (bool) { + return + interfaceId == type(IPermit).interfaceId || // 0x5604e225 + super.supportsInterface(interfaceId); + } + /**************************/ /*** Internal Functions ***/ /**************************/ From 5ba6d873e1afb565d11a8d9b49d0ae451516c230 Mon Sep 17 00:00:00 2001 From: mattcushman <36414299+mattcushman@users.noreply.github.com> Date: Wed, 28 Jun 2023 17:23:08 -0400 Subject: [PATCH 23/32] Sherlock-110: revert add settleable (#909) * Revert addQuoteToken when there is a settleable auction, plus some work on the baselines * Fixed testSettlePartialDebtSubsetPool, some questions * Fix tests: testSettleZeroExchangeRateResidualBankruptcy, testReserveAuctionNoFunds * Update docs, remove comment * Update test to show bucket exchange rate before settles --------- Co-authored-by: mwc Co-authored-by: grandizzy --- docs/Functions.md | 2 + src/base/Pool.sol | 3 + .../ERC20PoolLiquidationsLenderKick.t.sol | 20 +- .../ERC20PoolLiquidationsSettle.t.sol | 116 +++-------- .../ERC20Pool/ERC20PoolReserveAuction.t.sol | 40 ++-- .../ERC721PoolLiquidationsSettleAuction.t.sol | 184 ++++++++++-------- 6 files changed, 172 insertions(+), 193 deletions(-) diff --git a/docs/Functions.md b/docs/Functions.md index 49445287b..6a1ee5799 100644 --- a/docs/Functions.md +++ b/docs/Functions.md @@ -25,6 +25,8 @@ - pool inflator and inflatorUpdate state reverts on: + - block timestamp greater than expiry TransactionExpired() + - head auction not cleared AuctionNotCleared() - LenderActions.addQuoteToken(): - invalid bucket index InvalidIndex() - same block when bucket becomes insolvent BucketBankruptcyBlock() diff --git a/src/base/Pool.sol b/src/base/Pool.sol index fba318b41..51310167d 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -149,6 +149,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 expiry_ ) external override nonReentrant returns (uint256 bucketLP_) { _revertAfterExpiry(expiry_); + + _revertIfAuctionClearable(auctions, loans); + PoolState memory poolState = _accruePoolInterest(); // round to token precision diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol index d8c7b1d14..fc2b976c7 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol @@ -1152,15 +1152,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { }) ); - // add more liquidity to settle auction - _mintQuoteAndApproveTokens(_lender1, 40_000 * 1e18); - _addLiquidity({ - from: _lender1, - amount: 40_000 * 1e18, - index: 2500, - lpAward: 39_985.826748556412134387 * 1e18, - newLup: 3_863.654368867279344664 * 1e18 - }); + _settle({ from: _lender1, @@ -1212,8 +1204,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 49_645.701045977641587831 * 1e18, - pledgedCollateral: 4_973.729764048432419297 * 1e18, + poolSize: 9_645.701045977641587831 * 1e18, + pledgedCollateral: 4_973.703521110015138686 * 1e18, encumberedCollateral: 0, poolDebt: 0, actualUtilization: 0, @@ -1229,8 +1221,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: 2500, - lpBalance: 89_985.826748556412134387 * 1e18, - depositTime: _startTime + 80 hours + lpBalance: 50_000.000000000000000000 * 1e18, + depositTime: _startTime }); // assert lender1 as a kicker _assertKicker({ @@ -1256,7 +1248,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower3, borrowerDebt: 0, - borrowerCollateral: 994.751412316543869246 * 1e18, + borrowerCollateral: 994.725169378126588635 * 1e18, borrowert0Np: 21.125293269230769068 * 1e18, borrowerCollateralization: 1 * 1e18 }); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index bbb509694..265adb912 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -680,6 +680,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowerCollateralization: 0.974363394700228467 * 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.367201799558744044 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + // take entire collateral _take({ from: _lender, @@ -716,15 +733,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { index: _i9_52 }); - // 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.367201799558744044 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertLenderLpBalance({ lender: _lender1, index: _i9_91, @@ -732,16 +740,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime + 100 days + 10 hours }); - // adding to a different bucket for testing move in same block with bucket bankruptcy - _addLiquidityWithPenalty({ - from: _lender1, - amount: 100 * 1e18, - amountAdded: 99.987671232876712300 * 1e18, - index: _i9_52, - lpAward: 99.987671232876712300 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - // 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({ @@ -751,7 +749,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowert0Np: 10.307611531622595991 * 1e18, borrowerCollateralization: 0 }); - + assertTrue(block.timestamp - kickTime < 72 hours); // assert auction was kicked less than 72 hours ago // LP forfeited when forgive bad debt should be reflected in BucketBankruptcy event @@ -889,7 +887,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); } - function testSettleZeroExchangeRateResidualBankruptcy() external { + function testSettleZeroExchangeRateResidualBankruptcy() external tearDown { // Borrower2 borrows _borrow({ from: _borrower2, @@ -968,6 +966,15 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrowerCollateralization: 0.974363394700228467 * 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.367201799558744044 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); + // take entire collateral _take({ from: _lender, @@ -979,15 +986,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { isReward: true }); - // 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.367201799558744044 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - _assertLenderLpBalance({ lender: _lender1, index: _i9_91, @@ -995,34 +993,9 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime + 100 days + 10 hours }); - // adding to a different bucket for testing move in same block with bucket bankruptcy - _addLiquidityWithPenalty({ - from: _lender1, - amount: 100 * 1e18, - amountAdded: 99.987671232876712300 * 1e18, - index: _i9_52, - lpAward: 99.987671232876712300 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - (uint256 reserves, , , ,) = _poolUtils.poolReservesInfo(address(_pool)); - - // Add 10 more quote token than would be enough to cover debt, with reserves - _addLiquidity({ - from: _lender1, - amount: 2_884.311069344372084707 * 1e18 + 10 - reserves, - index: _i9_81, - lpAward: 2_020.307252493359351053 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - uint256 bucket1Deposit = 2_112.736560735960384000 * 1e18; - uint256 bucket2Deposit = 7_065.014537346601772213 * 1e18; - uint256 debtToSettle = 10_028.889031920233428709 * 1e18; - _assertBorrower({ borrower: _borrower2, - borrowerDebt: debtToSettle, + borrowerDebt: 10_028.889031920233428709 * 1e18, borrowerCollateral: 0, borrowert0Np: 10.307611531622595991 * 1e18, borrowerCollateralization: 0 @@ -1032,23 +1005,13 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { index: _i9_91, lpBalance: 2_099.367201799558744044 * 1e18, collateral: 0, - deposit: bucket1Deposit, - exchangeRate: 1.006368280367980193 * 1e18 - }); - - _assertBucket({ - index: _i9_81, - lpBalance: 7_020.307252493359351053 * 1e18, - collateral: 0, - deposit: bucket2Deposit, + deposit: 2_112.736560735960384000 * 1e18, exchangeRate: 1.006368280367980193 * 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.367201799558744044 * 1e18); - vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_81, 7_020.307252493359351053 * 1e18); _settle({ from: _lender, borrower: _borrower2, @@ -1065,25 +1028,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { exchangeRate: 1 * 1e18 }); - skip(1 hours); - // bucket is insolvent, balances are resetted - _assertBucketAssets({ - index: _i9_81, - lpBalance: 0, // bucket is bankrupt - collateral: 0, - deposit: 0, - exchangeRate: 1 * 1e18 - }); - - // add to bankrupt bucket with deposit to enable tearDown - _addLiquidity({ - from: _lender1, - amount: 1 * 1e18, - index: _i9_81, - lpAward: 1 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol index bd4e9e6e6..c7d28bf7e 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol @@ -178,34 +178,52 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { changePrank(_actor2); pool.updateInterest(); - pool.take(_actor3, 506252187686489913395361995, _actor2, new bytes(0)); + vm.expectRevert(IPoolErrors.NoReserves.selector); + pool.kickReserveAuction(); + // pool balance remains the same assertEq(_quote.balanceOf(address(pool)), 1017); - 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); + + uint256 initialPoolBalance = 103934; + uint256 initialAvailableAmount = 102917; + + assertEq(_quote.balanceOf(address(pool)), initialPoolBalance); + assertEq(_availableQuoteToken(), initialAvailableAmount); - // add tokens to have enough balance to kick new reserves auction - pool.addQuoteToken(100, 2572, block.timestamp + 1); pool.kickReserveAuction(); - // pool balance diminished by reward given to reserves kicker - assertEq(_quote.balanceOf(address(pool)), 1116); - assertEq(_availableQuoteToken(), 0); + + uint256 kickerReward = 12; + uint256 claimableTokens = 1229; + + ( , , uint256 claimable, , ) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(claimable, claimableTokens); + + // pool balance diminished by reward given to reserves kicker (12) + assertEq(_quote.balanceOf(address(pool)), initialPoolBalance - kickerReward); + // available quote token (available to remove / draw debt from) diminished by kicker reward + claimable tokens + assertEq(_availableQuoteToken(), initialAvailableAmount - (kickerReward + claimableTokens)); + skip(24 hours); // mint and approve ajna tokens for taker deal(address(_ajna), _actor3, 1e45); ERC20(address(_ajna)).approve(address(_pool), type(uint256).max); - pool.takeReserves(787); + pool.takeReserves(claimableTokens); - assertEq(_quote.balanceOf(address(pool)), 1017); - assertEq(_availableQuoteToken(), 0); + // quote token balance diminished by quote token taken from reserve auction + assertEq(_quote.balanceOf(address(pool)), initialPoolBalance - kickerReward - claimableTokens); + // available quote token (available to remove / draw debt from) is not modified + assertEq(_availableQuoteToken(), initialAvailableAmount - (kickerReward + claimableTokens)); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index f262f1a17..599e903c4 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -112,10 +112,38 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { } function testSettlePartialDebtSubsetPool() external tearDown { + _assertBucket({ + index: 2500, + lpBalance: 8_000 * 1e18, + collateral: 0, + deposit: 13_734.486139425783008000 * 1e18, + exchangeRate: 1.716810767428222876 * 1e18 + }); + // the 2 token ids are owned by borrower before settle assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 5_000 * 1e18, + index: 2499 + }); + + // adding more liquidity to settle all auctions + _addLiquidityNoEventCheck({ + from: _lender, + amount: 20_000 * 1e18, + index: 2500 + }); + + // lender adds liquidity in min bucket to and merge / remove the other NFTs + _addLiquidityNoEventCheck({ + from: _lender, + amount: 100 * 1e18, + index: MAX_FENWICK_INDEX + }); + // skip to make loans clearable skip(80 hours); @@ -124,13 +152,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 10_195.576288428866513838 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750385377189985519 * 1e18 - }); - - _addLiquidityNoEventCheck({ - from: _lender, - amount: 5_000 * 1e18, - index: 2499 + borrowerCollateralization: 0.757907990596315111 * 1e18 }); // first settle call settles partial borrower debt @@ -138,24 +160,24 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_485.081590832967738263 * 1e18 + settledDebt: 2_485.576684127234225966 * 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.287673250019003865 * 1e18, + collateral: 1.287929788232333535 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000001 * 1e18 + exchangeRate: 1.000199226172731231 * 1e18 }); // partial borrower debt is settled, borrower collateral decreased with the amount used to settle debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_195.576288428866513840 * 1e18, - borrowerCollateral: 0.712326749980996135 * 1e18, + borrowerDebt: 5_194.580157565210365777 * 1e18, + borrowerCollateral: 0.712070211767666465 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.527081453163032823 * 1e18 + borrowerCollateralization: 0.529627631336027971 * 1e18 }); _assertCollateralInvariants(); @@ -173,18 +195,11 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(_collateral.ownerOf(53), address(_pool)); assertEq(_collateral.ownerOf(73), address(_pool)); - // adding more liquidity to settle all auctions - _addLiquidityNoEventCheck({ - from: _lender, - amount: 20_000 * 1e18, - index: 2000 - }); - _settle({ from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_582.286197628570725612 * 1e18 + settledDebt: 2_258.399659496838436164 * 1e18 }); // no token id left in borrower token ids array @@ -195,18 +210,33 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 1); _assertBucket({ - index: 2000, - lpBalance: 20_000 * 1e18, - collateral: 0.111071996695171075 * 1e18, - deposit: 14_804.423711571133486162 * 1e18, - exchangeRate: 1.000000000000000002 * 1e18 + index: 2500, + lpBalance: 19_649.507551702938715450 * 1e18, + collateral: 0.712070211767666465 * 1e18, + deposit: 30_990.013747352002213011 * 1e18, + exchangeRate: 1.717152801066721367 * 1e18 + }); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 650.665648223383086331 * 1e18, + borrowerCollateral: 0, + borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowerCollateralization: 0 + }); + + _settle({ + from: _lender, + borrower: _borrower, + maxDepth: 5, + settledDebt: 323.391444837465801745 * 1e18 }); + _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 1 * 1e18 + borrowerCollateralization: 1.0 * 1e18 }); _assertCollateralInvariants(); @@ -219,60 +249,53 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBucket({ - index: 2000, - lpBalance: 20_000 * 1e18, - collateral: 0.329304013831793309 * 1e18, - deposit: 4_596.260291921984421072 * 1e18, - exchangeRate: 1.000000000000000003 * 1e18 + index: 2500, + lpBalance: 19_649.507551702938715450 * 1e18, + collateral: 3.354170784195916811 * 1e18, + deposit: 20_131.184679479470055267 * 1e18, + exchangeRate: 1.684039215572972305 * 1e18 }); _assertBucket({ index: 2499, lpBalance: 5_000 * 1e18, - collateral: 1.287673250019003865 * 1e18, + collateral: 1.287929788232333535 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000001 * 1e18 + exchangeRate: 1.000199226172731231 * 1e18 }); _assertBucket({ index: 7388, - lpBalance: 0.000000138075849129 * 1e18, - collateral: 1.383022736149202826 * 1e18, - deposit: 0, - exchangeRate: 1.000000000003575156 * 1e18 + lpBalance: 99.984931542573546395 * 1e18, + collateral: 0.357899427571749654 * 1e18, + deposit: 100.004851122084218862 * 1e18, + exchangeRate: 1.000199226172731231 * 1e18 }); - // borrower 2 can claim 2 NFT tokens (id 51 and 53) after settle + _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 2 * 1e18, + borrowerCollateral: 0, borrowert0Np: 1_769.243311298076895206 * 1e18, borrowerCollateralization: 1 * 1e18 }); _assertCollateralInvariants(); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower2, 0), 51); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower2, 1), 53); - // tokens used to 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)).bucketTokenIds(2), 73); + assertEq(ERC721Pool(address(_pool)).bucketTokenIds(3), 53); + assertEq(ERC721Pool(address(_pool)).bucketTokenIds(4), 51); // lender can claim 1 NFTs from bucket 2499 changePrank(_lender); _pool.removeCollateral(1, 2499); - // lender adds liquidity in min bucket and merge / removes the other NFTs - _addLiquidityNoEventCheck({ - from: _lender, - amount: 100 * 1e18, - index: MAX_FENWICK_INDEX - }); - uint256[] memory removalIndexes = new uint256[](3); - removalIndexes[0] = 2000; - removalIndexes[1] = 2499; + removalIndexes[0] = 2499; + removalIndexes[1] = 2500; removalIndexes[2] = MAX_FENWICK_INDEX; + _mergeOrRemoveCollateral({ from: _lender, toIndex: MAX_FENWICK_INDEX, @@ -283,34 +306,18 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); // the 3 NFTs claimed from pool are owned by lender - assertEq(_collateral.ownerOf(1), _lender); - assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(73), _lender); - assertEq(_collateral.ownerOf(51), address(_pool)); - assertEq(_collateral.ownerOf(53), address(_pool)); - - // borrower 2 can pull 2 NFTs from pool - _repayDebtNoLupCheck({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 0, - amountRepaid: 0, - collateralToPull: 2 - }); - - assertEq(_collateral.ownerOf(1), _lender); - assertEq(_collateral.ownerOf(3), _lender); + assertEq(_collateral.ownerOf(1), address(_pool)); + assertEq(_collateral.ownerOf(3), address(_pool)); assertEq(_collateral.ownerOf(73), _lender); - // the NFTs pulled from pool are owned by borrower - assertEq(_collateral.ownerOf(51), _borrower2); - assertEq(_collateral.ownerOf(53), _borrower2); + assertEq(_collateral.ownerOf(51), _lender); + assertEq(_collateral.ownerOf(53), _lender); _assertBucket({ - index: 2000, - lpBalance: 4_596.260291921984408543 * 1e18, - collateral: 0, - deposit: 4_596.260291921984421072 * 1e18, - exchangeRate: 1.000000000000000003 * 1e18 + index: 2500, + lpBalance: 15_721.542280862700379804 * 1e18, + collateral: 1.642100572428250346 * 1e18, + deposit: 20_131.184679479470055267 * 1e18, + exchangeRate: 1.684039215572972305 * 1e18 }); _assertBucket({ index: 2499, @@ -321,10 +328,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBucket({ index: MAX_FENWICK_INDEX, - lpBalance: 99.999999999642484483 * 1e18, - collateral: 0, - deposit: 100 * 1e18, - exchangeRate: 1.000000000003575156 * 1e18 + lpBalance: 99.984931542573546395 * 1e18, + collateral: 0.357899427571749654 * 1e18, + deposit: 100.004851122084218862 * 1e18, + exchangeRate: 1.000199226172731231 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -337,10 +344,23 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 0, + borrowert0Np: 1_769.243311298076895206 * 1e18, borrowerCollateralization: 1 * 1e18 }); + uint256[] memory removalIndexes2 = new uint256[](2); + removalIndexes2[0] = 2500; + removalIndexes2[1] = MAX_FENWICK_INDEX; + + _mergeOrRemoveCollateral({ + from: _lender, + toIndex: MAX_FENWICK_INDEX, + noOfNFTsToRemove: 2, + collateralMerged: 2 * 1e18, + removeCollateralAtIndex: removalIndexes2, + toIndexLps: 0 + }); + _assertCollateralInvariants(); } From 2e1e1b64d105c1caf726b8ea78db1c839d63f5b4 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 29 Jun 2023 05:16:29 +0300 Subject: [PATCH 24/32] Sherlock-85: Limit index isn't checked in repayDebt, so user control is void (#914) --- src/libraries/external/BorrowerActions.sol | 5 +++-- tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol | 10 ++++++++++ tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol | 9 +++++++-- tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol | 10 ++++++++++ tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol | 7 ++++++- 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/libraries/external/BorrowerActions.sol b/src/libraries/external/BorrowerActions.sol index a48af0de0..5a69e1120 100644 --- a/src/libraries/external/BorrowerActions.sol +++ b/src/libraries/external/BorrowerActions.sol @@ -375,8 +375,6 @@ library BorrowerActions { // calculate LUP only if it wasn't calculated in repay action if (!vars.repay) result_.newLup = Deposits.getLup(deposits_, result_.poolDebt); - _revertIfPriceDroppedBelowLimit(result_.newLup, limitIndex_); - 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 @@ -392,6 +390,9 @@ library BorrowerActions { result_.poolCollateral -= collateralAmountToPull_; } + // check limit price and revert if price dropped below + _revertIfPriceDroppedBelowLimit(result_.newLup, limitIndex_); + // update loan state Loans.update( loans_, diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index ea10a15de..2e94d7b82 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -551,6 +551,16 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { ERC20Pool(address(_pool)).repayDebt(from, 0, amount, from, indexLimit); } + function _assertRepayLimitIndexRevert( + address from, + uint256 amount, + uint256 indexLimit + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.LimitIndexExceeded.selector); + ERC20Pool(address(_pool)).repayDebt(from, amount, 0, from, indexLimit); + } + function _assertRepayNoDebtRevert( address from, address borrower, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol index a7b08969e..051594cd5 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol @@ -719,8 +719,13 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { }) ); - // should revert if LUP is below the limit - ( , , , , , uint256 lupIndex ) = _poolUtils.poolPricesInfo(address(_pool)); + // should revert if LUP is below the limit when repay or pull collateral + ( , , , , , uint256 lupIndex ) = _poolUtils.poolPricesInfo(address(_pool)); + _assertRepayLimitIndexRevert({ + from: _borrower, + amount: 20 * 1e18, + indexLimit: lupIndex - 1 + }); _assertPullLimitIndexRevert({ from: _borrower, amount: 20 * 1e18, diff --git a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol index 10a9fd879..78fdd9f46 100644 --- a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol +++ b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol @@ -637,6 +637,16 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { ERC721Pool(address(_pool)).repayDebt(from, 0, amount, from, indexLimit); } + function _assertRepayLimitIndexRevert( + address from, + uint256 amount, + uint256 indexLimit + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.LimitIndexExceeded.selector); + ERC721Pool(address(_pool)).repayDebt(from, amount, 0, from, indexLimit); + } + function _assertRepayNoDebtRevert( address from, address borrower, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol index dfeacf5b5..15df9a510 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol @@ -437,7 +437,12 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { }); // should revert if LUP is below the limit - ( , , , , , uint256 lupIndex ) = _poolUtils.poolPricesInfo(address(_pool)); + ( , , , , , uint256 lupIndex ) = _poolUtils.poolPricesInfo(address(_pool)); + _assertRepayLimitIndexRevert({ + from: _borrower, + amount: 20 * 1e18, + indexLimit: lupIndex - 1 + }); _assertPullLimitIndexRevert({ from: _borrower, amount: 2, From 3899b8041d0421179a5592ad06512b8ee46892de Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Thu, 29 Jun 2023 18:13:00 +0300 Subject: [PATCH 25/32] Sherlock-72: Lenders pay deposit fees due to no slippage control (#915) - add new function parameter to revert if price below lup --- src/base/Pool.sol | 8 ++++--- src/interfaces/pool/commons/IPoolErrors.sol | 3 ++- .../pool/commons/IPoolInternals.sol | 5 +++-- .../pool/commons/IPoolLenderActions.sol | 12 +++++----- src/libraries/external/LenderActions.sol | 4 ++++ tests/brownie/test_invariants.py | 16 +++++++------- tests/brownie/test_scaled_pool.py | 8 +++---- tests/brownie/test_stable_volatile.py | 4 ++-- .../ERC20TakeWithExternalLiquidity.t.sol | 10 ++++----- .../PurchaseQuoteWithExternalLiquidity.t.sol | 2 +- .../handlers/BaseERC20PoolPositionHandler.sol | 2 +- .../BaseERC721PoolPositionHandler.sol | 2 +- .../unbounded/UnboundedBasicPoolHandler.sol | 2 +- .../unit/ERC20Pool/ERC20PoolBorrow.t.sol | 7 ++++++ .../unit/ERC20Pool/ERC20PoolCollateral.t.sol | 4 ++-- .../unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol | 18 +++++++-------- .../unit/ERC20Pool/ERC20PoolInfoUtils.t.sol | 2 +- .../ERC20Pool/ERC20PoolInputValidation.t.sol | 6 ++--- .../ERC20Pool/ERC20PoolLiquidationsMisc.t.sol | 2 +- .../ERC20PoolLiquidationsSettle.t.sol | 8 +++---- .../unit/ERC20Pool/ERC20PoolMulticall.t.sol | 15 ++++++++----- .../unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 5 +++-- .../ERC20Pool/ERC20PoolReserveAuction.t.sol | 2 +- .../ERC20Pool/ERC20SafeTransferTokens.sol | 4 ++-- .../unit/ERC721Pool/ERC721DSTestPlus.sol | 2 +- .../unit/ERC721Pool/ERC721PoolBorrow.t.sol | 6 ++--- .../ERC721PoolInputValidation.t.sol | 6 ++--- .../unit/Positions/PositionManager.t.sol | 2 +- .../forge/unit/Rewards/RewardsDSTestPlus.sol | 2 +- tests/forge/unit/Rewards/RewardsManager.t.sol | 8 +++---- tests/forge/utils/DSTestPlus.sol | 22 ++++++++++++++----- 31 files changed, 115 insertions(+), 84 deletions(-) diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 51310167d..a71b63e42 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -146,7 +146,8 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function addQuoteToken( uint256 amount_, uint256 index_, - uint256 expiry_ + uint256 expiry_, + bool revertIfBelowLup_ ) external override nonReentrant returns (uint256 bucketLP_) { _revertAfterExpiry(expiry_); @@ -163,8 +164,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { deposits, poolState, AddQuoteParams({ - amount: amount_, - index: index_ + amount: amount_, + index: index_, + revertIfBelowLup: revertIfBelowLup_ }) ); diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index d440b1066..ad6a3eaa1 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -180,7 +180,8 @@ interface IPoolErrors { error PoolUnderCollateralized(); /** - * @notice Actor is attempting to remove using a bucket with price below the `LUP`. + * @notice Actor is attempting to add quote tokens at a price below the `LUP`. + * @notice Actor is attempting to kick with bucket price below the `LUP`. */ error PriceBelowLUP(); diff --git a/src/interfaces/pool/commons/IPoolInternals.sol b/src/interfaces/pool/commons/IPoolInternals.sol index 7a6e5f3da..8c86c902a 100644 --- a/src/interfaces/pool/commons/IPoolInternals.sol +++ b/src/interfaces/pool/commons/IPoolInternals.sol @@ -71,8 +71,9 @@ struct KickReserveAuctionParams { /// @dev Struct used to hold parameters for `LenderAction.addQuoteToken` action. struct AddQuoteParams { - uint256 amount; // [WAD] amount to be added - uint256 index; // the index in which to deposit + 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. diff --git a/src/interfaces/pool/commons/IPoolLenderActions.sol b/src/interfaces/pool/commons/IPoolLenderActions.sol index 907dbad02..6fc1e3b9e 100644 --- a/src/interfaces/pool/commons/IPoolLenderActions.sol +++ b/src/interfaces/pool/commons/IPoolLenderActions.sol @@ -13,15 +13,17 @@ interface IPoolLenderActions { /** * @notice Called by lenders to add an amount of credit at a specified price bucket. - * @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. - * @return bucketLP_ The amount of `LP` changed for the added quote tokens (`WAD` precision). + * @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). */ function addQuoteToken( uint256 amount_, uint256 index_, - uint256 expiry_ + uint256 expiry_, + bool revertIfBelowLup_ ) external returns (uint256 bucketLP_); /** diff --git a/src/libraries/external/LenderActions.sol b/src/libraries/external/LenderActions.sol index 5f92bcba5..72cd30953 100644 --- a/src/libraries/external/LenderActions.sol +++ b/src/libraries/external/LenderActions.sol @@ -89,6 +89,7 @@ library LenderActions { error InsufficientLiquidity(); error InsufficientCollateral(); error MoveToSameIndex(); + error PriceBelowLUP(); /***************************/ /*** External Functions ***/ @@ -171,7 +172,10 @@ library LenderActions { // 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)); } diff --git a/tests/brownie/test_invariants.py b/tests/brownie/test_invariants.py index 41f4fdadd..5aadf6b7f 100644 --- a/tests/brownie/test_invariants.py +++ b/tests/brownie/test_invariants.py @@ -327,7 +327,7 @@ class PoolStateMachine(BasePoolStateMachine): def setup(self): # add some initial liquidity in the pool - self.pool.addQuoteToken(MAX_LEND_AMOUNT, MAX_BUCKET, chain.time() + 30, {"from": lenders[0]}) + self.pool.addQuoteToken(MAX_LEND_AMOUNT, MAX_BUCKET, chain.time() + 30, False, {"from": lenders[0]}) ############## Lender rules ############## @@ -343,7 +343,7 @@ def rule_add_quote_token(self, st_lend_amount, st_index, st_lender, st_sleep): success = True try: - self.pool.addQuoteToken(lend_amount, st_index, chain.time() + 30, {"from": lenders[st_lender]}) + self.pool.addQuoteToken(lend_amount, st_index, chain.time() + 30, False, {"from": lenders[st_lender]}) chain.sleep(st_sleep) except: success = False @@ -363,7 +363,7 @@ def rule_swap_quote_for_collateral(self, st_lend_amount, st_bid_amount, 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, {"from": lenders[st_lender]}) + 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: @@ -388,7 +388,7 @@ def rule_draw_debt(self, st_borrow_amount, st_lender, st_borrower, st_sleep): 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, {"from": lenders[st_lender]}) + 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, @@ -441,7 +441,7 @@ def rule_swap_collateral_for_quote(self, st_bid_amount, st_lend_amount, st_index 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, {"from": lenders[st_lender]}) + 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]}) @@ -491,8 +491,8 @@ class PoolStateMachine(BasePoolStateMachine): def setup(self): # add some initial liquidity in the pool - self.pool.addQuoteToken(MAX_BORROW_AMOUNT, MAX_BUCKET, chain.time() + 30, {"from": lenders[0]}) - self.pool.addQuoteToken(MAX_BORROW_AMOUNT, MIN_BUCKET, chain.time() + 30, {"from": lenders[0]}) + 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 ############## @@ -515,7 +515,7 @@ def rule_draw_debt(self, st_borrow_amount, st_lender, st_borrower, st_sleep): 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, {"from": lenders[st_lender]}) + 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, diff --git a/tests/brownie/test_scaled_pool.py b/tests/brownie/test_scaled_pool.py index c926480d1..344dde473 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, {"from": lenders[0]}) + tx = scaled_pool.addQuoteToken(100 * 10**18, i, chain.time() + 30, False, {"from": lenders[0]}) add_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, {"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]}) + 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]}) col_txes = [] for i in range(10): diff --git a/tests/brownie/test_stable_volatile.py b/tests/brownie/test_stable_volatile.py index 589fa0d99..20428fe2e 100644 --- a/tests/brownie/test_stable_volatile.py +++ b/tests/brownie/test_stable_volatile.py @@ -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, {"from": lenders[i]}) + pool_helper.pool.addQuoteToken(deposit_amount, price_index, chain.time() + 30, False, {"from": lenders[i]}) def draw_initial_debt(borrowers, pool_helper, test_utils, chain, target_utilization): @@ -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, {"from": lender}) + tx = pool_helper.pool.addQuoteToken(quantity, deposit_index, chain.time() + 15, False, {"from": lender}) return deposit_price diff --git a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol index 64382c100..8ce92718b 100644 --- a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol +++ b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol @@ -54,11 +54,11 @@ 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); - _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); + _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); vm.stopPrank(); // borrower draws debt diff --git a/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol b/tests/forge/interactions/PurchaseQuoteWithExternalLiquidity.t.sol index 2582bebfa..c1166eb6d 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); + _ajnaPool.addQuoteToken(5_000 * 1e18, 500, type(uint256).max, false); vm.stopPrank(); } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol index 075e7cc2b..c07c02d8c 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol @@ -119,7 +119,7 @@ abstract contract BaseERC20PoolPositionHandler is UnboundedERC20PoolPositionsHan // Prepare test phase uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); _ensureQuoteAmount(_actor, boundedAmount); - try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes) { + try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes, false) { } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol index ff1995f3e..eeaedbb08 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol @@ -118,7 +118,7 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH // Prepare test phase uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); _ensureQuoteAmount(_actor, boundedAmount); - try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes) { + try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes, false) { } catch (bytes memory err) { _ensurePoolError(err); } diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol index 927747d5b..cacf4c04f 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol @@ -37,7 +37,7 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { // ensure actor always has amount of quote to add _ensureQuoteAmount(_actor, amount_); - try _pool.addQuoteToken(amount_, bucketIndex_, block.timestamp + 1 minutes) { + try _pool.addQuoteToken(amount_, bucketIndex_, block.timestamp + 1 minutes, false) { // amount is rounded in pool to token scale amount_ = _roundToScale(amount_, _pool.quoteTokenScale()); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol index 051594cd5..285405e3e 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol @@ -1011,6 +1011,13 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { 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, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol index 71bd2776b..ce5ca5a32 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol @@ -1045,7 +1045,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _mintQuoteAndApproveTokens(actor, 1000000000000 * 1e18); changePrank(actor); - _pool.addQuoteToken(913597152782868931694946846442, 2572, block.timestamp + 100); + _pool.addQuoteToken(913597152782868931694946846442, 2572, block.timestamp + 100, false); ERC20Pool(address(_pool)).drawDebt(actor, 456798576391434465847473423221, 7388, 170152459663184217402759609); skip(100 days); @@ -1061,7 +1061,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { _mintQuoteAndApproveTokens(actor, 1000000000000 * 1e18); changePrank(actor); - _pool.addQuoteToken(200, 2572, block.timestamp + 100); + _pool.addQuoteToken(200, 2572, block.timestamp + 100, false); 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/ERC20PoolGasLoadTest.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol index 9b44ebb24..3e3dd6091 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); - _pool.addQuoteToken(100_000 * 1e18, 1 + i, block.timestamp + 2 minutes); + _pool.addQuoteToken(100_000 * 1e18, 7388 - i, block.timestamp + 2 minutes, false); + _pool.addQuoteToken(100_000 * 1e18, 1 + i, block.timestamp + 2 minutes, false); vm.stopPrank(); _lenders.push(lender); @@ -272,7 +272,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { vm.startPrank(lender); skip(15 hours); - _pool.addQuoteToken(10_000 * 1e18, index_, block.timestamp + 2 minutes); + _pool.addQuoteToken(10_000 * 1e18, index_, block.timestamp + 2 minutes, false); skip(15 hours); _pool.removeQuoteToken(5_000 * 1e18, 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); + _pool.addQuoteToken(10_000 * 1e18, 7388 - i, block.timestamp + 2 minutes, false); skip(15 hours); - _pool.addQuoteToken(10_000 * 1e18, 1 + i, block.timestamp + 2 minutes); + _pool.addQuoteToken(10_000 * 1e18, 1 + i, block.timestamp + 2 minutes, false); 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); + _pool.addQuoteToken(500_000_000_000_000 * 1e18, 3_000, block.timestamp + 2 minutes, false); 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); + _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes, false); 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); + _pool.addQuoteToken(100_000 * 1e18, 1_000, block.timestamp + 2 minutes, false); vm.stopPrank(); @@ -472,7 +472,7 @@ contract ERC20PoolGasArbTakeLoadTest is ERC20PoolGasLoadTest { vm.startPrank(lender); - _pool.addQuoteToken(200_000 * 1e18, 5000 - i, block.timestamp + 2 minutes); + _pool.addQuoteToken(200_000 * 1e18, 5000 - i, block.timestamp + 2 minutes, false); vm.stopPrank(); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol index 6f75ea3e3..fac958abe 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol @@ -217,7 +217,7 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { changePrank(_lender); uint256 hpbIndex = 369; _quote.approve(address(emptyPool), type(uint256).max); - emptyPool.addQuoteToken(0.0213 * 1e18, hpbIndex, type(uint256).max); + emptyPool.addQuoteToken(0.0213 * 1e18, hpbIndex, type(uint256).max, false); assertEq(_poolUtils.momp(address(emptyPool)), _priceAt(hpbIndex)); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol index bb7b35c78..c82b82725 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol @@ -13,13 +13,13 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { function testValidateAddQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.addQuoteToken(0, 1000, block.timestamp + 1); + _pool.addQuoteToken(0, 1000, block.timestamp + 1, false); // revert on zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, 0, block.timestamp + 1); + _pool.addQuoteToken(1000, 0, block.timestamp + 1, false); // revert on index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1); + _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); } function testValidateMoveQuoteTokenInput() external tearDown { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index 0ca99665d..eb0f6198a 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -252,7 +252,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); + _pool.addQuoteToken(2_000 * 1e18, 5000, block.timestamp + 1 minutes, false); _pool.removeQuoteToken(2_000 * 1e18, 5000); skip(3 hours); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 265adb912..815bb2b5d 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -821,7 +821,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: bankruptcyTime + 1 }); - _pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes); + _pool.addQuoteToken(100 * 1e18, _i9_91, block.timestamp + 1 minutes, false); ERC20Pool(address(_pool)).addCollateral(4 * 1e18, _i9_91, block.timestamp + 1 minutes); _assertLenderLpBalance({ @@ -857,7 +857,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime + 100 days + 10 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); + _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); _assertLenderLpBalance({ @@ -1075,7 +1075,7 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { function testSettleAndBankruptcyOnHPBWithTinyDeposit() external { changePrank(actor6); - _pool.addQuoteToken(2_000_000 * 1e18, 2572, block.timestamp + 100); + _pool.addQuoteToken(2_000_000 * 1e18, 2572, block.timestamp + 100, false); skip(100 days); ERC20Pool(address(_pool)).drawDebt(actor6, 1000000 * 1e18, 7388, 372.489032271806320214 * 1e18); skip(100 days); @@ -1093,7 +1093,7 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { skip(10 days); changePrank(actor3); - _pool.addQuoteToken(2, 2571, block.timestamp + 100); + _pool.addQuoteToken(2, 2571, block.timestamp + 100, false); (uint256 bucketLps, uint256 collateral, , uint256 deposit, ) = _pool.bucketInfo(2571); assertEq(bucketLps, 2); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol index 6214be14c..b64a6c9e6 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolMulticall.t.sol @@ -33,24 +33,27 @@ contract ERC20PoolMulticallTest is ERC20HelperContract { bytes[] memory callsToExecute = new bytes[](3); callsToExecute[0] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256)", + "addQuoteToken(uint256,uint256,uint256,bool)", 10_000 * 1e18, 2550, - block.timestamp + 5 minutes + block.timestamp + 5 minutes, + false ); callsToExecute[1] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256)", + "addQuoteToken(uint256,uint256,uint256,bool)", 10_000 * 1e18, 2551, - block.timestamp + 5 minutes + block.timestamp + 5 minutes, + false ); callsToExecute[2] = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256)", + "addQuoteToken(uint256,uint256,uint256,bool)", 10_000 * 1e18, 2552, - block.timestamp + 5 minutes + block.timestamp + 5 minutes, + false ); changePrank(_lender); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index 7b059758c..ff071c79a 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -225,10 +225,11 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { // should revert if passing future timestamp but time has elapsed bytes memory data = abi.encodeWithSignature( - "addQuoteToken(uint256,uint256,uint256)", + "addQuoteToken(uint256,uint256,uint256,bool)", 50_000 * 1e18, 3333, - block.timestamp + 5 minutes + block.timestamp + 5 minutes, + false ); // should succeed if time hasn't passed diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol index c7d28bf7e..456c49a76 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol @@ -145,7 +145,7 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { ERC20Pool pool = ERC20Pool(address(_pool)); changePrank(_actor3); - pool.addQuoteToken(197806, 2572, block.timestamp + 1); + pool.addQuoteToken(197806, 2572, block.timestamp + 1, false); pool.drawDebt(_actor3, 98903, 7388, 37); // pool balance is amount added minus new debt assertEq(_quote.balanceOf(address(pool)), 98903); diff --git a/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol b/tests/forge/unit/ERC20Pool/ERC20SafeTransferTokens.sol index 772a96ab2..112c48397 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); + pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max, false); 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); + pool.addQuoteToken(1_000 * 1e18, 2549, type(uint256).max, false); changePrank(_borrower); diff --git a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol index 78fdd9f46..543a2b857 100644 --- a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol +++ b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol @@ -109,7 +109,7 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { } deal(_pool.quoteTokenAddress(), lender, depositRequired); Token(_pool.quoteTokenAddress()).approve(address(_pool) , depositRequired); - _pool.addQuoteToken(depositRequired, bucketIndex, block.timestamp + 1 minutes); + _pool.addQuoteToken(depositRequired, bucketIndex, block.timestamp + 1 minutes, false); (lenderLpBalance, ) = _pool.lenderInfo(bucketIndex, lender); lpsAsCollateral = _poolUtils.lpToCollateral(address(_pool), lenderLpBalance, bucketIndex); } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol index 15df9a510..3a63580db 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol @@ -572,7 +572,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); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes, false); // 10 borrowers draw debt for (uint i=0; i<10; ++i) { @@ -601,7 +601,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); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 1 minutes, false); // 9 other borrowers draw debt for (uint i=0; i<9; ++i) { @@ -649,7 +649,7 @@ contract ERC721ScaledQuoteTokenBorrowTest is ERC721NDecimalsHelperContract(4) { // add initial quote to the pool changePrank(_lender); - _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 30); + _pool.addQuoteToken(20_000 * 1e18, 2550, block.timestamp + 30, false); // borrower pledges a single NFT uint256[] memory tokenIdsToAdd = new uint256[](1); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol index 901366d61..cfb268c40 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol @@ -18,13 +18,13 @@ contract ERC721PoolBorrowTest is ERC721HelperContract { function testValidateAddQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.addQuoteToken(0, 1000, block.timestamp + 1); + _pool.addQuoteToken(0, 1000, block.timestamp + 1, false); // revert on zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, 0, block.timestamp + 1); + _pool.addQuoteToken(1000, 0, block.timestamp + 1, false); // revert on index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1); + _pool.addQuoteToken(1000, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); } function testValidateMoveQuoteTokenInput() external tearDown { diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol index 7dd06eae5..652888669 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -985,7 +985,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract amounts[0] = 30_000 * 1e18; changePrank(testMinter); - _pool.addQuoteToken(amounts[0], _i9_91, type(uint256).max); + _pool.addQuoteToken(amounts[0], _i9_91, type(uint256).max, false); _pool.increaseLPAllowance(address(_positionManager), indexes, amounts); _pool.approveLPTransferors(transferors); diff --git a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol b/tests/forge/unit/Rewards/RewardsDSTestPlus.sol index e14c360be..e4ac29094 100644 --- a/tests/forge/unit/Rewards/RewardsDSTestPlus.sol +++ b/tests/forge/unit/Rewards/RewardsDSTestPlus.sol @@ -398,7 +398,7 @@ abstract contract RewardsHelperContract is RewardsDSTestPlus { 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); + ERC20Pool(address(pool)).addQuoteToken(mintAmount, indexes[i], type(uint256).max, false); (lpBalances[i], ) = ERC20Pool(address(pool)).lenderInfo(indexes[i], minter); } diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index 0bed3241a..501b099a9 100644 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ b/tests/forge/unit/Rewards/RewardsManager.t.sol @@ -194,8 +194,8 @@ contract RewardsManagerTest is RewardsHelperContract { deal(address(_quoteOne), _minterOne, 400 * 1e18); changePrank(_minterOne); _quoteOne.approve(address(_pool), type(uint256).max); - _pool.addQuoteToken(200 * 1e18, 2_000, type(uint256).max); - _pool.addQuoteToken(200 * 1e18, 4_000, 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 @@ -1059,12 +1059,12 @@ contract RewardsManagerTest is RewardsHelperContract { 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); + 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); + ERC20Pool(address(_pool)).addQuoteToken(6_000.0 * 1e18, 2775, type(uint256).max, false); // borrower borrows (collateralToPledge) = _createTestBorrower(address(_pool), _borrower, 25_000 * 1e18, 2775); diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index bf0bed1b6..ed9edd177 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -130,7 +130,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 index ) internal { changePrank(from); - _pool.addQuoteToken(amount, index, type(uint256).max); + _pool.addQuoteToken(amount, index, type(uint256).max, false); // Add for tearDown lenders.add(from); @@ -162,7 +162,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { vm.expectEmit(true, true, false, true); emit AddQuoteToken(from, index, (amountAdded / quoteTokenScale) * quoteTokenScale, lpAward, newLup); _assertQuoteTokenTransferEvent(from, address(_pool), amount); - _pool.addQuoteToken(amount, index, type(uint256).max); + _pool.addQuoteToken(amount, index, type(uint256).max, false); // Add for tearDown lenders.add(from); @@ -791,7 +791,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('BucketBankruptcyBlock()')); - _pool.addQuoteToken(amount, index, type(uint256).max); + _pool.addQuoteToken(amount, index, type(uint256).max, false); } function _assertAddLiquidityAtIndex0Revert( @@ -800,7 +800,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.addQuoteToken(amount, 0, type(uint256).max); + _pool.addQuoteToken(amount, 0, type(uint256).max, false); } function _assertAddLiquidityDustRevert( @@ -810,7 +810,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); - _pool.addQuoteToken(amount, index, type(uint256).max); + _pool.addQuoteToken(amount, index, type(uint256).max, false); } function _assertAddLiquidityExpiredRevert( @@ -821,7 +821,17 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.TransactionExpired.selector); - _pool.addQuoteToken(amount, index, expiry); + _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); } function _assertArbTakeNoAuction( From 0332f341856e1efe4da8bb675886c8cfbee57b71 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Fri, 30 Jun 2023 16:27:52 +0300 Subject: [PATCH 26/32] Sherlock-111: Wrong Inflator used in calculating HTP to determine accrualIndex (#916) * Sherlock-111 * Fix unit tests * Update parallel htp calculations in invariants * Update htp calculation in invariants --------- Co-authored-by: prateek105 --- src/libraries/external/PoolCommons.sol | 2 +- .../base/handlers/unbounded/BaseHandler.sol | 25 +- .../ERC721Pool/ERC721PoolCollateral.t.sol | 86 +++--- .../ERC721PoolLiquidationsSettleAuction.t.sol | 274 +++++++++--------- tests/forge/unit/Rewards/ClaimRewards.t.sol | 26 +- tests/forge/unit/Rewards/RewardsManager.t.sol | 174 +++++------ 6 files changed, 284 insertions(+), 303 deletions(-) diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index 020f331d9..e4ebc2b8a 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -229,7 +229,7 @@ library PoolCommons { // calculate the highest threshold price newInflator_ = Maths.wmul(poolState_.inflator, pendingFactor); - uint256 htp = Maths.wmul(thresholdPrice_, newInflator_); + uint256 htp = Maths.wmul(thresholdPrice_, poolState_.inflator); uint256 accrualIndex; if (htp > MAX_PRICE) accrualIndex = 1; // if HTP is over the highest price bucket then no buckets earn interest diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 2c8a7c957..7748994be 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -368,35 +368,16 @@ abstract contract BaseHandler is Test { // poolLoansInfo returns 1e18 if no interest is pending or time elapsed... the contracts calculate 0 time elapsed which causes discrep if (pendingFactor == 1e18) return; - // get TP of worst loan, pendingInflator and poolDebt - uint256 maxThresholdPrice; - uint256 pendingInflator; - uint256 poolDebt; - { - (, poolDebt ,,) = _pool.debtInfo(); + // get TP of worst loan + (, uint256 htp,) = _pool.loansInfo(); - (uint256 inflator, uint256 inflatorUpdate) = _pool.inflatorInfo(); - - (, maxThresholdPrice,) = _pool.loansInfo(); - maxThresholdPrice = Maths.wdiv(maxThresholdPrice, inflator); - - (uint256 interestRate, ) = _pool.interestRateInfo(); - - pendingInflator = PoolCommons.pendingInflator( - inflator, - inflatorUpdate, - interestRate - ); - } - - // get HTP and deposit above HTP - uint256 htp = Maths.wmul(maxThresholdPrice, pendingInflator); uint256 accrualIndex; if (htp > MAX_PRICE) accrualIndex = 1; // if HTP is over the highest price bucket then no buckets earn interest else if (htp < MIN_PRICE) accrualIndex = MAX_FENWICK_INDEX; // if HTP is under the lowest price bucket then all buckets earn interest else accrualIndex = _poolInfo.priceToIndex(htp); + (, uint256 poolDebt, , ) = _pool.debtInfo(); uint256 lupIndex = _pool.depositIndex(poolDebt); // accrual price is less of lup and htp, and prices decrease as index increases diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol index 05b00308f..b963b3867 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol @@ -722,7 +722,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 99836282890, - poolSize: 574.548281134908793280 * 1e18, + poolSize: 574.548281134908793200 * 1e18, pledgedCollateral: 2 * 1e18, encumberedCollateral: 5_992_754_428.551908353085520210 * 1e18, poolDebt: 598.294326419208615388 * 1e18, @@ -742,80 +742,80 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { index: 3060, lpBalance: 20 * 1e18, collateral: 0.0000000000000000000 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3061, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3062, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3063, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3064, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3065, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3066, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3067, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 66.831193726562997920 * 1e18, - exchangeRate: 3.341559686328149896 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3068, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 20.003788944092390860 * 1e18, - exchangeRate: 1.000189447204619543 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ index: 3069, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 20.003788944092390860 * 1e18, - exchangeRate: 1.000189447204619543 * 1e18 + deposit: 57.465712770068876500 * 1e18, + exchangeRate: 2.873285638503443825 * 1e18 }); _assertBucket({ @@ -842,17 +842,17 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3060, lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.285325336911052408 * 1e18, + collateral: 0.245340879650286415 * 1e18, deposit: 0, - exchangeRate: 3.341559686328149897 * 1e18 + exchangeRate: 2.873285638503443827 * 1e18 }); _assertBucket({ index: 3061, lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.286751963595607668 * 1e18, + collateral: 0.246567584048537845 * 1e18, deposit: 0, - exchangeRate: 3.341559686328149900 * 1e18 + exchangeRate: 2.873285638503443827 * 1e18 }); _assertBucket({ @@ -874,8 +874,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { kickMomp: 0.000000099836282890 * 1e18, totalBondEscrowed: 5.907892673985352325 * 1e18, auctionPrice: 0.000004621809202112 * 1e18, - debtInAuction: 439.681348088864224563 * 1e18, - thresholdPrice: 385.774399985858744479 * 1e18, + debtInAuction: 467.777790958346588935 * 1e18, + thresholdPrice: 371.166459589091918644 * 1e18, neutralPrice: 310.164365384230997074 * 1e18 }) ); @@ -884,10 +884,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 99836282890, - poolSize: 374.163546520999771310 * 1e18, - pledgedCollateral: 1.139736976079754220 * 1e18, - encumberedCollateral: 4_404_023_621.084799630233909643 * 1e18, - poolDebt: 439.681348088864224563 * 1e18, + poolSize: 402.259989390482135517 * 1e18, + pledgedCollateral: 1.260291114332395208 * 1e18, + encumberedCollateral: 4_685_448_790.934513817364339575 * 1e18, + poolDebt: 467.777790958346588935 * 1e18, actualUtilization: 0.750721153846153847 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, @@ -904,10 +904,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 439.681348088864224563 * 1e18, - borrowerCollateral: 1.139736976079754220 * 1e18, + borrowerDebt: 467.777790958346588935 * 1e18, + borrowerCollateral: 1.260291114332395208 * 1e18, borrowert0Np: 78.825721153846153882 * 1e18, - borrowerCollateralization: 0.000000000258794474 * 1e18, + borrowerCollateralization: 0.000000000268979808 * 1e18, tokenIds: borrowerTokenIds }); @@ -930,10 +930,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 439.681343513273114473 * 1e18, - borrowerCollateral: 0.139736976079754220 * 1e18, + borrowerDebt: 467.777786382755478845 * 1e18, + borrowerCollateral: 0.260291114332395208 * 1e18, borrowert0Np: 78.825721153846153882 * 1e18, - borrowerCollateralization: 0.000000000031729389 * 1e18, + borrowerCollateralization: 0.000000000055553081 * 1e18, tokenIds: borrowerTokenIds }); @@ -962,8 +962,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { kickMomp: 0.000000099836282890 * 1e18, totalBondEscrowed: 5.907892720203444346 * 1e18, auctionPrice: 0, - debtInAuction: 439.681343513273114473 * 1e18, - thresholdPrice: 3_148.017628779219831352 * 1e18, + debtInAuction: 467.777786382755478845 * 1e18, + thresholdPrice: 1_798.004234437087055097 * 1e18, neutralPrice: 310.164365384230997074 * 1e18 }) ); @@ -972,7 +972,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 111.718947293453085949 * 1e18 + settledDebt: 118.857992573354662400 * 1e18 }); _assertBorrower({ @@ -1008,9 +1008,9 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3060, lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.285325336911052408 * 1e18, + collateral: 0.245340879650286415 * 1e18, deposit: 0, - exchangeRate: 3.341559686328149897 * 1e18 + exchangeRate: 2.873285638503443827 * 1e18 }); _assertLenderLpBalance({ lender: _borrower, @@ -1169,7 +1169,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50.000004233804493307 * 1e18, + poolSize: 50.000004233778718162 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 599e903c4..453ce67fa 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -116,8 +116,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2500, lpBalance: 8_000 * 1e18, collateral: 0, - deposit: 13_734.486139425783008000 * 1e18, - exchangeRate: 1.716810767428222876 * 1e18 + deposit: 13_293.371821008415088000 * 1e18, + exchangeRate: 1.661671477626051886 * 1e18 }); // the 2 token ids are owned by borrower before settle @@ -160,7 +160,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_485.576684127234225966 * 1e18 + settledDebt: 2_485.576684127234225434 * 1e18 }); // collateral in bucket used to settle auction increased with the amount used to settle debt @@ -174,7 +174,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // partial borrower debt is settled, borrower collateral decreased with the amount used to settle debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_194.580157565210365777 * 1e18, + borrowerDebt: 5_194.580157565210366847 * 1e18, borrowerCollateral: 0.712070211767666465 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0.529627631336027971 * 1e18 @@ -199,7 +199,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_258.399659496838436164 * 1e18 + settledDebt: 2_258.399659496838434005 * 1e18 }); // no token id left in borrower token ids array @@ -211,14 +211,14 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 19_649.507551702938715450 * 1e18, + lpBalance: 20_036.073477395793018984 * 1e18, collateral: 0.712070211767666465 * 1e18, - deposit: 30_990.013747352002213011 * 1e18, - exchangeRate: 1.717152801066721367 * 1e18 + deposit: 30_548.811547417239049073 * 1e18, + exchangeRate: 1.662002526074875972 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 650.665648223383086331 * 1e18, + borrowerDebt: 650.665648223383091746 * 1e18, borrowerCollateral: 0, borrowert0Np: 2_627.524038461538462750 * 1e18, borrowerCollateralization: 0 @@ -228,7 +228,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 323.391444837465801745 * 1e18 + settledDebt: 323.391444837465804436 * 1e18 }); _assertBorrower({ @@ -250,10 +250,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 19_649.507551702938715450 * 1e18, + lpBalance: 20_036.073477395793018984 * 1e18, collateral: 3.354170784195916811 * 1e18, - deposit: 20_131.184679479470055267 * 1e18, - exchangeRate: 1.684039215572972305 * 1e18 + deposit: 19_689.982479544706885705 * 1e18, + exchangeRate: 1.629527817447087792 * 1e18 }); _assertBucket({ index: 2499, @@ -314,10 +314,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 15_721.542280862700379804 * 1e18, + lpBalance: 15_976.708867181974059418 * 1e18, collateral: 1.642100572428250346 * 1e18, - deposit: 20_131.184679479470055267 * 1e18, - exchangeRate: 1.684039215572972305 * 1e18 + deposit: 19_689.982479544706885705 * 1e18, + exchangeRate: 1.629527817447087792 * 1e18 }); _assertBucket({ index: 2499, @@ -374,15 +374,15 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 3_433.621534856445752000 * 1e18, - exchangeRate: 1.716810767428222876 * 1e18 + deposit: 3_323.342955252103772000 * 1e18, + exchangeRate: 1.661671477626051886 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(32 hours); @@ -400,17 +400,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619361301 * 1e18, - borrowerCollateral: 0.300997199476505990 * 1e18, + borrowerDebt: 4_582.063964428011899646 * 1e18, + borrowerCollateral: 0.330122111965997525 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.258770970502146036 * 1e18 + borrowerCollateralization: 0.276978254692862222 * 1e18 }); _assertCollateralInvariants(); @@ -430,22 +430,22 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 2, - settledDebt: 2_223.210773740853090348 * 1e18 + settledDebt: 2_278.046992473852091989 * 1e18 }); _assertBucket({ index: 2500, lpBalance: 8_000 * 1e18, - collateral: 0.300997199476505990 * 1e18, - deposit: 11_773.847757000624329017 * 1e18, - exchangeRate: 1.617099612721855334 * 1e18 + collateral: 0.330122111965997525 * 1e18, + deposit: 11_222.172625306604949654 * 1e18, + exchangeRate: 1.562206295682965556 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, @@ -494,7 +494,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(32 hours); @@ -509,12 +509,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 1.699002800523494010 * 1e18, - quoteTokenAmount: 6_499.205062211668483663 * 1e18, - bondChange: 64.992050622116684837 * 1e18, + collateralArbed: 1.669877888034002475 * 1e18, + quoteTokenAmount: 6_387.793369052686121698 * 1e18, + bondChange: 63.877933690526861217 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 37.849749216362450585 * 1e18 + lpAwardKicker: 38.435354287866834063 * 1e18 }); // after bucket take, token id 3 is moved to pool claimable array (the most recent pledged) @@ -525,17 +525,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619361301 * 1e18, - borrowerCollateral: 0.300997199476505990 * 1e18, + borrowerDebt: 4_582.063964428011899646 * 1e18, + borrowerCollateral: 0.330122111965997525 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.258770970502146036 * 1e18 + borrowerCollateralization: 0.276978254692862222 * 1e18 }); _assertCollateralInvariants(); @@ -565,10 +565,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619361301 * 1e18, + borrowerDebt: 4_582.063964428011899646 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 781.829122098866670106 * 1e18, - borrowerCollateralization: 2.592032342562933134 * 1e18 + borrowert0Np: 801.113192353304652349 * 1e18, + borrowerCollateralization: 2.529637996454456058 * 1e18 }); _assertAuction( AuctionParams({ @@ -582,7 +582,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { totalBondEscrowed: 1_425.973870376971549568 * 1e18, auctionPrice: 0, debtInAuction: 0, - thresholdPrice: 1_490.588796066873120433 * 1e18, + thresholdPrice: 1_527.354654809337299882 * 1e18, neutralPrice: 0 }) ); @@ -601,17 +601,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBucket({ index: 6051, - lpBalance: 0.000023652411506879 * 1e18, - collateral: 0.300997199476505990 * 1e18, + lpBalance: 0.000025941052120484 * 1e18, + collateral: 0.330122111965997525 * 1e18, deposit: 0, - exchangeRate: 0.999999999999991497 * 1e18 + exchangeRate: 0.999999999999991014 * 1e18 }); // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs @@ -637,17 +637,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _borrower, borrower: _borrower, amountToRepay: 5_000 * 1e18, - amountRepaid: 4_471.766388200619361301 * 1e18, + amountRepaid: 4_582.063964428011899646 * 1e18, collateralToPull: 3, newLup: MAX_PRICE }); // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000023652411506878 * 1e18, + amount: 0.000025941052120483 * 1e18, index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000023652411506879 * 1e18 + lpRedeem: 0.000025941052120484 * 1e18 }); // the 3 NFTs pulled from pool are owned by borrower @@ -672,7 +672,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(32 hours); @@ -687,27 +687,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 1.699002800523494010 * 1e18, - quoteTokenAmount: 6_499.205062211668483663 * 1e18, - bondChange: 64.992050622116684837 * 1e18, + collateralArbed: 1.669877888034002475 * 1e18, + quoteTokenAmount: 6_387.793369052686121698 * 1e18, + bondChange: 63.877933690526861217 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 37.849749216362450585 * 1e18 + lpAwardKicker: 38.435354287866834063 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_471.766388200619361301 * 1e18, - borrowerCollateral: 0.300997199476505990 * 1e18, + borrowerDebt: 4_582.063964428011899646 * 1e18, + borrowerCollateral: 0.330122111965997525 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.258770970502146036 * 1e18 + borrowerCollateralization: 0.276978254692862222 * 1e18 }); _assertCollateralInvariants(); @@ -726,7 +726,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _borrower, borrower: _borrower, amountToRepay: 5_000 * 1e18, - amountRepaid: 4_471.766388200619361301 * 1e18, + amountRepaid: 4_582.063964428011899646 * 1e18, collateralToPull: 0, newLup: MAX_PRICE }); @@ -763,17 +763,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_784.974921636245059251 * 1e18, - collateral: 1.699002800523494010 * 1e18, - deposit: 1175, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 3_843.535428786683406029 * 1e18, + collateral: 1.669877888034002475 * 1e18, + deposit: 0, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBucket({ index: 6051, - lpBalance: 0.000023652411506879 * 1e18, - collateral: 0.300997199476505990 * 1e18, + lpBalance: 0.000025941052120484 * 1e18, + collateral: 0.330122111965997525 * 1e18, deposit: 0, - exchangeRate: 0.999999999999991497 * 1e18 + exchangeRate: 0.999999999999991014 * 1e18 }); // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs @@ -803,10 +803,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000023652411506878 * 1e18, + amount: 0.000025941052120483 * 1e18, index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000023652411506879 * 1e18 + lpRedeem: 0.000025941052120484 * 1e18 }); } @@ -821,15 +821,15 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 3_433.621534856445752000 * 1e18, - exchangeRate: 1.716810767428222876 * 1e18 + deposit: 3_323.342955252103772000 * 1e18, + exchangeRate: 1.661671477626051886 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(4 hours); @@ -856,7 +856,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 9201, + deposit: 9203, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ @@ -864,7 +864,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 9_904.062307087997104829 * 1e18, borrowerCollateral: 1.978621813918401907 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.764215028898934136 * 1e18 + borrowerCollateralization: 0.760412964078541435 * 1e18 }); _assertCollateralInvariants(); @@ -929,7 +929,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 9201, + deposit: 9203, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBucket({ @@ -988,8 +988,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 3_433.621534856445752000 * 1e18, - exchangeRate: 1.716810767428222876 * 1e18 + deposit: 3_323.342955252103772000 * 1e18, + exchangeRate: 1.661671477626051886 * 1e18 }); _assertBorrower({ @@ -997,7 +997,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(32 hours); @@ -1007,27 +1007,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.906830021600950636 * 1e18, - quoteTokenAmount: 3_468.902031908638183607 * 1e18, - bondChange: 34.689020319086381836 * 1e18, + collateralArbed: 0.877705109111459100 * 1e18, + quoteTokenAmount: 3_357.490338749655817817 * 1e18, + bondChange: 33.574903387496558178 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 20.202020202020202030 * 1e18 + lpAwardKicker: 20.202020202020202017 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_020.202020202020202030 * 1e18, - collateral: 0.906830021600950636 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 2_020.202020202020202017 * 1e18, + collateral: 0.877705109111459100 * 1e18, + deposit: 362, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7_471.766388200619358358 * 1e18, - borrowerCollateral: 1.093169978399049364 * 1e18, + borrowerDebt: 7_582.063964428011900489 * 1e18, + borrowerCollateral: 1.122294890888540900 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.556883685430732796 * 1e18 + borrowerCollateralization: 0.563403610033938441 * 1e18 }); _assertCollateralInvariants(); @@ -1054,12 +1054,12 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2000, - collateralArbed: 0.161346274954730238 * 1e18, - quoteTokenAmount: 7_547.238775960221574099 * 1e18, - bondChange: 75.472387759602215741 * 1e18, + collateralArbed: 0.163728054862748873 * 1e18, + quoteTokenAmount: 7_658.650469119203939887 * 1e18, + bondChange: 76.586504691192039399 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 75.472387759602215741 * 1e18 + lpAwardKicker: 76.586504691192039399 * 1e18 }); _assertBorrower({ @@ -1094,17 +1094,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2000, - lpBalance: 40_075.472387759602215741 * 1e18, - collateral: 0.161346274954730238 * 1e18, - deposit: 32_528.233611799380641641 * 1e18, - exchangeRate: 1 * 1e18 + lpBalance: 40_076.586504691192039399 * 1e18, + collateral: 0.163728054862748873 * 1e18, + deposit: 32_417.936035571988099513 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBucket({ index: 6051, - lpBalance: 0.000073222866272711 * 1e18, - collateral: 0.931823703444319126 * 1e18, + lpBalance: 0.000075324346213057 * 1e18, + collateral: 0.958566836025792027 * 1e18, deposit: 0, - exchangeRate: 1.000000000000005246 * 1e18 + exchangeRate: 0.999999999999996900 * 1e18 }); // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs @@ -1135,10 +1135,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // borrower removes tokens from auction price bucket for compensated collateral fraction _removeAllLiquidity({ from: _borrower, - amount: 0.000073222866272711 * 1e18, + amount: 0.000075324346213056 * 1e18, index: 6051, newLup: MAX_PRICE, - lpRedeem: 0.000073222866272711 * 1e18 + lpRedeem: 0.000075324346213057 * 1e18 }); } @@ -1152,8 +1152,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2502, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 3_433.621534856445752000 * 1e18, - exchangeRate: 1.716810767428222876 * 1e18 + deposit: 3_323.342955252103772000 * 1e18, + exchangeRate: 1.661671477626051886 * 1e18 }); _assertBorrower({ @@ -1161,7 +1161,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowerDebt: 10_190.456508610307854462 * 1e18, borrowerCollateral: 2 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.750762377759786560 * 1e18 + borrowerCollateralization: 0.747027241552026434 * 1e18 }); skip(32 hours); @@ -1171,27 +1171,27 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.906830021600950636 * 1e18, - quoteTokenAmount: 3_468.902031908638183607 * 1e18, - bondChange: 34.689020319086381836 * 1e18, + collateralArbed: 0.877705109111459100 * 1e18, + quoteTokenAmount: 3_357.490338749655817817 * 1e18, + bondChange: 33.574903387496558178 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 20.202020202020202030 * 1e18 + lpAwardKicker: 20.202020202020202017 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_020.202020202020202030 * 1e18, - collateral: 0.906830021600950636 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 2_020.202020202020202017 * 1e18, + collateral: 0.877705109111459100 * 1e18, + deposit: 362, + exchangeRate: 1.661957717681079631 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7_471.766388200619358358 * 1e18, - borrowerCollateral: 1.093169978399049364 * 1e18, + borrowerDebt: 7_582.063964428011900489 * 1e18, + borrowerCollateral: 1.122294890888540900 * 1e18, borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.556883685430732796 * 1e18 + borrowerCollateralization: 0.563403610033938441 * 1e18 }); _assertCollateralInvariants(); @@ -1213,7 +1213,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 3_714.709153177962409270 * 1e18 + settledDebt: 3_769.545371910961412793 * 1e18 }); _assertBorrower({ @@ -1249,16 +1249,16 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, lpBalance: 8_000 * 1e18, - collateral: 1.093169978399049364 * 1e18, - deposit: 8_769.974931189662198177 * 1e18, - exchangeRate: 1.624200736768212333 * 1e18 + collateral: 1.122294890888540900 * 1e18, + deposit: 8_218.389542394611030535 * 1e18, + exchangeRate: 1.569318637591693583 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_020.202020202020202030 * 1e18, - collateral: 0.906830021600950636 * 1e18, - deposit: 0, - exchangeRate: 1.717106505794775901 * 1e18 + lpBalance: 2_020.202020202020202017 * 1e18, + collateral: 0.877705109111459100 * 1e18, + deposit: 362, + exchangeRate: 1.661957717681079631 * 1e18 }); // lender merge / removes the other 2 NFTs diff --git a/tests/forge/unit/Rewards/ClaimRewards.t.sol b/tests/forge/unit/Rewards/ClaimRewards.t.sol index 7fe07fa5f..a54811626 100644 --- a/tests/forge/unit/Rewards/ClaimRewards.t.sol +++ b/tests/forge/unit/Rewards/ClaimRewards.t.sol @@ -96,7 +96,7 @@ contract ClaimRewardsOnStakeTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.798787696449363828 * 1e18, + tokensToBurn: 81.798787696449835897 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -114,7 +114,7 @@ contract ClaimRewardsOnStakeTest is RewardsHelperContract { tokenId: tokenIdTwo }); uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 4.089939384822468148 * 1e18); + assertEq(minterTwoBalance, 4.089939384822486675 * 1e18); vm.revertTo(stakeSnapshot); @@ -164,11 +164,11 @@ contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089939384822468148 * 1e18 + reward: 4.089939384822486675 * 1e18 }); uint256 updaterBalance = _ajnaToken.balanceOf(_updater); - assertEq(updaterBalance, 4.089939384822468148 * 1e18); + assertEq(updaterBalance, 4.089939384822486675 * 1e18); vm.revertTo(updateSnapshot); @@ -181,7 +181,7 @@ contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089939384822468148 * 1e18 + reward: 4.089939384822486675 * 1e18 }); updaterBalance = _ajnaToken.balanceOf(_updater); assertEq(updaterBalance, 1 * 1e18); @@ -197,7 +197,7 @@ contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089939384822468148 * 1e18 + reward: 4.089939384822486675 * 1e18 }); uint256 updaterBalance = _ajnaToken.balanceOf(_updater); assertEq(updaterBalance, 0); @@ -224,11 +224,11 @@ contract ClaimRewardsTest is ClaimRewardsOnStakeTest { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 19 * 1e18, - reward: 24.539636308934808886 * 1e18, + reward: 24.539636308934920041 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.539636308934808886 * 1e18); + assertEq(minterOneBalance, 24.539636308934920041 * 1e18); vm.revertTo(claimSnapshot); @@ -253,7 +253,7 @@ contract ClaimRewardsTest is ClaimRewardsOnStakeTest { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 5 * 1e18, - reward: 24.539636308934808886 * 1e18, + reward: 24.539636308934920041 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); @@ -297,7 +297,7 @@ contract ClaimRewardsTest is ClaimRewardsOnStakeTest { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 24.539636308934808886 * 1e18, + reward: 24.539636308934920041 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); @@ -319,12 +319,12 @@ contract ClaimRewardsOnUnstakeTest is ClaimRewardsOnStakeTest { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 24.539636308934808886 * 1e18, + reward: 24.539636308934920041 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 4.089939384822468148 * 1e18 + updateExchangeRatesReward: 4.089939384822486675 * 1e18 }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.539636308934808886 * 1e18); + assertEq(minterOneBalance, 24.539636308934920041 * 1e18); } function testClaimOnUnstakeWithInsufficientFunds() external { diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index 501b099a9..a0345e0b0 100644 --- a/tests/forge/unit/Rewards/RewardsManager.t.sol +++ b/tests/forge/unit/Rewards/RewardsManager.t.sol @@ -347,7 +347,7 @@ contract RewardsManagerTest is RewardsHelperContract { borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool), - tokensToBurn: 81.799082739441002012 * 1e18 + tokensToBurn: 81.799082739441061020 * 1e18 }); // call update exchange rate to enable claiming rewards @@ -355,7 +355,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972052373 * 1e18 }); // check only deposit owner can claim rewards @@ -370,7 +370,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenId, minAmountToReceive: 0, - reward: 40.899541369720500568 * 1e18, + reward: 40.899541369720523724 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); @@ -387,13 +387,13 @@ contract RewardsManagerTest is RewardsHelperContract { burnEvent: 1, rewardsEarned: 0 }); - assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720500568 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720523724 * 1e18); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.799082739441002012 * 1e18, + burned: 81.799082739441061020 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); @@ -443,7 +443,7 @@ contract RewardsManagerTest is RewardsHelperContract { // first reserve auction happens successfully -> epoch 1 uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2_555, pool: address(_pool) @@ -454,14 +454,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972057005 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.799082739441002012 * 1e18, + burned: 81.799082739441179038 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); @@ -473,7 +473,7 @@ contract RewardsManagerTest is RewardsHelperContract { borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool), - tokensToBurn: 150.531225765095992686 * 1e18 + tokensToBurn: 150.531225765096169950 * 1e18 }); // check owner can withdraw the NFT and rewards will be automatically claimed @@ -482,9 +482,9 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(2, 0), - reward: 78.702220033830716653 * 1e18, + reward: 78.702220033830793321 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 3.436607151282746917 * 1e18 + updateExchangeRatesReward: 3.436607151282747570 * 1e18 }); } @@ -519,7 +519,7 @@ contract RewardsManagerTest is RewardsHelperContract { // first reserve auction happens successfully Staker should receive rewards epoch 0 - 1 uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -530,7 +530,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972057005 * 1e18 }); skip(2 weeks); @@ -547,7 +547,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), epoch: 1, timestamp: block.timestamp - (2 weeks + 26 weeks + 24 hours), - burned: 81.799082739441002012 * 1e18, + burned: 81.799082739441179038 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); @@ -728,8 +728,8 @@ contract RewardsManagerTest is RewardsHelperContract { index: _i9_81, lpBalance: 10_000 * 1e18, collateral: 0, - deposit: 4_936.865539659334888884 * 1e18, - exchangeRate: 0.493686553965933489 * 1e18 + deposit: 4_886.628561176422153760 * 1e18, + exchangeRate: 0.488662856117642216 * 1e18 }); /***********************/ @@ -1345,7 +1345,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1356,7 +1356,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972057005 * 1e18 }); // burn rewards manager tokens and leave only 5 tokens available @@ -1364,7 +1364,7 @@ contract RewardsManagerTest is RewardsHelperContract { IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 5 * 1e18); + assertEq(managerBalance, 4.999999999999993052 * 1e18); // check reward generated are more than manager token balance uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1379,7 +1379,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 40.899541369720500568 * 1e18, + reward: 40.899541369720570039 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); @@ -1428,7 +1428,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 408.996298826179924310 * 1e18, + tokensToBurn: 408.996298826180042327 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6000, pool: address(_pool) @@ -1439,12 +1439,12 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 20.449814941308995996 * 1e18 + reward: 20.449814941309000626 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 20.449814941308995996 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 20.449814941309000626 * 1e18); uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 204.498149413089959965 * 1e18); + assertEq(rewardsEarned, 204.498149413090006279 * 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); /******************************/ @@ -1453,7 +1453,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079403940202 * 1e18, + tokensToBurn: 749.938293079404058517 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1464,13 +1464,13 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661198328 * 1e18 + reward: 17.047099712661199616 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 37.496914653970194324 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 37.496914653970200242 * 1e18); // check available rewards rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 374.969146539701943260 * 1e18); + assertEq(rewardsEarned, 374.969146539702002449 * 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); /*****************************/ @@ -1480,7 +1480,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger third reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_030.321595435443764986 * 1e18, + tokensToBurn: 1_030.321595435443883599 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1488,7 +1488,7 @@ contract RewardsManagerTest is RewardsHelperContract { // skip updating exchange rates and check available rewards uint256 rewardsEarnedNoUpdate = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedNoUpdate, 374.969146539701943260 * 1e18); + assertEq(rewardsEarnedNoUpdate, 374.969146539702002449* 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); // snapshot calling update exchange rate @@ -1499,10 +1499,10 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndexes, - reward: 14.019165117801987568 * 1e18 + reward: 14.019165117801987582 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 14.019165117801987568 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 14.019165117801987582 * 1e18); // check available rewards rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1519,7 +1519,7 @@ contract RewardsManagerTest is RewardsHelperContract { // triger fourth reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_285.690028219559662165 * 1e18, + tokensToBurn: 1_285.690028219559780957 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1527,7 +1527,7 @@ contract RewardsManagerTest is RewardsHelperContract { // check rewards earned rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 374.969146539701943260 * 1e18); + assertEq(rewardsEarned, 374.969146539702002449 * 1e18); // call update exchange rate _updateExchangeRates({ @@ -1540,7 +1540,7 @@ contract RewardsManagerTest is RewardsHelperContract { // check rewards earned won't increase since previous update was missed rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 374.969146539701943260 * 1e18); + assertEq(rewardsEarned, 374.969146539702002449 * 1e18); /*****************************/ /*** Fifth Reserve Auction ***/ @@ -1549,7 +1549,7 @@ contract RewardsManagerTest is RewardsHelperContract { // triger fifth reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_518.007030973479013922 * 1e18, + tokensToBurn: 1_518.007030973479132952 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1560,12 +1560,12 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndexes, - reward: 11.615850137695965354 * 1e18 + reward: 11.615850137695967876 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 11.615850137695965354 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 11.615850137695967876 * 1e18); rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 491.127647916661596787 * 1e18); + assertEq(rewardsEarned, 491.127647916661681237 * 1e18); // claim all rewards accrued since deposit _claimRewards({ @@ -1574,7 +1574,7 @@ contract RewardsManagerTest is RewardsHelperContract { tokenId: tokenIdOne, minAmountToReceive: 0, epochsClaimed: _epochsClaimedArray(5,0), - reward: 491.127647916661596787 * 1e18 + reward: 491.127647916661681237 * 1e18 }); assertEq(_ajnaToken.balanceOf(_minterOne), rewardsEarned); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); @@ -1652,7 +1652,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 133.010720463154801131 * 1e18, + tokensToBurn: 133.010720463154931188 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1664,24 +1664,24 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdTwo, claimedArray: _epochsClaimedArray(1, 0), - reward: 39.906143408239914821 * 1e18, + reward: 39.908147491580588274 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 6.651023502439557481 * 1e18 + updateExchangeRatesReward: 6.651023502439564179 * 1e18 }); uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 39.906143408239914821 * 1e18); + assertEq(minterTwoBalance, 39.908147491580588274 * 1e18); _unstakeToken({ owner: _minterThree, pool: address(_pool), tokenId: tokenIdThree, claimedArray: _epochsClaimedArray(1, 0), - reward: 33.250240325777047148 * 1e18, + reward: 33.248236242436447412 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); uint256 minterThreeBalance = _ajnaToken.balanceOf(_minterThree); - assertEq(minterThreeBalance, 33.250240325777047148 * 1e18); + assertEq(minterThreeBalance, 33.248236242436447412 * 1e18); assertGt(minterTwoBalance, minterThreeBalance); } @@ -1724,7 +1724,7 @@ contract RewardsManagerTest is RewardsHelperContract { // borrower takes actions providing reserves enabling reserve auctions uint256 firstTokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441061020 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -1748,7 +1748,7 @@ contract RewardsManagerTest is RewardsHelperContract { owner: _minterTwo, tokenId: tokenIdTwo }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 8.154774722201710814 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterTwo), 8.171892378490154686 * 1e18); // calculate rewards earned since exchange rates have been updated uint256 idOneRewardsAtOne = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1772,7 +1772,7 @@ contract RewardsManagerTest is RewardsHelperContract { // conduct second reserve auction uint256 secondTokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 175.885944654845768334 * 1e18, + tokensToBurn: 175.885944654845768512 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -1804,11 +1804,11 @@ contract RewardsManagerTest is RewardsHelperContract { uint256 idOneRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); assertLt(idOneRewardsAtTwo, secondTokensToBurn); assertGt(idOneRewardsAtTwo, 0); - assertEq(idOneRewardsAtTwo, 23.539670861841378258 * 1e18); + assertEq(idOneRewardsAtTwo, 23.539670861841372334 * 1e18); uint256 idTwoRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdTwo, _pool.currentBurnEpoch()); assertLt(idOneRewardsAtTwo + idTwoRewardsAtTwo, secondTokensToBurn); - assertEq(idTwoRewardsAtTwo, 23.507224958013744605 * 1e18); + assertEq(idTwoRewardsAtTwo, 23.507224958013738649 * 1e18); assertGt(idTwoRewardsAtTwo, 0); // minter one claims rewards accrued after second auction @@ -1818,7 +1818,7 @@ contract RewardsManagerTest is RewardsHelperContract { tokenId: tokenIdOne, minAmountToReceive: 0, epochsClaimed: _epochsClaimedArray(1,1), - reward: 23.539670861841378258 * 1e18 + reward: 23.539670861841372334 * 1e18 }); assertEq(_ajnaToken.balanceOf(_minterOne), idOneRewardsAtOne + idOneRewardsAtTwo); @@ -1832,7 +1832,7 @@ contract RewardsManagerTest is RewardsHelperContract { epochsClaimed: _epochsClaimedArray(1,1), reward: idTwoRewardsAtTwo }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 31.661999680215455419 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterTwo), 31.679117336503893335 * 1e18); // check there are no remaining rewards available after claiming uint256 remainingRewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1904,7 +1904,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction one uint256 tokensToBurnE1 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.797607524483578206 * 1e18, + tokensToBurn: 81.797607524484463335 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1914,14 +1914,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089880376224170616 * 1e18 + reward: 4.089880376224205350 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.797607524483578206 * 1e18, + burned: 81.797607524484463335 * 1e18, tokensToBurn: tokensToBurnE1, interest: 6.443638300196908069 * 1e18 }); @@ -1929,7 +1929,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction two uint256 tokensToBurnE2 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 308.522250520127764524 * 1e18, + tokensToBurn: 308.522250520128650190 * 1e18, borrowAmount: 1_000 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1939,14 +1939,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 11.336232149782180622 * 1e18 + reward: 11.336232149782168987 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 2, timestamp: block.timestamp - 24 hours, - burned: 308.522250520127764524 * 1e18, + burned: 308.522250520128650190 * 1e18, tokensToBurn: tokensToBurnE2, interest: 23.938554041534910348 * 1e18 }); @@ -1954,7 +1954,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction three uint256 tokensToBurnE3 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 676.508959571630871476 * 1e18, + tokensToBurn: 676.508959571631757977 * 1e18, borrowAmount: 2_000 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1964,14 +1964,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 18.399335452575174332 * 1e18 + reward: 18.399335452575176310 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 3, timestamp: block.timestamp - 24 hours, - burned: 676.508959571630871476 * 1e18, + burned: 676.508959571631757977 * 1e18, tokensToBurn: tokensToBurnE3, interest: 52.423541260157607958 * 1e18 }); @@ -1982,7 +1982,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(3, 0), - reward: 51.499239671312554526 * 1e18, + reward: 56.375746630969251081 * 1e18, indexes: firstIndexes, updateExchangeRatesReward: 0 }); @@ -1992,7 +1992,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdTwo, claimedArray: _epochsClaimedArray(3, 0), - reward: 286.755240114502701181 * 1e18, + reward: 281.878733154846255411 * 1e18, indexes: secondIndexes, updateExchangeRatesReward: 0 }); @@ -2025,7 +2025,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2036,7 +2036,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972057005 * 1e18 }); // _minterOne unstakes staked position @@ -2045,7 +2045,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 40.899541369720500568 * 1e18, + reward: 40.899541369720570039 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); @@ -2140,7 +2140,7 @@ contract RewardsManagerTest is RewardsHelperContract { uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2151,7 +2151,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972057005 * 1e18 }); // check owner can withdraw the NFT and rewards will be automatically claimed @@ -2165,7 +2165,7 @@ contract RewardsManagerTest is RewardsHelperContract { IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 5 * 1e18); + assertEq(managerBalance, 4.999999999999993052 * 1e18); // check reward generated are more than manager token balance uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -2183,13 +2183,13 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 40.899541369720500568 * 1e18, + reward: 40.899541369720570039 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); assertEq(PositionManager(address(_positionManager)).ownerOf(tokenIdOne), _minterOne); - assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720500568 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720570039 * 1e18); assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); // check can't claim rewards twice @@ -2227,7 +2227,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger ajna burns _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441179038 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2239,7 +2239,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 44.989495506692550625 * 1e18, + reward: 44.989495506692627044 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); @@ -2298,7 +2298,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441002012 * 1e18, + tokensToBurn: 81.799082739441061020 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -2327,9 +2327,9 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _minterOne, pool: address(_pool), indexes: firstIndexes, - reward: 4.089954136972050057 * 1e18 + reward: 4.089954136972052373 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_minterOne), 4.089954136972050057 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 4.089954136972052373 * 1e18); // check owner in pool with accrued interest can properly claim rewards _claimRewards({ @@ -2337,7 +2337,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 40.899541369720500568 * 1e18, + reward: 40.899541369720523724 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); @@ -2385,7 +2385,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 408.996298826179924310 * 1e18, + tokensToBurn: 408.996298826180042327 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6000, pool: address(_pool) @@ -2396,14 +2396,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 20.449814941308995996 * 1e18 + reward: 20.449814941309000626 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 20.449814941308995996 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 20.449814941309000626 * 1e18); uint256 rewardsEarnedFirstEpoch = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedFirstEpoch, 204.498149413089959965 * 1e18); + assertEq(rewardsEarnedFirstEpoch, 204.498149413090006279 * 1e18); - uint256 totalRewardEarned = 374.969146539701943260 * 1e18; + uint256 totalRewardEarned = 374.969146539702002449 * 1e18; uint256 snapshot = vm.snapshot(); @@ -2446,7 +2446,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079403940202 * 1e18, + tokensToBurn: 749.938293079404058517 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -2457,7 +2457,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661198328 * 1e18 + reward: 17.047099712661199616 * 1e18 }); uint256 newRewardsEarned = totalRewardEarned - rewardsEarnedFirstEpoch; @@ -2485,7 +2485,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079403940202 * 1e18, + tokensToBurn: 749.938293079404058517 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -2496,7 +2496,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661198328 * 1e18 + reward: 17.047099712661199616 * 1e18 }); // check available rewards From 04adfedd597ba19fd362f82d14a85a1649d87ebf Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Sat, 1 Jul 2023 00:13:17 +0300 Subject: [PATCH 27/32] Readable order of operations (#917) * Readable order of operations * Remove extra space --- src/libraries/external/PoolCommons.sol | 2 +- src/libraries/helpers/PoolHelper.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index e4ebc2b8a..659a6beae 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -281,7 +281,7 @@ library PoolCommons { if (poolState_.debt != 0) { // calculate meaningful actual utilization for interest rate update mau = int256(_utilization(debtEma_, depositEma_)); - mau102 = mau * PERCENT_102 / 1e18; + mau102 = (mau * PERCENT_102) / 1e18; } // calculate target utilization diff --git a/src/libraries/helpers/PoolHelper.sol b/src/libraries/helpers/PoolHelper.sol index fe9b14f77..afb6e633c 100644 --- a/src/libraries/helpers/PoolHelper.sol +++ b/src/libraries/helpers/PoolHelper.sol @@ -418,7 +418,7 @@ import { Maths } from '../internal/Maths.sol'; uint256 collateral_, uint256 momp_ ) pure returns (uint256 bondFactor_, uint256 bondSize_) { - uint256 thresholdPrice = borrowerDebt_ * Maths.WAD / collateral_; + uint256 thresholdPrice = (borrowerDebt_ * Maths.WAD) / collateral_; // bondFactor = min(30%, max(1%, (MOMP - thresholdPrice) / MOMP)) if (thresholdPrice >= momp_) { From 94be5c24dc448a9a0e914036450ac57b00c5ad11 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Sat, 1 Jul 2023 15:01:38 +0300 Subject: [PATCH 28/32] Sherlock-72 (continuation - move quote token): Lenders pay deposit fees due to no slippage control (#918) * Sherlock-72 (continuation - move quote token): Lenders pay deposit fees due to no slippage control * Shrink Pool contract size, fix brownie test --- src/PositionManager.sol | 6 +- src/base/Pool.sol | 64 ++++++++++++------- src/interfaces/pool/commons/IPoolErrors.sol | 2 +- .../pool/commons/IPoolInternals.sol | 9 +-- .../pool/commons/IPoolLenderActions.sol | 18 +++--- .../position/IPositionManagerOwnerActions.sol | 14 ++-- src/libraries/external/LenderActions.sol | 4 ++ tests/brownie/test_scaled_pool.py | 2 +- .../UnboundedERC20PoolPositionsHandler.sol | 2 +- .../UnboundedERC721PoolPositionsHandler.sol | 2 +- .../unbounded/UnboundedBasicPoolHandler.sol | 3 +- .../forge/unit/ERC20Pool/ERC20DSTestPlus.sol | 2 +- .../unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol | 2 +- .../ERC20Pool/ERC20PoolInputValidation.t.sol | 8 +-- .../ERC20PoolLiquidationsSettle.t.sol | 8 +-- .../unit/ERC20Pool/ERC20PoolQuoteToken.t.sol | 8 +++ .../ERC721PoolInputValidation.t.sol | 8 +-- .../unit/Positions/CodearenaReports.t.sol | 18 +++--- .../unit/Positions/PositionManager.t.sol | 20 +++--- tests/forge/utils/DSTestPlus.sol | 27 +++++--- 20 files changed, 137 insertions(+), 90 deletions(-) diff --git a/src/PositionManager.sol b/src/PositionManager.sol index 9a63f10c4..2bc3ee1e9 100644 --- a/src/PositionManager.sol +++ b/src/PositionManager.sol @@ -290,7 +290,8 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc uint256 tokenId_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_ + uint256 expiry_, + bool revertIfBelowLup_ ) external override nonReentrant mayInteract(pool_, tokenId_) { TokenInfo storage tokenInfo = positionTokens[tokenId_]; Position storage fromPosition = tokenInfo.positions[fromIndex_]; @@ -334,7 +335,8 @@ contract PositionManager is PermitERC721, IPositionManager, Multicall, Reentranc vars.maxQuote, fromIndex_, toIndex_, - expiry_ + expiry_, + revertIfBelowLup_ ); EnumerableSet.UintSet storage positionIndexes = tokenInfo.positionIndexes; diff --git a/src/base/Pool.sol b/src/base/Pool.sol index a71b63e42..5f26cb0fb 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -25,6 +25,7 @@ import { PoolState, AuctionsState, DepositsState, + Loan, LoansState, InflatorState, EmaState, @@ -32,6 +33,7 @@ import { PoolBalancesState, ReserveAuctionState, Bucket, + Lender, BurnEvent, Liquidation } from '../interfaces/pool/commons/IPoolState.sol'; @@ -182,13 +184,21 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 maxAmount_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_ + uint256 expiry_, + bool revertIfBelowLup_ ) external override nonReentrant returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_) { _revertAfterExpiry(expiry_); 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_; + uint256 newLup; ( fromBucketLP_, @@ -199,12 +209,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { buckets, deposits, poolState, - MoveQuoteParams({ - maxAmountToMove: maxAmount_, - fromIndex: fromIndex_, - toIndex: toIndex_, - thresholdPrice: Loans.getMax(loans).thresholdPrice - }) + moveParams ); // update pool interest rate state @@ -785,10 +790,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 index_ ) external view override returns (uint256, uint256, uint256, uint256, uint256) { uint256 scale = Deposits.scale(deposits, index_); + Bucket storage bucket = buckets[index_]; return ( - buckets[index_].lps, - buckets[index_].collateral, - buckets[index_].bankruptcyTime, + bucket.lps, + bucket.collateral, + bucket.bankruptcyTime, Maths.wmul(scale, Deposits.unscaledValueAt(deposits, index_)), scale ); @@ -826,15 +832,20 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { /// @inheritdoc IPoolState function debtInfo() external view returns (uint256, uint256, uint256, uint256) { - uint256 pendingInflator = PoolCommons.pendingInflator( - inflatorState.inflator, - inflatorState.inflatorUpdate, - interestState.interestRate - ); + uint256 t0Debt = poolBalances.t0Debt; + uint256 inflator = inflatorState.inflator; + return ( - Maths.ceilWmul(poolBalances.t0Debt, pendingInflator), - Maths.ceilWmul(poolBalances.t0Debt, inflatorState.inflator), - Maths.ceilWmul(poolBalances.t0DebtInAuction, inflatorState.inflator), + Maths.ceilWmul( + t0Debt, + PoolCommons.pendingInflator( + inflator, + inflatorState.inflatorUpdate, + interestState.interestRate + ) + ), + Maths.ceilWmul(t0Debt, inflator), + Maths.ceilWmul(poolBalances.t0DebtInAuction, inflator), interestState.t0Debt2ToCollateral ); } @@ -906,8 +917,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 index_, address lender_ ) external view override returns (uint256 lpBalance_, uint256 depositTime_) { - depositTime_ = buckets[index_].lenders[lender_].depositTime; - if (buckets[index_].bankruptcyTime < depositTime_) lpBalance_ = buckets[index_].lenders[lender_].lps; + Bucket storage bucket = buckets[index_]; + Lender storage lender = bucket.lenders[lender_]; + + depositTime_ = lender.depositTime; + if (bucket.bankruptcyTime < depositTime_) lpBalance_ = lender.lps; } /// @inheritdoc IPoolState @@ -923,17 +937,19 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function loanInfo( uint256 loanId_ ) external view override returns (address, uint256) { + Loan memory loan = Loans.getByIndex(loans, loanId_); return ( - Loans.getByIndex(loans, loanId_).borrower, - Loans.getByIndex(loans, loanId_).thresholdPrice + loan.borrower, + loan.thresholdPrice ); } /// @inheritdoc IPoolState function loansInfo() external view override returns (address, uint256, uint256) { + Loan memory maxLoan = Loans.getMax(loans); return ( - Loans.getMax(loans).borrower, - Maths.wmul(Loans.getMax(loans).thresholdPrice, inflatorState.inflator), + maxLoan.borrower, + Maths.wmul(maxLoan.thresholdPrice, inflatorState.inflator), Loans.noOfLoans(loans) ); } diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index ad6a3eaa1..b5fddaff9 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -180,7 +180,7 @@ interface IPoolErrors { error PoolUnderCollateralized(); /** - * @notice Actor is attempting to add quote tokens at a price below the `LUP`. + * @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(); diff --git a/src/interfaces/pool/commons/IPoolInternals.sol b/src/interfaces/pool/commons/IPoolInternals.sol index 8c86c902a..f1b62ca89 100644 --- a/src/interfaces/pool/commons/IPoolInternals.sol +++ b/src/interfaces/pool/commons/IPoolInternals.sol @@ -78,10 +78,11 @@ struct AddQuoteParams { /// @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 + 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 } /// @dev Struct used to hold parameters for `LenderAction.removeQuoteToken` action. diff --git a/src/interfaces/pool/commons/IPoolLenderActions.sol b/src/interfaces/pool/commons/IPoolLenderActions.sol index 6fc1e3b9e..25ac4c048 100644 --- a/src/interfaces/pool/commons/IPoolLenderActions.sol +++ b/src/interfaces/pool/commons/IPoolLenderActions.sol @@ -28,19 +28,21 @@ interface IPoolLenderActions { /** * @notice Called by lenders to move an amount of credit from a specified price bucket to another specified price bucket. - * @param maxAmount_ The maximum amount of quote token to be moved by a lender (`WAD` precision). - * @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. - * @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). + * @param maxAmount_ The maximum amount of quote token to be moved by a lender (`WAD` precision). + * @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). */ function moveQuoteToken( uint256 maxAmount_, uint256 fromIndex_, uint256 toIndex_, - uint256 expiry_ + uint256 expiry_, + bool revertIfBelowLup_ ) external returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_); /** diff --git a/src/interfaces/position/IPositionManagerOwnerActions.sol b/src/interfaces/position/IPositionManagerOwnerActions.sol index 6e468061a..3af266a9d 100644 --- a/src/interfaces/position/IPositionManagerOwnerActions.sol +++ b/src/interfaces/position/IPositionManagerOwnerActions.sol @@ -50,18 +50,20 @@ interface IPositionManagerOwnerActions { /** * @notice Called by owners to move liquidity between two buckets. - * @param pool_ The pool address associated with positions NFT. - * @param tokenId_ The tokenId of the positions NFT. - * @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 pool_ The pool address associated with positions NFT. + * @param tokenId_ The tokenId of the positions NFT. + * @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_ + uint256 expiry_, + bool revertIfBelowLup_ ) external; /** diff --git a/src/libraries/external/LenderActions.sol b/src/libraries/external/LenderActions.sol index 72cd30953..97501bf83 100644 --- a/src/libraries/external/LenderActions.sol +++ b/src/libraries/external/LenderActions.sol @@ -142,6 +142,7 @@ 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` */ @@ -233,6 +234,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 === Emit events === * @dev - `BucketBankruptcy` * @dev - `MoveQuoteToken` @@ -288,6 +290,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(); + movedAmount_ = Maths.wmul(movedAmount_, Maths.WAD - _depositFeeRate(poolState_.rate)); } diff --git a/tests/brownie/test_scaled_pool.py b/tests/brownie/test_scaled_pool.py index 344dde473..24a1a17d3 100644 --- a/tests/brownie/test_scaled_pool.py +++ b/tests/brownie/test_scaled_pool.py @@ -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, {"from": lenders[0]}) + tx = scaled_pool.moveQuoteToken(100 * 10**18, i, i + 30, chain.time() + 30, False, {"from": lenders[0]}) move_txes.append(tx) with capsys.disabled(): print("\n==================================") diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol index e18c751c1..e9204dcbf 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol @@ -242,7 +242,7 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan * @notice Struct holding parameters for moving the liquidity of a position. */ - try _positionManager.moveLiquidity(address(_pool), tokenId_, fromIndex_, toIndex_, block.timestamp + 30) { + try _positionManager.moveLiquidity(address(_pool), tokenId_, fromIndex_, toIndex_, block.timestamp + 30, false) { bucketIndexesByTokenId[tokenId_].add(toIndex_); bucketIndexesByTokenId[tokenId_].remove(fromIndex_); diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol index 9523c437b..e1e6acbf7 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol @@ -242,7 +242,7 @@ abstract contract UnboundedERC721PoolPositionsHandler is UnboundedBasePositionHa * @notice Struct holding parameters for moving the liquidity of a position. */ - try _positionManager.moveLiquidity(address(_pool), tokenId_, fromIndex_, toIndex_, block.timestamp + 30) { + try _positionManager.moveLiquidity(address(_pool), tokenId_, fromIndex_, toIndex_, block.timestamp + 30, false) { bucketIndexesByTokenId[tokenId_].add(toIndex_); bucketIndexesByTokenId[tokenId_].remove(fromIndex_); diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol index cacf4c04f..4bff808a3 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedBasicPoolHandler.sol @@ -112,7 +112,8 @@ abstract contract UnboundedBasicPoolHandler is BaseHandler { amount_, fromIndex_, toIndex_, - block.timestamp + 1 minutes + block.timestamp + 1 minutes, + false ) returns (uint256, uint256, uint256 movedAmount_) { (, uint256 fromBucketDepositTime) = _pool.lenderInfo(fromIndex_, _actor); diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index 2e94d7b82..076816f82 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -740,7 +740,7 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.LUPBelowHTP.selector); - ERC20Pool(address(_pool)).moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + ERC20Pool(address(_pool)).moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol index 3e3dd6091..8be2b0cc4 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolGasLoadTest.t.sol @@ -278,7 +278,7 @@ contract ERC20PoolCommonActionsGasLoadTest is ERC20PoolGasLoadTest { _pool.removeQuoteToken(5_000 * 1e18, index_); skip(15 hours); - _pool.moveQuoteToken(1_000 * 1e18, index_, index_ + 1, block.timestamp + 2 minutes); + _pool.moveQuoteToken(1_000 * 1e18, index_, index_ + 1, block.timestamp + 2 minutes, false); skip(15 hours); _pool.removeQuoteToken(type(uint256).max, index_); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol index c82b82725..fcb3e5632 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInputValidation.t.sol @@ -25,16 +25,16 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { function testValidateMoveQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1); + _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1, false); // revert on move to same index vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1, false); // revert on to zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1, false); // revert on to index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); } function testValidateRemoveQuoteTokenInput() external tearDown { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 815bb2b5d..f607bb907 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -812,7 +812,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); + _pool.moveQuoteToken(10 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); (, , uint256 bankruptcyTime, , ) = _pool.bucketInfo(_i9_91); _assertLenderLpBalance({ lender: _lender1, @@ -848,7 +848,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { depositTime: _startTime }); - _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes); + _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); _assertLenderLpBalance({ lender: _lender, @@ -858,7 +858,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); _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); + _pool.moveQuoteToken(1_000 * 1e18, _i9_52, _i9_91, block.timestamp + 1 minutes, false); _assertLenderLpBalance({ lender: _lender, @@ -876,7 +876,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { exchangeRate: 0.821534360361016385 * 1e18 }); - _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max); + _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max, false); _assertBucket({ index: _i9_72, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index ff071c79a..6ecfb0a3b 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -1223,6 +1223,14 @@ 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 _moveLiquidityWithPenalty({ from: _lender, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol index cfb268c40..c19b18895 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolInputValidation.t.sol @@ -30,16 +30,16 @@ contract ERC721PoolBorrowTest is ERC721HelperContract { function testValidateMoveQuoteTokenInput() external tearDown { // revert on zero amount vm.expectRevert(IPoolErrors.InvalidAmount.selector); - _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1); + _pool.moveQuoteToken(0, 1, 2, block.timestamp + 1, false); // revert on move to same index vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, 1, block.timestamp + 1, false); // revert on to zero index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, 0, block.timestamp + 1, false); // revert on to index greater than max index vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1); + _pool.moveQuoteToken(1000, 1, MAX_FENWICK_INDEX + 1, block.timestamp + 1, false); } function testValidateRemoveQuoteTokenInput() external tearDown { diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/Positions/CodearenaReports.t.sol index df64e5948..6bfe61eea 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/Positions/CodearenaReports.t.sol @@ -188,11 +188,11 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract changePrank(testMinter2); vm.expectRevert(IPoolErrors.BucketBankruptcyBlock.selector); - _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours); + _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours, false); // 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); + _positionManager.moveLiquidity(address(_pool), tokenId2, _i9_52, _i9_91, block.timestamp + 5 hours, false); // report 494: testMinter2 position at _i9_91 should not be bankrupt assertFalse(_positionManager.isPositionBucketBankrupt(tokenId2, _i9_91)); @@ -214,11 +214,11 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract // 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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_52, block.timestamp + 5 hours, false); // 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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_52, _i9_91, block.timestamp + 5 hours, false); assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_91)); assertFalse(_positionManager.isPositionBucketBankrupt(tokenId, _i9_52)); @@ -266,7 +266,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract vm.expectEmit(true, true, true, true); emit MoveLiquidity(testAddress1, tokenId1, mintIndex, moveIndex, 2_500 * 1e18, 2_500 * 1e18); changePrank(address(testAddress1)); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); // check from and to positions after move // from position should have 0 LP and 0 deposit time (FROM Position struct is deleted) @@ -339,7 +339,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract // 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); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); } /** @@ -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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_91, block.timestamp + 5 hours, false); 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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_81, block.timestamp + 5 hours, false); vm.revertTo(preMoveDownState); @@ -764,7 +764,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract exchangeRate: 1e18 }); - _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_52, block.timestamp + 5 hours); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_81, _i9_52, block.timestamp + 5 hours, false); _assertBucketAssets({ index: _i9_81, diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol index 652888669..d351c68b8 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -962,7 +962,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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_91, _i9_72, block.timestamp + 30, false); // check lender state after bankruptcy before rememorializing _assertLenderLpBalance({ @@ -1565,7 +1565,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); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); } function testMoveLiquidity() external tearDown { @@ -1709,7 +1709,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract 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); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); // check pool state _assertLenderLpBalance({ @@ -1829,7 +1829,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract 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); + _positionManager.moveLiquidity(address(_pool), tokenId2, mintIndex, moveIndex, block.timestamp + 30, false); // check pool state _assertLenderLpBalance({ @@ -1881,7 +1881,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract changePrank(address(testAddress2)); vm.expectRevert(IPositionManagerErrors.RemovePositionFailed.selector); - _positionManager.moveLiquidity(address(_pool), tokenId2, 1000, 2000, block.timestamp + 30); + _positionManager.moveLiquidity(address(_pool), tokenId2, 1000, 2000, block.timestamp + 30, false); } function testMoveLiquidityWithInterest() external tearDown { @@ -1960,7 +1960,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // lender 1 moves liquidity changePrank(lender1); - _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30); + _positionManager.moveLiquidity(address(_pool), tokenId1, mintIndex, moveIndex, block.timestamp + 30, false); // check pool state _assertLenderLpBalance({ @@ -2411,7 +2411,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); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); // minter cannot redeem positions on behalf of lender (is not approved) vm.expectRevert(IPositionManagerErrors.NoAuth.selector); @@ -2426,7 +2426,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); + _positionManager.moveLiquidity(address(_pool), tokenId, 2550, 2551, block.timestamp + 30, false); _assertLenderLpBalance({ lender: lender, @@ -2918,7 +2918,7 @@ 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); + _positionManager.moveLiquidity(address(_pool), tokenId, _i9_72, testIndex, block.timestamp + 5 hours, false); _assertBucketAssets({ index: _i9_91, @@ -3273,7 +3273,7 @@ contract PositionManagerERC721PoolTest is PositionManagerERC721PoolHelperContrac 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); + _positionManager.moveLiquidity(address(_pool), tokenId, indexes[0], indexes[1], block.timestamp + 30, false); // check LP balance _assertLenderLpBalance({ diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index ed9edd177..653f0ddd7 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -297,7 +297,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); + (uint256 lpbFrom, uint256 lpbTo, ) = _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); assertEq(lpbFrom, lpRedeemFrom); assertEq(lpbTo, lpAwardTo); @@ -1235,7 +1235,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(abi.encodeWithSignature('BucketBankruptcyBlock()')); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } function _assertMoveLiquidityLupBelowHtpRevert( @@ -1246,7 +1246,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.LUPBelowHTP.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } function _assertMoveLiquidityExpiredRevert( @@ -1258,7 +1258,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.TransactionExpired.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, expiry); + _pool.moveQuoteToken(amount, fromIndex, toIndex, expiry, false); } function _assertMoveLiquidityDustRevert( @@ -1269,7 +1269,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.DustAmountNotExceeded.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } function _assertMoveLiquidityToSameIndexRevert( @@ -1280,7 +1280,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.MoveToSameIndex.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } function _assertMoveLiquidityToIndex0Revert( @@ -1290,7 +1290,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.InvalidIndex.selector); - _pool.moveQuoteToken(amount, fromIndex, 0, type(uint256).max); + _pool.moveQuoteToken(amount, fromIndex, 0, type(uint256).max, false); } function _assertMoveDepositLockedByAuctionDebtRevert( @@ -1301,7 +1301,18 @@ abstract contract DSTestPlus is Test, IPoolEvents { ) internal { changePrank(from); vm.expectRevert(IPoolErrors.RemoveDepositLockedByAuctionDebt.selector); - _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max); + _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); } function _assertTakeAuctionInCooldownRevert( From 2af7d818c9e53d36b28bed0a068cd2d6b8e0a245 Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Sun, 2 Jul 2023 07:48:31 +0300 Subject: [PATCH 29/32] Sherlock-110 (moveQuoteToken continuation): move quote token revert if auction clearable (#919) --- docs/Functions.md | 2 ++ src/base/Pool.sol | 21 ++++++++++++------- .../ERC20Pool/ERC20PoolLiquidationsMisc.t.sol | 13 ++++++++++++ tests/forge/utils/DSTestPlus.sol | 11 ++++++++++ 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/docs/Functions.md b/docs/Functions.md index 6a1ee5799..115d20e1d 100644 --- a/docs/Functions.md +++ b/docs/Functions.md @@ -66,7 +66,9 @@ - pool inflator and inflatorUpdate state reverts on: + - block timestamp greater than expiry TransactionExpired() - deposits locked RemoveDepositLockedByAuctionDebt() + - head auction not cleared AuctionNotCleared() - LenderActions.moveQuoteToken(): - same index MoveToSameIndex() - dust amount DustAmountNotExceeded() diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 5f26cb0fb..3643fd56c 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -34,6 +34,8 @@ import { ReserveAuctionState, Bucket, Lender, + Borrower, + Kicker, BurnEvent, Liquidation } from '../interfaces/pool/commons/IPoolState.sol'; @@ -188,6 +190,9 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { bool revertIfBelowLup_ ) external override nonReentrant returns (uint256 fromBucketLP_, uint256 toBucketLP_, uint256 movedAmount_) { _revertAfterExpiry(expiry_); + + _revertIfAuctionClearable(auctions, loans); + PoolState memory poolState = _accruePoolInterest(); _revertIfAuctionDebtLocked(deposits, poolState.t0DebtInAuction, fromIndex_, poolState.inflator); @@ -759,7 +764,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { address prev_, bool alreadyTaken_ ) { - Liquidation memory liquidation = auctions.liquidations[borrower_]; + Liquidation storage liquidation = auctions.liquidations[borrower_]; return ( liquidation.kicker, liquidation.bondFactor, @@ -778,10 +783,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function borrowerInfo( address borrower_ ) external view override returns (uint256, uint256, uint256) { + Borrower storage borrower = loans.borrowers[borrower_]; return ( - loans.borrowers[borrower_].t0Debt, - loans.borrowers[borrower_].collateral, - loans.borrowers[borrower_].t0Np + borrower.t0Debt, + borrower.collateral, + borrower.t0Np ); } @@ -821,7 +827,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { /// @inheritdoc IPoolState function burnInfo(uint256 burnEventEpoch_) external view returns (uint256, uint256, uint256) { - BurnEvent memory burnEvent = reserveAuction.burnEvents[burnEventEpoch_]; + BurnEvent storage burnEvent = reserveAuction.burnEvents[burnEventEpoch_]; return ( burnEvent.timestamp, @@ -906,9 +912,10 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { function kickerInfo( address kicker_ ) external view override returns (uint256, uint256) { + Kicker storage kicker = auctions.kickers[kicker_]; return( - auctions.kickers[kicker_].claimable, - auctions.kickers[kicker_].locked + kicker.claimable, + kicker.locked ); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index eb0f6198a..4298bcb0f 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -250,6 +250,19 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { toIndex: _i9_81 }); + uint256 snapshot = vm.snapshot(); + skip(73 hours); + + // lender cannot move funds if auction not cleared + _assertMoveDepositAuctionNotClearedRevert({ + from: _lender, + amount: 10.0 * 1e18, + fromIndex: _i9_72, + toIndex: _i9_81 + }); + + vm.revertTo(snapshot); + // 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); diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index 653f0ddd7..ef8eaa9df 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -1304,6 +1304,17 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); } + function _assertMoveDepositAuctionNotClearedRevert( + address from, + uint256 amount, + uint256 fromIndex, + uint256 toIndex + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionNotCleared.selector); + _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, false); + } + function _assertMoveDepositBelowLUPRevert( address from, uint256 amount, From f61fba542822684c7ac4afa5ccf9a7e9701a016e Mon Sep 17 00:00:00 2001 From: Prateek Gupta Date: Tue, 4 Jul 2023 00:07:33 +0530 Subject: [PATCH 30/32] Revert "Increment nonce on approve to avoid signature replay (#906)" (#920) This reverts commit d4c9ad2687c6f0ef23aae47bfef29bdd978bd164. --- src/base/PermitERC721.sol | 15 ----------- .../unit/Positions/PositionManager.t.sol | 26 ++----------------- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/src/base/PermitERC721.sol b/src/base/PermitERC721.sol index 7a7401a51..0615b713b 100644 --- a/src/base/PermitERC721.sol +++ b/src/base/PermitERC721.sol @@ -278,21 +278,6 @@ abstract contract PermitERC721 is ERC721, IPermit { _nonces[tokenId]++; } - /** - * @notice _approve override to be able to increment the permit nonce - * @inheritdoc ERC721 - */ - function _approve( - address to, - uint256 tokenId - ) internal virtual override { - // increment the permit nonce of this tokenId to ensure it can't be reused - _incrementNonce(tokenId); - - // Approve the NFT to the to address - super._approve(to, tokenId); - } - /** * @notice _transfer override to be able to increment the permit nonce * @inheritdoc ERC721 diff --git a/tests/forge/unit/Positions/PositionManager.t.sol b/tests/forge/unit/Positions/PositionManager.t.sol index d351c68b8..71f307a05 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -1330,7 +1330,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract spenderContract.transferFromWithPermit(address(recipientContract), tokenId, deadline, signature); // check nonces increment with transfer - assertEq(_positionManager.nonces(tokenId), 2); + assertEq(_positionManager.nonces(tokenId), 1); // check retrieving token nonces for non existent tokens will revert vm.expectRevert(IPermit.NonExistentToken.selector); @@ -1379,28 +1379,6 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.nonces(tokenId), 0); } - function testPermitSignatureReplayReverts() external { - // generate addresses and set test params - (address testMinter, uint256 minterPrivateKey) = makeAddrAndKey("testMinter"); - address testSpender = makeAddr("spender"); - - changePrank(testMinter); - uint256 tokenId = _mintNFT(testMinter, testMinter, address(_pool)); - assertEq(_positionManager.ownerOf(tokenId), testMinter); - - uint256 deadline = block.timestamp + 1 days; - bytes memory signature = _getPermitSig(testSpender, tokenId, 0, deadline, minterPrivateKey); - - _positionManager.permit(testSpender, tokenId, deadline, signature); - - // minter revokes approval - _positionManager.approve(address(0), tokenId); - - // spender tries to get approval with the same signature - vm.expectRevert(IPermit.NotAuthorized.selector); - _positionManager.permit(testSpender, tokenId, deadline, signature); - } - /** * @notice Tests permit signatures are invalid after each transfer due to incremented nonce. */ @@ -1464,7 +1442,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract assertEq(_positionManager.ownerOf(tokenId), testMinter); // check nonces after transfer - assertEq(_positionManager.nonces(tokenId), 3); + assertEq(_positionManager.nonces(tokenId), 2); } /** From 5e7f5cfc12a5ffee152d41e6121b161bc046936d Mon Sep 17 00:00:00 2001 From: Ian Harvey Date: Tue, 4 Jul 2023 05:15:02 -0400 Subject: [PATCH 31/32] Rewards Invariants: Significant improvements (#897) * added multiple staked positions * alphabetized functions, made position with indexes accurate, updateExchangeRates now updates buckets that have position in them * reverted alphabetization change so PR is easier to read * cleaned up and removed excess tracking * cleanup log typo * cleaned up how already claimed rewards are tracked * Fix kickWithDeposit handler call in rewards manager regression test * updateExchangeRate now creates positions * removed unused tracker * fixed unit tests * Add rewardsManager handler with ERC721Pool (#899) Co-authored-by: Ian Harvey * fixed regression_gen * Rewards invariants erc721pool (#908) * Add rewardsManager handler with ERC721Pool * made number of max epochs customizable and removed excess logging --------- Co-authored-by: prateek105 Co-authored-by: Ian Harvey * renamed vars made epoch periods longer * added dynamic updating * cleaned up map checking * tests now pass without failing when no position is created via add quote token * refactored positions cleanly * refactored rewards and positions * clean up * cleanup * renamed test files, hardcoded pool hash, added MAX_AJNA_AMOUNT to readme --------- Co-authored-by: Ian Harvey Co-authored-by: prateek105 Co-authored-by: Prateek Gupta --- Makefile | 3 +- tests/README.md | 2 + .../ERC20PoolRewardsInvariants.t.sol | 69 +++ .../ERC721PoolPositionsInvariants.t.sol | 1 - .../ERC721PoolRewardsInvariants.t.sol | 70 +++ .../RewardsInvariants.t.sol | 40 +- .../handlers/BaseERC20PoolPositionHandler.sol | 198 -------- .../handlers/ERC20PoolPositionHandler.sol | 11 +- .../handlers/ERC20PoolRewardsHandler.sol | 73 +++ .../handlers/ERC721PoolPositionHandler.sol | 11 +- .../handlers/ERC721PoolRewardsHandler.sol | 71 +++ ...ionHandler.sol => PositionPoolHandler.sol} | 33 +- .../handlers/RewardsHandler.sol | 188 ------- .../handlers/RewardsPoolHandler.sol | 189 +++++++ .../UnboundedBasePositionHandler.sol | 47 +- .../UnboundedERC721PoolPositionsHandler.sol | 313 ------------ ...r.sol => UnboundedPositionPoolHandler.sol} | 155 +++--- ...er.sol => UnboundedRewardsPoolHandler.sol} | 99 +++- .../base/handlers/unbounded/BaseHandler.sol | 2 +- .../IPositionsAndRewardsHandler.sol | 15 +- ...ressionTestERC20PoolPositionManager.t.sol} | 12 +- ...egressionTestERC20PoolRewardsManager.t.sol | 480 ++++++++++++++++++ ...ressionTestERC721PoolPositionManager.t.sol | 18 + ...gressionTestERC721PoolRewardsManager.t.sol | 31 ++ .../RegressionTestRewardsManager.t.sol | 371 -------------- 25 files changed, 1237 insertions(+), 1265 deletions(-) create mode 100644 tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol rename tests/forge/invariants/PositionsAndRewards/handlers/{BaseERC721PoolPositionHandler.sol => PositionPoolHandler.sol} (89%) delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol create mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol delete mode 100644 tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol rename tests/forge/invariants/PositionsAndRewards/handlers/unbounded/{UnboundedERC20PoolPositionsHandler.sol => UnboundedPositionPoolHandler.sol} (78%) rename tests/forge/invariants/PositionsAndRewards/handlers/unbounded/{UnboundedRewardsHandler.sol => UnboundedRewardsPoolHandler.sol} (78%) rename tests/forge/regression/PositionAndRewards/{RegressionTestPositionManager.t.sol => RegressionTestERC20PoolPositionManager.t.sol} (92%) create mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol create mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol create mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol delete mode 100644 tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol diff --git a/Makefile b/Makefile index add7a8466..8efb142aa 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,8 @@ 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 :; forge t --mt invariant --nmc ${CONTRACT_EXCLUDES} --mc Rewards +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 diff --git a/tests/README.md b/tests/README.md index 4ee047dc4..b46490a88 100644 --- a/tests/README.md +++ b/tests/README.md @@ -75,6 +75,8 @@ 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 | | 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 | 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| diff --git a/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol new file mode 100644 index 000000000..571d464b4 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/ERC20PoolRewardsInvariants.t.sol @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.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 { + + TokenWithNDecimals internal _collateral; + ERC20Pool internal _erc20pool; + ERC20PoolRewardsHandler internal _erc20poolrewardsHandler; + + function setUp() public override virtual { + + super.setUp(); + + _collateral = new TokenWithNDecimals("Collateral", "C", uint8(vm.envOr("COLLATERAL_PRECISION", uint256(18)))); + _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); + _erc20impl = _erc20poolFactory.implementation(); + _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); + _erc721impl = _erc721poolFactory.implementation(); + _erc20pool = ERC20Pool(_erc20poolFactory.deployPool(address(_collateral), address(_quote), 0.05 * 10**18)); + _pool = Pool(address(_erc20pool)); + _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); + _rewardsManager = new RewardsManager(address(_ajna), _positionManager); + + // fund the rewards manager with 100M ajna + _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); + + excludeContract(address(_ajna)); + excludeContract(address(_collateral)); + excludeContract(address(_quote)); + excludeContract(address(_erc20poolFactory)); + excludeContract(address(_erc721poolFactory)); + excludeContract(address(_erc20pool)); + excludeContract(address(_poolInfo)); + excludeContract(address(_erc20impl)); + excludeContract(address(_erc721impl)); + excludeContract(address(_positionManager)); + excludeContract(address(_rewardsManager)); + + _erc20poolrewardsHandler = new ERC20PoolRewardsHandler( + address(_rewardsManager), + address(_positionManager), + address(_erc20pool), + address(_ajna), + address(_quote), + address(_collateral), + address(_poolInfo), + NUM_ACTORS, + address(this) + ); + + _handler = address(_erc20poolrewardsHandler); + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol index 66a8eed06..b7689f116 100644 --- a/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol +++ b/tests/forge/invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol @@ -3,7 +3,6 @@ pragma solidity 0.8.18; import "@std/console.sol"; - import { Pool } from 'src/base/Pool.sol'; import { ERC20Pool } from 'src/ERC20Pool.sol'; import { ERC721Pool } from 'src/ERC721Pool.sol'; diff --git a/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol b/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol new file mode 100644 index 000000000..a45e599ea --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/ERC721PoolRewardsInvariants.t.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import "@std/console.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 } from '../../utils/Tokens.sol'; + +import { ERC721PoolRewardsHandler } from './handlers/ERC721PoolRewardsHandler.sol'; +import { RewardsInvariants } from './RewardsInvariants.t.sol'; + +contract ERC721PoolRewardsInvariants is RewardsInvariants { + + NFTCollateralToken internal _collateral; + ERC721Pool internal _erc721pool; + ERC721PoolRewardsHandler internal _erc721poolrewardsHandler; + + function setUp() public override virtual { + + super.setUp(); + + uint256[] memory tokenIds; + _collateral = new NFTCollateralToken(); + _erc20poolFactory = new ERC20PoolFactory(address(_ajna)); + _erc20impl = _erc20poolFactory.implementation(); + _erc721poolFactory = new ERC721PoolFactory(address(_ajna)); + _erc721pool = ERC721Pool(_erc721poolFactory.deployPool(address(_collateral), address(_quote), tokenIds, 0.05 * 10**18)); + _erc721impl = _erc721poolFactory.implementation(); + _pool = Pool(address(_erc721pool)); + _positionManager = new PositionManager(_erc20poolFactory, _erc721poolFactory); + _rewardsManager = new RewardsManager(address(_ajna), _positionManager); + + // fund the rewards manager with 100M ajna + _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); + + excludeContract(address(_ajna)); + excludeContract(address(_collateral)); + excludeContract(address(_quote)); + excludeContract(address(_erc20poolFactory)); + excludeContract(address(_erc721poolFactory)); + excludeContract(address(_erc721pool)); + excludeContract(address(_poolInfo)); + excludeContract(address(_erc20impl)); + excludeContract(address(_erc721impl)); + excludeContract(address(_positionManager)); + excludeContract(address(_rewardsManager)); + + _erc721poolrewardsHandler = new ERC721PoolRewardsHandler( + address(_rewardsManager), + address(_positionManager), + address(_erc721pool), + address(_ajna), + address(_quote), + address(_collateral), + 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 index e9078afa8..53c1b8a42 100644 --- a/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol +++ b/tests/forge/invariants/PositionsAndRewards/RewardsInvariants.t.sol @@ -3,46 +3,16 @@ pragma solidity 0.8.18; import "@std/console.sol"; -import { Maths } from 'src/libraries/internal/Maths.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; -import { _getEpochInfo } from 'src/RewardsManager.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 { RewardsHandler } from './handlers/RewardsHandler.sol'; -import { ERC20PoolPositionsInvariants } from './ERC20PoolPositionsInvariants.t.sol'; +import { PositionsInvariants } from './PositionsInvariants.sol'; -contract RewardsInvariants is ERC20PoolPositionsInvariants { +abstract contract RewardsInvariants is PositionsInvariants { RewardsManager internal _rewardsManager; - RewardsHandler internal _rewardsHandler; - - function setUp() public override virtual { - - super.setUp(); - - _rewardsManager = new RewardsManager(address(_ajna), _positionManager); - - // fund the rewards manager with 100M ajna - _ajna.mint(address(_rewardsManager), 100_000_000 * 1e18); - - excludeContract(address(_erc20positionHandler)); - excludeContract(address(_rewardsManager)); - - _rewardsHandler = new RewardsHandler( - address(_rewardsManager), - address(_positionManager), - address(_erc20pool), - address(_ajna), - address(_quote), - address(_collateral), - address(_poolInfo), - NUM_ACTORS, - address(this) - ); - - _handler = address(_rewardsHandler); - } function invariant_rewards_RW1_RW2() public useCurrentTimestamp { @@ -76,7 +46,7 @@ contract RewardsInvariants is ERC20PoolPositionsInvariants { function invariant_call_summary() public virtual override useCurrentTimestamp { console.log("\nCall Summary\n"); - console.log("--Positions--------"); + 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")); diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol deleted file mode 100644 index c07c02d8c..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC20PoolPositionHandler.sol +++ /dev/null @@ -1,198 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import '@std/console.sol'; - -import { Maths } from 'src/libraries/internal/Maths.sol'; - -import { _priceAt } from 'src/libraries/helpers/PoolHelper.sol'; - -import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; -import { PositionManager } from 'src/PositionManager.sol'; -import { ERC20Pool } from 'src/ERC20Pool.sol'; - -import { UnboundedERC20PoolPositionsHandler } from './unbounded/UnboundedERC20PoolPositionsHandler.sol'; - -abstract contract BaseERC20PoolPositionHandler is UnboundedERC20PoolPositionsHandler { - - using EnumerableSet for EnumerableSet.UintSet; - - /********************************/ - /*** Positions Test Functions ***/ - /********************************/ - - function memorializePositions( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BPositionHandler.memorialize']++; - // Pre action // - (uint256 tokenId, uint256[] memory indexes) = _preMemorializePositions(_lenderBucketIndex, amountToAdd_); - - // Action phase // - _memorializePositions(tokenId, indexes); - } - - function redeemPositions( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BPositionHandler.redeem']++; - // Pre action // - (uint256 tokenId, uint256[] memory indexes) = _preRedeemPositions(_lenderBucketIndex, amountToAdd_); - - // Action phase // - _redeemPositions(tokenId, indexes); - } - - function mint( - uint256 actorIndex_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BPositionHandler.mint']++; - - // Action phase // - _mint(); - } - - function burn( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 skippedTime_, - uint256 amountToAdd_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BPositionHandler.burn']++; - // Pre action // - (uint256 tokenId_) = _preBurn(_lenderBucketIndex, amountToAdd_); - - // Action phase // - _burn(tokenId_); - } - - function moveLiquidity( - uint256 actorIndex_, - uint256 skippedTime_, - uint256 amountToMove_, - uint256 fromIndex_, - uint256 toIndex_ - ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BPositionHandler.moveLiquidity']++; - // Pre action // - ( - uint256 tokenId, - uint256 fromIndex, - uint256 toIndex - ) = _preMoveLiquidity(amountToMove_, fromIndex_, toIndex_); - - // retrieve info of bucket from pool - ( - , - uint256 bucketCollateral, - , - , - ) = _pool.bucketInfo(fromIndex); - - // to avoid LP mismatch revert return if bucket has collateral or exchangeRate < 1e18 - if (bucketCollateral != 0) return; - if (_pool.bucketExchangeRate(fromIndex) < 1e18) return; - - // Action phase // - _moveLiquidity(tokenId, fromIndex, toIndex); - } - - function _preMemorializePositions( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, 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) { - // Prepare test phase - uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); - _ensureQuoteAmount(_actor, boundedAmount); - try _pool.addQuoteToken(boundedAmount, bucketIndex_, block.timestamp + 1 minutes, false) { - } catch (bytes memory err) { - _ensurePoolError(err); - } - } - - indexes_ = new uint256[](1); - indexes_[0] = bucketIndex_; - - uint256[] memory lpBalances = new uint256[](1); - - // mint position NFT - tokenId_ = _mint(); - - (lpBalances[0], ) = _pool.lenderInfo(bucketIndex_, _actor); - _pool.increaseLPAllowance(address(_positionManager), indexes_, lpBalances); - } - - function _preRedeemPositions( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - - (tokenId_, indexes_) = _getNFTPosition(bucketIndex_, amountToAdd_); - - // approve positionManager to transfer LP tokens - address[] memory transferors = new address[](1); - transferors[0] = address(_positionManager); - - _pool.approveLPTransferors(transferors); - } - - function _preBurn( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_) { - uint256[] memory indexes; - - // check and create the position - (tokenId_, indexes) = _preRedeemPositions(bucketIndex_, amountToAdd_); - - _redeemPositions(tokenId_, indexes); - } - - function _preMoveLiquidity( - uint256 amountToMove_, - uint256 fromIndex_, - uint256 toIndex_ - ) internal returns (uint256 tokenId_, uint256 boundedFromIndex_, uint256 boundedToIndex_) { - boundedFromIndex_ = constrictToRange(fromIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); - boundedToIndex_ = constrictToRange(toIndex_, LENDER_MIN_BUCKET_INDEX, LENDER_MAX_BUCKET_INDEX); - - uint256[] memory indexes; - (tokenId_, indexes) = _getNFTPosition(boundedFromIndex_, amountToMove_); - boundedFromIndex_ = indexes[0]; - - } - - function _getNFTPosition( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - - // Check for exisiting nft positions in PositionManager - uint256[] memory tokenIds = getTokenIdsByActor(address(_actor)); - - if (tokenIds.length != 0 ) { - // use existing position NFT - tokenId_ = tokenIds[0]; - indexes_ = getBucketIndexesByTokenId(tokenId_); - } else { - // create a position for the actor - (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); - _memorializePositions(tokenId_, indexes_); - } - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol index e856860fd..27e2378a5 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolPositionHandler.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.18; -import { PositionManager } from 'src/PositionManager.sol'; +import { PositionManager } from 'src/PositionManager.sol'; -import { BaseERC20PoolPositionHandler } from './BaseERC20PoolPositionHandler.sol'; -import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; +import { PositionPoolHandler } from './PositionPoolHandler.sol'; +import { BaseERC20PoolHandler } from '../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; -contract ERC20PoolPositionHandler is BaseERC20PoolPositionHandler { +contract ERC20PoolPositionHandler is PositionPoolHandler, BaseERC20PoolHandler { constructor( address positions_, @@ -22,5 +22,8 @@ contract ERC20PoolPositionHandler is BaseERC20PoolPositionHandler { // Position manager _positionManager = PositionManager(positions_); + + // pool hash for mint() call + _poolHash = bytes32(keccak256("ERC20_NON_SUBSET_HASH")); } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol new file mode 100644 index 000000000..f97570036 --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC20PoolRewardsHandler.sol @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { RewardsManager } from 'src/RewardsManager.sol'; +import { PositionManager } from 'src/PositionManager.sol'; + +import { RewardsPoolHandler } from './RewardsPoolHandler.sol'; +import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; + +contract ERC20PoolRewardsHandler is RewardsPoolHandler, ReserveERC20PoolHandler { + + constructor( + address rewards_, + address positions_, + address pool_, + address ajna_, + address quote_, + address collateral_, + address poolInfo_, + uint256 numOfActors_, + address testContract_ + ) ReserveERC20PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { + + // 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_, + uint256 bucketSubsetToUpdate_ + ) 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); + + + _repayDebt(type(uint256).max); + } + + skip(20 days); // epochs are spaced a minimum of 14 days apart + + (, 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 + indexes_ = _randomizeExchangeRateIndexes(indexes_, bucketSubsetToUpdate_); + if (indexes_.length != 0) { _updateExchangeRate(indexes_); } + } + } + +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol index 856f87f4f..443bd7519 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolPositionHandler.sol @@ -2,12 +2,12 @@ pragma solidity 0.8.18; -import { PositionManager } from 'src/PositionManager.sol'; +import { PositionManager } from 'src/PositionManager.sol'; -import { BaseERC721PoolPositionHandler } from './BaseERC721PoolPositionHandler.sol'; -import { BaseERC721PoolHandler } from '../../ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol'; +import { PositionPoolHandler } from './PositionPoolHandler.sol'; +import { BaseERC721PoolHandler } from '../../ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol'; -contract ERC721PoolPositionHandler is BaseERC721PoolPositionHandler { +contract ERC721PoolPositionHandler is PositionPoolHandler, BaseERC721PoolHandler { constructor( address positions_, @@ -22,5 +22,8 @@ contract ERC721PoolPositionHandler is BaseERC721PoolPositionHandler { // Position manager _positionManager = PositionManager(positions_); + + // pool hash for mint() call + _poolHash = bytes32(keccak256("ERC721_NON_SUBSET_HASH")); } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol new file mode 100644 index 000000000..9b72b89de --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/ERC721PoolRewardsHandler.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { RewardsManager } from 'src/RewardsManager.sol'; +import { PositionManager } from 'src/PositionManager.sol'; + +import { RewardsPoolHandler } from './RewardsPoolHandler.sol'; +import { ReserveERC721PoolHandler } from '../../ERC721Pool/handlers/ReserveERC721PoolHandler.sol'; + +contract ERC721PoolRewardsHandler is RewardsPoolHandler, ReserveERC721PoolHandler { + + constructor( + address rewards_, + address positions_, + address pool_, + address ajna_, + address quote_, + address collateral_, + address poolInfo_, + uint256 numOfActors_, + address testContract_ + ) ReserveERC721PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { + + // 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_, + uint256 bucketSubsetToUpdate_ + ) 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); + } + + skip(20 days); // epochs are spaced a minimum of 14 days apart + + (, 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 + indexes_ = _randomizeExchangeRateIndexes(indexes_, bucketSubsetToUpdate_); + if (indexes_.length != 0) { _updateExchangeRate(indexes_); } + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol similarity index 89% rename from tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol index eeaedbb08..f6dc30cd5 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BaseERC721PoolPositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/PositionPoolHandler.sol @@ -2,21 +2,11 @@ pragma solidity 0.8.18; -import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import '@std/console.sol'; - import { Maths } from 'src/libraries/internal/Maths.sol'; -import { _priceAt } from 'src/libraries/helpers/PoolHelper.sol'; - -import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; -import { PositionManager } from 'src/PositionManager.sol'; - -import { UnboundedERC721PoolPositionsHandler } from './unbounded/UnboundedERC721PoolPositionsHandler.sol'; +import { UnboundedPositionPoolHandler } from './unbounded/UnboundedPositionPoolHandler.sol'; -abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsHandler { - - using EnumerableSet for EnumerableSet.UintSet; +abstract contract PositionPoolHandler is UnboundedPositionPoolHandler { /********************************/ /*** Positions Test Functions ***/ @@ -45,7 +35,10 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH numberOfCalls['BPositionHandler.redeem']++; // Pre action // (uint256 tokenId, uint256[] memory indexes) = _preRedeemPositions(_lenderBucketIndex, amountToAdd_); - + + // NFT doesn't have a position associated with it, return + if (indexes.length == 0) return; + // Action phase // _redeemPositions(tokenId, indexes); } @@ -97,6 +90,9 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH , ) = _pool.bucketInfo(fromIndex); + // NFT doesn't have a position associated with it, return + if (fromIndex == 0) return; + // to avoid LP mismatch revert return if bucket has collateral or exchangeRate < 1e18 if (bucketCollateral != 0) return; if (_pool.bucketExchangeRate(fromIndex) < 1e18) return; @@ -115,8 +111,8 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH // add quote token if they don't have a position if (lpBalanceBefore == 0) { - // Prepare test phase - uint256 boundedAmount = constrictToRange(amountToAdd_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); + // bound 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) { } catch (bytes memory err) { @@ -172,8 +168,7 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH uint256[] memory indexes; (tokenId_, indexes) = _getNFTPosition(boundedFromIndex_, amountToMove_); - boundedFromIndex_ = indexes[0]; - + boundedFromIndex_ = indexes.length != 0 ? indexes[0]: 0; } function _getNFTPosition( @@ -193,5 +188,5 @@ abstract contract BaseERC721PoolPositionHandler is UnboundedERC721PoolPositionsH (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); _memorializePositions(tokenId_, indexes_); } - } -} + } +} \ No newline at end of file diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol deleted file mode 100644 index b824f6be9..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsHandler.sol +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-License-Identifier: UNLICENSED - -pragma solidity 0.8.18; - -import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; - -import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; - -import { UnboundedRewardsHandler } from './unbounded/UnboundedRewardsHandler.sol'; - -import { ReserveERC20PoolHandler } from '../../ERC20Pool/handlers/ReserveERC20PoolHandler.sol'; -import { BaseERC20PoolPositionHandler } from './BaseERC20PoolPositionHandler.sol'; - -contract RewardsHandler is UnboundedRewardsHandler, BaseERC20PoolPositionHandler, ReserveERC20PoolHandler { - - constructor( - address rewards_, - address positions_, - address pool_, - address ajna_, - address quote_, - address collateral_, - address poolInfo_, - uint256 numOfActors_, - address testContract_ - ) ReserveERC20PoolHandler(pool_, ajna_, quote_, collateral_, poolInfo_, numOfActors_, testContract_) { - - // Position manager - _positionManager = PositionManager(positions_); - - // Rewards manager - _rewardsManager = RewardsManager(rewards_); - } - - /*******************************/ - /*** Rewards Test Functions ***/ - /*******************************/ - - function stake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BRewardsHandler.stake']++; - // Pre action - (uint256 tokenId,) = _preStake(_lenderBucketIndex, amountToAdd_); - - // Action phase - _stake(tokenId); - } - - function unstake( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BRewardsHandler.unstake']++; - // Pre action - uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); - - // 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_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BRewardsHandler.emergencyUnstake']++; - - // Pre action - uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); - - // Action phase - _emergencyUnstake(tokenId); - } - - function updateExchangeRate( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BRewardsHandler.updateRate']++; - - // Pre action // - uint256[] memory indexes = _preUpdateExchangeRate(_lenderBucketIndex); - - // Action phase - _updateExchangeRate(indexes); - } - - function claimRewards( - uint256 actorIndex_, - uint256 bucketIndex_, - uint256 amountToAdd_, - uint256 skippedTime_ - ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { - numberOfCalls['BRewardsHandler.claimRewards']++; - - // Pre action // - uint256 tokenId = _preUnstake(_lenderBucketIndex, amountToAdd_); - - uint256 currentEpoch = _pool.currentBurnEpoch(); - - // Action phase - _claimRewards(tokenId, currentEpoch); - } - - /*******************************/ - /*** Rewards Tests Functions ***/ - /*******************************/ - - function _preStake( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { - - (tokenId_, indexes_) = _preMemorializePositions(bucketIndex_, amountToAdd_); - - _memorializePositions(tokenId_, indexes_); - - // Approve rewards contract to transfer token - _positionManager.approve(address(_rewardsManager), tokenId_); - - } - - function _preUnstake( - uint256 bucketIndex_, - uint256 amountToAdd_ - ) internal returns (uint256 tokenId_) { - - // TODO: Check if the actor has a NFT position or a staked position is tracking events - - // Create a staked position - uint256[] memory indexes; - (tokenId_, indexes)= _preStake(bucketIndex_, amountToAdd_); - _stake(tokenId_); - - _advanceEpochRewardStakers(amountToAdd_, indexes); - } - - function _advanceEpochRewardStakers( - uint256 amountToAdd_, - uint256[] memory indexes_ - ) internal { - - // 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(20 days); // epochs are spaced a minimum of 14 days apart - - _repayDebt(type(uint256).max); - } - - (, 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 checked - _rewardsManager.updateBucketExchangeRatesAndClaim(address(_pool), keccak256("ERC20_NON_SUBSET_HASH"), indexes_); - - } - - function _preUpdateExchangeRate( - uint256 bucketIndex_ - ) internal pure returns (uint256[] memory indexes_) { - indexes_ = new uint256[](1); - indexes_[0] = bucketIndex_; - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol new file mode 100644 index 000000000..4124c4efb --- /dev/null +++ b/tests/forge/invariants/PositionsAndRewards/handlers/RewardsPoolHandler.sol @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { PositionPoolHandler } from './PositionPoolHandler.sol'; +import { UnboundedRewardsPoolHandler } from './unbounded/UnboundedRewardsPoolHandler.sol'; + +abstract contract RewardsPoolHandler is UnboundedRewardsPoolHandler, PositionPoolHandler { + + /*******************************/ + /*** Rewards Test Functions ***/ + /*******************************/ + + function stake( + uint256 actorIndex_, + uint256 bucketIndex_, + uint256 amountToAdd_, + uint256 skippedTime_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + 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_, + uint256 bucketSubsetToUpdate_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.unstake']++; + // Pre action + (uint256 tokenId, uint256[] memory indexes) = _preUnstake( + _lenderBucketIndex, + amountToAdd_, + numberOfEpochs_, + bucketSubsetToUpdate_ + ); + + // 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_, + uint256 bucketSubsetToUpdate_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.emergencyUnstake']++; + + // Pre action + (uint256 tokenId, uint256[] memory indexes) = _preUnstake( + _lenderBucketIndex, + amountToAdd_, + numberOfEpochs_, + bucketSubsetToUpdate_ + ); + + // 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_) { + numberOfCalls['BRewardsHandler.updateRate']++; + + // Pre action // + uint256[] memory indexes = getBucketIndexesWithPosition(); + + // 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_, + uint256 bucketSubsetToUpdate_ + ) external useRandomActor(actorIndex_) useRandomLenderBucket(bucketIndex_) useTimestamps skipTime(skippedTime_) { + numberOfCalls['BRewardsHandler.claimRewards']++; + + // Pre action // + (uint256 tokenId, uint256[] memory indexes) = _preUnstake( + _lenderBucketIndex, + amountToAdd_, + numberOfEpochs_, + bucketSubsetToUpdate_ + ); + + // NFT doesn't have a position associated with it, return + if (indexes.length == 0) return; + + // Action phase + _claimRewards(tokenId, _pool.currentBurnEpoch()); + } + + /*******************************/ + /*** 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_, + uint256 bucketSubsetToUpdate_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + (tokenId_, indexes_)= _getStakedPosition(bucketIndex_, amountToAdd_); + + if (indexes_.length != 0) { + _advanceEpochRewardStakers( + amountToAdd_, + indexes_, + numberOfEpochs_, + bucketSubsetToUpdate_ + ); + } + } + + function _getStakedPosition( + uint256 bucketIndex_, + uint256 amountToAdd_ + ) internal returns (uint256 tokenId_, uint256[] memory indexes_) { + + // Check for exisiting staked positions in RewardsManager + uint256[] memory tokenIds = getStakedTokenIdsByActor(address(_actor)); + + if (tokenIds.length != 0 ) { + // use existing position NFT + tokenId_ = tokenIds[0]; + indexes_ = getBucketIndexesByTokenId(tokenId_); + } else { + // retreive or create a NFT position + (tokenId_, indexes_)= _getNFTPosition(bucketIndex_, amountToAdd_); + + // approve rewards contract to transfer token + _positionManager.approve(address(_rewardsManager), tokenId_); + + // stake the position + _stake(tokenId_); + } + } +} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol index 093b902e1..3f55f3b95 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedBasePositionHandler.sol @@ -1,18 +1,12 @@ - // SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.18; import '@std/Test.sol'; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; -import { Strings } from '@openzeppelin/contracts/utils/Strings.sol'; - -import { IPositionManagerOwnerActions } from 'src/interfaces/position/IPositionManagerOwnerActions.sol'; -import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.sol'; -import { Maths } from "src/libraries/internal/Maths.sol"; -import { PositionManager } from 'src/PositionManager.sol'; -import { RewardsManager } from 'src/RewardsManager.sol'; +import { PositionManager } from 'src/PositionManager.sol'; +import { RewardsManager } from 'src/RewardsManager.sol'; /** * @dev this contract manages multiple lenders @@ -24,33 +18,27 @@ abstract contract UnboundedBasePositionHandler is Test { PositionManager internal _positionManager; RewardsManager internal _rewardsManager; - uint256 MAX_AJNA_AMOUNT = vm.envOr("MAX_AJNA_AMOUNT_ERC20", uint256(100_000_000 * 1e18)); + bytes32 internal _poolHash; - // Position invariant test state // + uint256 MAX_AJNA_AMOUNT = vm.envOr("MAX_AJNA_AMOUNT_ERC20", uint256(100_000_000 * 1e18)); - // used for PM1_PM2_PM3 tracking - mapping(uint256 => EnumerableSet.UintSet) internal tokenIdsByBucketIndex; + // positionManager & rewardsManager EnumerableSet.UintSet internal bucketIndexesWithPosition; - - // used for removing all CT and QT to reset bucket exchange rate - mapping(uint256 => address) internal actorByTokenId; - mapping(address => EnumerableSet.UintSet) internal tokenIdsByActor; mapping(uint256 => EnumerableSet.UintSet) internal bucketIndexesByTokenId; - // used to track LP changes in `_redeemPositions()` and `_memorializePositions()` - mapping(uint256 => uint256) internal bucketIndexToActorPositionManLps; - mapping(uint256 => uint256) internal bucketIndexToPositionManPoolLps; - mapping(uint256 => uint256) internal bucketIndexToActorPoolLps; + // positionManager + mapping(uint256 => EnumerableSet.UintSet) internal tokenIdsByBucketIndex; + mapping(address => EnumerableSet.UintSet) internal tokenIdsByActor; + // used to track changes in `_redeemPositions()` and `_memorializePositions()` + mapping(uint256 => uint256) internal actorLpsBefore; + mapping(uint256 => uint256) internal posManLpsBefore; mapping(uint256 => uint256) internal bucketIndexToDepositTime; - // Rewards invariant test state // + // rewardsManager + mapping(address => EnumerableSet.UintSet) internal stakedTokenIdsByActor; mapping(uint256 => uint256) public rewardsClaimedPerEpoch; // staking rewards per epoch mapping(uint256 => uint256) public updateRewardsClaimedPerEpoch; // updating rewards per epoch - mapping(uint256 => uint256) public rewardsAlreadyClaimed; // tracks rewards already claimed - uint256 public totalStakerRewPerEpoch; // amount of reserve decrease - uint256 public totalUpdaterRewPerEpoch; // amount of reserve increase - using EnumerableSet for EnumerableSet.UintSet; function getBucketIndexesWithPosition() public view returns(uint256[] memory) { @@ -69,6 +57,10 @@ abstract contract UnboundedBasePositionHandler is Test { return tokenIdsByActor[actor_].values(); } + function getStakedTokenIdsByActor(address actor_) public view returns(uint256[] memory) { + return stakedTokenIdsByActor[actor_].values(); + } + function _ensurePositionsManagerError(bytes memory err_) internal pure { bytes32 err = keccak256(err_); @@ -82,11 +74,14 @@ abstract contract UnboundedBasePositionHandler is Test { err == keccak256(abi.encodeWithSignature("NotAjnaPool()")) || err == keccak256(abi.encodeWithSignature("RemovePositionFailed()")) || err == keccak256(abi.encodeWithSignature("WrongPool()")) || + err == keccak256(abi.encodeWithSignature("NoAllowance()")) || err == keccak256(abi.encodeWithSignature("MoveToSameIndex()")) || err == keccak256(abi.encodeWithSignature("RemoveDepositLockedByAuctionDebt()")) || err == keccak256(abi.encodeWithSignature("DustAmountNotExceeded()")) || err == keccak256(abi.encodeWithSignature("InvalidIndex()")) || - err == keccak256(abi.encodeWithSignature("LUPBelowHTP()")), + err == keccak256(abi.encodeWithSignature("LUPBelowHTP()")) || + err == keccak256(abi.encodeWithSignature("InsufficientLP()")) || + err == keccak256(abi.encodeWithSignature("AuctionNotCleared()")), "Unexpected revert error" ); } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol deleted file mode 100644 index e1e6acbf7..000000000 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC721PoolPositionsHandler.sol +++ /dev/null @@ -1,313 +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 { BaseERC721PoolHandler } from '../../../ERC721Pool/handlers/unbounded/BaseERC721PoolHandler.sol'; -import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.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 UnboundedERC721PoolPositionsHandler is UnboundedBasePositionHandler, BaseERC721PoolHandler { - - using EnumerableSet for EnumerableSet.UintSet; - - function _memorializePositions( - uint256 tokenId_, - uint256[] memory indexes_ - ) internal { - numberOfCalls['UBPositionHandler.memorialize']++; - - for(uint256 i=0; i < indexes_.length; i++) { - - // store vals pre action to check after memorializing: - (uint256 actorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); - (uint256 posManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); - - bucketIndexToActorPoolLps[indexes_[i]] = actorLps; - bucketIndexToPositionManPoolLps[indexes_[i]] = posManLps; - - // positionManager is assigned the most recent depositTime - bucketIndexToDepositTime[indexes_[i]] = (actorDepositTime >= posManDepositTime) ? actorDepositTime : posManDepositTime; - - // assert that the underlying LP balance in PositionManager is 0 - (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); - require(posPreActionLps == 0, "tokenID already has lps associated on memorialize"); - - } - - try _positionManager.memorializePositions(address(_pool), tokenId_, indexes_) { - - // track created positions - for ( uint256 i = 0; i < indexes_.length; i++) { - // PM1_PM2_PM3 tracking - bucketIndexesWithPosition.add(indexes_[i]); - tokenIdsByBucketIndex[indexes_[i]].add(tokenId_); - - // info used to tearDown buckets - bucketIndexesByTokenId[tokenId_].add(indexes_[i]); - } - - // info used track actors positions - actorByTokenId[tokenId_] = address(_actor); - tokenIdsByActor[address(_actor)].add(tokenId_); - - // Post action Checks // - for(uint256 i=0; i < indexes_.length; i++) { - uint256 bucketIndex = indexes_[i]; - - // assert that the LP that now exists in the pool contract matches the amount added by the actor - (uint256 poolLps, uint256 poolDepositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); - require(poolLps == bucketIndexToActorPoolLps[bucketIndex] + bucketIndexToPositionManPoolLps[bucketIndex], - "PM7: pool contract lps do not match amount added by actor"); - - require(poolDepositTime == bucketIndexToDepositTime[bucketIndex], - "PM7: positionManager depositTime does not match most recent depositTime"); - - // assert that the positionManager LP balance of the actor has increased - (uint256 posLps,) = _positionManager.getPositionInfo(tokenId_, bucketIndex); - require(posLps == bucketIndexToActorPoolLps[bucketIndex], - "PM7: positionManager lps do not match amount added by actor"); - - delete bucketIndexToActorPoolLps[bucketIndex]; - delete bucketIndexToPositionManPoolLps[bucketIndex]; - delete bucketIndexToDepositTime[bucketIndex]; - } - - } catch (bytes memory err) { - _ensurePositionsManagerError(err); - } - } - - function _mint() internal returns (uint256 tokenIdResult) { - numberOfCalls['UBPositionHandler.mint']++; - try _positionManager.mint(address(_pool), _actor, keccak256("ERC721_NON_SUBSET_HASH")) 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"); - - // assert that poolKey is returns correct pool address - address poolAddress = _positionManager.poolKey(tokenId); - 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"); - - } catch (bytes memory err) { - _ensurePositionsManagerError(err); - } - } - - function _redeemPositions( - uint256 tokenId_, - uint256[] memory indexes_ - ) internal { - numberOfCalls['UBPositionHandler.redeem']++; - - address preActionOwner = _positionManager.ownerOf(tokenId_); - - for (uint256 i=0; i < indexes_.length; i++) { - - // store vals in mappings to check lps - (uint256 poolPreActionActorLps,) = _pool.lenderInfo(indexes_[i], preActionOwner); - (uint256 poolPreActionPosManLps,) = _pool.lenderInfo(indexes_[i], address(_positionManager)); - - bucketIndexToActorPoolLps[indexes_[i]] = poolPreActionActorLps; - bucketIndexToPositionManPoolLps[indexes_[i]] = poolPreActionPosManLps; - - // assert that the underlying LP balance in PositionManager is greater than 0 - (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); - require(posPreActionLps > 0, "tokenID does not have lps associated on redemption"); - } - - try _positionManager.redeemPositions(address(_pool), tokenId_, indexes_) { - // remove tracked positions - for ( uint256 i = 0; i < indexes_.length; i++) { - bucketIndexesWithPosition.remove(indexes_[i]); - tokenIdsByBucketIndex[indexes_[i]].remove(tokenId_); - } - - // info for tear down - delete actorByTokenId[tokenId_]; - delete bucketIndexesByTokenId[tokenId_]; - tokenIdsByActor[address(_actor)].remove(tokenId_); - - // Post action Checks // - // assert that the minter is still the owner - require(_positionManager.ownerOf(tokenId_) == preActionOwner, - 'PM8: previous owner is no longer owner on redemption'); - - // assert that poolKey is still same - address poolAddress = _positionManager.poolKey(tokenId_); - require(poolAddress == address(_pool), 'PM8: poolKey has changed on redemption'); - - // 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'); - - for(uint256 i=0; i < indexes_.length; i++) { - uint256 bucketIndex = indexes_[i]; - - uint256 actorPoolLps = bucketIndexToActorPoolLps[bucketIndex]; - uint256 positionManPoolLps = bucketIndexToPositionManPoolLps[bucketIndex]; - - (uint256 poolActorLps,) = _pool.lenderInfo(bucketIndex, preActionOwner); - (uint256 poolPosLps,) = _pool.lenderInfo(bucketIndex, address(_positionManager)); - - // assert PositionsMan LP in pool matches the amount redeemed by actor - // positionMan has now == positionMan pre - actor's LP change - require(poolPosLps == positionManPoolLps - (poolActorLps - actorPoolLps), - "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 == actorPoolLps + (positionManPoolLps - 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"); - - // delete mappings for reuse - delete bucketIndexToActorPoolLps[bucketIndex]; - delete bucketIndexToPositionManPoolLps[bucketIndex]; - } - - } catch (bytes memory err) { - _ensurePositionsManagerError(err); - } - - } - - function _getQuoteAtIndex( - uint256 lp, - uint256 index - ) internal view returns (uint256 quoteAtIndex_) { - // retrieve info of bucket from pool - ( - uint256 bucketLP, - uint256 bucketCollateral, - , - uint256 bucketDeposit, - ) = _pool.bucketInfo(index); - - // calculate the max amount of quote tokens that can be moved, given the tracked LP - quoteAtIndex_ = _lpToQuoteToken( - bucketLP, - bucketCollateral, - bucketDeposit, - lp, - bucketDeposit, - _priceAt(index) - ); - } - - function _moveLiquidity( - uint256 tokenId_, - uint256 fromIndex_, - uint256 toIndex_ - ) internal { - numberOfCalls['UBPositionHandler.moveLiquidity']++; - - // update interest so pre and post token amounts are equal - _pool.updateInterest(); - - // fromIndex values - (uint256 preActionFromLps,) = _positionManager.getPositionInfo(tokenId_, fromIndex_); - uint256 preActionFromIndexQuote = _getQuoteAtIndex(preActionFromLps, fromIndex_); - - // toIndex values - (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) { - - bucketIndexesByTokenId[tokenId_].add(toIndex_); - bucketIndexesByTokenId[tokenId_].remove(fromIndex_); - - // Post Action Checks // - // remove tracked positios - bucketIndexesWithPosition.remove(fromIndex_); - tokenIdsByBucketIndex[fromIndex_].remove(tokenId_); - - // track created positions - bucketIndexesWithPosition.add(toIndex_); - tokenIdsByBucketIndex[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"); - - // 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"); - - // get post action QT represented in positionManager for tokenID - uint256 postActionFromIndexQuote = _getQuoteAtIndex(fromLps, fromIndex_); - uint256 postActionToIndexQuote = _getQuoteAtIndex(toLps, toIndex_); - - // positionManager's total QT postAction is less than or equal to preAction - // can be less than or equal due to fee on movements above -> below LUP - - greaterThanWithinDiff( - preActionFromIndexQuote + preActionToIndexQuote, - postActionFromIndexQuote + postActionToIndexQuote, - 1, - "PM6: positiionManager QT balance has increased by `1` margin" - ); - - - } catch (bytes memory err) { - _ensurePositionsManagerError(err); - } - } - - - - function _burn( - uint256 tokenId_ - ) internal { - numberOfCalls['UBPositionHandler.burn']++; - 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"); - - // assert that poolKey is returns zero address - address poolAddress = _positionManager.poolKey(tokenId_); - 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"); - } catch (bytes memory err) { - _ensurePositionsManagerError(err); - } - } -} diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol similarity index 78% rename from tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol index e9204dcbf..154fc10f4 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedERC20PoolPositionsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedPositionPoolHandler.sol @@ -16,15 +16,21 @@ 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'; + /** * @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 UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHandler, BaseERC20PoolHandler { +abstract contract UnboundedPositionPoolHandler is UnboundedBasePositionHandler, BaseHandler { using EnumerableSet for EnumerableSet.UintSet; + /*********************************/ + /*** Position Helper Functions ***/ + /*********************************/ + function _memorializePositions( uint256 tokenId_, uint256[] memory indexes_ @@ -34,67 +40,68 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan for(uint256 i=0; i < indexes_.length; i++) { // store vals pre action to check after memorializing: - (uint256 actorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); - (uint256 posManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); + (uint256 poolPreActionActorLps, uint256 actorDepositTime) = _pool.lenderInfo(indexes_[i], address(_actor)); + (uint256 poolPreActionPosManLps, uint256 posManDepositTime) = _pool.lenderInfo(indexes_[i], address(_positionManager)); - bucketIndexToActorPoolLps[indexes_[i]] = actorLps; - bucketIndexToPositionManPoolLps[indexes_[i]] = posManLps; + actorLpsBefore[indexes_[i]] = poolPreActionActorLps; + posManLpsBefore[indexes_[i]] = poolPreActionPosManLps; // positionManager is assigned the most recent depositTime bucketIndexToDepositTime[indexes_[i]] = (actorDepositTime >= posManDepositTime) ? actorDepositTime : posManDepositTime; - - // assert that the underlying LP balance in PositionManager is 0 - (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); - require(posPreActionLps == 0, "tokenID already has lps associated on memorialize"); - } try _positionManager.memorializePositions(address(_pool), tokenId_, indexes_) { // track created positions for ( uint256 i = 0; i < indexes_.length; i++) { - // PM1_PM2_PM3 tracking - bucketIndexesWithPosition.add(indexes_[i]); - tokenIdsByBucketIndex[indexes_[i]].add(tokenId_); - - // info used to tearDown buckets - bucketIndexesByTokenId[tokenId_].add(indexes_[i]); - } + uint256 bucketIndex = indexes_[i]; - // info used track actors positions - actorByTokenId[tokenId_] = address(_actor); - tokenIdsByActor[address(_actor)].add(tokenId_); + bucketIndexesWithPosition.add(bucketIndex); + tokenIdsByBucketIndex[bucketIndex].add(tokenId_); - // Post action Checks // - for(uint256 i=0; i < indexes_.length; i++) { - uint256 bucketIndex = indexes_[i]; + // info used to tearDown buckets + bucketIndexesByTokenId[tokenId_].add(bucketIndex); - // assert that the LP that now exists in the pool contract matches the amount added by the actor (uint256 poolLps, uint256 poolDepositTime) = _pool.lenderInfo(bucketIndex, address(_positionManager)); - require(poolLps == bucketIndexToActorPoolLps[bucketIndex] + bucketIndexToPositionManPoolLps[bucketIndex], - "PM7: pool contract lps do not match amount added by actor"); require(poolDepositTime == bucketIndexToDepositTime[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[bucketIndex] + posManLpsBefore[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 == bucketIndexToActorPoolLps[bucketIndex], + require(posLps == actorLpsBefore[bucketIndex], "PM7: positionManager lps do not match amount added by actor"); - delete bucketIndexToActorPoolLps[bucketIndex]; - delete bucketIndexToPositionManPoolLps[bucketIndex]; + delete actorLpsBefore[bucketIndex]; + delete posManLpsBefore[bucketIndex]; delete bucketIndexToDepositTime[bucketIndex]; } + // info used track actors positions + tokenIdsByActor[address(_actor)].add(tokenId_); + } catch (bytes memory err) { + + // cleanup buckets so they don't interfere with future calls + for ( uint256 i = 0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + + delete actorLpsBefore[bucketIndex]; + delete posManLpsBefore[bucketIndex]; + delete bucketIndexToDepositTime[bucketIndex]; + } _ensurePositionsManagerError(err); } } function _mint() internal returns (uint256 tokenIdResult) { numberOfCalls['UBPositionHandler.mint']++; - try _positionManager.mint(address(_pool), _actor, keccak256("ERC20_NON_SUBSET_HASH")) returns (uint256 tokenId) { + + try _positionManager.mint(address(_pool), _actor, _poolHash) returns (uint256 tokenId) { tokenIdResult = tokenId; @@ -125,60 +132,39 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan for (uint256 i=0; i < indexes_.length; i++) { - // store vals in mappings to check lps (uint256 poolPreActionActorLps,) = _pool.lenderInfo(indexes_[i], preActionOwner); (uint256 poolPreActionPosManLps,) = _pool.lenderInfo(indexes_[i], address(_positionManager)); - bucketIndexToActorPoolLps[indexes_[i]] = poolPreActionActorLps; - bucketIndexToPositionManPoolLps[indexes_[i]] = poolPreActionPosManLps; - - // assert that the underlying LP balance in PositionManager is greater than 0 - (uint256 posPreActionLps,) = _positionManager.getPositionInfo(tokenId_, indexes_[i]); - require(posPreActionLps > 0, "tokenID does not have lps associated on redemption"); + // store vals in mappings to check lps + actorLpsBefore[indexes_[i]] = poolPreActionActorLps; + posManLpsBefore[indexes_[i]] = poolPreActionPosManLps; } try _positionManager.redeemPositions(address(_pool), tokenId_, indexes_) { + // remove tracked positions for ( uint256 i = 0; i < indexes_.length; i++) { - bucketIndexesWithPosition.remove(indexes_[i]); - tokenIdsByBucketIndex[indexes_[i]].remove(tokenId_); - } - - // info for tear down - delete actorByTokenId[tokenId_]; - delete bucketIndexesByTokenId[tokenId_]; - tokenIdsByActor[address(_actor)].remove(tokenId_); - - // Post action Checks // - // assert that the minter is still the owner - require(_positionManager.ownerOf(tokenId_) == preActionOwner, - 'PM8: previous owner is no longer owner on redemption'); - - // assert that poolKey is still same - address poolAddress = _positionManager.poolKey(tokenId_); - require(poolAddress == address(_pool), 'PM8: poolKey has changed on redemption'); + uint256 bucketIndex = indexes_[i]; - // 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'); + tokenIdsByBucketIndex[bucketIndex].remove(tokenId_); - for(uint256 i=0; i < indexes_.length; i++) { - uint256 bucketIndex = indexes_[i]; + // if no other positions exist for this bucketIndex, remove from bucketIndexesWithPosition + if (getTokenIdsByBucketIndex(bucketIndex).length == 0) { - uint256 actorPoolLps = bucketIndexToActorPoolLps[bucketIndex]; - uint256 positionManPoolLps = bucketIndexToPositionManPoolLps[bucketIndex]; + bucketIndexesWithPosition.remove(bucketIndex); + } (uint256 poolActorLps,) = _pool.lenderInfo(bucketIndex, preActionOwner); (uint256 poolPosLps,) = _pool.lenderInfo(bucketIndex, address(_positionManager)); // assert PositionsMan LP in pool matches the amount redeemed by actor // positionMan has now == positionMan pre - actor's LP change - require(poolPosLps == positionManPoolLps - (poolActorLps - actorPoolLps), + require(poolPosLps == posManLpsBefore[bucketIndex] - (poolActorLps - actorLpsBefore[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 == actorPoolLps + (positionManPoolLps - poolPosLps), + require(poolActorLps == actorLpsBefore[bucketIndex] + (posManLpsBefore[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 @@ -187,14 +173,37 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan require(posDepositTime == 0, "PM8: tokenId has depositTime after redemption"); // delete mappings for reuse - delete bucketIndexToActorPoolLps[bucketIndex]; - delete bucketIndexToPositionManPoolLps[bucketIndex]; + delete actorLpsBefore[bucketIndex]; + delete posManLpsBefore[bucketIndex]; } + // info for tear down + delete bucketIndexesByTokenId[tokenId_]; + tokenIdsByActor[address(_actor)].remove(tokenId_); + + // assert that the minter is still the owner + 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'); + + // 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'); + } catch (bytes memory err) { + + for ( uint256 i = 0; i < indexes_.length; i++) { + uint256 bucketIndex = indexes_[i]; + // delete mappings for reuse + delete actorLpsBefore[bucketIndex]; + delete posManLpsBefore[bucketIndex]; + } + _ensurePositionsManagerError(err); } - } function _getQuoteAtIndex( @@ -248,10 +257,14 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan bucketIndexesByTokenId[tokenId_].remove(fromIndex_); // Post Action Checks // - // remove tracked positios - bucketIndexesWithPosition.remove(fromIndex_); + // remove tracked positions tokenIdsByBucketIndex[fromIndex_].remove(tokenId_); + // if no other positions exist for this bucketIndex, remove from bucketIndexesWithPosition + if (getTokenIdsByBucketIndex(fromIndex_).length == 0) { + bucketIndexesWithPosition.remove(fromIndex_); + } + // track created positions bucketIndexesWithPosition.add(toIndex_); tokenIdsByBucketIndex[toIndex_].add(tokenId_); @@ -273,7 +286,6 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan // positionManager's total QT postAction is less than or equal to preAction // can be less than or equal due to fee on movements above -> below LUP - greaterThanWithinDiff( preActionFromIndexQuote + preActionToIndexQuote, postActionFromIndexQuote + postActionToIndexQuote, @@ -281,7 +293,6 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan "PM6: positiionManager QT balance has increased by `1` margin" ); - } catch (bytes memory err) { _ensurePositionsManagerError(err); } @@ -304,9 +315,9 @@ abstract contract UnboundedERC20PoolPositionsHandler is UnboundedBasePositionHan // 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"); + } catch (bytes memory err) { _ensurePositionsManagerError(err); } } -} - +} \ No newline at end of file diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol similarity index 78% rename from tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol rename to tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol index 6bd8eb746..313cd545e 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/unbounded/UnboundedRewardsPoolHandler.sol @@ -2,25 +2,37 @@ 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 } from 'src/libraries/helpers/PoolHelper.sol'; +import { + _depositFeeRate, + _lpToQuoteToken, + _priceAt + } from 'src/libraries/helpers/PoolHelper.sol'; import { Maths } from "src/libraries/internal/Maths.sol"; -import { UnboundedERC20PoolPositionsHandler } from './UnboundedERC20PoolPositionsHandler.sol'; +import { BaseERC20PoolHandler } from '../../../ERC20Pool/handlers/unbounded/BaseERC20PoolHandler.sol'; +import { UnboundedBasePositionHandler } from './UnboundedBasePositionHandler.sol'; -import { _depositFeeRate } from 'src/libraries/helpers/PoolHelper.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 UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler { +abstract contract UnboundedRewardsPoolHandler is UnboundedPositionPoolHandler { using EnumerableSet for EnumerableSet.UintSet; + /********************************/ + /*** Rewards Helper Functions ***/ + /********************************/ + function _stake( uint256 tokenId_ ) internal updateLocalStateAndPoolInterest { @@ -33,6 +45,9 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler 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) { @@ -53,23 +68,29 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler // 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)) { - rewardsAlreadyClaimed[epoch] = _rewardsManager.rewardsClaimed(epoch); + rewardsEarnedInEpochPreAction[epoch] = _rewardsManager.rewardsClaimed(epoch); } // total the rewards earned pre action totalRewardsEarnedPreAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(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; @@ -83,8 +104,8 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler "RW6: epoch after claim rewards is not claimed"); } - if (rewardsAlreadyClaimed[epoch] != 0) { - require(rewardsAlreadyClaimed[epoch] == _rewardsManager.rewardsClaimed(epoch), + if (rewardsEarnedInEpochPreAction[epoch] > 0) { + require(rewardsEarnedInEpochPreAction[epoch] == _rewardsManager.rewardsClaimed(epoch), "RW10: staker has claimed rewards from the same epoch twice"); } @@ -132,6 +153,13 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler 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++) { @@ -140,10 +168,6 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler totalRewardsEarnedPostAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); } - // actor should receive tokenId, positionManager loses ownership - tokenIdsByActor[address(_actor)].add(tokenId_); - tokenIdsByActor[address(_rewardsManager)].remove(tokenId_); - require(totalRewardsEarnedPreAction == totalRewardsEarnedPostAction, "rewards were earned on emergency unstake"); @@ -203,15 +227,16 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler // 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)) { - rewardsAlreadyClaimed[epoch] = _rewardsManager.rewardsClaimed(epoch); + rewardsEarnedInEpochPreAction[epoch] = _rewardsManager.rewardsClaimed(epoch); } - - // total staking rewards earned across all actors in epoch pre action - totalRewardsEarnedPreAction += _rewardsManager.rewardsClaimed(epoch); + // total the rewards earned pre action + totalRewardsEarnedPreAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); } try _rewardsManager.claimRewards(tokenId_, epoch_, 0) { @@ -229,16 +254,17 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler "RW6: epoch after claim rewards is not claimed"); } - if (rewardsAlreadyClaimed[epoch] != 0) { - require(rewardsAlreadyClaimed[epoch] == _rewardsManager.rewardsClaimed(epoch), + if (rewardsEarnedInEpochPreAction[epoch] > 0) { + require(rewardsEarnedInEpochPreAction[epoch] == _rewardsManager.rewardsClaimed(epoch), "RW10: staker has claimed rewards from the same epoch twice"); } - // total staking rewards earned across all actors in epoch post action - totalRewardsEarnedPostAction += _rewardsManager.rewardsClaimed(epoch); + // total rewards earned across all actors in epoch post action + totalRewardsEarnedPostAction += _rewardsManager.rewardsClaimed(epoch) + _rewardsManager.updateRewardsClaimed(epoch); - // reset staking rewards earned in epoch - rewardsClaimedPerEpoch[epoch] = _rewardsManager.rewardsClaimed(epoch); + // reset staking and updating rewards earned in epoch + rewardsClaimedPerEpoch[epoch] = _rewardsManager.rewardsClaimed(epoch); + updateRewardsClaimedPerEpoch[epoch] = _rewardsManager.updateRewardsClaimed(epoch); } (, , uint256 lastClaimedEpoch) = _rewardsManager.getStakeInfo(tokenId_); @@ -256,6 +282,29 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler } } + function _advanceEpochRewardStakers( + uint256 amountToAdd_, + uint256[] memory indexes_, + uint256 numberOfEpochs_, + uint256 bucketSubsetToUpdate_ + ) internal virtual; + + + function _randomizeExchangeRateIndexes( + uint256[] memory indexes_, + uint256 bucketSubsetToUpdate_ + ) internal pure returns (uint256[] memory boundBuckets_) { + + uint256 boundIndexes = constrictToRange(bucketSubsetToUpdate_, 0, indexes_.length); + boundBuckets_ = new uint256[](boundIndexes); + + if (boundBuckets_.length !=0) { + for (uint256 i = 0; i < boundIndexes; i++) { + boundBuckets_[i] = indexes_[i]; + } + } + } + function _ensureRewardsManagerError(bytes memory err_) internal pure { bytes32 err = keccak256(err_); @@ -270,4 +319,4 @@ abstract contract UnboundedRewardsHandler is UnboundedERC20PoolPositionsHandler "Unexpected revert error" ); } -} +} \ No newline at end of file diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 7748994be..3cc9ee2f4 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -61,7 +61,7 @@ abstract contract BaseHandler is Test { mapping(address => mapping(uint256 => uint256)) public lenderDepositTime; // mapping of lender address to bucket index to deposit time address[] public actors; - mapping(bytes => uint256) public numberOfCalls; // Logging + mapping(bytes => uint256) public numberOfCalls; // Logging mapping(bytes => uint256) public numberOfActions; // Logging mapping(address => uint256[]) public touchedBuckets; // Bucket tracking diff --git a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol index a9ea056e8..e89d324e4 100644 --- a/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol +++ b/tests/forge/invariants/interfaces/IPositionsAndRewardsHandler.sol @@ -3,13 +3,16 @@ pragma solidity 0.8.18; interface IPositionsAndRewardsHandler { - - function rewardsClaimedPerEpoch(uint256) external view returns(uint256); - function updateRewardsClaimedPerEpoch(uint256) external view returns(uint256); - function epochToRewardsSnapshot(uint256) external view returns(uint256); - + // positionManager & rewardsManager function getBucketIndexesWithPosition() external view returns(uint256[] memory); - function getTokenIdsByBucketIndex(uint256) external view returns(uint256[] memory); function getBucketIndexesByTokenId(uint256) external view returns(uint256[] memory); + + // positionManager function getTokenIdsByActor() external view returns(uint256[] memory); + function getTokenIdsByBucketIndex(uint256) external view returns(uint256[] memory); + + // rewardsManager + function rewardsClaimedPerEpoch(uint256) external view returns(uint256); + function updateRewardsClaimedPerEpoch(uint256) external view returns(uint256); + function getStakedTokenIdsByActor() external view returns(uint256[] memory); } \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol similarity index 92% rename from tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol rename to tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol index 0e8cb9d97..dea6c5e7a 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestPositionManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolPositionManager.t.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.18; import { ERC20PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC20PoolPositionsInvariants.t.sol"; -contract RegressionTestPositionManager is ERC20PoolPositionsInvariants { +contract RegressionTestERC20PoolPositionManager is ERC20PoolPositionsInvariants { function setUp() public override { super.setUp(); @@ -119,6 +119,16 @@ contract RegressionTestPositionManager is ERC20PoolPositionsInvariants { function test_regression_position_manager() external { _erc20positionHandler.redeemPositions(79335468733065507138817566659594782917024872257218805, 1889027018179489664211573893, 43578107449528230070726540147644518395094194018887636259089111851, 0); + } + // This EVM revert fires a `NoAllowance()` error. certain pool errors fire in positionManager calls + // fix: import specific pool errors into positionManager catch + // Add quote token was failing due to a rounding issue in amount supplied that resulted in an attempt to add zero QT to the pool + // fix: altered the addQuoteToken call in preMemorializePosition method + function test_regression_failure_evm_revert_5() external { + _erc20positionHandler.moveLiquidity(35855801402931413691347, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 3); + _erc20positionHandler.mint(1, 6981663636108743728471595901895228956316688268); + _erc20positionHandler.failed(); + _erc20positionHandler.redeemPositions(9941, 12031, 22960, 1397); } } diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol new file mode 100644 index 000000000..33b9ffe90 --- /dev/null +++ b/tests/forge/regression/PositionAndRewards/RegressionTestERC20PoolRewardsManager.t.sol @@ -0,0 +1,480 @@ + +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, 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, 4579, 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, 0); + _erc20poolrewardsHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 120615857050623137463512130550262626813346106); + invariant_positions_PM1_PM2_PM3(); + } + + function test_regression_rewards_PM1_4() public { + _erc20poolrewardsHandler.moveLiquidity(832921267658491751933537549, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 62241022956197145532, 1165012150, 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, 0); + } + + // 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, 0); + } + + // 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, 672432889047616138980078995830, 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, 0); + _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, 0); + _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, 0); + } + + // 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, 19432349521828210006920603112382926535859550351439231094, 1); + _erc20poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 28562572353266841739143693967402627296578365988173585532380692, 0); + _erc20poolrewardsHandler.removeCollateral(880053353375737921406212405707, 1753558590, 6280826978696699921318109415672827430264350217031853972826832132306719032380, 787979188955935138704416864067); + _erc20poolrewardsHandler.moveLiquidity(11088, 1034959661872260168, 999999999999999212021821301557602448736097220, 25426918372734382433143072945767633116982163690088039971661147586959577591865, 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, 0); + _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, 55874229446601275, 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, 0); + _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, 3153442172782088538684911, 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, 251040383784310909950712987871787320169957089, 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, 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, 1711, 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, 1767503704449485978933058571939541599529908587415055225570810956, 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, 515992583720, 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, 255697520996289263807310886, 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, 0); + _erc20poolrewardsHandler.takeAuction(2000097453768943289819883643139, 1616, 9008, 2957522668165515327594480); + _erc20poolrewardsHandler.kickAuction(1023868299540571449491438, 2726, 3501, 1009546288143049196); + _erc20poolrewardsHandler.claimRewards(1850558667714835415003, 1128770330214, 48160424827244602174656651208212101506580, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 5, 0); + _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, 2, 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, 24040659239847326449, 688903335135867866827970099664435153097141537805976741866417852208381952); + _erc20poolrewardsHandler.settleAuction(86639131860678742534809729831583343741269560864832321, 261140637, 18623697431831025536282119954975103467560305081672865, 18753717689854910664818243334489713190658697158135381); + _erc20poolrewardsHandler.moveLiquidity(688023305723199887936675774367107725948935104557465010923465143476322304, 426, 1361140653919103091484439143, 2492532610214694144077601771204, 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, 0); + } + + // 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, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6059353902491193986166404361793496); + _erc20poolrewardsHandler.takeAuction(20887, 7435, 2230322682, 5173); + _erc20poolrewardsHandler.removeQuoteToken(1, 37847095259185386235427787, 7586404791082, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc20poolrewardsHandler.kickReserveAuction(746270214, 3227); + _erc20poolrewardsHandler.claimRewards(3, 17838572802108205165768007139310483904447158906777650273909618150730155082, 179308467167974215120170861599730499666095743876089926251458944458077, 3, 2, 0); + _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 410137998186978556584901507876419312185968499332529, 0); + _erc20poolrewardsHandler.repayDebt(17165, 29, 4926); + _erc20poolrewardsHandler.redeemPositions(10181896186129835628862076, 4191, 2070, 4316); + _erc20poolrewardsHandler.unstake(2, 721416428842444814, 1, 1, 2, 0); + _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, 0); + } + + // 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, 52534, 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, 73559801971876655830284650454672056023206176402691276845053940498149797, 2453039451665641392603351405279); + _erc20poolrewardsHandler.pullCollateral(2227999026154255580938434049821, 1929, 21209080205145509799924600234705734221480599); + _erc20poolrewardsHandler.unstake(77763028316274741760991770148, 889544954655483052642168760960, 1000073821603105106, 14781730360850539958536528862089, 1, 0); + _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, 0); + _erc20poolrewardsHandler.lenderKickAuction(1, 0, 58846077910505664190879804); + _erc20poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); + _erc20poolrewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc20poolrewardsHandler.moveLiquidity(7886, 1223, 249959471556478, 8036, 957); + _erc20poolrewardsHandler.drawDebt(3724423259505818275008000000000, 5967, 5194); + _erc20poolrewardsHandler.claimRewards(1, 0, 0, 330972817125, 3, 0); + } + + // 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, 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, 0); + _erc20poolrewardsHandler.burn(688021852742675773311740551529319527808439204801695657427445806654554112, 30320319961996759187294, 7002942661907890346192131385494, 4372348210670480168); + _erc20poolrewardsHandler.unstake(1356091896433556140, 20806050335329426573872365432402, 5853329116210293074909437460260, 202213678846911363250835224523544374961057849761087685126829207099, 0, 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, 0); + _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, 0); + _erc20poolrewardsHandler.claimRewards(226258926917592116664863093705619544, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 18029537521280273078473, 64387518121614299931212379232668997590869195864587409918593738, 3, 0); + _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, 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, 0); + _erc20poolrewardsHandler.redeemPositions(1605595040568071691761529272186, 6374589932811962143806364569626, 504869791, 703741879815086064785063845794263063501986986299046618128871452969759630); + _erc20poolrewardsHandler.stake(9240016643022332539182984, 695264275347035435556335000, 999952379124307148259328110510, 3501569749230777430235792877533); + _erc20poolrewardsHandler.claimRewards(290604600286948252496463313490999079578398159220189531705245153689, 1229050267483794368236552210802835, 37012905065727386300525031553852696, 2, 3, 0); + _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, 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, 0); + _erc20poolrewardsHandler.kickReserveAuction(60878538920082033291777355178031898195946345, 151301); + _erc20poolrewardsHandler.failed(); + _erc20poolrewardsHandler.updateExchangeRate(3723, 14193362190521867625362174086119, 2984847556915278249, 1431948565575439403); + _erc20poolrewardsHandler.unstake(620475720165697999262823248208783049842251523083896535779413924216, 115545045573751618433375484275813400274137417951043663590237066664176780, 600099763819723634604346206, 26269036480442907031637331641942418161332430845896343, 9, 0); + _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, 0); + _erc20poolrewardsHandler.transferLps(3536960038764358210048752718460, 134319387439720762165052351935, 723, 869949153720793397042, 21774); + _erc20poolrewardsHandler.moveLiquidity(24860115440580498809182, 67836324731985777005501908631161678093421222411927620708449, 0, 2, 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, 2); + _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, 38429779365541845038); + _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, 571403097017002970217793625212942424774848098644003); + } + + // 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, 695); + _erc20poolrewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639932, 34424191262358238003767015512550467320952787658814634693105516384280765757, 1); + _erc20poolrewardsHandler.stake(1393087899760396821662448, 0, 2, 0); + _erc20poolrewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639935, 5116902771599276991193476659475872307811128145867445833445550672, 39432975197416494829678821326411300701120551523826226104277956561932827108228, 1400506682660594660722797942017241426449513741223482862482308212423, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _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, 60249307989625514041093966022923819939033804); + _erc20poolrewardsHandler.kickReserveAuction(150771469208542706010213463867, 43354246406661751231666714345663189); + _erc20poolrewardsHandler.takeAuction(3534600738871654532093694, 710900971556109763949049343751907780671963860281451036129946241395772330, 32791, 92899073076001134670575647915681268872801635774755826272901748142573588803419); + _erc20poolrewardsHandler.removeQuoteToken(1999999571196206119106253024650, 999999999999999359435426300823017114351704074, 847975398478536617553572420, 997892034638190564617566391041); + _erc20poolrewardsHandler.unstake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 15705207428248257128809996708067820574434789987097242585735992570899338201, 3, 120654062796568739935506875947855859740423212347571712122719, 46804941067673252); + _erc20poolrewardsHandler.lenderKickAuction(114769084034992770447742921711671102586, 1495429900, 15541); + _erc20poolrewardsHandler.moveLiquidity(948940574329580087951488104576612006868387916754938, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); + } + +} diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol new file mode 100644 index 000000000..47ec1d428 --- /dev/null +++ b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolPositionManager.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED + +pragma solidity 0.8.18; + +import { ERC721PoolPositionsInvariants } from "../../invariants/PositionsAndRewards/ERC721PoolPositionsInvariants.t.sol"; + +contract RegressionTestERC721PoolPositionsManager is ERC721PoolPositionsInvariants { + + function setUp() public override { + super.setUp(); + } + + // `NoAllowance()` revert was firing but wasn't tracked by positionManager handler class + function test_regression_failure_no_allowance_err() external { + _erc721positionHandler.moveLiquidity(2, 2726918499846956781196026606977128745, 4671573035498269269631531108867257349254074281251805650007376127, 65229405930547405981803897204924144159227983393929014243, 136472940433983213576424627235038299016985732062067347200674016); + _erc721positionHandler.memorializePositions(10365, 771, 8152, 3186); + } +} \ No newline at end of file diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol new file mode 100644 index 000000000..16c600a22 --- /dev/null +++ b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol @@ -0,0 +1,31 @@ +// 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, 103015036129420501082640292999971233764824083444698625545321391489266878218522, 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, 0); + } +} diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol deleted file mode 100644 index d77ecafd4..000000000 --- a/tests/forge/regression/PositionAndRewards/RegressionTestRewardsManager.t.sol +++ /dev/null @@ -1,371 +0,0 @@ - -pragma solidity 0.8.18; - -import { RewardsInvariants } from "../../invariants/PositionsAndRewards/RewardsInvariants.t.sol"; -import { PoolInfoUtils } from 'src/PoolInfoUtils.sol'; - -import '@std/console.sol'; - -contract RegressionTestRewardsManager is RewardsInvariants { - - 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 { - _rewardsHandler.unstake(156983341, 3, 1057, 627477641256361); - _rewardsHandler.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 { - _rewardsHandler.addCollateral(378299828523348996450409252968204856717337200844620995950755116109442848, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 52986329559447389847739820276326448003115507778858588690614563138365, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.memorializePositions(2386297678015684371711534521507, 1, 2015255596877246640, 0); - _rewardsHandler.moveLiquidity(999999999999999999999999999999999999999542348, 2634, 6160, 4579, 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 { - _rewardsHandler.memorializePositions(1072697513541617411598352761547948569235246260453338, 49598781763341098132796575116941537, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 59786055813720421827623480119157950185156928336); - _rewardsHandler.drawDebt(71602122977707056985766204553433920464603022469065, 0, 3); - _rewardsHandler.settleAuction(1533, 6028992255037431023, 999999999999998827363045226813101730497689206, 3712); - _rewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 14721144691130718757631011689447950991492275176685060291564256, false, 136782600565674582447300799997512602488616407787063657498, 12104321153503350510632448265168933687786653851546540372949180052575211); - _rewardsHandler.unstake(5219408520630054730985988951364206956803005171136246340104521696738150, 2, 0, 7051491938468651247212916289972038814809873); - _rewardsHandler.settleAuction(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 120615857050623137463512130550262626813346106); - invariant_positions_PM1_PM2_PM3(); - } - - function test_regression_rewards_PM1_4() public { - _rewardsHandler.moveLiquidity(832921267658491751933537549, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 62241022956197145532, 1165012150, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 108613063553696015935192567274231711586207468226993603118670370534031542, 2, 1); - _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); - _rewardsHandler.settleAuction(1694548149298356876485941302354, 9052, 1444291546717740702970, 1303240033616582679504132393648); - _rewardsHandler.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 { - _rewardsHandler.kickAuction(4927, 15287, 1672621391, 7794); - _rewardsHandler.removeQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2, 3); - _rewardsHandler.takeAuction(2575, 5650, 2711, 12004413); - _rewardsHandler.mint(1515215594322469882937526919173, 2864); - _rewardsHandler.removeQuoteToken(11445, 2303142144561970723486793685729, 3879, 1008905021187010892); - _rewardsHandler.redeemPositions(23630504830242022841459200705989645184404322170375013590678501625107, 1, 282473030835977356124316597209309127812, 0); - _rewardsHandler.redeemPositions(4829, 7399, 20165, 19797); - _rewardsHandler.addQuoteToken(8330901901683684346410, 1944730599598704240629, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.mint(52483, 375); - _rewardsHandler.removeQuoteToken(242161003333451991910682, 833804465517702, 0, 153306087017); - _rewardsHandler.claimRewards(5460042422485935527540305190804180316252530934172557782973004, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2317020199583405169185090105199, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - } - - // 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 { - _rewardsHandler.redeemPositions(535, 10526, 16402, 90638196); - _rewardsHandler.moveQuoteToken(3, 3, 3665933105380066469, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 35609320936341689682324970775); - _rewardsHandler.lenderKickAuction(65195123838887638071598468995195715179071041842210505440218069543269527898574, 1428, 1550); - _rewardsHandler.updateExchangeRate(3324, 3433, 385); - _rewardsHandler.removeQuoteToken(487993211956248337274085963929265840000354071708865988088685578811819, 8714694397591072960002001972219030782403253520, 0, 0); - _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 3, 0); - _rewardsHandler.addQuoteToken(8049702985159192133654841011926250176578891096284667148191654768576101, 420390974052856985135062265979816823871512, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 6168047604119363323178237637165700555180739052007127817776433423995137133826); - _rewardsHandler.pledgeCollateral(38623724134600076305519407, 1, 42313782903); - _rewardsHandler.takeAuction(2520288506, 56779, 10626, 2578); - _rewardsHandler.updateExchangeRate(2374, 3180, 11271); - _rewardsHandler.moveQuoteToken(3, 84452381279, 65209096465360247728023547148755401892588275436, 1, 97710781974409185143365462469280072552935020234615584635942788); - _rewardsHandler.claimRewards(4219, 7299, 3792253, 3829); - } - - // 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 { - _rewardsHandler.takeAuction(7657762660104020786102326341030666744203129169035726688092178, 1, 3, 63603943629412590405183648739466756021204); - _rewardsHandler.moveLiquidity(853498184631967766239539459019, 860800972267934599, 2712933514310088838415608172991, 672432889047616138980078995830, 1940131010529342263123392466824); - _rewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 427572220473655037333866875012561018809807470070214697627941860984, 44890261877119855592686274106685080718432502924958626579185298373762938186596); - // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) - // epoch: 1 - // burned 27895 - _rewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); - _rewardsHandler.pledgeCollateral(1, 0, 2); - _rewardsHandler.pledgeCollateral(46380480507328, 10, 1); - // stake ( update ex rates -> stake ) -> kick res -> take res -> unstake( update ex rates -> unstake) - // epoch: 2 - // burned 27895 - _rewardsHandler.claimRewards(1852732090424016924140170274064383911484, 183940675308906, 0, 53861119148520095956903865568282398357460507464813555898544376318790433189); - _rewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639932, 395769107397432386894162390920154234120, 10606604808645482457593038172768629927057694502686); - _rewardsHandler.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 - _rewardsHandler.unstake(10754921060610721338628656060623251463708357833056948746687720475, 2630, 3678, 47729066275298389217682475444047844926190); - } - - // 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 { - _rewardsHandler.repayDebt(85714, 1049291847999068770, 999999999999999999999999628872336833145697942); - _rewardsHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 36806208, 15184194898560474755071902858637273513435561597233554208311133688, 467793045980282819019245873531034252276885664851); - _rewardsHandler.takeReserves(430754706367378, 137895823818768170443343531843552347803975, 136256767494531323); - _rewardsHandler.removeQuoteToken(151907177410358060568159872791300321117419489937830, 7129107044982420534725125240530941606156790404561718416111313794090, 9379839670333585391370, 64411724624691339174378); - _rewardsHandler.repayDebt(115792089237316195423570985008687907853269984665640564039457584007913129639933, 4761347487120837320733494601307653768982862843053132338897249261174, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.moveLiquidity(1387083372699602, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1, 19432349521828210006920603112382926535859550351439231094, 1); - _rewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639935, 28562572353266841739143693967402627296578365988173585532380692, 0); - _rewardsHandler.removeCollateral(880053353375737921406212405707, 1753558590, 6280826978696699921318109415672827430264350217031853972826832132306719032380, 787979188955935138704416864067); - _rewardsHandler.moveLiquidity(11088, 1034959661872260168, 999999999999999212021821301557602448736097220, 25426918372734382433143072945767633116982163690088039971661147586959577591865, 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 { - _rewardsHandler.unstake(4735, 7947, 99648028073174186569406251043082614463523861559444314198794141049070931765266, 165); - _rewardsHandler.memorializePositions(1017586779835017595, 2000093450358386131913319801132, 999999999999999994705800289221, 5936); - _rewardsHandler.lenderKickAuction(0, 552702177486359210209998874773373639789414577510403177176780671, 1); - _rewardsHandler.lenderKickAuction(5408465446957, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1244705446892222810789723108370662428040158); - _rewardsHandler.pledgeCollateral(17006067685850655253277243263894458277559455, 365821919836536381007791134, 3); - _rewardsHandler.transferLps(1020398235799939978, 8615, 10094997325303278, 6365, 16905); - _rewardsHandler.moveQuoteToken(31568984050285372419235475362633334556373463, 2459831956710974374263868230506844670431779539018807045, 5569725293573705060280053370462598629680698918, 3, 0); - _rewardsHandler.drawDebt(2189769129255122063229251712703191878940949, 1, 30); - _rewardsHandler.redeemPositions(4988, 1000000019294578543, 113393, 20000); - _rewardsHandler.moveLiquidity(11546346822809939448153205354420218227887882771387, 17456495056515572411115147660, 182412808598764326152439106919570567805594493064808060386470, 55874229446601275, 34611500787879233737900); - } - - function test_regression_PM1_PM2_PM3_failure() external { - _rewardsHandler.addQuoteToken(1000476160430240196, 31831819542854202372682438294297749483895311991281138887779537875208920731861, 1690250244645061953490579723838, 8303344632134790875350129671); - _rewardsHandler.redeemPositions(24517164785660125111092467892090015256239780879372312856314705897654233071616, 789619793367986175384776327373, 17366, 27337330393966417869011597343142520438331591211099340735032445540394415961142); - _rewardsHandler.mint(4918260799182, 7979); - _rewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); - _rewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 541386860615883, 3, 1427594577268427); - _rewardsHandler.repayDebt(3, 73, 14148592833); - _rewardsHandler.withdrawBonds(408448193972491682247856759691, 6725156476034981825430803209361659548467896941475, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.burn(207659258550486295439876272535780992392904995291122705229127151, 747338929, 1252191612369811194685436, 1); - _rewardsHandler.settleAuction(40898023934445005959403090083409155881516500501072076223, 14829255767842040071, 22556694249976650341045163634875596221258685026085348004092232963852919995373, 0); - _rewardsHandler.lenderKickAuction(3, 1763503097380079097391449321238134748267573906097584829633224009446989852620, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.failed(); - _rewardsHandler.pledgeCollateral(992967362603883335031186827777494890596884348, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.moveLiquidity(1439924512892792038061585821476, 12312838412972807476774254, 1386973529615993967509458441, 3153442172782088538684911, 25874047955237976217666127598767369999822558723350386077928985570803529547776); - - invariant_positions_PM1_PM2_PM3(); - } - - // exchange rate is below one and a moveLiquidity() call occurs - function test_regression_exchangerate_lt_one_failure() external { - _rewardsHandler.settleAuction(1, 38076326081732675084782953958723025268483402, 32122014834284740581605218790860586945, 675323572528116699998584163938054267674059083708770338684825); - _rewardsHandler.takeAuction(3187233434979664450766064117497382244786499427506246277958134435335, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 68185348, 0); - _rewardsHandler.removeQuoteToken(9799774902, 0, 171307717744339938462212153344256080, 22090621942183459004431027189984935997454202251794379); - _rewardsHandler.settleAuction(10469641420936113, 158810559950203569266889779145, 2729976800298283367181, 629830085692443228137978633631); - _rewardsHandler.kickAuction(1999638989041095890000000, 2621683063801908884388370586075, 5202919328337784754771241, 1704327030); - _rewardsHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639934, 0, 16473, 1298950632239640199, 92988305527741837015515230); - _rewardsHandler.addQuoteToken(4513829468825775442619016612, 119081395592772229137, 2956368200448621153724264764841, 43337887745458188956665754735863930); - _rewardsHandler.redeemPositions(1280000, 107418549682317941, 373995538053150407541675996799144040378996115919481128822550428, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.moveLiquidity(67209037983603756736, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 107047380550, 251040383784310909950712987871787320169957089, 136465421231555); - _rewardsHandler.burn(0, 215634488088281622713592282980500574552450094015166108001671516324248273978, 2872470631302225600444008164197436445, 3825369962689014919985865); - _rewardsHandler.redeemPositions(9321565985916881685418690197371166789551668163901391336422536021610052010235, 1000001049598692774037881, 1000916926448247166, 1294903748407840); - _rewardsHandler.memorializePositions(11357398784982391024848846139138331345877617925164801651509999164448020739, 129054800695, 2, 0); - _rewardsHandler.unstake(1008040767152967082, 2705590298374864519261, 2711436202524373179865882211354132, 1058992097359326876866506180); - _rewardsHandler.drawDebt(0, 2, 2); - _rewardsHandler.settleAuction(3, 109119248607504264825921197422518323470603, 2736316384792465597, 12368015967168137); - _rewardsHandler.lenderKickAuction(1, 34593728349238363, 2); - _rewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2); - _rewardsHandler.takeReserves(37288205583577963230409441522973702491285105267336919446, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2); - _rewardsHandler.redeemPositions(46789, 6151865526048672236676594, 9043006728606892937350259542, 93268112651994959075836677); - _rewardsHandler.moveLiquidity(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3563135139286698066907701283845339, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1711, 0); - } - - // exchange rate was less than one in fromBucket during `moveLiquidity()` call - function test_regression_exchangerate_lt_one_unstake_failure() external { - _rewardsHandler.addQuoteToken(6142020986804765534920167884740010286243484147097745265674427, 112422117, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.removeCollateral(10151503789076003424768351930, 50838311790159949733482050440261, 787978286748398677564101888697, 743157368739340183819239223268107466431333883452773104647798952518671555); - _rewardsHandler.updateExchangeRate(21755610456008175749216891385815221667397636280908693792396899755901148039675, 76822710358333592680973548681291198, 183811652651622670286097901303322315169696013956957316331731965); - _rewardsHandler.moveQuoteToken(3843466665413066001504591, 1000009389351870783, 1000172353696212579, 2796008107630611079450058960364, 10168864164675898312163); - _rewardsHandler.moveLiquidity(673087759601966739507343763016554, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 2339943610295551416526796192911912414311026002620, 1767503704449485978933058571939541599529908587415055225570810956, 9446221296393433187709657992720367407411357294298157052447175); - _rewardsHandler.stake(999999999999999505134320049118757567405586786, 1025431341927257246, 1090, 13569953566136947230136843); - _rewardsHandler.moveQuoteToken(1051099440087016359, 1357438875313834074678021636760282066916630639717893146590321, 63313628, 84622650405653151060672, 28876); - _rewardsHandler.bucketTake(7462, 1121098501725271973, false, 999999999999999999999989741489665556227804536, 442072679406687075418827994186); - _rewardsHandler.moveLiquidity(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 515992583720, 11542363425921008807915173674517106); - } - - // auction was clearable when `moveLiquidity()` was called, which fired a revert - function test_regression_auction_clearable_remove_collateral() external { - _rewardsHandler.takeReserves(1033259874529284986, 115792089237316195423570985008687907853269984665640564039457584007913129537237, 999999999999999999999999999611297087410149302); - _rewardsHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, true, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); - _rewardsHandler.settleAuction(1019166912441147606, 1174, 24356906371720, 1427315247291615855384771361467057592874190974); - _rewardsHandler.drawDebt(31570870468988913, 2490457201062127395317721901417, 14518); - _rewardsHandler.removeQuoteToken(234409660495649, 601338041799139892223226281710979, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 51209466403350773952498018); - _rewardsHandler.removeCollateral(1615097416247525221325833769791620, 999999999999998491682012949797990382689794890, 72294939771647531696639626124859859519954417706042013154, 1123754474529168009989296); - _rewardsHandler.addQuoteToken(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1418766863689180288802735178388574160614681714182842545424322601317331241, 0); - _rewardsHandler.burn(10779801302631984284074768919, 1022785462636254549, 4247197939956962367856295710228836, 714087046845131802724051059732250799440226582946566742486292756992468224); - _rewardsHandler.settleAuction(44188076061165790147414944966563643572374763434799334, 1, 6140, 982305872882119302926935288339691246129501298); - _rewardsHandler.failed(); - _rewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 0, 1373087264969562284412462993767160637254468276739905307938530638280854638702); - _rewardsHandler.pledgeCollateral(10321692057145851776062997, 45715379632908488147290369180827577791327034825339732187105428425706, 73584310749102695099025849803685991935361634); - _rewardsHandler.moveQuoteToken(267424702347976937182244333, 53012, 1000122761636267185545584328894, 81844228617571507568624913, 2091433423541324315018709); - _rewardsHandler.memorializePositions(4341569243600918031477893648, 1037146955303444803059178, 541740178036862, 1079117209305474618); - _rewardsHandler.moveLiquidity(7990221475142856060836580, 5177379241789726416494109766258664604084660827937056770440668685154449638506, 270858793106233, 255697520996289263807310886, 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 { - _rewardsHandler.claimRewards(115792089237316195423570985008687907853269984665640564039457584007913129639933, 486888075223510502299880936499251496488108390102993365331518154575959314103, 1489390063300625330233647743808860618285793249553177794776030333650229253556, 29413051449830420745080834496160737679746193111333313068326); - _rewardsHandler.takeAuction(2000097453768943289819883643139, 1616, 9008, 2957522668165515327594480); - _rewardsHandler.kickAuction(1023868299540571449491438, 2726, 3501, 1009546288143049196); - _rewardsHandler.claimRewards(1850558667714835415003, 1128770330214, 48160424827244602174656651208212101506580, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.memorializePositions(2706256741681, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 1224263559891519537412449982749693535319617589850332219938434821323); - _rewardsHandler.kickAuction(2470057927126901389325412029621991572541444590040210706345694, 33212171733138561367109746153438995283000410403806989, 1143982811769352536641977506, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.addQuoteToken(11577, 2847, 701077953563936355129549681402475369359939627904709959917807724349081600, 6164); - _rewardsHandler.mint(7455, 2274); - _rewardsHandler.transferLps(3, 461323124985628625982, 3, 2265109234892451242814665907719473205880324711447657612395270, 36536442103629333036112242276175423646850388752964235954199714605113762301); - _rewardsHandler.addCollateral(4807, 1257702269788440403102767606588, 10232361733685599944417, 8154); - _rewardsHandler.moveLiquidity(1147643, 1101373970, 1, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _rewardsHandler.redeemPositions(715216745373273013565709474193709288265853036742499324291033262974521344, 925844451104042264560, 21216664920724276219251928893592593152072674630296951273414530379050570789349, 64994818096056336519112112386345118349558865048523329927782158963716200486113); - _rewardsHandler.addCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _rewardsHandler.drawDebt(7803620494871325091384326, 1000000000005890305, 808187899175442127626759093647); - _rewardsHandler.stake(1881897373701350, 1, 384457493842895898324057, 2); - _rewardsHandler.kickAuction(1801888015, 36313972, 14589, 68230236911552087964619588008895983939113692817643498711581573912769382961420); - _rewardsHandler.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 { - _rewardsHandler.settleAuction(2, 3, 132571599922733151315276632984852300695962190184833433609822587845, 7127747531336); - _rewardsHandler.failed(); - _rewardsHandler.pledgeCollateral(66498430692251244700, 1672526787, 999118417682487042682458556356); - _rewardsHandler.settleAuction(102521875, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 2); - _rewardsHandler.redeemPositions(0, 11874544000691612616189791308069964024776658688403726762, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.moveLiquidity(6932062779809046417357379434, 37304063095178465963, 289377204519251903, 24040659239847326449, 688903335135867866827970099664435153097141537805976741866417852208381952); - _rewardsHandler.settleAuction(86639131860678742534809729831583343741269560864832321, 261140637, 18623697431831025536282119954975103467560305081672865, 18753717689854910664818243334489713190658697158135381); - _rewardsHandler.moveLiquidity(688023305723199887936675774367107725948935104557465010923465143476322304, 426, 1361140653919103091484439143, 2492532610214694144077601771204, 1690059365); - _rewardsHandler.removeCollateral(3, 75640118, 25456, 2); - _rewardsHandler.stake(1201518266017002700145955555, 422051400149996, 191695523226259206952824982, 2575958376257460112331288247217); - _rewardsHandler.removeCollateral(1724406295, 1153800818710038190908366, 198135760955974969122979112, 4072468695723038050466180656348448601624931627598867728374067772641581); - _rewardsHandler.moveQuoteToken(1, 2, 7848862956757903893727, 108398233646184752124495509729309782170036195843104530456166511127401848014, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.kickAuction(1033780344472464085003, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 4939129467716821333159227066); - _rewardsHandler.memorializePositions(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 5339231111427732, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 49134859377105172171787763664088172754470175); - _rewardsHandler.takeReserves(1000017062814174578, 695225158368402414621475732431414969707809712405441717937557041383099862, 1000099679120030632); - _rewardsHandler.updateExchangeRate(1798084723794266922073360424201, 1000261123000933782, 1010104555201180320207069905273); - _rewardsHandler.kickReserveAuction(14193, 4151); - _rewardsHandler.claimRewards(84674527179871518692009907151225958831784072125472174554, 1123074827467033894904599425374, 0, 2); - } - - // 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 { - _rewardsHandler.redeemPositions(1513, 5414, 496, 2041); - _rewardsHandler.moveLiquidity(1634580778705039759, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3513140137853878345040965, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 6059353902491193986166404361793496); - _rewardsHandler.takeAuction(20887, 7435, 2230322682, 5173); - _rewardsHandler.removeQuoteToken(1, 37847095259185386235427787, 7586404791082, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.kickReserveAuction(746270214, 3227); - _rewardsHandler.claimRewards(3, 17838572802108205165768007139310483904447158906777650273909618150730155082, 179308467167974215120170861599730499666095743876089926251458944458077, 3); - _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 3, 410137998186978556584901507876419312185968499332529, 0); - _rewardsHandler.repayDebt(17165, 29, 4926); - _rewardsHandler.redeemPositions(10181896186129835628862076, 4191, 2070, 4316); - _rewardsHandler.unstake(2, 721416428842444814, 1, 1); - _rewardsHandler.bucketTake(1701628611252955073601757907075824586952502043588380, 9931050451872161232934786702827793159570303822, true, 2925965874111818002623246439633594772, 3); - _rewardsHandler.bucketTake(2, 15470539950385543111949808932971047871463497008525518386, false, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); - _rewardsHandler.redeemPositions(115792089237316195423570985008687907853269984665640564039457584007913129639933, 2652132885321220255, 2, 1557926034); - } - - function test_regression_rewards_revert() external { - _rewardsHandler.takeReserves(1, 176264227116073539466710292640534, 0); - _rewardsHandler.drawDebt(1, 57859908193408492548049732123715354988106416421644089, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.addQuoteToken(1807664453705980418, 3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.drawDebt(14810, 12501, 11607381230457826577033271); - _rewardsHandler.kickAuction(126, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 296936791599072888382604547047579799590572591); - _rewardsHandler.bucketTake(2084, 265280, false, 621014983179582, 6560); - _rewardsHandler.redeemPositions(7465, 451605496, 3970, 1512); - _rewardsHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 1751716589805844630991620468, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.kickReserveAuction(11967, 1005568066651507152); - _rewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 2724518779079179784049138199493777186815675, 1874); - _rewardsHandler.addQuoteToken(3981, 1690101581, 97503618599900271359071534105156178950663445728441824941278920981153136631167, 999999999999999999999989741489665556227804536); - _rewardsHandler.bucketTake(247, 1291084637306870208638, false, 14752, 753); - _rewardsHandler.updateExchangeRate(3, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.pullCollateral(1266635973860390773360, 1, 3); - _rewardsHandler.mint(0, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.takeAuction(2214845414466110799205272778680836428372471699, 49004997820594553259859787080944156522906733, 3, 271825241); - _rewardsHandler.repayDebt(221806598861099254438373725802873431978648517331723635037739192841369, 11212235606391953616223043585188034400902381408644500974587575, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - _rewardsHandler.unstake(230323675018036494562757, 21630132699099546696940190603184460107953215649, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); - } - - // 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 { - _rewardsHandler.bucketTake(29456557203126366201854827466482433206831494327361303, 19307664601998129837361, false, 3492651658979151995106448, 0); - _rewardsHandler.lenderKickAuction(4429580015302257459201655018526, 2770867242698718418626, 9388); - _rewardsHandler.repayDebt(1000000034925771973, 6930625368245303852701363167, 695149882294170920069268290133705109872933519679164510383901578196897792); - _rewardsHandler.moveLiquidity(41132919728951221583605488, 1102564553356549573347, 3410238307441803358653636, 52534, 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 { - _rewardsHandler.redeemPositions(696309158766729979589534440166220067073887038152281856742599135926157312, 1870474563221356095022900189266, 18339, 1788135699833095102184812046279); - _rewardsHandler.kickReserveAuction(2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.memorializePositions(3671371551743995865, 99428, 1769100398, 7346319752739159); - _rewardsHandler.removeQuoteToken(2192844669750518881733689799257684129590332632218546259991943830203, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 3, 419); - _rewardsHandler.bucketTake(1606233188525778759956925750889, 999999999999999529711266919982837439648513939, false, 9949287379244091378213227, 3763880249088816172848545904993); - _rewardsHandler.settleAuction(55047125510583885662282424543762268712076435621770843340435135, 110421716658405583291991613217254392572785222796303390816855215908218229630, 1, 292423500273437202726891613067834132052054453755096719350366291073639790); - _rewardsHandler.takeAuction(6950266099624730892351521874528127288800419, 193622918230501420262501464441837, 3, 20111879376924408726124755543747277966848148390627132304350); - _rewardsHandler.bucketTake(2, 747496798808534888002766542, true, 221618799467305555283, 661410089069342); - _rewardsHandler.settleAuction(39300471897997857700471, 363003327028528645286555715801688230394596448247050, 10248673406547114848805417911883714616830860910846335722973488061592062643, 115792089237316195423570985008687907853269984665640564039457584007913129639933); - _rewardsHandler.updateExchangeRate(3, 4485331781540521052468660062240, 3); - _rewardsHandler.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 { - _rewardsHandler.transferLps(13692, 15203, 2000001367681895243673966806260, 13770006083256457112227, 1672449141); - _rewardsHandler.takeReserves(4947313423932616986372909633726, 3107772, 18585868099953215630514); - _rewardsHandler.bucketTake(3, 3, true, 5727003712726959800, 115792089237316195423570985008687907853269984665640564039457584007913129639934); - _rewardsHandler.moveLiquidity(3157314460140, 999999999964761098816798416093, 100749181527550271579655357, 73559801971876655830284650454672056023206176402691276845053940498149797, 2453039451665641392603351405279); - _rewardsHandler.pullCollateral(2227999026154255580938434049821, 1929, 21209080205145509799924600234705734221480599); - _rewardsHandler.unstake(77763028316274741760991770148, 889544954655483052642168760960, 1000073821603105106, 14781730360850539958536528862089); - _rewardsHandler.memorializePositions(3, 2, 357097079890085816811291167102020270214, 1); - _rewardsHandler.takeAuction(9839460449437189937506383151267733565283, 75862151750582034326928310158878873987779724, 442512581894915658301040013323770372275116408434438200991, 4465076566725287152347371577222429); - _rewardsHandler.takeReserves(18196, 115792089237316195423570985008687907853269984665640564039457459248091501068020, 7726328457662922431145272); - _rewardsHandler.updateExchangeRate(934079800963406838548241273326154438, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 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 { - _rewardsHandler.bucketTake(4645898402004950106563597036, 1, true, 3, 2); - _rewardsHandler.kickReserveAuction(3, 144); - _rewardsHandler.claimRewards(44705418907931161819765043998797583827, 151688058596538037321153972615358552, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 5828173); - _rewardsHandler.lenderKickAuction(1, 0, 58846077910505664190879804); - _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1); - _rewardsHandler.burn(115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.moveLiquidity(7886, 1223, 249959471556478, 8036, 957); - _rewardsHandler.drawDebt(3724423259505818275008000000000, 5967, 5194); - _rewardsHandler.claimRewards(1, 0, 0, 330972817125); - } - - // 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 { - _rewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 87088279133912395360162508437887139725077665220, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 3); - _rewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 564626589538129677125005778268696423, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - _rewardsHandler.takeReserves(11684, 194771708143610511040376640, 2726053605342047396811); - _rewardsHandler.repayDebt(3262, 43081368297850871705277077223467592454899175043611071, 10274); - _rewardsHandler.redeemPositions(127647, 176264227116073539466710292640534, 3642, 6424); - _rewardsHandler.unstake(15694742330810166545782643648487796809086809379390, 607818605291333492717424880577475155800497188006507929455743410345480887752, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935); - - invariant_rewards_RW1_RW2(); - } -} From 3052ba43fec575db901e4bb86ce61eacb03d065a Mon Sep 17 00:00:00 2001 From: Ed Noepel <46749157+EdNoepel@users.noreply.github.com> Date: Tue, 4 Jul 2023 10:02:58 -0400 Subject: [PATCH 32/32] fix typo (#921) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5d086c12d..eb4ae39ab 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ make analyze ## Licensing For purposes of the Business Service License: (i) the term “Licensor” means Ajna Labs, LLC, (ii) the term Licensed Work means Licensor’s proprietary software marketed under the name _The Ajna Protocol™_ and useful for purposes of facilitating the lending and borrowing of digital assets, (iii) the term “Additional Use Grants” means a grant of rights in the Licensed Work that are not included in the Business Service License and are granted by Licensor pursuant to a separate agreement between Licensor and one or more third parties, and (iv) the term “Change Date” means April 1, 2026 or such other date as Licensor may specify on or before April 1, 2026. -The licnesed work is under the [Business Service License](https://github.com/ajna-finance/contracts/blob/develop/LICENSE) ("BUSL license") with but not limited to the following exceptions: +The licensed work is under the [Business Service License](https://github.com/ajna-finance/contracts/blob/develop/LICENSE) ("BUSL license") with but not limited to the following exceptions: - To facilitate integrations, public-facing interfaces are licensed under `MIT`, as indicated in their SPDX headers. - As a derivative work of [ds-math](https://github.com/dapphub/ds-math/), `Maths.sol` is licensed under `GPL-3.0-or-later`, as indicated in its SPDX header. - As a derivative work of [SafeERC20Namer](https://github.com/Uniswap/solidity-lib/blob/master/contracts/libraries/SafeERC20Namer.sol), `SafeTokenNamer.sol` is licensed under `GPL-3.0-or-later`, as indicated in its SPDX header.