diff --git a/.gitignore b/.gitignore index 784a5b2dc..b2563a5a2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ node_modules .env .env.prod .idea/ -.vscode/*.log +.vscode/ __pycache__/ reports/ .gas-snapshot diff --git a/docs/Functions.md b/docs/Functions.md index 115d20e1d..9faa39193 100644 --- a/docs/Functions.md +++ b/docs/Functions.md @@ -386,19 +386,12 @@ - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - BorrowerActions.drawDebt(): - - SettlerActions._settleAuction(): - - _removeAuction(): - - decrement kicker locked accumulator, increment kicker claimable accumumlator - - decrement auctions count accumulator - - decrement auctions.totalBondEscrowed accumulator - - update auction queue state - Loans.update(): - _upsert(): - insert or update loan in loans array - remove(): - remove loan from loans array - update borrower in address => borrower mapping - - decrement poolBalances.t0DebtInAuction accumulator - increment poolBalances.pledgedCollateral accumulator - increment poolBalances.t0Debt accumulator - _updateInterestState(): @@ -416,8 +409,6 @@ emit events: - BorrowerActions.drawDebt(): - - SettlerActions._settleAuction(): - - AuctionNFTSettle or AuctionSettle - DrawDebt - PoolCommons.updateInterestRate(): - UpdateInterestRate @@ -435,12 +426,6 @@ - update scaling array state - increment reserveAuction.totalInterestEarned accumulator - BorrowerActions.repayDebt(): - - SettlerActions._settleAuction(): - - _removeAuction(): - - decrement kicker locked accumulator, increment kicker claimable accumumlator - - decrement auctions count accumulator - - decrement auctions.totalBondEscrowed accumulator - - update auction queue state - Loans.update(): - _upsert(): - insert or update loan in loans array @@ -448,7 +433,6 @@ - remove loan from loans array - update borrower in address => borrower mapping - decrement poolBalances.t0Debt accumulator - - decrement poolBalances.t0DebtInAuction accumulator - decrement poolBalances.pledgedCollateral accumulator - _updateInterestState(): - PoolCommons.updateInterestRate(): @@ -465,8 +449,6 @@ emit events: - BorrowerActions.repayDebt(): - - SettlerActions._settleAuction: - - AuctionNFTSettle or AuctionSettle - RepayDebt - PoolCommons.updateInterestRate(): - UpdateInterestRate @@ -567,7 +549,6 @@ - insufficient collateral InsufficientCollateral() - _prepareTake(): - loan is not in auction NoAuction() - - in 1 hour cool down period TakeNotPastCooldown() - _takeLoan(): - borrower debt less than pool min debt AmountLTMinDebt() @@ -630,7 +611,6 @@ - insufficient collateral InsufficientCollateral() - _prepareTake(): - loan is not in auction NoAuction() - - in 1 hour cool down period TakeNotPastCooldown() - _takeLoan(): - borrower debt less than pool min debt AmountLTMinDebt() diff --git a/docs/drawio/bucketTake.drawio b/docs/drawio/bucketTake.drawio index a9ed91da5..d3318de61 100644 --- a/docs/drawio/bucketTake.drawio +++ b/docs/drawio/bucketTake.drawio @@ -1,234 +1,234 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/drawio/drawDebt.drawio b/docs/drawio/drawDebt.drawio index e4f8da895..339be3a0a 100644 --- a/docs/drawio/drawDebt.drawio +++ b/docs/drawio/drawDebt.drawio @@ -1,244 +1,210 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/drawio/repayDebt.drawio b/docs/drawio/repayDebt.drawio index f35d240d5..34e3721e4 100644 --- a/docs/drawio/repayDebt.drawio +++ b/docs/drawio/repayDebt.drawio @@ -1,251 +1,217 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/drawio/take.drawio b/docs/drawio/take.drawio index 1cf7fec86..0a9aa99f4 100644 --- a/docs/drawio/take.drawio +++ b/docs/drawio/take.drawio @@ -1,202 +1,202 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ERC20Pool.sol b/src/ERC20Pool.sol index 20ee2f00a..566b75b49 100644 --- a/src/ERC20Pool.sol +++ b/src/ERC20Pool.sol @@ -121,10 +121,9 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { /** * @inheritdoc IERC20PoolBorrowerActions * @dev === Write state === - * @dev - decrement `poolBalances.t0DebtInAuction` accumulator * @dev - increment `poolBalances.pledgedCollateral` accumulator * @dev - increment `poolBalances.t0Debt` accumulator - * @dev - update `t0Debt2ToCollateral` ratio only if loan not in auction, debt and collateral pre action are considered 0 if auction settled + * @dev - update `t0Debt2ToCollateral` ratio * @dev === Emit events === * @dev - `DrawDebt` */ @@ -143,7 +142,6 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { DrawDebtResult memory result = BorrowerActions.drawDebt( auctions, - buckets, deposits, loans, poolState, @@ -161,21 +159,13 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { poolState.t0Debt = result.t0PoolDebt; 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( - result.settledAuction ? 0 : result.debtPreAction, // debt pre settle (for loan in auction) not taken into account - result.debtPostAction, - result.settledAuction ? 0 : result.collateralPreAction, // collateral pre settle (for loan in auction) not taken into account - result.collateralPostAction - ); - } + // adjust t0Debt2ToCollateral ratio + _updateT0Debt2ToCollateral( + result.debtPreAction, + result.debtPostAction, + result.collateralPreAction, + result.collateralPostAction + ); // update pool interest rate state _updateInterestState(poolState, result.newLup); @@ -201,9 +191,8 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { * @inheritdoc IERC20PoolBorrowerActions * @dev === Write state === * @dev - decrement `poolBalances.t0Debt accumulator` - * @dev - decrement `poolBalances.t0DebtInAuction accumulator` * @dev - decrement `poolBalances.pledgedCollateral accumulator` - * @dev - update `t0Debt2ToCollateral` ratio only if loan not in auction, debt and collateral pre action are considered 0 if auction settled + * @dev - update `t0Debt2ToCollateral` ratio * @dev === Emit events === * @dev - `RepayDebt` */ @@ -223,7 +212,6 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { RepayDebtResult memory result = BorrowerActions.repayDebt( auctions, - buckets, deposits, loans, poolState, @@ -240,21 +228,13 @@ contract ERC20Pool is FlashloanablePool, IERC20Pool { poolState.t0Debt = result.t0PoolDebt; 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( - result.settledAuction ? 0 : result.debtPreAction, // debt pre settle (for loan in auction) not taken into account - result.debtPostAction, - result.settledAuction ? 0 : result.collateralPreAction, // collateral pre settle (for loan in auction) not taken into account - result.collateralPostAction - ); - } + // adjust t0Debt2ToCollateral ratio + _updateT0Debt2ToCollateral( + result.debtPreAction, + result.debtPostAction, + result.collateralPreAction, + result.collateralPostAction + ); // update pool interest rate state _updateInterestState(poolState, result.newLup); diff --git a/src/ERC721Pool.sol b/src/ERC721Pool.sol index 668980fa5..8965bbd4b 100644 --- a/src/ERC721Pool.sol +++ b/src/ERC721Pool.sol @@ -155,7 +155,6 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { DrawDebtResult memory result = BorrowerActions.drawDebt( auctions, - buckets, deposits, loans, poolState, @@ -173,21 +172,13 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { poolState.t0Debt = result.t0PoolDebt; 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( - result.settledAuction ? 0 : result.debtPreAction, // debt pre settle (for loan in auction) not taken into account - result.debtPostAction, - result.settledAuction ? 0 : result.collateralPreAction, // collateral pre settle (for loan in auction) not taken into account - result.collateralPostAction - ); - } + // adjust t0Debt2ToCollateral ratio + _updateT0Debt2ToCollateral( + result.debtPreAction, + result.debtPostAction, + result.collateralPreAction, + result.collateralPostAction + ); // update pool interest rate state _updateInterestState(poolState, result.newLup); @@ -200,8 +191,6 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { _transferFromSenderToPool(borrowerTokenIds[borrowerAddress_], tokenIdsToPledge_); } - if (result.settledAuction) _rebalanceTokens(borrowerAddress_, result.remainingCollateral); - // move borrowed amount from pool to sender if (amountToBorrow_ != 0) { // update pool balances t0 debt state @@ -238,7 +227,6 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { RepayDebtResult memory result = BorrowerActions.repayDebt( auctions, - buckets, deposits, loans, poolState, @@ -255,23 +243,13 @@ contract ERC721Pool is FlashloanablePool, IERC721Pool { poolState.t0Debt = result.t0PoolDebt; 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 - if (!result.inAuction) { - _updateT0Debt2ToCollateral( - result.settledAuction ? 0 : result.debtPreAction, // debt pre settle (for loan in auction) not taken into account - result.debtPostAction, - result.settledAuction ? 0 : result.collateralPreAction, // collateral pre settle (for loan in auction) not taken into account - result.collateralPostAction - ); - } + // adjust t0Debt2ToCollateral ratio + _updateT0Debt2ToCollateral( + result.debtPreAction, + result.debtPostAction, + result.collateralPreAction, + result.collateralPostAction + ); // update pool interest rate state _updateInterestState(poolState, result.newLup); diff --git a/src/PoolInfoUtils.sol b/src/PoolInfoUtils.sol index 581f7baf3..beed3f53a 100644 --- a/src/PoolInfoUtils.sol +++ b/src/PoolInfoUtils.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.18; +import { Math } from '@openzeppelin/contracts/utils/math/Math.sol'; + import { IPool, IERC20Token } from './interfaces/pool/IPool.sol'; import { @@ -56,8 +58,8 @@ contract PoolInfoUtils { ) { IPool pool = IPool(ajnaPool_); - uint256 kickMomp; - ( , , , kickTime_, kickMomp, neutralPrice_, , , , ) = pool.auctionInfo(borrower_); + uint256 referencePrice; + ( , , , kickTime_, referencePrice, neutralPrice_, , , ) = pool.auctionInfo(borrower_); if (kickTime_ != 0) { (debtToCover_, collateral_, ) = this.borrowerInfo(ajnaPool_, borrower_); @@ -65,7 +67,7 @@ contract PoolInfoUtils { uint256 lup_ = _priceAt(pool.depositIndex(poolDebt)); isCollateralized_ = _isCollateralized(debtToCover_, collateral_, lup_, pool.poolType()); - price_ = _auctionPrice(kickMomp, neutralPrice_, kickTime_); + price_ = _auctionPrice(referencePrice, kickTime_); } } @@ -98,7 +100,10 @@ contract PoolInfoUtils { uint256 pendingInflator = PoolCommons.pendingInflator(inflator, lastInflatorUpdate, interestRate); uint256 t0Debt; - (t0Debt, collateral_, t0Np_) = pool.borrowerInfo(borrower_); + uint256 npTpRatio; + (t0Debt, collateral_, npTpRatio) = pool.borrowerInfo(borrower_); + + t0Np_ = collateral_ == 0 ? 0 : Math.mulDiv(t0Debt, npTpRatio, collateral_); debt_ = Maths.ceilWmul(t0Debt, pendingInflator); } @@ -407,26 +412,6 @@ contract PoolInfoUtils { (, htp_, ) = IPool(ajnaPool_).loansInfo(); } - /** - * @notice Returns current `MOMP` for a given pool. - */ - function momp( - address ajnaPool_ - ) external view returns (uint256) { - IPool pool = IPool(ajnaPool_); - - ( , , uint256 noOfLoans) = pool.loansInfo(); - noOfLoans += pool.totalAuctionsInPool(); - if (noOfLoans == 0) { - // if there are no borrowers, return the HPB - return _priceAt(pool.depositIndex(1)); - } else { - // otherwise, calculate the MOMP - (uint256 debt, , , ) = pool.debtInfo(); - return _priceAt(pool.depositIndex(Maths.wdiv(debt, noOfLoans * 1e18))); - } - } - /** * @notice Calculates origination fee rate for a pool. * @notice Calculated as greater of the current annualized interest rate divided by `52` (one week of interest) or `5` bps. diff --git a/src/base/Pool.sol b/src/base/Pool.sol index 3643fd56c..0f7cf3504 100644 --- a/src/base/Pool.sol +++ b/src/base/Pool.sol @@ -306,20 +306,17 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { ); // update in memory pool state struct - poolState.debt = result.poolDebt; - poolState.t0Debt = result.t0PoolDebt; poolState.t0DebtInAuction += result.t0KickedDebt; // adjust t0Debt2ToCollateral ratio _updateT0Debt2ToCollateral( - result.debtPreAction, + result.t0KickedDebt, 0, // debt post kick (for loan in auction) not taken into account result.collateralPreAction, 0 // collateral post kick (for loan in auction) not taken into account ); // update pool balances state - poolBalances.t0Debt = poolState.t0Debt; poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; // update pool interest rate state _updateInterestState(poolState, result.lup); @@ -330,8 +327,6 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { /** * @inheritdoc IPoolKickerActions * @dev === Write state === - * @dev increment `poolBalances.t0DebtInAuction` and `poolBalances.t0Debt` accumulators - * @dev update `t0Debt2ToCollateral` ratio, debt and collateral post action are considered 0 */ function lenderKick( uint256 index_, @@ -351,20 +346,17 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { ); // update in memory pool state struct - poolState.debt = result.poolDebt; - poolState.t0Debt = result.t0PoolDebt; poolState.t0DebtInAuction += result.t0KickedDebt; // adjust t0Debt2ToCollateral ratio _updateT0Debt2ToCollateral( - result.debtPreAction, + result.t0KickedDebt, 0, // debt post kick (for loan in auction) not taken into account result.collateralPreAction, 0 // collateral post kick (for loan in auction) not taken into account ); // update pool balances state - poolBalances.t0Debt = poolState.t0Debt; poolBalances.t0DebtInAuction = poolState.t0DebtInAuction; // update pool interest rate state @@ -418,7 +410,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { */ function kickReserveAuction() external override nonReentrant { // start a new claimable reserve auction, passing in relevant parameters such as the current pool size, debt, balance, and inflator value - uint256 kickerAward = KickerActions.kickReserveAuction( + KickerActions.kickReserveAuction( auctions, reserveAuction, KickReserveAuctionParams({ @@ -428,9 +420,6 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { inflator: inflatorState.inflator }) ); - - // transfer kicker award to msg.sender - _transferQuoteToken(msg.sender, kickerAward); } /** @@ -601,7 +590,6 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { // update in memory pool state struct poolState_.debt = result_.poolDebt; poolState_.t0Debt = result_.t0PoolDebt; - poolState_.t0DebtInAuction += result_.t0DebtPenalty; poolState_.t0DebtInAuction -= result_.t0DebtInAuctionChange; poolState_.collateral -= (result_.collateralAmount + result_.compensatedCollateral); // deduct collateral taken plus collateral compensated if NFT auction settled @@ -757,12 +745,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { uint256 bondFactor_, uint256 bondSize_, uint256 kickTime_, - uint256 kickMomp_, + uint256 referencePrice_, uint256 neutralPrice_, address head_, address next_, - address prev_, - bool alreadyTaken_ + address prev_ ) { Liquidation storage liquidation = auctions.liquidations[borrower_]; return ( @@ -770,12 +757,11 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { liquidation.bondFactor, liquidation.bondSize, liquidation.kickTime, - liquidation.kickMomp, + liquidation.referencePrice, liquidation.neutralPrice, auctions.head, liquidation.next, - liquidation.prev, - liquidation.alreadyTaken + liquidation.prev ); } @@ -787,7 +773,7 @@ abstract contract Pool is Clone, ReentrancyGuard, Multicall, IPool { return ( borrower.t0Debt, borrower.collateral, - borrower.t0Np + borrower.npTpRatio ); } diff --git a/src/interfaces/pool/commons/IPoolBorrowerActions.sol b/src/interfaces/pool/commons/IPoolBorrowerActions.sol index 87339159d..ccfaacd12 100644 --- a/src/interfaces/pool/commons/IPoolBorrowerActions.sol +++ b/src/interfaces/pool/commons/IPoolBorrowerActions.sol @@ -8,8 +8,8 @@ pragma solidity 0.8.18; interface IPoolBorrowerActions { /** - * @notice Called by fully colalteralized borrowers to restamp the `Neutral Price` of the loan (only if loan is fully collateralized and not in auction). - * The reason for stamping the neutral price on the loan is to provide some certainty to the borrower as to at what price they can expect to be liquidated. + * @notice Called by fully collateralized borrowers to restamp the `Np to Tp ratio` of the loan (only if loan is fully collateralized and not in auction). + * The reason for stamping the `Np to Tp ratio` on the loan is to provide some certainty to the borrower as to at what price they can expect to be liquidated. * This action can restamp only the loan of `msg.sender`. */ function stampLoan() external; diff --git a/src/interfaces/pool/commons/IPoolErrors.sol b/src/interfaces/pool/commons/IPoolErrors.sol index b5fddaff9..52f8cca27 100644 --- a/src/interfaces/pool/commons/IPoolErrors.sol +++ b/src/interfaces/pool/commons/IPoolErrors.sol @@ -25,6 +25,11 @@ interface IPoolErrors { */ error AuctionNotClearable(); + /** + * @notice Auction does not meet requirements to take liquidity. + */ + error AuctionNotTakeable(); + /** * @notice Head auction should be cleared prior of executing this action. */ @@ -195,11 +200,6 @@ interface IPoolErrors { */ error ReserveAuctionTooSoon(); - /** - * @notice Take was called before `1` hour had passed from kick time. - */ - error TakeNotPastCooldown(); - /** * @notice Current block timestamp has reached or exceeded a user-provided expiration. */ diff --git a/src/interfaces/pool/commons/IPoolEvents.sol b/src/interfaces/pool/commons/IPoolEvents.sol index 32b2c9466..ededcc548 100644 --- a/src/interfaces/pool/commons/IPoolEvents.sol +++ b/src/interfaces/pool/commons/IPoolEvents.sol @@ -340,8 +340,8 @@ interface IPoolEvents { ); /** - * @notice Emitted when a loan `Neutral Price` is restamped. - * @param borrower Identifies the loan to update the `Neutral Price`. + * @notice Emitted when a loan `Np to Tp ratio` is restamped. + * @param borrower Identifies the loan to update the `Np to Tp ratio`. */ event LoanStamped( address indexed borrower diff --git a/src/interfaces/pool/commons/IPoolInternals.sol b/src/interfaces/pool/commons/IPoolInternals.sol index f1b62ca89..468988855 100644 --- a/src/interfaces/pool/commons/IPoolInternals.sol +++ b/src/interfaces/pool/commons/IPoolInternals.sol @@ -13,9 +13,7 @@ pragma solidity 0.8.18; /// @dev Struct used to return result of `KickerAction.kick` action. 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 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 @@ -43,7 +41,6 @@ struct TakeResult { uint256 collateralAmount; // [WAD] amount of collateral taken uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP uint256 quoteTokenAmount; // [WAD] amount of quote tokens paid by taker for taken collateral, used in take action - uint256 t0DebtPenalty; // [WAD] t0 penalty applied on first take uint256 excessQuoteToken; // [WAD] (NFT only) amount of quote tokens to be paid by taker to borrower for fractional collateral, used in take action uint256 remainingCollateral; // [WAD] amount of borrower collateral remaining after take uint256 poolDebt; // [WAD] current pool debt @@ -98,13 +95,10 @@ struct RemoveQuoteParams { /// @dev Struct used to return result of `BorrowerActions.drawDebt` action. struct DrawDebtResult { - bool inAuction; // true if loan still in auction after pledge more collateral, false otherwise uint256 newLup; // [WAD] new pool LUP after draw debt uint256 poolCollateral; // [WAD] total amount of collateral in pool after pledge collateral uint256 poolDebt; // [WAD] total accrued debt in pool after draw debt uint256 remainingCollateral; // [WAD] amount of borrower collateral after draw debt (for NFT can be diminished if auction settled) - bool settledAuction; // true if collateral pledged settles auction - uint256 t0DebtInAuctionChange; // [WAD] change of t0 pool debt in auction after pledge collateral uint256 t0PoolDebt; // [WAD] amount of t0 debt in pool after draw debt uint256 debtPreAction; // [WAD] The amount of borrower t0 debt before draw debt uint256 debtPostAction; // [WAD] The amount of borrower t0 debt after draw debt @@ -114,17 +108,14 @@ struct DrawDebtResult { /// @dev Struct used to return result of `BorrowerActions.repayDebt` action. struct RepayDebtResult { - bool inAuction; // true if loan still in auction after repay, false otherwise uint256 newLup; // [WAD] new pool LUP after draw debt uint256 poolCollateral; // [WAD] total amount of collateral in pool after pull collateral uint256 poolDebt; // [WAD] total accrued debt in pool after repay debt uint256 remainingCollateral; // [WAD] amount of borrower collateral after pull collateral - bool settledAuction; // true if repay debt settles auction - uint256 t0DebtInAuctionChange; // [WAD] change of t0 pool debt in auction after repay debt uint256 t0PoolDebt; // [WAD] amount of t0 debt in pool after repay uint256 quoteTokenToRepay; // [WAD] quote token amount to be transferred from sender to pool uint256 debtPreAction; // [WAD] The amount of borrower t0 debt before repay debt uint256 debtPostAction; // [WAD] The amount of borrower t0 debt after repay debt uint256 collateralPreAction; // [WAD] The amount of borrower collateral before repay debt uint256 collateralPostAction; // [WAD] The amount of borrower collateral after repay debt -} \ No newline at end of file +} diff --git a/src/interfaces/pool/commons/IPoolState.sol b/src/interfaces/pool/commons/IPoolState.sol index 930a99850..027e7670c 100644 --- a/src/interfaces/pool/commons/IPoolState.sol +++ b/src/interfaces/pool/commons/IPoolState.sol @@ -9,17 +9,16 @@ interface IPoolState { /** * @notice Returns details of an auction for a given borrower address. - * @param borrower_ Address of the borrower that is liquidated. - * @return kicker_ Address of the kicker that is kicking the auction. - * @return bondFactor_ The factor used for calculating bond size. - * @return bondSize_ The bond amount in quote token terms. - * @return kickTime_ Time the liquidation was initiated. - * @return kickMomp_ Price where the average loan utilizes deposit, at the time when the loan is liquidated (kicked). - * @return neutralPrice_ `Neutral Price` of auction. - * @return head_ Address of the head auction. - * @return next_ Address of the next auction in queue. - * @return prev_ Address of the prev auction in queue. - * @return alreadyTaken_ True if take has been called on auction + * @param borrower_ Address of the borrower that is liquidated. + * @return kicker_ Address of the kicker that is kicking the auction. + * @return bondFactor_ The factor used for calculating bond size. + * @return bondSize_ The bond amount in quote token terms. + * @return kickTime_ Time the liquidation was initiated. + * @return referencePrice_ Price used to determine auction start price. + * @return neutralPrice_ `Neutral Price` of auction. + * @return head_ Address of the head auction. + * @return next_ Address of the next auction in queue. + * @return prev_ Address of the prev auction in queue. */ function auctionInfo(address borrower_) external @@ -29,12 +28,11 @@ interface IPoolState { uint256 bondFactor_, uint256 bondSize_, uint256 kickTime_, - uint256 kickMomp_, + uint256 referencePrice_, uint256 neutralPrice_, address head_, address next_, - address prev_, - bool alreadyTaken_ + address prev_ ); /** @@ -60,7 +58,7 @@ interface IPoolState { * @param borrower_ Address of the borrower. * @return t0Debt_ Amount of debt borrower would have had if their loan was the first debt drawn from the pool. * @return collateral_ Amount of collateral that the borrower has deposited, in collateral token. - * @return t0Np_ t0 `Neutral Price` + * @return npTpRatio_ Np to Tp ratio of borrower at the time of last borrow or pull collateral. */ function borrowerInfo(address borrower_) external @@ -68,7 +66,7 @@ interface IPoolState { returns ( uint256 t0Debt_, uint256 collateral_, - uint256 t0Np_ + uint256 npTpRatio_ ); /** @@ -388,7 +386,7 @@ struct Loan { struct Borrower { uint256 t0Debt; // [WAD] Borrower debt time-adjusted as if it was incurred upon first loan of pool. uint256 collateral; // [WAD] Collateral deposited by borrower. - uint256 t0Np; // [WAD] Neutral Price time-adjusted as if it was incurred upon first loan of pool. + uint256 npTpRatio; // [WAD] Np to Tp ratio at the time of last borrow or pull collateral. } /**********************/ @@ -407,15 +405,14 @@ struct AuctionsState { /// @dev Struct holding liquidation state. struct Liquidation { - address kicker; // address that initiated liquidation - uint96 bondFactor; // [WAD] bond factor used to start liquidation - uint96 kickTime; // timestamp when liquidation was started - address prev; // previous liquidated borrower in auctions queue - uint96 kickMomp; // [WAD] Momp when liquidation was started - address next; // next liquidated borrower in auctions queue - uint160 bondSize; // [WAD] liquidation bond size - uint96 neutralPrice; // [WAD] Neutral Price when liquidation was started - bool alreadyTaken; // true if take has been called on auction + address kicker; // address that initiated liquidation + uint96 bondFactor; // [WAD] bond factor used to start liquidation + uint96 kickTime; // timestamp when liquidation was started + address prev; // previous liquidated borrower in auctions queue + uint96 referencePrice; // [WAD] used to calculate auction start price + address next; // next liquidated borrower in auctions queue + uint160 bondSize; // [WAD] liquidation bond size + uint96 neutralPrice; // [WAD] Neutral Price when liquidation was started } /// @dev Struct holding kicker state. diff --git a/src/libraries/external/BorrowerActions.sol b/src/libraries/external/BorrowerActions.sol index 5a69e1120..02ce36855 100644 --- a/src/libraries/external/BorrowerActions.sol +++ b/src/libraries/external/BorrowerActions.sol @@ -25,7 +25,6 @@ import { _revertOnMinDebt } from '../helpers/RevertsHelper.sol'; -import { Buckets } from '../internal/Buckets.sol'; import { Deposits } from '../internal/Deposits.sol'; import { Loans } from '../internal/Loans.sol'; import { Maths } from '../internal/Maths.sol'; @@ -51,7 +50,7 @@ library BorrowerActions { uint256 t0BorrowAmount; // [WAD] t0 amount to borrow uint256 t0DebtChange; // [WAD] additional t0 debt resulted from draw debt action bool pledge; // true if pledge action - bool stampT0Np; // true if loan's t0 neutral price should be restamped (when drawing debt or pledge settles auction) + bool stampNpTpRatio; // true if loan's Np to Tp ratio should be restamped (when drawing debt or pledge settles auction) } /// @dev Struct used for `repayDebt` function local vars. @@ -60,8 +59,7 @@ library BorrowerActions { uint256 compensatedCollateral; // [WAD] amount of borrower collateral that is compensated with LP (NFTs only) bool pull; // true if pull action bool repay; // true if repay action - bool stampT0Np; // true if loan's t0 neutral price should be restamped (when repay settles auction or pull collateral) - uint256 t0DebtInAuctionChange; // [WAD] t0 change amount of debt after repayment + bool stampNpTpRatio; // true if loan's Np to Tp ratio should be restamped (when repay settles auction or pull collateral) uint256 t0RepaidDebt; // [WAD] t0 debt repaid } @@ -93,10 +91,6 @@ library BorrowerActions { /** * @notice See `IERC20PoolBorrowerActions` and `IERC721PoolBorrowerActions` for descriptions * @dev === Write state === - * @dev - `SettlerActions._settleAuction` (`_removeAuction`): - * @dev decrement kicker locked accumulator, increment kicker claimable accumumlator - * @dev decrement auctions count accumulator - * @dev update auction queue state * @dev - `Loans.update` (`_upsert`): * @dev insert or update loan in loans array * @dev remove loan from loans array @@ -107,12 +101,10 @@ library BorrowerActions { * @dev borrower debt less than pool min debt `AmountLTMinDebt()` * @dev limit price reached `LimitIndexExceeded()` * @dev borrower cannot draw more debt `BorrowerUnderCollateralized()` - * @dev === Emit events === - * @dev - `SettlerActions._settleAuction`: `AuctionNFTSettle` or `AuctionSettle` + * @dev borrower cannot be in auction `AuctionActive()` */ function drawDebt( AuctionsState storage auctions_, - mapping(uint256 => Bucket) storage buckets_, DepositsState storage deposits_, LoansState storage loans_, PoolState calldata poolState_, @@ -127,6 +119,9 @@ library BorrowerActions { // revert if not enough pool balance to borrow if (amountToBorrow_ > maxAvailable_) revert InsufficientLiquidity(); + // revert if borrower is in auction + if(_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); + DrawDebtLocalVars memory vars; vars.pledge = collateralToPledge_ != 0; vars.borrow = amountToBorrow_ != 0; @@ -138,7 +133,6 @@ library BorrowerActions { vars.borrowerDebt = Maths.wmul(borrower.t0Debt, poolState_.inflator); - result_.inAuction = _inAuction(auctions_, borrowerAddress_); result_.debtPreAction = borrower.t0Debt; result_.collateralPreAction = borrower.collateral; result_.t0PoolDebt = poolState_.t0Debt; @@ -153,36 +147,6 @@ library BorrowerActions { result_.remainingCollateral += collateralToPledge_; result_.newLup = Deposits.getLup(deposits_, result_.poolDebt); - // if loan is auctioned and becomes collateralized by newly pledged collateral then settle auction - if ( - result_.inAuction && - _isCollateralized(vars.borrowerDebt, borrower.collateral, result_.newLup, poolState_.poolType) - ) { - // stamp borrower t0Np when exiting from auction - vars.stampT0Np = true; - - // borrower becomes re-collateralized, entire borrower debt is removed from pool auctions debt accumulator - result_.inAuction = false; - result_.settledAuction = true; - result_.t0DebtInAuctionChange = borrower.t0Debt; - - // settle auction and update borrower's collateral with value after settlement - ( - result_.remainingCollateral, - vars.compensatedCollateral - ) = SettlerActions._settleAuction( - auctions_, - buckets_, - deposits_, - borrowerAddress_, - borrower.collateral, - poolState_.poolType - ); - result_.poolCollateral -= vars.compensatedCollateral; - - borrower.collateral = result_.remainingCollateral; - } - // add new amount of collateral to pledge to pool balance result_.poolCollateral += collateralToPledge_; } @@ -191,9 +155,6 @@ library BorrowerActions { // only intended recipient can borrow quote if (borrowerAddress_ != msg.sender) revert BorrowerNotSender(); - // an auctioned borrower in not allowed to draw more debt (even if collateralized at the new LUP) if auction is not settled - if (result_.inAuction) revert AuctionActive(); - vars.t0BorrowAmount = Maths.ceilWdiv(amountToBorrow_, poolState_.inflator); // t0 debt change is t0 amount to borrow plus the origination fee @@ -225,22 +186,18 @@ library BorrowerActions { revert BorrowerUnderCollateralized(); } - // stamp borrower t0Np when draw debt - vars.stampT0Np = true; + // stamp borrower Np to Tp ratio when draw debt + vars.stampNpTpRatio = true; } // update loan state Loans.update( loans_, - auctions_, - deposits_, borrower, borrowerAddress_, - result_.poolDebt, poolState_.rate, - result_.newLup, - result_.inAuction, - vars.stampT0Np + false, // loan not in auction + vars.stampNpTpRatio ); result_.debtPostAction = borrower.t0Debt; @@ -250,10 +207,6 @@ library BorrowerActions { /** * @notice See `IERC20PoolBorrowerActions` and `IERC721PoolBorrowerActions` for descriptions * @dev === Write state === - * @dev - `SettlerActions._settleAuction` (`_removeAuction`): - * @dev decrement kicker locked accumulator, increment kicker claimable accumumlator - * @dev decrement auctions count accumulator - * @dev update auction queue state * @dev - `Loans.update` (`_upsert`): * @dev insert or update loan in loans array * @dev remove loan from loans array @@ -264,12 +217,10 @@ library BorrowerActions { * @dev borrower not sender `BorrowerNotSender()` * @dev not enough collateral to pull `InsufficientCollateral()` * @dev limit price reached `LimitIndexExceeded()` - * @dev === Emit events === - * @dev - `SettlerActions._settleAuction`: `AuctionNFTSettle` or `AuctionSettle` + * @dev borrower cannot be in auction `AuctionActive()` */ function repayDebt( AuctionsState storage auctions_, - mapping(uint256 => Bucket) storage buckets_, DepositsState storage deposits_, LoansState storage loans_, PoolState calldata poolState_, @@ -287,11 +238,12 @@ library BorrowerActions { // revert if no amount to pull or repay if (!vars.repay && !vars.pull) revert InvalidAmount(); + if(_inAuction(auctions_, borrowerAddress_)) revert AuctionActive(); + Borrower memory borrower = loans_.borrowers[borrowerAddress_]; vars.borrowerDebt = Maths.wmul(borrower.t0Debt, poolState_.inflator); - result_.inAuction = _inAuction(auctions_, borrowerAddress_); result_.debtPreAction = borrower.t0Debt; result_.collateralPreAction = borrower.collateral; result_.t0PoolDebt = poolState_.t0Debt; @@ -329,39 +281,6 @@ library BorrowerActions { ); result_.newLup = Deposits.getLup(deposits_, result_.poolDebt); - - // if loan is auctioned and becomes collateralized by repaying debt then settle auction - if (result_.inAuction) { - if (_isCollateralized(vars.borrowerDebt, borrower.collateral, result_.newLup, poolState_.poolType)) { - // stamp borrower t0Np when exiting from auction - vars.stampT0Np = true; - - // borrower becomes re-collateralized, entire borrower debt is removed from pool auctions debt accumulator - result_.inAuction = false; - result_.settledAuction = true; - result_.t0DebtInAuctionChange = borrower.t0Debt; - - // settle auction and update borrower's collateral with value after settlement - ( - result_.remainingCollateral, - vars.compensatedCollateral - ) = SettlerActions._settleAuction( - auctions_, - buckets_, - deposits_, - borrowerAddress_, - borrower.collateral, - poolState_.poolType - ); - result_.poolCollateral -= vars.compensatedCollateral; - - borrower.collateral = result_.remainingCollateral; - } else { - // partial repay, remove only the paid debt from pool auctions debt accumulator - result_.t0DebtInAuctionChange = vars.t0RepaidDebt; - } - } - borrower.t0Debt -= vars.t0RepaidDebt; } @@ -369,9 +288,6 @@ library BorrowerActions { // only intended recipient can pull collateral if (borrowerAddress_ != msg.sender) revert BorrowerNotSender(); - // an auctioned borrower in not allowed to pull collateral (even if collateralized at the new LUP) if auction is not settled - if (result_.inAuction) revert AuctionActive(); - // calculate LUP only if it wasn't calculated in repay action if (!vars.repay) result_.newLup = Deposits.getLup(deposits_, result_.poolDebt); @@ -382,8 +298,8 @@ library BorrowerActions { borrower.collateral - encumberedCollateral < collateralAmountToPull_ ) revert InsufficientCollateral(); - // stamp borrower t0Np when pull collateral action - vars.stampT0Np = true; + // stamp borrower Np to Tp ratio when pull collateral action + vars.stampNpTpRatio = true; borrower.collateral -= collateralAmountToPull_; @@ -396,15 +312,11 @@ library BorrowerActions { // update loan state Loans.update( loans_, - auctions_, - deposits_, borrower, borrowerAddress_, - result_.poolDebt, poolState_.rate, - result_.newLup, - result_.inAuction, - vars.stampT0Np + false, // loan not in auction + vars.stampNpTpRatio ); result_.debtPostAction = borrower.t0Debt; @@ -449,18 +361,14 @@ library BorrowerActions { ) ) revert BorrowerUnderCollateralized(); - // update loan state to stamp Neutral Price + // update loan state to stamp Np to Tp ratio Loans.update( loans_, - auctions_, - deposits_, borrower, msg.sender, - poolState_.debt, poolState_.rate, - newLup_, false, // loan not in auction - true // stamp Neutral Price of the loan + true // stamp Np to Tp ratio of the loan ); emit LoanStamped(msg.sender); diff --git a/src/libraries/external/KickerActions.sol b/src/libraries/external/KickerActions.sol index 909a7ebe0..39f9e47e0 100644 --- a/src/libraries/external/KickerActions.sol +++ b/src/libraries/external/KickerActions.sol @@ -25,8 +25,7 @@ import { } from '../../interfaces/pool/commons/IPoolInternals.sol'; import { - MAX_NEUTRAL_PRICE, - _auctionPrice, + MAX_INFLATED_PRICE, _bondParams, _bpf, _claimableReserves, @@ -59,12 +58,10 @@ library KickerActions { uint256 borrowerDebt; // [WAD] the accrued debt of kicked borrower uint256 borrowerCollateral; // [WAD] amount of kicked borrower collateral uint256 neutralPrice; // [WAD] neutral price recorded in kick action - uint256 noOfLoans; // number of loans and auctions in pool (used to calculate MOMP) - uint256 momp; // [WAD] MOMP of kicked auction + uint256 htp; // [WAD] highest threshold price in pool + uint256 referencePrice; // [WAD] used to calculate auction start price uint256 bondFactor; // [WAD] bond factor of kicked auction uint256 bondSize; // [WAD] bond size of kicked auction - uint256 t0KickPenalty; // [WAD] t0 debt added as kick penalty - uint256 kickPenalty; // [WAD] current debt added as kick penalty } /// @dev Struct used for `lenderKick` function local vars. @@ -200,13 +197,12 @@ library KickerActions { * @dev no reserves to claim `NoReserves()` * @dev === Emit events === * @dev - `KickReserveAuction` - * @return kickerAward_ The `LP`s awarded to reserve auction kicker. */ function kickReserveAuction( AuctionsState storage auctions_, ReserveAuctionState storage reserveAuction_, KickReserveAuctionParams calldata params_ - ) external returns (uint256 kickerAward_) { + ) external { // retrieve timestamp of latest burn event and last burn timestamp uint256 latestBurnEpoch = reserveAuction_.latestBurnEventEpoch; uint256 lastBurnTimestamp = reserveAuction_.burnEvents[latestBurnEpoch].timestamp; @@ -226,9 +222,7 @@ library KickerActions { params_.poolBalance ); - kickerAward_ = Maths.wmul(0.01 * 1e18, claimable); - - curUnclaimedAuctionReserve += claimable - kickerAward_; + curUnclaimedAuctionReserve += claimable; if (curUnclaimedAuctionReserve == 0) revert NoReserves(); @@ -293,9 +287,8 @@ library KickerActions { Borrower storage borrower = loans_.borrowers[borrowerAddress_]; - kickResult_.debtPreAction = borrower.t0Debt; + kickResult_.t0KickedDebt = borrower.t0Debt; kickResult_.collateralPreAction = borrower.collateral; - kickResult_.t0KickedDebt = kickResult_.debtPreAction ; // add amount to remove to pool debt in order to calculate proposed LUP // for regular kick this is the currrent LUP in pool @@ -312,28 +305,22 @@ library KickerActions { } // calculate auction params + // neutral price = Tp * Np to Tp ratio // neutral price is capped at 50 * max pool price vars.neutralPrice = Maths.min( - Maths.wmul(borrower.t0Np, poolState_.inflator), - MAX_NEUTRAL_PRICE + Math.mulDiv(vars.borrowerDebt, borrower.npTpRatio, vars.borrowerCollateral), + MAX_INFLATED_PRICE ); // check if NP is not less than price at the limit index provided by the kicker - done to prevent frontrunning kick auction call with a large amount of loan // which will make it harder for kicker to earn a reward and more likely that the kicker is penalized _revertIfPriceDroppedBelowLimit(vars.neutralPrice, limitIndex_); - vars.noOfLoans = Loans.noOfLoans(loans_) + auctions_.noOfAuctions; - - vars.momp = _priceAt( - Deposits.findIndexOfSum( - deposits_, - Maths.wdiv(poolState_.debt, vars.noOfLoans * 1e18) - ) - ); + vars.htp = Maths.wmul(Loans.getMax(loans_).thresholdPrice, poolState_.inflator); + vars.referencePrice = Maths.min(Maths.max(vars.htp, vars.neutralPrice), MAX_INFLATED_PRICE); (vars.bondFactor, vars.bondSize) = _bondParams( vars.borrowerDebt, - vars.borrowerCollateral, - vars.momp + borrower.npTpRatio ); // record liquidation info @@ -343,7 +330,7 @@ library KickerActions { borrowerAddress_, vars.bondSize, vars.bondFactor, - vars.momp, + vars.referencePrice, vars.neutralPrice ); @@ -353,23 +340,9 @@ library KickerActions { // remove kicked loan from heap Loans.remove(loans_, borrowerAddress_, loans_.indices[borrowerAddress_]); - // when loan is kicked, penalty of three months of interest is added - vars.t0KickPenalty = Maths.wdiv(Maths.wmul(kickResult_.t0KickedDebt, poolState_.rate), 4 * 1e18); - vars.kickPenalty = Maths.wmul(vars.t0KickPenalty, poolState_.inflator); - - 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; - emit Kick( borrowerAddress_, - vars.borrowerDebt + vars.kickPenalty, + vars.borrowerDebt, vars.borrowerCollateral, vars.bondSize ); @@ -417,7 +390,7 @@ library KickerActions { * @param borrowerAddress_ Address of the borrower that is kicked. * @param bondSize_ Bond size to cover newly kicked auction. * @param bondFactor_ Bond factor of the newly kicked auction. - * @param momp_ Current pool `MOMP`. + * @param referencePrice_ Used to calculate auction start price. * @param neutralPrice_ Current pool `Neutral Price`. */ function _recordAuction( @@ -426,16 +399,16 @@ library KickerActions { address borrowerAddress_, uint256 bondSize_, uint256 bondFactor_, - uint256 momp_, + uint256 referencePrice_, uint256 neutralPrice_ ) internal { // record liquidation info - liquidation_.kicker = msg.sender; - liquidation_.kickTime = uint96(block.timestamp); - liquidation_.kickMomp = uint96(momp_); // cannot exceed max price enforced by _priceAt() function - liquidation_.bondSize = SafeCast.toUint160(bondSize_); - liquidation_.bondFactor = SafeCast.toUint96(bondFactor_); - liquidation_.neutralPrice = SafeCast.toUint96(neutralPrice_); + liquidation_.kicker = msg.sender; + liquidation_.kickTime = uint96(block.timestamp); + liquidation_.referencePrice = SafeCast.toUint96(referencePrice_); + liquidation_.bondSize = SafeCast.toUint160(bondSize_); + liquidation_.bondFactor = SafeCast.toUint96(bondFactor_); + liquidation_.neutralPrice = SafeCast.toUint96(neutralPrice_); // increment number of active auctions ++auctions_.noOfAuctions; diff --git a/src/libraries/external/PoolCommons.sol b/src/libraries/external/PoolCommons.sol index 659a6beae..164dff91a 100644 --- a/src/libraries/external/PoolCommons.sol +++ b/src/libraries/external/PoolCommons.sol @@ -298,8 +298,8 @@ library PoolCommons { newInterestRate_ = Maths.wmul(poolState_.rate, DECREASE_COEFFICIENT); } - // bound rates between 10 bps and 50000% - newInterestRate_ = Maths.min(500 * 1e18, Maths.max(0.001 * 1e18, newInterestRate_)); + // bound rates between 10 bps and 400% + newInterestRate_ = Maths.min(4 * 1e18, Maths.max(0.001 * 1e18, newInterestRate_)); } /** diff --git a/src/libraries/external/SettlerActions.sol b/src/libraries/external/SettlerActions.sol index b42888023..6f065d85f 100644 --- a/src/libraries/external/SettlerActions.sol +++ b/src/libraries/external/SettlerActions.sol @@ -226,8 +226,7 @@ library SettlerActions { compensatedCollateral_ = borrowerCollateral_ - remainingCollateral_; uint256 auctionPrice = _auctionPrice( - auctions_.liquidations[borrowerAddress_].kickMomp, - auctions_.liquidations[borrowerAddress_].neutralPrice, + auctions_.liquidations[borrowerAddress_].referencePrice, auctions_.liquidations[borrowerAddress_].kickTime ); diff --git a/src/libraries/external/TakerActions.sol b/src/libraries/external/TakerActions.sol index f7131b744..04624aafa 100644 --- a/src/libraries/external/TakerActions.sol +++ b/src/libraries/external/TakerActions.sol @@ -25,10 +25,10 @@ import { import { _auctionPrice, _bpf, - _isCollateralized, _priceAt, _reserveAuctionPrice, - _roundToScale + _roundToScale, + _roundUpToScale } from '../helpers/PoolHelper.sol'; import { _revertOnMinDebt } from '../helpers/RevertsHelper.sol'; @@ -74,24 +74,26 @@ library TakerActions { /// @dev Struct used for `take` function local vars. struct TakeLocalVars { - uint256 auctionPrice; // [WAD] The price of auction. - uint256 bondChange; // [WAD] The change made on the bond size (beeing reward or penalty). - uint256 borrowerDebt; // [WAD] The accrued debt of auctioned borrower. - int256 bpf; // The bond penalty factor. - uint256 bucketPrice; // [WAD] The bucket price. - uint256 bucketScale; // [WAD] The bucket scale. - uint256 collateralAmount; // [WAD] The amount of collateral taken. - uint256 excessQuoteToken; // [WAD] Difference of quote token that borrower receives after take (for fractional NFT only) - uint256 factor; // The take factor, calculated based on bond penalty factor. - bool isRewarded; // True if kicker is rewarded (auction price lower than neutral price), false if penalized (auction price greater than neutral price). - address kicker; // Address of auction kicker. - uint256 quoteTokenAmount; // [WAD] Scaled quantity in Fenwick tree and before 1-bpf factor, paid for collateral - uint256 t0RepayAmount; // [WAD] The amount of debt (quote tokens) that is recovered / repayed by take t0 terms. - uint256 t0BorrowerDebt; // [WAD] Borrower's t0 debt. - uint256 t0DebtPenalty; // [WAD] Borrower's t0 penalty - 7% from current debt if intial take, 0 otherwise. - uint256 unscaledDeposit; // [WAD] Unscaled bucket quantity - uint256 unscaledQuoteTokenAmount; // [WAD] The unscaled token amount that taker should pay for collateral taken. - } + uint256 auctionPrice; // [WAD] The price of auction. + uint256 bondChange; // [WAD] The change made on the bond size (beeing reward or penalty). + uint256 borrowerDebt; // [WAD] The accrued debt of auctioned borrower. + int256 bpf; // The bond penalty factor. + uint256 bondFactor; // [WAD] The bond factor. + uint256 bucketPrice; // [WAD] The bucket price. + uint256 bucketScale; // [WAD] The bucket scale. + uint256 collateralAmount; // [WAD] The amount of collateral taken. + uint256 excessQuoteToken; // [WAD] Difference of quote token that borrower receives after take (for fractional NFT only) + uint256 factor; // The take factor, calculated based on bond penalty factor. + bool isRewarded; // True if kicker is rewarded (auction price lower than neutral price), false if penalized (auction price greater than neutral price). + address kicker; // Address of auction kicker. + uint256 quoteTokenAmount; // [WAD] Scaled quantity in Fenwick tree and before 1-bpf factor, paid for collateral + uint256 t0RepayAmount; // [WAD] The amount of debt (quote tokens) that is recovered / repayed by take t0 terms. + uint256 t0BorrowerDebt; // [WAD] Borrower's t0 debt. + uint256 unscaledDeposit; // [WAD] Unscaled bucket quantity + uint256 unscaledQuoteTokenAmount; // [WAD] The unscaled token amount that taker should pay for collateral taken. + uint256 depositCollateralConstraint; // [WAD] Constraint on bucket take from deposit present in bucket + uint256 debtCollateralConstraint; // [WAD] Constraint on take due to debt. + } /**************/ /*** Events ***/ @@ -108,6 +110,7 @@ library TakerActions { /**************/ // See `IPoolErrors` for descriptions + error AuctionNotTakeable(); error AuctionPriceGtBucketPrice(); error CollateralRoundingNeededButNotPossible(); error InsufficientLiquidity(); @@ -117,7 +120,6 @@ library TakerActions { error NoReserves(); error NoReservesAuction(); error ReserveAuctionTooSoon(); - error TakeNotPastCooldown(); /***************************/ /*** External Functions ***/ @@ -167,7 +169,6 @@ library TakerActions { borrower.collateral -= vars.collateralAmount; borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; // update pool params after take - poolState_.t0Debt += vars.t0DebtPenalty; poolState_.t0Debt -= vars.t0RepayAmount; poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); @@ -185,7 +186,6 @@ library TakerActions { result_.t0PoolDebt = poolState_.t0Debt; result_.poolDebt = poolState_.debt; result_.collateralAmount = vars.collateralAmount; - result_.t0DebtPenalty = vars.t0DebtPenalty; // if settled then debt in auction changed is the entire borrower debt, otherwise only repaid amount result_.t0DebtInAuctionChange = result_.settledAuction ? vars.t0BorrowerDebt : vars.t0RepayAmount; } @@ -241,7 +241,6 @@ library TakerActions { borrower.collateral -= vars.collateralAmount; borrower.t0Debt = vars.t0BorrowerDebt - vars.t0RepayAmount; // update pool params after take - poolState_.t0Debt += vars.t0DebtPenalty; poolState_.t0Debt -= vars.t0RepayAmount; poolState_.debt = Maths.wmul(poolState_.t0Debt, poolState_.inflator); @@ -259,7 +258,6 @@ library TakerActions { result_.t0PoolDebt = poolState_.t0Debt; result_.poolDebt = poolState_.debt; result_.collateralAmount = vars.collateralAmount; - result_.t0DebtPenalty = vars.t0DebtPenalty; result_.quoteTokenAmount = vars.quoteTokenAmount; result_.excessQuoteToken = vars.excessQuoteToken; // if settled then debt in auction changed is the entire borrower debt, otherwise only repaid amount @@ -341,6 +339,9 @@ library TakerActions { ) internal returns (TakeLocalVars memory vars_) { Liquidation storage liquidation = auctions_.liquidations[params_.borrower]; + // Auction may not be taken in the same block it was kicked + if (liquidation.kickTime == block.timestamp) revert AuctionNotTakeable(); + vars_ = _prepareTake( liquidation, borrower_.t0Debt, @@ -421,6 +422,9 @@ library TakerActions { ) internal returns (TakeLocalVars memory vars_) { Liquidation storage liquidation = auctions_.liquidations[params_.borrower]; + // Auction may not be taken in the same block it was kicked + if (liquidation.kickTime == block.timestamp) revert AuctionNotTakeable(); + vars_= _prepareTake( liquidation, borrower_.t0Debt, @@ -475,7 +479,7 @@ library TakerActions { /** * @notice Performs update of an auctioned loan that was taken (using bucket or regular take). - * @notice If borrower becomes recollateralized then auction is settled. Update loan's state. + * @notice If borrower's debt has been fully covered, then auction is settled. Update loan's state. * @dev === Reverts on === * @dev borrower debt less than pool min debt `AmountLTMinDebt()` * @param auctions_ Struct for pool auctions state. @@ -515,12 +519,10 @@ library TakerActions { poolState_.quoteTokenScale ); - // calculate new lup with repaid debt from take - newLup_ = Deposits.getLup(deposits_, poolState_.debt); - remainingCollateral_ = borrower_.collateral; - if (_isCollateralized(borrowerDebt, borrower_.collateral, newLup_, poolState_.poolType)) { + // if debt is fully repaid, settle the auction + if (borrower_.t0Debt == 0) { settledAuction_ = true; // settle auction and update borrower's collateral with value after settlement @@ -536,19 +538,18 @@ library TakerActions { borrower_.collateral = remainingCollateral_; } - // update loan state, stamp borrower t0Np only when exiting from auction + // update loan state, stamp borrower Np to Tp ratio only when exiting from auction Loans.update( loans_, - auctions_, - deposits_, borrower_, borrowerAddress_, - poolState_.debt, poolState_.rate, - newLup_, !settledAuction_, - settledAuction_ // stamp borrower t0Np if exiting from auction + settledAuction_ // stamp borrower Np to Tp ratio if exiting from auction ); + + // calculate new lup with repaid debt from take + newLup_ = Deposits.getLup(deposits_, poolState_.debt); } /** @@ -676,11 +677,8 @@ library TakerActions { /** * @notice Utility function to validate take and calculate take's parameters. - * @dev write state: - * - update liquidation.alreadyTaken state * @dev reverts on: * - loan is not in auction NoAuction() - * - in 1 hour cool down period TakeNotPastCooldown() * @param liquidation_ Liquidation struct holding auction details. * @param t0Debt_ Borrower t0 debt. * @param collateral_ Borrower collateral. @@ -688,31 +686,23 @@ library TakerActions { * @return vars The prepared vars for take action. */ function _prepareTake( - Liquidation storage liquidation_, + Liquidation memory liquidation_, uint256 t0Debt_, uint256 collateral_, uint256 inflator_ - ) internal returns (TakeLocalVars memory vars) { + ) internal view returns (TakeLocalVars memory vars) { uint256 kickTime = liquidation_.kickTime; if (kickTime == 0) revert NoAuction(); - if (block.timestamp - kickTime <= 1 hours) revert TakeNotPastCooldown(); vars.t0BorrowerDebt = t0Debt_; - // if first take borrower debt is increased by 7% penalty - if (!liquidation_.alreadyTaken) { - vars.t0DebtPenalty = Maths.wmul(t0Debt_, 0.07 * 1e18); - vars.t0BorrowerDebt += vars.t0DebtPenalty; - - liquidation_.alreadyTaken = true; - } - vars.borrowerDebt = Maths.wmul(vars.t0BorrowerDebt, inflator_); uint256 neutralPrice = liquidation_.neutralPrice; - vars.auctionPrice = _auctionPrice(liquidation_.kickMomp, neutralPrice, kickTime); + vars.auctionPrice = _auctionPrice(liquidation_.referencePrice, kickTime); + vars.bondFactor = liquidation_.bondFactor; vars.bpf = _bpf( vars.borrowerDebt, collateral_, @@ -740,39 +730,46 @@ library TakerActions { TakeLocalVars memory ) { // price is the current auction price, which is the price paid by the LENDER for collateral - // from the borrower point of view, the price is actually (1-bpf) * price, as the rewards to the - // bond holder are effectively paid for by the borrower. - uint256 borrowerPayoffFactor = (vars.isRewarded) ? Maths.WAD - uint256(vars.bpf) : Maths.WAD; - uint256 borrowerPrice = (vars.isRewarded) ? Maths.wmul(borrowerPayoffFactor, vars.auctionPrice) : vars.auctionPrice; + // from the borrower point of view, there is a take penalty of (1.25 * bondFactor - 0.25 * bpf) + // Therefore the price is actually price * (1.0 - 1.25 * bondFactor + 0.25 * bpf) + uint256 takePenaltyFactor = uint256(5 * int256(vars.bondFactor) - vars.bpf + 3) / 4; // Round up + uint256 borrowerPrice = Maths.floorWmul(vars.auctionPrice, Maths.WAD - takePenaltyFactor); + + // To determine the value of quote token removed from a bucket in a bucket take call, we need to account for whether the bond is + // rewarded or not. If the bond is rewarded, we need to remove the bond reward amount from the amount removed, else it's simply the + // collateral times auction price. + uint256 netRewardedPrice = (vars.isRewarded) ? Maths.wmul(Maths.WAD - uint256(vars.bpf), vars.auctionPrice) : vars.auctionPrice; + + // auctions may not be zero-bid; prevent divide-by-zero in constraint calculations + if (vars.auctionPrice == 0) revert InvalidAmount(); - // If there is no unscaled quote token bound, then we pass in max, but that cannot be scaled without an overflow. So we check in the line below. - vars.quoteTokenAmount = (vars.unscaledDeposit != type(uint256).max) ? Maths.wmul(vars.unscaledDeposit, vars.bucketScale) : type(uint256).max; + // Collateral taken in bucket takes is constrained by the deposit available at the price including the reward. This is moot in the case of takes. + vars.depositCollateralConstraint = (vars.unscaledDeposit != type(uint256).max) ? _roundToScale(Math.mulDiv(vars.unscaledDeposit, vars.bucketScale, netRewardedPrice), collateralScale_) : type(uint256).max; - uint256 borrowerCollateralValue = Maths.wmul(totalCollateral_, borrowerPrice); + // Collateral taken is also constained by the borrower's debt, at the price they receive. + vars.debtCollateralConstraint = borrowerPrice != 0 ? _roundUpToScale(Maths.ceilWdiv(vars.borrowerDebt, borrowerPrice), collateralScale_) : type(uint256).max; - if (vars.quoteTokenAmount <= vars.borrowerDebt && vars.quoteTokenAmount <= borrowerCollateralValue) { + if (vars.depositCollateralConstraint <= vars.debtCollateralConstraint && vars.depositCollateralConstraint <= totalCollateral_) { // quote token used to purchase is constraining factor - vars.collateralAmount = _roundToScale(Maths.wdiv(vars.quoteTokenAmount, borrowerPrice), collateralScale_); + vars.collateralAmount = vars.depositCollateralConstraint; 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) + Math.mulDiv(vars.collateralAmount, netRewardedPrice, vars.bucketScale) ); - - } else if (vars.borrowerDebt <= borrowerCollateralValue) { + } else if (vars.debtCollateralConstraint <= totalCollateral_) { // borrower debt is constraining factor - vars.collateralAmount = _roundToScale(Maths.wdiv(vars.borrowerDebt, borrowerPrice), collateralScale_); + vars.collateralAmount = vars.debtCollateralConstraint; vars.t0RepayAmount = vars.t0BorrowerDebt; - vars.unscaledQuoteTokenAmount = Maths.wdiv(vars.borrowerDebt, vars.bucketScale); - - vars.quoteTokenAmount = (vars.isRewarded) ? Maths.wdiv(vars.borrowerDebt, borrowerPayoffFactor) : vars.borrowerDebt; + vars.unscaledQuoteTokenAmount = Math.mulDiv(vars.collateralAmount, netRewardedPrice, vars.bucketScale); + vars.quoteTokenAmount = Maths.wdiv(vars.borrowerDebt, Maths.WAD - takePenaltyFactor); } else { // collateral available is constraint vars.collateralAmount = totalCollateral_; vars.t0RepayAmount = Math.mulDiv(totalCollateral_, borrowerPrice, inflator_); - vars.unscaledQuoteTokenAmount = Math.mulDiv(totalCollateral_, borrowerPrice, vars.bucketScale); + vars.unscaledQuoteTokenAmount = Math.mulDiv(totalCollateral_, netRewardedPrice, vars.bucketScale); vars.quoteTokenAmount = Maths.wmul(vars.collateralAmount, vars.auctionPrice); } diff --git a/src/libraries/helpers/PoolHelper.sol b/src/libraries/helpers/PoolHelper.sol index afb6e633c..621001e82 100644 --- a/src/libraries/helpers/PoolHelper.sol +++ b/src/libraries/helpers/PoolHelper.sol @@ -25,7 +25,7 @@ import { Maths } from '../internal/Maths.sol'; uint256 constant MIN_PRICE = 99_836_282_890; uint256 constant MAX_PRICE = 1_004_968_987.606512354182109771 * 1e18; - uint256 constant MAX_NEUTRAL_PRICE = 50_248_449_380.325617709105488550 * 1e18; // 50 * MAX_PRICE + uint256 constant MAX_INFLATED_PRICE = 50_248_449_380.325617709105488550 * 1e18; // 50 * MAX_PRICE /// @dev deposit buffer (extra margin) used for calculating reserves uint256 constant DEPOSIT_BUFFER = 1.000000001 * 1e18; @@ -346,24 +346,27 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Calculates auction price. - * @param kickMomp_ `MOMP` recorded at the time of kick. - * @param neutralPrice_ `Neutral Price` of the auction. - * @param kickTime_ Time when auction was kicked. - * @return price_ Calculated auction price. + * @param referencePrice_ Recorded at kick, used to calculate start price. + * @param kickTime_ Time when auction was kicked. + * @return price_ Calculated auction price. */ function _auctionPrice( - uint256 kickMomp_, - uint256 neutralPrice_, + uint256 referencePrice_, uint256 kickTime_ ) view returns (uint256 price_) { - uint256 elapsedHours = Maths.wdiv((block.timestamp - kickTime_) * 1e18, 1 hours * 1e18); - - elapsedHours -= Maths.min(elapsedHours, 1e18); // price locked during cure period - - int256 timeAdjustment = PRBMathSD59x18.mul(-1 * 1e18, int256(elapsedHours)); - uint256 referencePrice = Maths.max(kickMomp_, neutralPrice_); - - price_ = 32 * Maths.wmul(referencePrice, uint256(PRBMathSD59x18.exp2(timeAdjustment))); + uint256 elapsedMinutes = Maths.wdiv((block.timestamp - kickTime_) * 1e18, 1 minutes * 1e18); + + int256 timeAdjustment; + if (elapsedMinutes < 120 * 1e18) { + timeAdjustment = PRBMathSD59x18.mul(-1 * 1e18, int256(elapsedMinutes / 20)); + price_ = 256 * Maths.wmul(referencePrice_, uint256(PRBMathSD59x18.exp2(timeAdjustment))); + } else if (elapsedMinutes < 840 * 1e18) { + timeAdjustment = PRBMathSD59x18.mul(-1 * 1e18, int256((elapsedMinutes - 120 * 1e18) / 120)); + price_ = 4 * Maths.wmul(referencePrice_, uint256(PRBMathSD59x18.exp2(timeAdjustment))); + } else { + timeAdjustment = PRBMathSD59x18.mul(-1 * 1e18, int256((elapsedMinutes - 840 * 1e18) / 60)); + price_ = Maths.wmul(referencePrice_, uint256(PRBMathSD59x18.exp2(timeAdjustment))) / 16; + } } /** @@ -409,29 +412,18 @@ import { Maths } from '../internal/Maths.sol'; /** * @notice Calculates bond parameters of an auction. - * @param borrowerDebt_ Borrower's debt before entering in liquidation. - * @param collateral_ Borrower's collateral before entering in liquidation. - * @param momp_ Current pool `momp`. + * @param borrowerDebt_ Borrower's debt before entering in liquidation. + * @param npTpRatio_ Borrower's Np to Tp ratio */ function _bondParams( uint256 borrowerDebt_, - uint256 collateral_, - uint256 momp_ + uint256 npTpRatio_ ) pure returns (uint256 bondFactor_, uint256 bondSize_) { - uint256 thresholdPrice = (borrowerDebt_ * Maths.WAD) / collateral_; - - // bondFactor = min(30%, max(1%, (MOMP - thresholdPrice) / MOMP)) - if (thresholdPrice >= momp_) { - bondFactor_ = 0.01 * 1e18; - } else { - bondFactor_ = Maths.min( - 0.3 * 1e18, - Maths.max( - 0.01 * 1e18, - 1e18 - Maths.wdiv(thresholdPrice, momp_) - ) - ); - } + // bondFactor = min((NP-to-TP-ratio - 1)/10, 0.03) + bondFactor_ = Maths.min( + 0.03 * 1e18, + (npTpRatio_ - 1e18) / 10 + ); bondSize_ = Maths.wmul(bondFactor_, borrowerDebt_); } diff --git a/src/libraries/internal/Deposits.sol b/src/libraries/internal/Deposits.sol index a0bb157c0..428997f05 100644 --- a/src/libraries/internal/Deposits.sol +++ b/src/libraries/internal/Deposits.sol @@ -71,7 +71,7 @@ library Deposits { /** * @notice Finds index and sum of first bucket that EXCEEDS the given sum - * @dev Used in `LUP` and `MOMP` calculation + * @dev Used in `LUP` calculation * @param deposits_ Struct for deposits state. * @param targetSum_ The sum to find index for. * @return sumIndex_ Smallest index where prefixsum greater than the sum. @@ -134,7 +134,7 @@ library Deposits { /** * @notice Finds index of passed sum. Helper function for `findIndexAndSumOfSum`. - * @dev Used in `LUP` and `MOMP` calculation + * @dev Used in `LUP` calculation * @param deposits_ Deposits state struct. * @param sum_ The sum to find index for. * @return sumIndex_ Smallest index where prefixsum greater than the sum. diff --git a/src/libraries/internal/Loans.sol b/src/libraries/internal/Loans.sol index c7f8e5f00..764b9ef20 100644 --- a/src/libraries/internal/Loans.sol +++ b/src/libraries/internal/Loans.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.18; +import { PRBMathSD59x18 } from "@prb-math/contracts/PRBMathSD59x18.sol"; + import { AuctionsState, Borrower, @@ -61,27 +63,19 @@ library Loans { * @dev remove loan from `loans` array * @dev - update borrower in `address => borrower` mapping * @param loans_ Holds loans heap data. - * @param auctions_ Struct for pool auctions state. - * @param deposits_ Struct for pool deposits state. * @param borrower_ Borrower struct with borrower details. * @param borrowerAddress_ Borrower's address to update. - * @param poolDebt_ Pool's current debt. * @param poolRate_ Pool's current rate. - * @param lup_ Current LUP. * @param inAuction_ Whether the loan is in auction or not. - * @param t0NpUpdate_ Whether the neutral price of borrower should be updated or not. + * @param npTpRatioUpdate_ Whether the Np to Tp ratio of borrower should be updated or not. */ function update( LoansState storage loans_, - AuctionsState storage auctions_, - DepositsState storage deposits_, Borrower memory borrower_, address borrowerAddress_, - uint256 poolDebt_, uint256 poolRate_, - uint256 lup_, bool inAuction_, - bool t0NpUpdate_ + bool npTpRatioUpdate_ ) internal { bool activeBorrower = borrower_.t0Debt != 0 && borrower_.collateral != 0; @@ -105,16 +99,9 @@ library Loans { } } - // update t0 neutral price of borrower - if (t0NpUpdate_) { - if (t0ThresholdPrice != 0) { - uint256 loansInPool = loans_.loans.length - 1 + auctions_.noOfAuctions; - uint256 curMomp = _priceAt(Deposits.findIndexOfSum(deposits_, Maths.wdiv(poolDebt_, loansInPool * 1e18))); - - borrower_.t0Np = (1e18 + poolRate_) * curMomp * t0ThresholdPrice / lup_ / 1e18; - } else { - borrower_.t0Np = 0; - } + // update Np to Tp ratio of borrower + if (npTpRatioUpdate_) { + borrower_.npTpRatio = 1.04 * 1e18 + uint256(PRBMathSD59x18.sqrt(int256(poolRate_))) / 2; } // save borrower state diff --git a/tests/INVARIANTS.md b/tests/INVARIANTS.md index 67c2cced0..ee1a17b95 100644 --- a/tests/INVARIANTS.md +++ b/tests/INVARIANTS.md @@ -23,8 +23,8 @@ - **A3**: number of borrowers with debt (`LoansState.borrowers.length` with `t0Debt != 0`) = number of loans (`LoansState.loans.length -1`) + number of auctioned borrowers (`AuctionsState.noOfAuctions`) - **A4**: number of recorded auctions (`AuctionsState.noOfAuctions`) = length of auctioned borrowers (count of borrowers in `AuctionsState.liquidations` with `kickTime != 0`) - **A5**: for each `Liquidation` recorded in liquidation mapping (`AuctionsState.liquidations`) the kicker address (`Liquidation.kicker`) has a locked balance (`Kicker.locked`) equal or greater than liquidation bond size (`Liquidation.bondSize`) -- **A6**: if a `Liquidation` is not taken then the take flag (`Liquidation.alreadyTaken`) should be `False`, if already taken then the take flag should be `True` - **A7**: total bond escrowed accumulator (`AuctionsState.totalBondEscrowed`) should increase when auction is kicked with the difference needed to cover the bond and should decrease only when kicker bonds withdrawn (`Pool.withdrawBonds`). Claimable bonds should be available for withdrawal from pool at any time. +- **A8**: Upon a take/arbtake/deposittake the kicker reward <= borrower penalty ## Loans - **L1**: for each `Loan` in loans array (`LoansState.loans`) starting from index 1, the corresponding address (`Loan.borrower`) is not `0x`, the threshold price (`Loan.thresholdPrice`) is different than 0 and the id mapped in indices mapping (`LoansState.indices`) equals index of loan in loans array. @@ -70,12 +70,13 @@ - **RE4**: Reserves are unchanged by withdrawing deposit (quote token) from a bucket after the penalty period hes expired - **RE5**: Reserves are unchanged by adding collateral token into a bucket - **RE6**: Reserves are unchanged by removing collateral token from a bucket -- **RE7**: Reserves increase by 7% of the loan quantity upon the first take (including depositTake or arbTake) and increase/decrease by bond penalty/reward on take. -- **RE8**: Reserves are unchanged under takes/depositTakes/arbTakes after the first take but increase/decrease by bond penalty/reward on take. -- **RE9**: Reserves increase by 3 months of interest when a loan is kicked +- **RE7**: Reserves increase by bond penalty/reward plus borrower penalty on take above TP. +- **RE8**: Reserves increase by bond penalty/reward plus borrower penalty on bucket takes above TP. +- **RE9**: Reserves unchanges by takes and bucket takes below TP. - **RE10**: Reserves increase by origination fee: max(1 week interest, 0.05% of borrow amount), on draw debt - **RE11**: Reserves decrease by claimableReserves by kickReserveAuction - **RE12**: Reserves decrease by amount of reserve used to settle a auction +- **RE13**: Reserves are unchanged by kick ## Rewards - **RW1**: Staking rewards must be less than reward cap percentage multiplied by ajna burned (`newRewards < REWARD_CAP * totalBurnedInPeriod`) for any given time period (`epoch`) diff --git a/tests/brownie/conftest.py b/tests/brownie/conftest.py index 3f1a9d411..20c72aa62 100644 --- a/tests/brownie/conftest.py +++ b/tests/brownie/conftest.py @@ -112,7 +112,7 @@ def availableLiquidity(self): return quoteBalance - reserves; def borrowerInfo(self, borrower_address): - # returns (debt, collateral, mompFactor) + # returns (debt, collateral, t0NeutralPrice) return self.pool_info_utils.borrowerInfo(self.pool.address, borrower_address) def bucketInfo(self, index): diff --git a/tests/forge/interactions/BalancerUniswapExample.sol b/tests/forge/interactions/BalancerUniswapExample.sol index 0652466be..d5b3ca405 100644 --- a/tests/forge/interactions/BalancerUniswapExample.sol +++ b/tests/forge/interactions/BalancerUniswapExample.sol @@ -53,7 +53,7 @@ contract BalancerUniswapTaker { // take auction from Ajna pool, give USDC, receive WETH IAjnaPool(decoded.ajnaPool).take(decoded.borrower, decoded.maxAmount, address(this), new bytes(0)); - uint256 usdcBalanceAfterTake = 85496538; + uint256 usdcBalanceAfterTake = 81080126; assert(tokens[0].balanceOf(address(this)) == usdcBalanceAfterTake); // USDC balance after Ajna take assert(tokens[1].balanceOf(address(this)) == 2000000000000000000); // WETH balance after Ajna take diff --git a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol index 8ce92718b..74d4644f9 100644 --- a/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol +++ b/tests/forge/interactions/ERC20TakeWithExternalLiquidity.t.sol @@ -105,7 +105,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { }) ); vm.expectEmit(true, true, false, true); - emit Take(_borrower, 14.503461444385064128 * 1e18, 2.0 * 1e18, 0.145034614443850641 * 1e18, true); + emit Take(_borrower, 18.919873153126569032 * 1e18, 2.0 * 1e18, 0.287210105092827748 * 1e18, true); taker.take(tokens, amounts, data); assertGt(usdc.balanceOf(address(this)), 0); // could vary @@ -126,7 +126,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { // call take using taker contract bytes memory data = abi.encode(address(_ajnaPool)); vm.expectEmit(true, true, false, true); - emit Take(_borrower, 14.503461444385064128 * 1e18, 2.0 * 1e18, 0.145034614443850641 * 1e18, true); + emit Take(_borrower, 18.919873153126569032 * 1e18, 2.0 * 1e18, 0.287210105092827748 * 1e18, true); _ajnaPool.take(_borrower, takeAmount, address(taker), data); // confirm we earned some quote token @@ -136,7 +136,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { function testTakeCalleeDiffersFromSender() external { // _lender is msg.sender, QT & CT balances pre take - assertEq(usdc.balanceOf(_lender), 119_999.999999926999804657 * 1e18); + assertEq(usdc.balanceOf(_lender), 119_999.999999926999703463 * 1e18); assertEq(weth.balanceOf(_lender), 0); // callee, _lender1 QT & CT balances pre take @@ -148,7 +148,7 @@ contract ERC20TakeWithExternalLiquidityTest is Test { _ajnaPool.take(_borrower, 1_001 * 1e18, _lender1, new bytes(0)); // _lender is has QT deducted from balance - assertEq(usdc.balanceOf(_lender), 119_999.999999926985301195 * 1e18); + assertEq(usdc.balanceOf(_lender), 119_999.999999926980783589 * 1e18); assertEq(weth.balanceOf(_lender), 0); // callee, _lender1 receives CT from take diff --git a/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol b/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol index bd6ba3eb5..cbf94628c 100644 --- a/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol +++ b/tests/forge/interactions/ERC721TakeWithExternalLiquidity.sol @@ -80,14 +80,14 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract { // call take using taker contract bytes memory data = abi.encode(address(_pool)); vm.expectEmit(true, true, false, true); - uint256 quoteTokenPaid = 529.576903317769475648 * 1e18; + uint256 quoteTokenPaid = 1_161.844718489711575688 * 1e18; uint256 collateralPurchased = 2 * 1e18; - uint256 bondChange = 5.295769033177694756 * 1e18; + uint256 bondChange = 17.637197723169355130 * 1e18; emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true); _pool.take(_borrower, 2, address(taker), data); // confirm we earned some quote token - assertEq(_quote.balanceOf(address(taker)), 970.423096682230524352 * 1e18); + assertEq(_quote.balanceOf(address(taker)), 338.155281510288424312 * 1e18); } function testTakeNFTCalleeDiffersFromSender() external { @@ -103,21 +103,21 @@ contract ERC721TakeWithExternalLiquidityTest is ERC721HelperContract { _collateral.setApprovalForAll(address(marketPlace), true); // _lender is msg.sender, QT & CT balances pre take - assertEq(_quote.balanceOf(_lender), 49_979.825641778370686641 * 1e18); + assertEq(_quote.balanceOf(_lender), 49_969.374638518350819260 * 1e18); assertEq(_quote.balanceOf(address(taker)), 0); // call take using taker contract changePrank(_lender); bytes memory data = abi.encode(address(_pool)); vm.expectEmit(true, true, false, true); - uint256 quoteTokenPaid = 529.576903317769475648 * 1e18; + uint256 quoteTokenPaid = 1_161.844718489711575688 * 1e18; uint256 collateralPurchased = 2 * 1e18; - uint256 bondChange = 5.295769033177694756 * 1e18; + uint256 bondChange = 17.637197723169355130 * 1e18; emit Take(_borrower, quoteTokenPaid, collateralPurchased, bondChange, true); _pool.take(_borrower, 2, address(taker), data); // _lender is msg.sender, QT & CT balances post take - assertEq(_quote.balanceOf(_lender), 49_450.248738460601210993 * 1e18); + assertEq(_quote.balanceOf(_lender), 48_807.529920028639243572 * 1e18); assertEq(_quote.balanceOf(address(taker)), 1_500.0 * 1e18); // QT is increased as NFTTakeExample contract sells the NFT } } diff --git a/tests/forge/invariants/ERC20Pool/PanicExitERC20PoolInvariants.t.sol b/tests/forge/invariants/ERC20Pool/PanicExitERC20PoolInvariants.t.sol index 0fa61a418..b9df8f249 100644 --- a/tests/forge/invariants/ERC20Pool/PanicExitERC20PoolInvariants.t.sol +++ b/tests/forge/invariants/ERC20Pool/PanicExitERC20PoolInvariants.t.sol @@ -72,7 +72,6 @@ contract PanicExitERC20PoolInvariants is BasicERC20PoolInvariants, LiquidationIn _invariant_A2(); _invariant_A3_A4(); _invariant_A5(); - _invariant_A6(); _invariant_A7(); invariant_call_summary(); diff --git a/tests/forge/invariants/ERC20Pool/RealWorldScenarioInvariants.t.sol b/tests/forge/invariants/ERC20Pool/RealWorldScenarioInvariants.t.sol index 0c9f27076..c1a2195cf 100644 --- a/tests/forge/invariants/ERC20Pool/RealWorldScenarioInvariants.t.sol +++ b/tests/forge/invariants/ERC20Pool/RealWorldScenarioInvariants.t.sol @@ -66,7 +66,6 @@ contract RealWorldScenarioInvariants is ReserveInvariants, LiquidationERC20PoolI _invariant_A2(); _invariant_A3_A4(); _invariant_A5(); - _invariant_A6(); _invariant_A7(); invariant_reserves(); diff --git a/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol index 1fbce5195..fceda2a40 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/BasicERC20PoolHandler.sol @@ -73,14 +73,20 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.pledgeCollateral']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _prePledgeCollateral(amountToPledge_); // Action phase _pledgeCollateral(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } function pullCollateral( @@ -90,6 +96,15 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.pullCollateral']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _prePullCollateral(amountToPull_); @@ -104,14 +119,20 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.drawDebt']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _preDrawDebt(amountToBorrow_); // Action phase _drawDebt(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } function repayDebt( @@ -121,14 +142,20 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.repayDebt']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _preRepayDebt(amountToRepay_); // Action phase _repayDebt(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } /*******************************/ @@ -168,13 +195,22 @@ contract BasicERC20PoolHandler is UnboundedBasicERC20PoolHandler, BasicPoolHandl ) internal override returns (uint256 boundedAmount_) { boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT); + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return boundedAmount_; + // Pre Condition // 1. borrower's debt should exceed minDebt // 2. pool needs sufficent quote token to draw debt // 3. drawDebt should not make borrower under collateralized // 1. borrower's debt should exceed minDebt - (uint256 debt, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + (uint256 debt,, ) = _poolInfo.borrowerInfo(address(_pool), _actor); (uint256 minDebt, , , ) = _poolInfo.poolUtilizationInfo(address(_pool)); if (boundedAmount_ < minDebt && minDebt < MAX_DEBT_AMOUNT) boundedAmount_ = minDebt + 1; diff --git a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol index ef5429ca7..9903290a0 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/PanicExitERC20PoolHandler.sol @@ -60,7 +60,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded _actor = _borrowers[borrowerIndex_]; changePrank(_actor); - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(_actor); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor); if (block.timestamp > kickTime + 72 hours) { numberOfCalls['BPanicExitPoolHandler.settleDebt']++; _settleAuction(_actor, numberOfBuckets); @@ -71,7 +71,6 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded (, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); _pullCollateral(collateral); - _auctionSettleStateReset(_actor); _resetSettledAuction(_actor, borrowerIndex_); } @@ -165,7 +164,7 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded function settleHeadAuction( uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { _settleAuction(headAuction, 10); _resetSettledAuction(headAuction, 0); @@ -219,9 +218,8 @@ contract PanicExitERC20PoolHandler is UnboundedLiquidationPoolHandler, Unbounded } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); if (kickTime == 0) { - alreadyTaken[borrower_] = false; if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol b/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol index 32416051a..32878fffe 100644 --- a/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol +++ b/tests/forge/invariants/ERC20Pool/handlers/TradingERC20PoolHandler.sol @@ -171,9 +171,8 @@ contract TradingERC20PoolHandler is UnboundedLiquidationPoolHandler, UnboundedBa } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); if (kickTime == 0) { - alreadyTaken[borrower_] = false; if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/ERC721Pool/PanicExitERC721PoolInvariants.t.sol b/tests/forge/invariants/ERC721Pool/PanicExitERC721PoolInvariants.t.sol index 882a16ad5..be00c021c 100644 --- a/tests/forge/invariants/ERC721Pool/PanicExitERC721PoolInvariants.t.sol +++ b/tests/forge/invariants/ERC721Pool/PanicExitERC721PoolInvariants.t.sol @@ -70,7 +70,6 @@ contract PanicExitERC721PoolInvariants is BasicERC721PoolInvariants, Liquidation _invariant_A2(); _invariant_A3_A4(); _invariant_A5(); - _invariant_A6(); _invariant_A7(); invariant_call_summary(); diff --git a/tests/forge/invariants/ERC721Pool/RealWorldScenarioInvariants.t.sol b/tests/forge/invariants/ERC721Pool/RealWorldScenarioInvariants.t.sol index 8ead081ac..7131ba3ee 100644 --- a/tests/forge/invariants/ERC721Pool/RealWorldScenarioInvariants.t.sol +++ b/tests/forge/invariants/ERC721Pool/RealWorldScenarioInvariants.t.sol @@ -64,7 +64,6 @@ contract RealWorldScenarioInvariants is ReserveInvariants, LiquidationERC721Pool _invariant_A2(); _invariant_A3_A4(); _invariant_A5(); - _invariant_A6(); _invariant_A7(); invariant_reserves(); diff --git a/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol index acbf9ea25..7111ff0f2 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/BasicERC721PoolHandler.sol @@ -87,14 +87,20 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.pledgeCollateral']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _prePledgeCollateral(amountToPledge_); // Action phase _pledgeCollateral(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } function pullCollateral( @@ -104,6 +110,15 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.pullCollateral']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _prePullCollateral(amountToPull_); @@ -118,14 +133,20 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.drawDebt']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _preDrawDebt(amountToBorrow_); // Action phase _drawDebt(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } function repayDebt( @@ -135,14 +156,20 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan ) external useRandomActor(actorIndex_) useTimestamps skipTime(skippedTime_) writeLogs { numberOfCalls['BBasicHandler.repayDebt']++; + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debtToCover, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return; + // Prepare test phase uint256 boundedAmount = _preRepayDebt(amountToRepay_); // Action phase _repayDebt(boundedAmount); - - // Cleanup phase - _auctionSettleStateReset(_actor); } /*******************************/ @@ -201,13 +228,22 @@ contract BasicERC721PoolHandler is UnboundedBasicERC721PoolHandler, BasicPoolHan ) internal override returns (uint256 boundedAmount_) { boundedAmount_ = constrictToRange(amountToBorrow_, MIN_DEBT_AMOUNT, MAX_DEBT_AMOUNT); + // borrower cannot make any action when in auction + (uint256 kickTime, + uint256 collateral, + uint256 debt, + bool isCollateralized, + uint256 price, + uint256 np) = _poolInfo.auctionStatus(address(_pool), _actor); + if (kickTime != 0) return boundedAmount_; + // Pre Condition // 1. borrower's debt should exceed minDebt // 2. pool needs sufficent quote token to draw debt // 3. drawDebt should not make borrower under collateralized // 1. borrower's debt should exceed minDebt - (uint256 debt, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); + (debt, collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); (uint256 minDebt, , , ) = _poolInfo.poolUtilizationInfo(address(_pool)); if (boundedAmount_ < minDebt && minDebt < MAX_DEBT_AMOUNT) boundedAmount_ = minDebt + 1; diff --git a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol index f01bfe0b3..2051776b7 100644 --- a/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol +++ b/tests/forge/invariants/ERC721Pool/handlers/PanicExitERC721PoolHandler.sol @@ -58,7 +58,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde _actor = _borrowers[borrowerIndex_]; changePrank(_actor); - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(_actor); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(_actor); if (block.timestamp > kickTime + 72 hours) { numberOfCalls['BPanicExitPoolHandler.settleDebt']++; _settleAuction(_actor, numberOfBuckets); @@ -69,7 +69,6 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde (, uint256 collateral, ) = _poolInfo.borrowerInfo(address(_pool), _actor); _pullCollateral(collateral); - _auctionSettleStateReset(_actor); _resetSettledAuction(_actor, borrowerIndex_); } @@ -163,7 +162,7 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde function settleHeadAuction( uint256 skippedTime_ ) external useTimestamps skipTime(skippedTime_) writeLogs { - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { _settleAuction(headAuction, 10); _resetSettledAuction(headAuction, 0); @@ -217,9 +216,8 @@ contract PanicExitERC721PoolHandler is UnboundedLiquidationPoolHandler, Unbounde } function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); if (kickTime == 0) { - alreadyTaken[borrower_] = false; if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol b/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol index c1a9b2742..78c4054c0 100644 --- a/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol +++ b/tests/forge/invariants/PositionsAndRewards/handlers/BucketBankruptcyERC20PoolRewardsHandler.sol @@ -154,7 +154,7 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl ) external useTimestamps useRandomActor(takerIndex_) skipTime(skippedTime_) writeLogs { address borrower = _borrowers[constrictToRange(borrowerIndex_, 0, _borrowers.length - 1)]; - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); // Kick borrower if not already kicked if (kickTime == 0) { @@ -255,9 +255,8 @@ contract BucketBankruptcyERC20PoolRewardsHandler is UnboundedBasicERC20PoolHandl /*******************************/ function _resetSettledAuction(address borrower_, uint256 borrowerIndex_) internal { - (,,, uint256 kickTime,,,,,,) = _pool.auctionInfo(borrower_); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower_); if (kickTime == 0) { - alreadyTaken[borrower_] = false; if (borrowerIndex_ != 0) _activeBorrowers.remove(borrowerIndex_); } } diff --git a/tests/forge/invariants/base/BasicInvariants.t.sol b/tests/forge/invariants/base/BasicInvariants.t.sol index cacc1baba..ad199a7ea 100644 --- a/tests/forge/invariants/base/BasicInvariants.t.sol +++ b/tests/forge/invariants/base/BasicInvariants.t.sol @@ -321,7 +321,7 @@ abstract contract BasicInvariants is BaseInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); if (kickTime == 0) { (uint256 borrowerT0Debt, uint256 borrowerCollateral, ) = _pool.borrowerInfo(borrower); diff --git a/tests/forge/invariants/base/LiquidationInvariants.t.sol b/tests/forge/invariants/base/LiquidationInvariants.t.sol index 19db71e26..4788bcd48 100644 --- a/tests/forge/invariants/base/LiquidationInvariants.t.sol +++ b/tests/forge/invariants/base/LiquidationInvariants.t.sol @@ -19,8 +19,8 @@ abstract contract LiquidationInvariants is BasicInvariants { _invariant_A2(); _invariant_A3_A4(); _invariant_A5(); - _invariant_A6(); _invariant_A7(); + _invariant_A8(); } /// @dev checks sum of all borrower's t0debt is equals to total pool t0debtInAuction @@ -30,7 +30,7 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , ,) = _pool.auctionInfo(borrower); if (kickTime != 0) { (uint256 t0debt, , ) = _pool.borrowerInfo(borrower); @@ -62,7 +62,7 @@ abstract contract LiquidationInvariants is BasicInvariants { uint256 lockedBonds; for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , uint256 bond, , , , , , , ) = _pool.auctionInfo(borrower); + (, , uint256 bond, , , , , , ) = _pool.auctionInfo(borrower); lockedBonds += bond; } require(lockedBonds == kickerLockedBond, "A2: bonds in auctions != than kicker locked bonds"); @@ -94,7 +94,7 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); if (kickTime != 0) borrowersKicked += 1; } @@ -108,28 +108,13 @@ abstract contract LiquidationInvariants is BasicInvariants { for (uint256 i = 0; i < actorCount; i++) { address borrower = IBaseHandler(_handler).actors(i); - (address kicker, , uint256 bondSize, , , , , , , ) = _pool.auctionInfo(borrower); + (address kicker, , uint256 bondSize, , , , , , ) = _pool.auctionInfo(borrower); (, uint256 lockedAmount) = _pool.kickerInfo(kicker); require(lockedAmount >= bondSize, "Auction Invariant A5"); } } - /// @dev if a Liquidation is not taken then the take flag (Liquidation.alreadyTaken) should be False, if already taken then the take flag should be True - function _invariant_A6() internal view { - uint256 actorCount = IBaseHandler(_handler).getActorsCount(); - - for (uint256 i = 0; i < actorCount; i++) { - address borrower = IBaseHandler(_handler).actors(i); - (, , , , , , , , , bool alreadyTaken) = _pool.auctionInfo(borrower); - - require( - alreadyTaken == IBaseHandler(_handler).alreadyTaken(borrower), - "Auction Invariant A6" - ); - } - } - /// @dev total bond escrowed should increase when auctioned kicked with the difference needed to cover the bond and should decrease only when kicker bonds withdrawned function _invariant_A7() internal view { uint256 previousTotalBondEscrowed = IBaseHandler(_handler).previousTotalBonds(); @@ -144,6 +129,17 @@ abstract contract LiquidationInvariants is BasicInvariants { "Auction Invariant A7" ); } + + /// @dev kicker reward should be less than or equals to kicker penalty on take. + function _invariant_A8() internal view { + uint256 borrowerPenalty = IBaseHandler(_handler).borrowerPenalty(); + uint256 kickerReward = IBaseHandler(_handler).kickerReward(); + + console.log("Borrower Penalty -->", borrowerPenalty); + console.log("Kicker Reward -->", kickerReward); + + require(kickerReward <= borrowerPenalty, "Auction Invariant A8"); + } function invariant_call_summary() public virtual override useCurrentTimestamp { console.log("\nCall Summary\n"); diff --git a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol index db7e2551f..e2446cede 100644 --- a/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/LiquidationPoolHandler.sol @@ -55,13 +55,13 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas address borrower; // try to take from head auction if any - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { (, uint256 auctionedCollateral, ) = _poolInfo.borrowerInfo(address(_pool), headAuction); borrower = headAuction; amount_ = auctionedCollateral / 2; - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); // skip to make auction takeable if (block.timestamp - kickTime < 1 hours) { vm.warp(block.timestamp + 61 minutes); @@ -91,11 +91,11 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas address borrower; // try to take from head auction if any - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { borrower = headAuction; - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower); // skip to make auction takeable if (block.timestamp - kickTime < 1 hours) { vm.warp(block.timestamp + 61 minutes); @@ -126,7 +126,7 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas address borrower; // try to settle head auction if any - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { borrower = headAuction; } else { @@ -139,8 +139,6 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas _settleAuction(borrower, LENDER_MAX_BUCKET_INDEX - LENDER_MIN_BUCKET_INDEX); - // Cleanup phase - _auctionSettleStateReset(borrower); } /*******************************/ @@ -152,7 +150,7 @@ abstract contract LiquidationPoolHandler is UnboundedLiquidationPoolHandler, Bas borrower_ = actors[borrowerIndex_]; amount_ = constrictToRange(amount_, MIN_QUOTE_AMOUNT, MAX_QUOTE_AMOUNT); - ( , , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower_); + ( , , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); borrowerKicked_ = kickTime != 0; diff --git a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol index 6838cc788..effd3183a 100644 --- a/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/BaseHandler.sol @@ -81,13 +81,13 @@ abstract contract BaseHandler is Test { uint256 public increaseInBonds; // amount of bond increase uint256 public decreaseInBonds; // amount of bond decrease + // Take penalty test state + uint256 public borrowerPenalty; // Borrower penalty on take + uint256 public kickerReward; // Kicker reward on take + // All Buckets used in invariant testing that also includes Buckets where collateral is added when a borrower is in auction and has partial NFT EnumerableSet.UintSet internal buckets; - // auctions invariant test state - bool public firstTake; // if take is called on auction first time - mapping(address => bool) public alreadyTaken; // mapping borrower address to true if auction taken atleast once - string internal path = "logFile.txt"; bool internal logToFile; uint256 internal logVerbosity; @@ -132,9 +132,9 @@ abstract contract BaseHandler is Test { address currentActor = _actor; // clear head auction if more than 72 hours passed - (, , , , , , address headAuction, , , ) = _pool.auctionInfo(address(0)); + (, , , , , , address headAuction, , ) = _pool.auctionInfo(address(0)); if (headAuction != address(0)) { - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(headAuction); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(headAuction); if (block.timestamp - kickTime > 72 hours) { (uint256 auctionedDebt, , ) = _poolInfo.borrowerInfo(address(_pool), headAuction); @@ -145,7 +145,6 @@ abstract contract BaseHandler is Test { _ensureQuoteAmount(headAuction, auctionedDebt); _repayBorrowerDebt(headAuction, auctionedDebt); - _auctionSettleStateReset(headAuction); } } @@ -299,6 +298,7 @@ abstract contract BaseHandler is Test { err == keccak256(abi.encodeWithSignature("InvalidIndex()")) || err == keccak256(abi.encodeWithSignature("InsufficientLP()")) || err == keccak256(abi.encodeWithSignature("AuctionNotCleared()")) || + err == keccak256(abi.encodeWithSignature("AuctionNotTakeable()")) || err == keccak256(abi.encodeWithSignature("TransferorNotApproved()")) || err == keccak256(abi.encodeWithSignature("TransferToSameOwner()")) || err == keccak256(abi.encodeWithSignature("NoAllowance()")) || @@ -311,7 +311,6 @@ abstract contract BaseHandler is Test { err == keccak256(abi.encodeWithSignature("LimitIndexExceeded()")) || err == keccak256(abi.encodeWithSignature("PriceBelowLUP()")) || err == keccak256(abi.encodeWithSignature("NoAuction()")) || - err == keccak256(abi.encodeWithSignature("TakeNotPastCooldown()")) || err == keccak256(abi.encodeWithSignature("AuctionPriceGtBucketPrice()")) || err == keccak256(abi.encodeWithSignature("AuctionNotClearable()")) || err == keccak256(abi.encodeWithSignature("ReserveAuctionTooSoon()")) || @@ -346,6 +345,10 @@ abstract contract BaseHandler is Test { // record reserves before each action (previousReserves, , , , ) = _poolInfo.poolReservesInfo(address(_pool)); + // reset penalties before each action + borrowerPenalty = 0; + kickerReward = 0; + // reset the bonds before each action increaseInBonds = 0; decreaseInBonds = 0; @@ -429,41 +432,11 @@ abstract contract BaseHandler is Test { /*** Auctions Helper Functions ***/ /*********************************/ - /** - * @dev Called by actions that can settle auctions in order to reset test state. - */ - function _auctionSettleStateReset(address actor_) internal { - (address kicker, , , , , , , , , ) = _pool.auctionInfo(actor_); - - // auction is settled if kicker is 0x - bool auctionSettled = kicker == address(0); - // reset alreadyTaken flag if auction is settled - if (auctionSettled) alreadyTaken[actor_] = false; - } - function _getKickerBond(address kicker_) internal view returns (uint256 bond_) { (uint256 claimableBond, uint256 lockedBond) = _pool.kickerInfo(kicker_); bond_ = claimableBond + lockedBond; } - function _updateCurrentTakeState(address borrower_, uint256 borrowert0Debt_, uint256 inflator_) internal { - if (!alreadyTaken[borrower_]) { - alreadyTaken[borrower_] = true; - - // **RE7**: Reserves increase by 7% of the loan quantity upon the first take. - increaseInReserves += Maths.wmul( - Maths.wmul(borrowert0Debt_, 0.07 * 1e18), - inflator_ - ); - - firstTake = true; - - } else firstTake = false; - - // reset taken flag in case auction was settled by take action - _auctionSettleStateReset(borrower_); - } - function _recordSettleBucket( address borrower_, uint256 borrowerCollateralBefore_, @@ -516,7 +489,7 @@ abstract contract BaseHandler is Test { ( , , , , , , - address headAuction, , , + address headAuction, , ) = _pool.auctionInfo(address(0)); printLog("Time = ", block.timestamp); @@ -619,21 +592,21 @@ abstract contract BaseHandler is Test { string memory data; address nextBorrower; uint256 kickTime; - uint256 kickMomp; + uint256 referencePrice; uint256 bondFactor; uint256 bondSize; uint256 neutralPrice; - (,,,,,, nextBorrower,,,) = _pool.auctionInfo(address(0)); + (,,,,,, nextBorrower,,) = _pool.auctionInfo(address(0)); while (nextBorrower != address(0)) { data = string(abi.encodePacked("Borrower ", Strings.toHexString(uint160(nextBorrower), 20), " Auction Details :")); printInNextLine(data); - (, bondFactor, bondSize, kickTime, kickMomp, neutralPrice,, nextBorrower,,) = _pool.auctionInfo(nextBorrower); + (, bondFactor, bondSize, kickTime, referencePrice, neutralPrice,, nextBorrower,) = _pool.auctionInfo(nextBorrower); - printLog("Bond Factor = ", bondFactor); - printLog("Bond Size = ", bondSize); - printLog("Kick Time = ", kickTime); - printLog("Kick Momp = ", kickMomp); - printLog("Neutral Price = ", neutralPrice); + printLog("Bond Factor = ", bondFactor); + printLog("Bond Size = ", bondSize); + printLog("Kick Time = ", kickTime); + printLog("Reference Price = ", referencePrice); + printLog("Neutral Price = ", neutralPrice); } printInNextLine("======================="); } diff --git a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol index 2f5c135b5..e0bba0001 100644 --- a/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol +++ b/tests/forge/invariants/base/handlers/unbounded/UnboundedLiquidationPoolHandler.sol @@ -3,10 +3,12 @@ pragma solidity 0.8.18; import '@openzeppelin/contracts/utils/structs/EnumerableSet.sol'; +import { Math } from '@openzeppelin/contracts/utils/math/Math.sol'; import { Maths } from 'src/libraries/internal/Maths.sol'; import { _priceAt, _indexOf, MIN_PRICE, MAX_PRICE } from 'src/libraries/helpers/PoolHelper.sol'; import { MAX_FENWICK_INDEX } from 'src/libraries/helpers/PoolHelper.sol'; +import { Buckets } from 'src/libraries/internal/Buckets.sol'; import { BaseHandler } from './BaseHandler.sol'; @@ -32,7 +34,6 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { numberOfCalls['UBLiquidationHandler.kickAuction']++; (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); - (uint256 interestRate, ) = _pool.interestRateInfo(); // ensure actor always has the amount to pay for bond _ensureQuoteAmount(_actor, borrowerDebt); @@ -42,9 +43,6 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { try _pool.kick(borrower_, 7388) { numberOfActions['kick']++; - // **RE9**: Reserves increase by 3 months of interest when a loan is kicked - increaseInReserves += Maths.wdiv(Maths.wmul(borrowerDebt, interestRate), 4 * 1e18); - uint256 kickerBondAfter = _getKickerBond(_actor); // **A7**: totalBondEscrowed should increase when auctioned kicked with the difference needed to cover the bond @@ -62,7 +60,6 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { (address maxBorrower, , ) = _pool.loansInfo(); (uint256 borrowerDebt, , ) = _poolInfo.borrowerInfo(address(_pool), maxBorrower); - (uint256 interestRate, ) = _pool.interestRateInfo(); ( , , , uint256 depositBeforeAction, ) = _pool.bucketInfo(bucketIndex_); fenwickDeposits[bucketIndex_] = depositBeforeAction; @@ -76,9 +73,6 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ( , , , uint256 depositAfterAction, ) = _pool.bucketInfo(bucketIndex_); - // **RE9**: Reserves increase by 3 months of interest when a loan is kicked - increaseInReserves += Maths.wdiv(Maths.wmul(borrowerDebt, interestRate), 4 * 1e18); - uint256 kickerBondAfter = _getKickerBond(_actor); // **A7**: totalBondEscrowed should increase when auctioned kicked with the difference needed to cover the bond @@ -130,7 +124,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.takeAuction']++; - (address kicker, , , , , , , , , ) = _pool.auctionInfo(borrower_); + (address kicker, , , , , , , , ) = _pool.auctionInfo(borrower_); ( uint256 borrowerDebtBeforeTake, @@ -147,17 +141,15 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { try _pool.take(borrower_, amount_, taker_, bytes("")) { numberOfActions['take']++; - (uint256 borrowerDebtAfterTake, , ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + (uint256 borrowerDebtAfterTake, uint256 borrowerCollateralAfterTake, ) = _poolInfo.borrowerInfo(address(_pool), borrower_); uint256 totalBondAfterTake = _getKickerBond(kicker); uint256 totalBalanceAfterTake = _quote.balanceOf(address(_pool)) * _pool.quoteTokenScale(); - if (borrowerDebtBeforeTake > borrowerDebtAfterTake) { - // **RE7**: Reserves decrease with debt covered by take. - decreaseInReserves += borrowerDebtBeforeTake - borrowerDebtAfterTake; - } else { - // **RE7**: Reserves increase by take penalty on first take. - increaseInReserves += borrowerDebtAfterTake - borrowerDebtBeforeTake; - } + // **RE7**: Reserves decrease with debt covered by take. + decreaseInReserves += borrowerDebtBeforeTake - borrowerDebtAfterTake; + + // **A8**: kicker reward <= Borrower penalty + borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, auctionPrice) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); if (totalBondBeforeTake > totalBondAfterTake) { // **RE7**: Reserves increase by bond penalty on take. @@ -171,6 +163,9 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // **A7**: Total Bond increase by bond penalty on take. increaseInBonds += totalBondAfterTake - totalBondBeforeTake; + + // **A8**: kicker reward <= Borrower penalty + kickerReward += totalBondAfterTake - totalBondBeforeTake; } // **RE7**: Reserves increase with the quote token paid by taker. @@ -185,16 +180,6 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ); } - if (!alreadyTaken[borrower_]) { - alreadyTaken[borrower_] = true; - - firstTake = true; - - } else firstTake = false; - - // reset taken flag in case auction was settled by take action - _auctionSettleStateReset(borrower_); - } catch (bytes memory err) { _ensurePoolError(err); } @@ -208,12 +193,11 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { ) internal updateLocalStateAndPoolInterest { numberOfCalls['UBLiquidationHandler.bucketTake']++; - (uint256 borrowerT0Debt, , ) = _pool.borrowerInfo(borrower_); + ( uint256 borrowerDebtBeforeTake, uint256 borrowerCollateralBeforeTake,) = _poolInfo.borrowerInfo(address(_pool), borrower_); - (address kicker, , , , , , , , , ) = _pool.auctionInfo(borrower_); + (address kicker, , , , , , , , ) = _pool.auctionInfo(borrower_); ( , , , , uint256 auctionPrice, ) = _poolInfo.auctionStatus(address(_pool), borrower_); uint256 auctionBucketIndex = auctionPrice < MIN_PRICE ? 7388 : (auctionPrice > MAX_PRICE ? 0 : _indexOf(auctionPrice)); - ( , , , uint256 pendingInflator, ) = _poolInfo.poolLoansInfo(address(_pool)); LocalBucketTakeVars memory beforeBucketTakeVars = getBucketTakeInfo(bucketIndex_, kicker, _actor, auctionBucketIndex, borrower_); @@ -225,10 +209,34 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { // **B7**: when awarded bucket take LP : taker deposit time = timestamp of block when award happened if (afterBucketTakeVars.takerLps > beforeBucketTakeVars.takerLps) lenderDepositTime[taker_][bucketIndex_] = block.timestamp; + (uint256 borrowerDebtAfterTake, uint256 borrowerCollateralAfterTake, ) = _poolInfo.borrowerInfo(address(_pool), borrower_); + if (afterBucketTakeVars.kickerLps > beforeBucketTakeVars.kickerLps) { // **B7**: when awarded bucket take LP : kicker deposit time = timestamp of block when award happened lenderDepositTime[kicker][bucketIndex_] = block.timestamp; + + // when kicker and taker are same, kicker Reward = total Reward (lps) - taker Reward (Collateral Price * difference of bucket used and auction price) + if (!depositTake_ && kicker == _actor) { + uint256 totalReward = lpToQuoteToken(afterBucketTakeVars.kickerLps - beforeBucketTakeVars.kickerLps, bucketIndex_); + uint256 takerReward = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, _priceAt(bucketIndex_) - auctionPrice); + + // **A8**: kicker reward <= Borrower penalty + kickerReward = totalReward - takerReward; + } else { + // **A8**: kicker reward <= Borrower penalty + kickerReward = lpToQuoteToken(afterBucketTakeVars.kickerLps - beforeBucketTakeVars.kickerLps, bucketIndex_); + } + } + + // **A8**: kicker reward <= Borrower penalty + if (depositTake_) { + borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, _priceAt(bucketIndex_)) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); + } else { + borrowerPenalty = Maths.wmul(borrowerCollateralBeforeTake - borrowerCollateralAfterTake, auctionPrice) - (borrowerDebtBeforeTake - borrowerDebtAfterTake); } + + // reserves are increased by take penalty of borrower (Deposit used from bucket - Borrower debt reduced) + increaseInReserves += borrowerPenalty; if (beforeBucketTakeVars.kickerBond > afterBucketTakeVars.kickerBond) { // **RE7**: Reserves increase by bond penalty on take. @@ -242,7 +250,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { exchangeRateShouldNotChange[bucketIndex_] = true; // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower_); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); if (kickTime == 0 && _pool.poolType() == 1) { buckets.add(auctionBucketIndex); if (beforeBucketTakeVars.borrowerLps < afterBucketTakeVars.borrowerLps) { @@ -253,8 +261,6 @@ 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, pendingInflator); - } catch (bytes memory err) { _ensurePoolError(err); } @@ -358,7 +364,7 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { } } // **CT2**: Keep track of bucketIndex when borrower is removed from auction to check collateral added into that bucket - (, , , uint256 kickTime, , , , , , ) = _pool.auctionInfo(borrower_); + (, , , uint256 kickTime, , , , , ) = _pool.auctionInfo(borrower_); if (kickTime == 0 && collateral % 1e18 != 0 && _pool.poolType() == 1) { buckets.add(7388); lenderDepositTime[borrower_][7388] = block.timestamp; @@ -376,4 +382,18 @@ abstract contract UnboundedLiquidationPoolHandler is BaseHandler { (bucketTakeVars.borrowerLps, ) = _pool.lenderInfo(auctionBucketIndex_, borrower_); } + // Helper function to calculate quote tokens from lps in a bucket irrespective of deposit available. + function lpToQuoteToken(uint256 lps_, uint256 bucketIndex_) internal view returns(uint256 quoteTokens_) { + (uint256 bucketLP, uint256 bucketCollateral , , uint256 bucketDeposit, ) = _pool.bucketInfo(bucketIndex_); + + quoteTokens_ = Buckets.lpToQuoteTokens( + bucketCollateral, + bucketLP, + bucketDeposit, + lps_, + _priceAt(bucketIndex_), + Math.Rounding.Down + ); + } + } diff --git a/tests/forge/invariants/interfaces/IBaseHandler.sol b/tests/forge/invariants/interfaces/IBaseHandler.sol index 9f3d4c658..4f8e365bb 100644 --- a/tests/forge/invariants/interfaces/IBaseHandler.sol +++ b/tests/forge/invariants/interfaces/IBaseHandler.sol @@ -27,14 +27,14 @@ interface IBaseHandler { function previousReserves() external view returns(uint256); function increaseInReserves() external view returns(uint256); function decreaseInReserves() external view returns(uint256); + + function borrowerPenalty() external view returns(uint256); + function kickerReward() external view returns(uint256); function previousTotalBonds() external view returns(uint256); function increaseInBonds() external view returns(uint256); function decreaseInBonds() external view returns(uint256); - - function firstTake() external view returns(bool); - function alreadyTaken(address) external view returns(bool); - + function lenderDepositTime(address lender, uint256 bucketIndex) external view returns(uint256); function getBuckets() external view returns(uint256[] memory); diff --git a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol index 1e9db81d5..95e2220f2 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestLiquidationERC20Pool.t.sol @@ -512,6 +512,43 @@ contract RegressionTestLiquidationERC20Pool is LiquidationERC20PoolInvariants { invariant_auction(); } + + function test_regression_failure_A8_1() external { + _liquidationERC20PoolHandler.addCollateral(12589, 3027, 11546, 12397); + _liquidationERC20PoolHandler.kickAuction(5580373056879638310723579957702553697154185800606952317169116065283, 673628694582737773359188839547197377524455313247730645, 3238434615599720181679028733329070536752833214808374986356341951234757433, 1); + _liquidationERC20PoolHandler.bucketTake(3483959044, 7480, false, 6128, 931366652); + + invariant_auction(); + } + + function test_regression_failure_A8_2() external { + _liquidationERC20PoolHandler.lenderKickAuction(32707, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _liquidationERC20PoolHandler.stampLoan(1, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _liquidationERC20PoolHandler.takeAuction(71607203288150432617752586299752325700809962217893299105344626635399670961037, 1407433933, 201963073509, 0); + + invariant_auction(); + } + + function test_regression_failure_A8_3() external { + _liquidationERC20PoolHandler.takeAuction(26177409091395859259214754727, 2228, 1235, 1028254131108805440); + invariant_auction(); + } + + function test_regression_failure_A8_4() external { + _liquidationERC20PoolHandler.withdrawBonds(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1106571879666471992422126415932998667, 1); + _liquidationERC20PoolHandler.takeAuction(1, 4357181303565761581481420624418625341908084, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1); + _liquidationERC20PoolHandler.pullCollateral(1649091324340025315995186327618864160776161241, 2181528126871, 1965741113938939463317126670739876832461939774927378255531235325395); + _liquidationERC20PoolHandler.drawDebt(68161, 14061, 973436887473582363402221359893); + _liquidationERC20PoolHandler.transferLps(115792089237316195423570985008687907853269984665640564039457584007913129639935, 213151482981712477628530516228567956560745791366283812631912364452304, 3, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _liquidationERC20PoolHandler.drawDebt(0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 1); + _liquidationERC20PoolHandler.takeAuction(2485, 5272, 1031840912, 18777070038542195298214975226471); + _liquidationERC20PoolHandler.removeQuoteToken(115792089237316195423570985008687907853269984665640564039457584007913129639933, 0, 25856141553490006665960451029957189196503921259365569544991571288943654, 265387129941213675242); + _liquidationERC20PoolHandler.removeCollateral(683263830118317396029527361129696006836175820138018328290112399795517091, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1352261258086370231859932358250510979577984135169417106550, 45451622258719725310627650697080694167655914828437); + _liquidationERC20PoolHandler.moveQuoteToken(192523996731194721095627, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 2270685815936828125225767305289, 516849470254903023103, 4286673537243475793235534545886); + _liquidationERC20PoolHandler.addQuoteToken(128222088341180102397575833404514544302942993744794712, 108603807113347866118, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _liquidationERC20PoolHandler.bucketTake(437995719506453073927178171450999258981540842, 1, false, 10505745254535225521787303755428772101316447294490000685852, 1); + invariant_auction(); + } } contract RegressionTestLiquidationWith10BucketsERC20Pool is LiquidationERC20PoolInvariants { diff --git a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol index 10c0cf95e..7f3200454 100644 --- a/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol +++ b/tests/forge/regression/ERC20Pool/RegressionTestReservesERC20Pool.t.sol @@ -1055,6 +1055,24 @@ contract RegressionTestReserveERC20Pool is ReserveERC20PoolInvariants { invariant_reserves(); } + function test_regression_rw_reserves_failure_2() external { + _reserveERC20PoolHandler.pullCollateral(467812928760450922852130520517, 0, 8875981380220900699974754772374433563827538899982250783154248); + _reserveERC20PoolHandler.stampLoan(40175363097800960342714213669375739863439895429878092142484989154449, 409061); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 0, 0); + _reserveERC20PoolHandler.lenderKickAuction(6739921392061593446919, 6665134088409172498708598665753565015506650372591945929089778543248096029475, 28995118252860325273433400612247); + _reserveERC20PoolHandler.bucketTake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639933, false, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3); + invariant_reserves(); + } + + function test_regression_rw_reserves_failure_3() external { + _reserveERC20PoolHandler.pullCollateral(689310072489575950194610941862218313559051158375867529942715794, 99036455857404432, 6869705889740062461982024); + _reserveERC20PoolHandler.settleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 6742192, 213010309037469, 559253357385477068169816814589744715662918367352352023924236308825157221); + _reserveERC20PoolHandler.bucketTake(1016146854898171779840580985646, 702533447184886148876700400367357570569398118557415200792466345280405503, false, 529372371950495425561109650, 2068665645832452894016891); + _reserveERC20PoolHandler.transferLps(22896729871095067, 33099474, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 3, 0); + _reserveERC20PoolHandler.addCollateral(1243, 20194462732101988290791998389, 1689661434, 2016395110395212283077154); + _reserveERC20PoolHandler.takeAuction(1053065795079038070957917, 7983715169874533544149183933, 10149841974673137113234915054, 14423198); + } + } contract RegressionTestReserveWith10BucketsERC20Pool is ReserveERC20PoolInvariants { diff --git a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol index 9aaa9abd1..3daac912b 100644 --- a/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol +++ b/tests/forge/regression/ERC721Pool/RegressionTestReservesERC721Pool.t.sol @@ -1265,10 +1265,9 @@ contract RegressionTestReserveEvmRevertERC721Pool is ReserveERC721PoolInvariants /* Test failed because neutral price doesn't fit in uint96 type. pool inflator 1788146574311565067709708 - borrower t0NP 1226147737092460887612598 + borrower npTpRatio 1226147737092460887612598 borrower debt 4502726079310150309955771136797 borrower collateral 87000000000000000000 - momp 6822206200573474997951871 bond bondSize 45027260793101503099557711368 bond factor 10000000000000000 neutral price 2192531875681761460142783972780 diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol b/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol index 1784d5640..f538c0792 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestBankBankruptcyERC20PoolRewards.sol @@ -36,5 +36,196 @@ contract RegressionTestBankBankruptcyERC20PoolRewards is BucketBankruptcyERC20Po invariant_positions_PM1_PM2_PM3(); } + + function test_regression_interest_accumalation_overflow() external { + _bucketBankruptcyerc20poolrewardsHandler.stake(320307692307692307841, 2490, 10917, 403196809217289663458043223580906563641609617294); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(15059177663891191985498469564581, 21691241494814563657, 5959198137984416944871985040941211962546971878394061014854717427126670802); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 306748590411024027068452057, 3); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 3, 3, 44869774749435413944328478986895177316804030, 2); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 667409171832157313382210046675580725011953, 170966693897056629150807196294457349572402758607401923355019500107511084513); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19549319890719740959827156450505379259184673736260904583824030491, 16629388526339); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1, 57, 2126726397172127776919, 3); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(10662442004167, 0, 5497097760623451146595, 3162190482019759261701358441242229); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4633); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(195082403288206510116943243208164172979846145506483861331524728636984, 5999490491512003998567204139527071137962581199636349206, 1); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(193, 115638053, 82905768405815550325167864157103591796198207319836507298376269364238808467864); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 728230189013838280072632353261014942101509879986, 1074852977686923754516502207503688995019457654331626079784, 8647989100256796072321456855285912878676340053147534437521304860653); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3941357502157973923804, 2, 806977082765068646659096738618743289712629038, 95470398010431964952450128551272930452522452449699886025877059807238, 1); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36183411359542968180819498843191329944675962195184522815400173109497640044908, 5526, 3966754565367876855970249316229461606728002012105551523079085776320493, 12000000000000000000786344314428468140209160332, 1514); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19347515940517406236500101946818541192254229344198927883872669126, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1236588951273351231845418839930179263983011495754, 38238240862444672488745854665, 105710195453976313965439090442863258002796095759252242871256962165021905861650, 447301751254033913445893214690834296930546521452); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(46514948025651225960345695072605648432715982671974779016300427285754698287368, 3286, 3218715805466846511984533600393324923883748231); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3950340310148269005, 5673061940259815795875572950552217903, 0); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(201, 16652, 456263400021039761424850168808020383038614345114, 185177884615384615469); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(844186718371423468438148597031199325852724093549, 8971, 1238939858024599757491003772585973626666495470478); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(14560967560043099906703147047009467303604341499091340414611613631940255690293, 1721, 1330742788975674320956191865797062835971931496250, 8012); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(610999999999999999999, 18990, 2964); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 2202462407395028941916385359630457052998061369773792102517381208520162, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(259629493051510264, 23614305666380977416230669400318875317806232271123308657121989217833132243233, 2497, 27835018298679073652989722292632508325056543016077421626954570959368347669748, 1606); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4650754146616051773693243800451532316887707892427, 2674637045933147252314476540226577815868397623, 1637859); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(32610811746778589434426055746005034344393175264036753585460265204263347653842, 16005, 105710195453976313965439090442863258002796095759252242871256962165021905861709); + _bucketBankruptcyerc20poolrewardsHandler.stake(27241022853949367504447088193, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 128000899661578863761148718566665636525956915466064429, 1336719368342255666688); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(41124169807925345164795, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1313063028941469943130200174691186594877948408346228981); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2166715437819344420775617703353734409787244706488647403995037751254234644362, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7532212); + _bucketBankruptcyerc20poolrewardsHandler.stake(14552177917818508405730171864883921324, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 84190559757713757784279975706433133519542327009581632460886117089373); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(37747710333430245980940452738832839721522435977096927851794211126014890045043, 105710195453976313965439090442863258002796095759252242871256962165021905861568, 4881, 3966754565367876869122194268884518216957992861677661334548387666061342); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(159533269946056829911817908703969087399676830547153393250667762079770747, 120375821746749532031, 553664897755275959629); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2318, 371788003, 105710195453976313965439090442863258002796095759252242871256962165021905861824, 57957110594642022010328291066590663082489422500, 378363461538461538635); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 3108493389566117837926341948558162909763275523381432406469124236768340906924, 32229393624772079505360513009288184415901939, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2836923789, 82757687462225415771947516030365134680378685014411112583900985134363263813950, 17992734256423583958967370161492784553176489409); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2, 1599018514952142375998297880); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(55687575924400638, 727999999999999999999, 15644); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2673041966562049323144905243406346442490148198615, 1285995676085316511341291864375645429377044076357986037173062379358204); + _bucketBankruptcyerc20poolrewardsHandler.stake(27836410677470140405893559165022839553284246026566794216457, 26100442293941930306313869947915225019447736484493936778052910988, 1100121169003966414850619669523011925033070895519974812092, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(751722115384615384963, 87573722621992251438460370142942144054516549109457068516979097052450755011736, 3966754565367876854520184869943068556144348793969914759895680118784807, 27984893582647316189577999054762964794852908603917399358854612125647292485578); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(15048, 20980142891430666358441099170678931589412918730, 26229794335232538522551515320652626439652093573752750988891734989405951307592); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1623645501211, 581895706741971570416382, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(16294, 37775847772112785254257, 20408); + _bucketBankruptcyerc20poolrewardsHandler.stake(233076476716696715, 19720626000000000000021835, 14786, 880); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(91, 48915418688551403693013933582174377748045,1, 0); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(8520254760456735866522434792660074894149362458110124278618188561008801076487, 4508341423132101367979353817313302855733981519104609141429822885854284517273, 1045732366170946687500335725634396288218029048535); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(5250764587436405674967118092556206155749365731, 141015099610895938496827107324000508240276523703380995216176939659, 0); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.stake(75715332515, 20249, 139492422255, 105710195453976313965439090442863258002796095759252242871256962165021905861575); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(5433, 21391, 754284941459726849420512743397530252182784738229, 23905); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(192677, 4773, 2683, 940037522744286018063446172177794105409762773472); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1423000347840435497235966844164533984931800601575, 288276923076923077057, 17572, 4256931000379123634785033661970275022184774617022768398310874942392452426, 139403335757771137); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2, 2587348281013517652545024121589073614070441106624530521348844741, 519685398); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(84919864282925853877573619845135091960602695946894030665170367426270992811938, 15050648105662257143935681434472465116789984907642743379717753234643085664126, 22213, 16413, 175589814974774645221481909980815519088940506341); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3966754565367876881842889880294569887040448346346191805828869027190062, 4571, 5227); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(907000000000000000000, 2868991328, 99389371209329274803747059355072193342651880195070161537527945916651123372097); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2784308567599248162087449504, 3589, 476777860815159664263285898208782485328810582592); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(0, 93446225603511499598845951183108384660272702, 2024254557338330727781790737102999642155730612363585, 191889378792020151); + _bucketBankruptcyerc20poolrewardsHandler.stake(36183411359542968180819498843191329944675962195184522815400173109497640044984, 50146794086275195190991942805708459010074680271220970599602693206755183387706, 2065, 32789382558206698454860319624949663673430750389618486004860947532855016388844); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3, 29811238, 69968346427577179605244273168972327088469976079256197056454, 1497742154395667232899123570108019263133908353144179120765); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(3, 0, 87185381081925833627461609395751279524164897425148697297070669197775260); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(17279999, 3966754565367876867473138000603430830185306546546874883932992520117722, 776481524764705302352605934280580955971144914555, 962787287); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(19060901126391672628476228072540859898, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(26920601521589162671147619654088067061266745140905760588388649977853848299620, 1875, 27835018298679073652989722292632508325056543016077421626954570959368347669985); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(553591494574561111154252750468593088203, 26003311767849788325482998126201562168467079599, 3503171015763161693096394522251351236934013944546); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36822330623891827054618617680243779734013976879104614005453233537599913890987, 2030, 351827466436279533, 36183411359542968180819498843191329944675962195184522815400173109497640045092, 431); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(4307769405459937793464500814388987723043870007160919438680139924065536869, 20774, 20905556733966496908705142171609168952816592958194260630754626678628699156025, 112677305303603608793464000990919617579761525091244043308691041092632466067909, 3966754565367876866027363177544639294642486780494516334079839883146086); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(5612107944, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3758652); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3, 13063704682547015731607989179567642095598985357156794100666758119236, 1663082272433979660889799306293339760568971320019141218266316592279716982939); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(698213858938870538487, 14890451379766624461267359941375, 48557935465010072094981800005966219309615168007618540929696328537074564550805); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(355000000000000000000, 49046620449355538574108822723048473721226797556007972061207479861126558122006, 13060); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 1); + _bucketBankruptcyerc20poolrewardsHandler.stake(320307692307692307841, 2490, 10917, 403196809217289663458043223580906563641609617294); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(15059177663891191985498469564581, 21691241494814563657, 5959198137984416944871985040941211962546971878394061014854717427126670802); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 2, 306748590411024027068452057, 3); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 3, 3, 44869774749435413944328478986895177316804030, 2); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639933, 667409171832157313382210046675580725011953, 170966693897056629150807196294457349572402758607401923355019500107511084513); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 19549319890719740959827156450505379259184673736260904583824030491, 16629388526339); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1, 57, 2126726397172127776919, 3); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(10662442004167, 0, 5497097760623451146595, 3162190482019759261701358441242229); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 4633); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(195082403288206510116943243208164172979846145506483861331524728636984, 5999490491512003998567204139527071137962581199636349206, 1); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(193, 115638053, 82905768405815550325167864157103591796198207319836507298376269364238808467864); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639933, 728230189013838280072632353261014942101509879986, 1074852977686923754516502207503688995019457654331626079784, 8647989100256796072321456855285912878676340053147534437521304860653); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(3941357502157973923804, 2, 806977082765068646659096738618743289712629038, 95470398010431964952450128551272930452522452449699886025877059807238, 1); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36183411359542968180819498843191329944675962195184522815400173109497640044908, 5526, 3966754565367876855970249316229461606728002012105551523079085776320493, 12000000000000000000786344314428468140209160332, 1514); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 19347515940517406236500101946818541192254229344198927883872669126, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(1236588951273351231845418839930179263983011495754, 38238240862444672488745854665, 105710195453976313965439090442863258002796095759252242871256962165021905861650, 447301751254033913445893214690834296930546521452); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(46514948025651225960345695072605648432715982671974779016300427285754698287368, 3286, 3218715805466846511984533600393324923883748231); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3950340310148269005, 5673061940259815795875572950552217903, 0); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(201, 16652, 456263400021039761424850168808020383038614345114, 185177884615384615469); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(844186718371423468438148597031199325852724093549, 8971, 1238939858024599757491003772585973626666495470478); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(14560967560043099906703147047009467303604341499091340414611613631940255690293, 1721, 1330742788975674320956191865797062835971931496250, 8012); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(610999999999999999999, 18990, 2964); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 2202462407395028941916385359630457052998061369773792102517381208520162, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(259629493051510264, 23614305666380977416230669400318875317806232271123308657121989217833132243233, 2497, 27835018298679073652989722292632508325056543016077421626954570959368347669748, 1606); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639934, 4650754146616051773693243800451532316887707892427, 2674637045933147252314476540226577815868397623, 1637859); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(32610811746778589434426055746005034344393175264036753585460265204263347653842, 16005, 105710195453976313965439090442863258002796095759252242871256962165021905861709); + _bucketBankruptcyerc20poolrewardsHandler.stake(27241022853949367504447088193, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 128000899661578863761148718566665636525956915466064429, 1336719368342255666688); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(41124169807925345164795, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1313063028941469943130200174691186594877948408346228981); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2166715437819344420775617703353734409787244706488647403995037751254234644362, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 7532212); + _bucketBankruptcyerc20poolrewardsHandler.stake(14552177917818508405730171864883921324, 0, 115792089237316195423570985008687907853269984665640564039457584007913129639934, 84190559757713757784279975706433133519542327009581632460886117089373); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(37747710333430245980940452738832839721522435977096927851794211126014890045043, 105710195453976313965439090442863258002796095759252242871256962165021905861568, 4881, 3966754565367876869122194268884518216957992861677661334548387666061342); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(159533269946056829911817908703969087399676830547153393250667762079770747, 120375821746749532031, 553664897755275959629); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(2318, 371788003, 105710195453976313965439090442863258002796095759252242871256962165021905861824, 57957110594642022010328291066590663082489422500, 378363461538461538635); + _bucketBankruptcyerc20poolrewardsHandler.stake(1, 3108493389566117837926341948558162909763275523381432406469124236768340906924, 32229393624772079505360513009288184415901939, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2836923789, 82757687462225415771947516030365134680378685014411112583900985134363263813950, 17992734256423583958967370161492784553176489409); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2, 1599018514952142375998297880); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(55687575924400638, 727999999999999999999, 15644); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(1, 2673041966562049323144905243406346442490148198615, 1285995676085316511341291864375645429377044076357986037173062379358204); + _bucketBankruptcyerc20poolrewardsHandler.stake(27836410677470140405893559165022839553284246026566794216457, 26100442293941930306313869947915225019447736484493936778052910988, 1100121169003966414850619669523011925033070895519974812092, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(751722115384615384963, 87573722621992251438460370142942144054516549109457068516979097052450755011736, 3966754565367876854520184869943068556144348793969914759895680118784807, 27984893582647316189577999054762964794852908603917399358854612125647292485578); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(15048, 20980142891430666358441099170678931589412918730, 26229794335232538522551515320652626439652093573752750988891734989405951307592); + _bucketBankruptcyerc20poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 1623645501211, 581895706741971570416382, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(16294, 37775847772112785254257, 20408); + _bucketBankruptcyerc20poolrewardsHandler.stake(233076476716696715, 19720626000000000000021835, 14786, 880); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(91, 48915418688551403693013933582174377748045,1, 0); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(8520254760456735866522434792660074894149362458110124278618188561008801076487, 4508341423132101367979353817313302855733981519104609141429822885854284517273, 1045732366170946687500335725634396288218029048535); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(5250764587436405674967118092556206155749365731, 141015099610895938496827107324000508240276523703380995216176939659, 0); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.stake(75715332515, 20249, 139492422255, 105710195453976313965439090442863258002796095759252242871256962165021905861575); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(5433, 21391, 754284941459726849420512743397530252182784738229, 23905); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(192677, 4773, 2683, 940037522744286018063446172177794105409762773472); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(1423000347840435497235966844164533984931800601575, 288276923076923077057, 17572, 4256931000379123634785033661970275022184774617022768398310874942392452426, 139403335757771137); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(2, 2587348281013517652545024121589073614070441106624530521348844741, 519685398); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(84919864282925853877573619845135091960602695946894030665170367426270992811938, 15050648105662257143935681434472465116789984907642743379717753234643085664126, 22213, 16413, 175589814974774645221481909980815519088940506341); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3966754565367876881842889880294569887040448346346191805828869027190062, 4571, 5227); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(907000000000000000000, 2868991328, 99389371209329274803747059355072193342651880195070161537527945916651123372097); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(2784308567599248162087449504, 3589, 476777860815159664263285898208782485328810582592); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(0, 93446225603511499598845951183108384660272702, 2024254557338330727781790737102999642155730612363585, 191889378792020151); + _bucketBankruptcyerc20poolrewardsHandler.stake(36183411359542968180819498843191329944675962195184522815400173109497640044984, 50146794086275195190991942805708459010074680271220970599602693206755183387706, 2065, 32789382558206698454860319624949663673430750389618486004860947532855016388844); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(3, 29811238, 69968346427577179605244273168972327088469976079256197056454, 1497742154395667232899123570108019263133908353144179120765); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(3, 0, 87185381081925833627461609395751279524164897425148697297070669197775260); + _bucketBankruptcyerc20poolrewardsHandler.moveQuoteTokenToLowerBucket(17279999, 3966754565367876867473138000603430830185306546546874883932992520117722, 776481524764705302352605934280580955971144914555, 962787287); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(19060901126391672628476228072540859898, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(26920601521589162671147619654088067061266745140905760588388649977853848299620, 1875, 27835018298679073652989722292632508325056543016077421626954570959368347669985); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(553591494574561111154252750468593088203, 26003311767849788325482998126201562168467079599, 3503171015763161693096394522251351236934013944546); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(36822330623891827054618617680243779734013976879104614005453233537599913890987, 2030, 351827466436279533, 36183411359542968180819498843191329944675962195184522815400173109497640045092, 431); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(4307769405459937793464500814388987723043870007160919438680139924065536869, 20774, 20905556733966496908705142171609168952816592958194260630754626678628699156025, 112677305303603608793464000990919617579761525091244043308691041092632466067909, 3966754565367876866027363177544639294642486780494516334079839883146086); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(5612107944, 2, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 3, 3758652); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(3, 13063704682547015731607989179567642095598985357156794100666758119236, 1663082272433979660889799306293339760568971320019141218266316592279716982939); + _bucketBankruptcyerc20poolrewardsHandler.failed(); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(698213858938870538487, 14890451379766624461267359941375, 48557935465010072094981800005966219309615168007618540929696328537074564550805); + _bucketBankruptcyerc20poolrewardsHandler.moveStakedLiquidity(0, 0, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _bucketBankruptcyerc20poolrewardsHandler.lenderKickAuction(355000000000000000000, 49046620449355538574108822723048473721226797556007972061207479861126558122006, 13060); + _bucketBankruptcyerc20poolrewardsHandler.takeOrSettleAuction(115792089237316195423570985008687907853269984665640564039457584007913129639932, 0, 1); + } } diff --git a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol index 6274ecf03..be7a4f29d 100644 --- a/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol +++ b/tests/forge/regression/PositionAndRewards/RegressionTestERC721PoolRewardsManager.t.sol @@ -28,4 +28,49 @@ contract RegressionTestERC721PoolRewardsManager is ERC721PoolRewardsInvariants { _erc721poolrewardsHandler.takeAuction(148878580729371224992950595085688885987, 52018, 3863548495672151022795311051855, 1224829895266858456828928840866630331525272263026827096173292323394330361); _erc721poolrewardsHandler.claimRewards(339802229099465406190265268924204103831957337149846935, 1, 2641, 1084164255431, 3); } + + // issue in _preDrawDebt when borrower is in auction and tried to repayDebt and pull collateral, and check all debt is repaid. + // fix: return _preDrawDebt when borrower is in auction. + function test_regression_RW1_RW2() external { + _erc721poolrewardsHandler.stampLoan(3097, 99133); + _erc721poolrewardsHandler.kickAuction(31354931781638678607228669297131712859126084785867252355217498662940140921971, 1058, 11754, 12849); + _erc721poolrewardsHandler.takeReserves(115792089237316195423570985008687907853269984665640564039457584007913129639934, 33731052920955697617409005891040394080922214120333458396693390120882665651,1720188968454217720935353179268130063921306460048647700482); + _erc721poolrewardsHandler.pledgeCollateral(1757924641683012822782278927906643733124399771812893540782608051864, 146672722799504441441256193696, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc721poolrewardsHandler.mint(12138, 7557); + _erc721poolrewardsHandler.addQuoteToken(13384168457563664686794224199997478429074004894884217417626102307452469562, 399627080535825658763553985697630307858997509589356607284924675010621,15021260382761, 2149748001246586660242584607929003545953); + _erc721poolrewardsHandler.mint(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639934); + _erc721poolrewardsHandler.settleAuction(1735287903719074628042764789671363295, 3, 23993967057076184216275526949268, 4106476); + _erc721poolrewardsHandler.drawDebt(77622297016072599381603815616169164633892036937355547901, 10261965, 115792089237316195423570985008687907853269984665640564039457584007913129639935); + _erc721poolrewardsHandler.stampLoan(115792089237316195423570985008687907853269984665640564039457584007913129639934, 15628038388); + _erc721poolrewardsHandler.redeemPositions(22801150734449629332972378409816953484259939113298558, 563212509531357473751756674, 236487328781308137707, 114005983); + _erc721poolrewardsHandler.unstake(115792089237316195423570985008687907853269984665640564039457584007913129639932, 209638772009545859528, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1852809668170365878555741120106, 8537278537524035545583862060040379261058217549); + _erc721poolrewardsHandler.emergencyUnstake(5762, 4833, 23085, 23329, 10160); + _erc721poolrewardsHandler.lenderKickAuction(38567162678744729883825485304193880641, 1436018647533119237198979383384378157898748977466826312550, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _erc721poolrewardsHandler.mergeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639935, 40700253390048296022217103829550); + _erc721poolrewardsHandler.stake(115792089237316195423570985008687907853269984665640564039457584007913129639935, 13666289603396405051, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 105); + _erc721poolrewardsHandler.takeAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 1, 28190); + _erc721poolrewardsHandler.kickReserveAuction(1886, 65412); + _erc721poolrewardsHandler.takeReserves(7740, 4448, 3713); + _erc721poolrewardsHandler.pullCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639933, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _erc721poolrewardsHandler.repayDebt(110349606679412691172957834289542550319383271247755660854362242977991410020198, 6715, 4023); + _erc721poolrewardsHandler.mergeCollateral(0, 59747238056737534481206780725787707244999); + _erc721poolrewardsHandler.emergencyUnstake(0, 115792089237316195423570985008687907853269984665640564039457584007913129639932, 51729897709415, 23006395802429129288475054106, 1); + _erc721poolrewardsHandler.removeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639934, 1, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _erc721poolrewardsHandler.bucketTake(17736, 12855, false, 3289, 1123); + _erc721poolrewardsHandler.pledgeCollateral(115792089237316195423570985008687907853269984665640564039457584007913129639932, 115792089237316195423570985008687907853269984665640564039457584007913129639933, 1); + _erc721poolrewardsHandler.kickAuction(115792089237316195423570985008687907853269984665640564039457584007913129639935, 115792089237316195423570985008687907853269984665640564039457584007913129639935, 1347071909069112433439054986249189622, 115792089237316195423570985008687907853269984665640564039457584007913129639933); + _erc721poolrewardsHandler.lenderKickAuction(3, 1, 37246476355849); + _erc721poolrewardsHandler.failed(); + _erc721poolrewardsHandler.burn(143, 1108823922,48884, 5811); + _erc721poolrewardsHandler.memorializePositions(7222, 6164, 14919869490272923636577259832825010352693700464430964509126832818182799243080, 26284); + _erc721poolrewardsHandler.takeAuction(1110452889, 6058, 3016184996, 12922961544511690602711642372921216522520321844072048399134131509470247863750); + _erc721poolrewardsHandler.mergeCollateral(5967, 3326); + _erc721poolrewardsHandler.bucketTake(1, 1714375381109265815411514882158434660321706149315054174553444757, true, 2, 2); + _erc721poolrewardsHandler.unstake(3, 28372160064709526166669973508287087795611038423150717571367, 54636530394327258458081903942670329383, 3, 115792089237316195423570985008687907853269984665640564039457584007913129639932); + _erc721poolrewardsHandler.updateExchangeRate(36456, 17137, 1560275421, 17005); + _erc721poolrewardsHandler.stampLoan(3352512690189013572483301109122336596527121909930416357921778362671464454374, 5992531996617362563537972); + _erc721poolrewardsHandler.pledgeCollateral(174922928606654802364580162287611825, 4, 56551201532130900086); + _erc721poolrewardsHandler.emergencyUnstake(2247288760962719055600016280767970105290, 0, 2, 11596164422216101546875614140375574915418729056483, 61337865928763100451538345828); + _erc721poolrewardsHandler.emergencyUnstake(1023240505530161435702165, 18496758270674070880, 45978599603359075781444831263900707496437331655382222738127705004512629605795, 110349606679412691172957834289542550319383271247755660854362242977991410020756, 4078); + } } diff --git a/tests/forge/unit/Auctions.t.sol b/tests/forge/unit/Auctions.t.sol index 9ef451527..68e51296e 100644 --- a/tests/forge/unit/Auctions.t.sol +++ b/tests/forge/unit/Auctions.t.sol @@ -29,28 +29,44 @@ contract AuctionsTest is DSTestPlus { function testAuctionPrice() external { skip(6238); - uint256 momp = 8_678.5 * 1e18; - uint256 neutralPrice = 8_600.0 * 1e18; - uint256 kickTime = block.timestamp; + uint256 referencePrice = 8_678.5 * 1e18; + uint256 kickTime = block.timestamp; - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 277_712 * 1e18); - skip(1444); // price should not change in the first hour - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 277_712 * 1e18); - - skip(5756); // 2 hours - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 138_856 * 1e18); - skip(2394); // 2 hours, 39 minutes, 54 seconds - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 87_574.910740335995562528 * 1e18); - skip(2586); // 3 hours, 23 minutes - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 53_227.960156860514117568 * 1e18); - skip(3); // 3 seconds later - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 53_197.223359425583052544 * 1e18); - skip(20153); // 8 hours, 35 minutes, 53 seconds - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 1_098.26293050754894624 * 1e18); - skip(97264); // 36 hours - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 0.00000808248283696 * 1e18); - skip(129600); // 72 hours - assertEq(_auctionPrice(momp, neutralPrice, kickTime), 0); + assertEq(_auctionPrice(referencePrice, kickTime), 2_221_696 * 1e18); + skip(44 minutes); // 44 minutes + assertEq(_auctionPrice(referencePrice, kickTime), 483_524.676068186452113664 * 1e18); + skip(16 minutes); // 1 hour + assertEq(_auctionPrice(referencePrice, kickTime), 277_712 * 1e18); + skip(99 minutes); // 2 hours, 39 minutes + assertEq(_auctionPrice(referencePrice, kickTime), 27_712.130183984744559172 * 1e18); + skip(3); // 3 seconds later + assertEq(_auctionPrice(referencePrice, kickTime), 27_704.127762591858494776 * 1e18); + skip(57 + 80 minutes); // 4 hours + assertEq(_auctionPrice(referencePrice, kickTime), 17_357 * 1e18); + skip(1 hours); // 5 hours + assertEq(_auctionPrice(referencePrice, kickTime), 12_273.252401054905374068 * 1e18); + skip(1 hours); // 6 hours + assertEq(_auctionPrice(referencePrice, kickTime), 8_678.5 * 1e18); + skip(2 hours); // 8 hours + assertEq(_auctionPrice(referencePrice, kickTime), 4_339.25 * 1e18); + skip(2 hours); // 10 hours + assertEq(_auctionPrice(referencePrice, kickTime), 2_169.625 * 1e18); + skip(1 hours); // 11 hours + assertEq(_auctionPrice(referencePrice, kickTime), 1_534.15655013186316308 * 1e18); + skip(1 hours); // 12 hours + assertEq(_auctionPrice(referencePrice, kickTime), 1084.8125 * 1e18); + skip(1 hours); // 13 hours + assertEq(_auctionPrice(referencePrice, kickTime), 767.07827506593158154 * 1e18); + skip(2 hours); // 15 hours + assertEq(_auctionPrice(referencePrice, kickTime), 271.203125 * 1e18); + skip(3 hours); // 18 hours + assertEq(_auctionPrice(referencePrice, kickTime), 33.900390625 * 1e18); + skip(6 hours); // 24 hours + assertEq(_auctionPrice(referencePrice, kickTime), 0.529693603515625 * 1e18); + skip(12 hours); // 36 hours + assertEq(_auctionPrice(referencePrice, kickTime), 0.000129319727420501 * 1e18); + skip(36 hours); // 72 hours + assertEq(_auctionPrice(referencePrice, kickTime), 0.000000000000001627 * 1e18); } /** diff --git a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol index 076816f82..26da8704a 100644 --- a/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol +++ b/tests/forge/unit/ERC20Pool/ERC20DSTestPlus.sol @@ -34,6 +34,7 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { address borrower ) internal { changePrank(borrower); + uint256 borrowerT0debt; uint256 borrowerCollateral; (borrowerT0debt, borrowerCollateral, ) = _pool.borrowerInfo(borrower); @@ -120,6 +121,32 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { assertEq(collateralBalanceNormalized, bucketCollateral + pledgedCollateral); } + function redeemBankruptBucketCollateral( + EnumerableSet.UintSet storage buckets, + address lender + ) internal { + // skip some time to pass bucket bankruptcy block + skip(1 hours); + + for (uint256 i = 0; i < buckets.length(); i++) { + uint256 bucketIndex = buckets.at(i); + (, uint256 quoteTokens, uint256 collateral, uint256 bucketLps, ,) = _poolUtils.bucketInfo(address(_pool), bucketIndex); + if (bucketLps == 0 && quoteTokens == 0 && collateral != 0) { + changePrank(lender); + + // mint and approve collateral tokens + deal(_pool.collateralAddress(), lender, 1 * 1e18); + IERC20(_pool.collateralAddress()).approve(address(_pool), type(uint256).max); + + // add collateral to get some lps. + ERC20Pool(address(_pool)).addCollateral(1 * 1e18, bucketIndex, block.timestamp + 10 minutes); + + // remove all collateral + ERC20Pool(address(_pool)).removeCollateral(type(uint256).max, bucketIndex); + } + } + } + function validateEmpty( EnumerableSet.UintSet storage buckets ) internal { @@ -133,8 +160,9 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { assertEq(collateral, 0); } ( , uint256 loansCount, , , ) = _poolUtils.poolLoansInfo(address(_pool)); - (uint256 debt, , ,) = _pool.debtInfo(); + (uint256 debt, , uint256 t0DebtInAuction ,) = _pool.debtInfo(); assertEq(debt, 0); + assertEq(t0DebtInAuction, 0); assertEq(loansCount, 0); assertEq(_pool.pledgedCollateral(), 0); } @@ -143,14 +171,34 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { _; validateCollateral(bucketsUsed, borrowers); + // Skip time to make all auctioned borrowers settleable + skip(73 hours); + + // Settle any auctions and then repay debt for (uint i = 0; i < borrowers.length(); i++) { - repayDebt(borrowers.at(i)); + address borrower = borrowers.at(i); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); + if (kickTime != 0) { + changePrank(borrower); + _pool.settle(borrower, bucketsUsed.length() + 1); + + // Settle again if not settled, this can happen when less reserves calculated with DEPOSIT_BUFFER and borrower is not fully settled + (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); + if (kickTime != 0) { + _pool.settle(borrower, bucketsUsed.length() + 1); + } + } + repayDebt(borrower); } + // Lenders pull all liquidity and collateral from buckets for (uint i = 0; i < lenders.length(); i++) { redeemLendersLp(lenders.at(i), lendersDepositedIndex[lenders.at(i)]); } + // Redeem all collateral in bankrupt buckets + if (lenders.length() != 0) redeemBankruptBucketCollateral(bucketsUsed, lenders.at(0)); + validateEmpty(bucketsUsed); } @@ -581,6 +629,15 @@ abstract contract ERC20DSTestPlus is DSTestPlus, IERC20PoolEvents { ERC20Pool(address(_pool)).repayDebt(borrower, 0, amount, borrower, MAX_FENWICK_INDEX); } + function _assertRepayAuctionActiveRevert( + address from, + uint256 maxAmount + ) internal override { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionActive.selector); + ERC20Pool(address(_pool)).repayDebt(from, maxAmount, 0, from, MAX_FENWICK_INDEX); + } + function _assertRepayMinDebtRevert( address from, address borrower, diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol index 285405e3e..817847215 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolBorrow.t.sol @@ -354,7 +354,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 441.424038461538461742 * 1e18, + borrowert0Np: 484.222578900118175410 * 1e18, borrowerCollateralization: 7.082081907682151400 * 1e18 }); @@ -389,7 +389,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 60 * 1e18, - borrowert0Np: 441.424038461538461742 * 1e18, + borrowert0Np: 403.518815750098479508 * 1e18, borrowerCollateralization: 8.488027144729466085 * 1e18 }); _assertLenderInterest(liquidityAdded, 44.110379805202100000 * 1e18); @@ -427,7 +427,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 441.213836538461538664 * 1e18, + borrowert0Np: 483.986975517230275430 * 1e18, borrowerCollateralization: 7.063769822178689107 * 1e18 }); _assertLenderInterest(liquidityAdded, 69.130567554535450000 * 1e18); @@ -462,7 +462,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 443.294835576923077127 * 1e18, + borrowert0Np: 486.269617724627962428 * 1e18, borrowerCollateralization: 7.053240081812639175 * 1e18 }); _assertLenderInterest(liquidityAdded, 96.693504733499050000 * 1e18); @@ -494,7 +494,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 443.294835576923077127 * 1e18, + borrowert0Np: 486.269617724627962428 * 1e18, borrowerCollateralization: 7.041675495797803839 * 1e18 }); _assertLenderInterest(liquidityAdded, 127.061165904636850000 * 1e18); @@ -520,12 +520,11 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { interestRateUpdate: _startTime + 50 days }) ); - assertEq(_poolUtils.momp(address(_pool)), 2_981.007422784467321543 * 1e18); _assertBorrower({ borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 50 * 1e18, - borrowert0Np: 443.294835576923077127 * 1e18, + borrowert0Np: 486.269617724627962428 * 1e18, borrowerCollateralization: 7.028976350457301320 * 1e18 }); } @@ -933,7 +932,7 @@ contract ERC20PoolBorrowTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 500.480769230769231 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 10.510096153846153851 * 1e18, + borrowert0Np: 11.529109021431385128 * 1e18, borrowerCollateralization: 300.799971477982403259 * 1e18 }); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol index ce5ca5a32..45139395f 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolCollateral.t.sol @@ -107,7 +107,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_020.192307692307702000 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 220.712019230769230871 * 1e18, + borrowert0Np: 242.111289450059087705 * 1e18, borrowerCollateralization: 14.181637252165253251 * 1e18 }); @@ -146,7 +146,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 441.424038461538461742 * 1e18, + borrowert0Np: 484.222578900118175410 * 1e18, borrowerCollateralization: 7.081111825921092812 * 1e18 }); @@ -182,7 +182,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 7.061038044473493202 * 1e18, - borrowert0Np: 3_140.657612229160876676 * 1e18, + borrowert0Np: 3_445.079304012847629269 * 1e18, borrowerCollateralization: 1 * 1e18 }); @@ -250,7 +250,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_020.192307692307702000 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 220.712019230769230871 * 1e18, + borrowert0Np: 242.111289450059087705 * 1e18, borrowerCollateralization: 14.181637252165253251 * 1e18 }); @@ -275,7 +275,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 50 * 1e18, - borrowert0Np: 441.424038461538461742 * 1e18, + borrowert0Np: 484.222578900118175410 * 1e18, borrowerCollateralization: 7.081111825921092812 * 1e18 }); @@ -297,7 +297,7 @@ contract ERC20PoolCollateralTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 21_049.006823139002918431 * 1e18, borrowerCollateral: 7.061038044473493202 * 1e18, - borrowert0Np: 3_140.657612229160876676 * 1e18, + borrowert0Np: 3_445.079304012847629269 * 1e18, borrowerCollateralization: 1 * 1e18 }); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol index fac958abe..f55ffafeb 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolInfoUtils.t.sol @@ -92,10 +92,10 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { } function testPoolInfoUtilsBorrowerInfo() external { - (uint256 debt, uint256 collateral, uint256 t0Np) = _poolUtils.borrowerInfo(address(_pool), _borrower); + (uint256 debt, uint256 collateral, uint256 npTpRatio) = _poolUtils.borrowerInfo(address(_pool), _borrower); assertEq(debt, 21_020.192307692307702000 * 1e18); assertEq(collateral, 100 * 1e18); - assertEq(t0Np, 220.712019230769230871 * 1e18); + assertEq(npTpRatio, 242.111289450059087705 * 1e18); } function testPoolInfoUtilsBucketInfo() external { @@ -205,22 +205,6 @@ contract ERC20PoolInfoUtilsTest is ERC20HelperContract { assertEq(lenderInterestMargin, 0.849999999999999999 * 1e18); } - function testMomp() external { - assertEq(_poolUtils.momp(address(_pool)), 2_981.007422784467321543 * 1e18); - - // ensure calculation does not revert on pools with no loans and no deposit - IERC20 otherCollateral = new Token("MompTestCollateral", "MTC"); - IERC20Pool emptyPool = ERC20Pool(_poolFactory.deployPool(address(otherCollateral), address(_quote), 0.05 * 10**18)); - assertEq(_poolUtils.momp(address(emptyPool)), MIN_PRICE); - - // should return HPB on pools with liquidity but no loans - changePrank(_lender); - uint256 hpbIndex = 369; - _quote.approve(address(emptyPool), type(uint256).max); - emptyPool.addQuoteToken(0.0213 * 1e18, hpbIndex, type(uint256).max, false); - assertEq(_poolUtils.momp(address(emptyPool)), _priceAt(hpbIndex)); - } - function testBorrowFeeRate() external { assertEq(_poolUtils.borrowFeeRate(address(_pool)), 0.000961538461538462 * 1e18); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol index 9df8a42bb..f3ab8cbcd 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsArbTake.t.sol @@ -107,14 +107,14 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); @@ -146,7 +146,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -158,17 +158,17 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.995306391810796636 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.778456451861613481 * 1e18, + debt: 19.534277977147272573 * 1e18, collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 + bond: 0.296536979149981005 * 1e18, + transferAmount: 0.296536979149981005 * 1e18 }); _assertAuction( @@ -176,26 +176,25 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 328.175870016074179200 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889228225930806740 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 2_879.954914386826585856 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767138988573636287 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.195342779771472726 * 1e18 + locked: 0.296536979149981005 * 1e18 }); } function testArbTakeCollateralRestrict() external tearDown { - skip(6.5 hours); _assertLenderLpBalance({ @@ -219,10 +218,10 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.779116873676490457 * 1e18, + borrowerDebt: 19.534930245606410328 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.982985835729561629 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995273158676181149 * 1e18 }); // add liquidity to accrue interest and update reserves before arb take @@ -231,7 +230,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { amount: 1 * 1e18, amountAdded: 0.999876712328767123 * 1e18, index: _i9_52, - lpAward: 0.999873539529846321 * 1e18, + lpAward: 0.999873539625283938 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -239,39 +238,39 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { index: _i9_91, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_010.436713885571218000 * 1e18, - exchangeRate: 1.005218356942785609 * 1e18 + deposit: 2_010.436713693675662000 * 1e18, + exchangeRate: 1.005218356846837831 * 1e18 }); _assertReserveAuction({ - reserves: 24.540827358578637024 * 1e18, + reserves: 24.296647707318004711 * 1e18, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - + _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, // should be the same after arb take, kicker will be rewarded with LP - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, // should be the same after arb take, kicker will be rewarded with LP + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 7.251730722192532064 * 1e18, - debtInAuction: 19.779116873676490457 * 1e18, - thresholdPrice: 9.889558436838245228 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 9.459936576563284516 * 1e18, + debtInAuction: 19.534930245606410328 * 1e18, + thresholdPrice: 9.767465122803205164 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.779116873676490457 * 1e18, + borrowerDebt: 19.534930245606410328 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.982985835729561629 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995273158676181149 * 1e18 }); // Amount is restricted by the collateral in the loan @@ -281,35 +280,35 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { kicker: _lender, index: _i9_91, collateralArbed: 2 * 1e18, - quoteTokenAmount: 14.503461444385064128 * 1e18, - bondChange: 0.145034614443850641 * 1e18, + quoteTokenAmount: 18.919873153126569032 * 1e18, + bondChange: 0.287210105092827748 * 1e18, isReward: true, - lpAwardTaker: 5.303234074136771188 * 1e18, - lpAwardKicker: 0.144281701027576469 * 1e18 + lpAwardTaker: 0.909749138101538138 * 1e18, + lpAwardKicker: 0.285719120762723106 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i9_91, - lpBalance: 5.303234074136771188 * 1e18, + lpBalance: 0.909749138101538138 * 1e18, depositTime: _startTime + 100 days + 6.5 hours }); _assertLenderLpBalance({ lender: _lender, index: _i9_91, - lpBalance: 2_000.144281701027576469 * 1e18, // rewarded with LP in bucket + lpBalance: 2_000.285719120762723106 * 1e18, // rewarded with LP in bucket depositTime: _startTime + 100 days + 6.5 hours }); _assertBucket({ index: _i9_91, - lpBalance: 2_005.447515775164347657 * 1e18, + lpBalance: 2_001.195468258864261244 * 1e18, collateral: 2 * 1e18, - deposit: 1_996.078287055630004514 * 1e18, - exchangeRate: 1.005218356942785610 * 1e18 + deposit: 1_991.804050645641920716 * 1e18, + exchangeRate: 1.005218356846837832 * 1e18 }); // reserves should remain the same after arb take _assertReserveAuction({ - reserves: 25.925365539735991348 * 1e18, + reserves: 24.296647707318004709 * 1e18, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, @@ -317,9 +316,9 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6.805228224892631304 * 1e18, + borrowerDebt: 0.902267197572669045 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertAuction( @@ -327,15 +326,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, // bond size remains the same, kicker was rewarded with LP - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, // bond size remains the same, kicker was rewarded with LP + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 7.251730722192532064 * 1e18, - debtInAuction: 6.805228224892631304 * 1e18, + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 9.459936576563284516 * 1e18, + debtInAuction: 0.902267197572669045 * 1e18, thresholdPrice: 0, - neutralPrice: 10.255495938002318100 * 1e18 + neutralPrice: 11.249823884323541351 * 1e18 }) ); @@ -348,7 +347,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeDebtRestrict() external tearDown { - skip(5 hours); _assertAuction( @@ -356,15 +354,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 20.510991876004636192 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889482233342512890 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 15.909653511519124956 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767389860091370755 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); @@ -375,13 +373,13 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { lpAward: 25_000 * 1e18, newLup: 1_505.263728469068226832 * 1e18 }); - + _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.778964466685025781 * 1e18, + borrowerDebt: 19.534779720182741511 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 152.208547722958917634 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 154.111154569495900146 * 1e18 }); // Amount is restricted by the debt in the loan @@ -390,25 +388,25 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 1.031812215971460994 * 1e18, - quoteTokenAmount: 21.163491979352977585 * 1e18, - bondChange: 0.195342779771472726 * 1e18, + collateralArbed: 1.256467421916368415 * 1e18, + quoteTokenAmount: 19.989961331201132696 * 1e18, + bondChange: 0.296536979149981005 * 1e18, isReward: false, - lpAwardTaker: 1_531.986011313779866429 * 1e18, + lpAwardTaker: 1_871.324874882549437558 * 1e18, lpAwardKicker: 0 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 0.968187784028539006 * 1e18, + borrowerCollateral: 0.743532578083631585 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_531.986011313779866429 * 1e18, + lpBalance: 1_871.324874882549437558 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ @@ -419,13 +417,13 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }); _assertBucket({ index: _i1505_26, - lpBalance: 26_531.986011313779866429 * 1e18, - collateral: 1.031812215971460994 * 1e18, - deposit: 24_978.836508020647022415 * 1e18, - exchangeRate: 1 * 1e18 + lpBalance: 26_871.324874882549437558 * 1e18, + collateral: 1.256467421916368415 * 1e18, + deposit: 24_980.010038668798867303 * 1e18, + exchangeRate: 1.000000000000000000 * 1e18 }); _assertReserveAuction({ - reserves: 26.111547973458754924 * 1e18, + reserves: 25.039216891441214202 * 1e18, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, @@ -434,7 +432,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeDepositRestrict() external tearDown { - skip(5 hours); _assertAuction( @@ -442,15 +439,15 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 20.510991876004636192 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889482233342512890 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 15.909653511519124956 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767389860091370755 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); @@ -464,10 +461,10 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.778964466685025781 * 1e18, + borrowerDebt: 19.534779720182741511 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.982993410135902682 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995280827762601466 * 1e18 }); // Amount is restricted by the deposit in the bucket @@ -476,48 +473,48 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.731315193857015473 * 1e18, - quoteTokenAmount: 14.99999999999999999 * 1e18, - bondChange: 0.15 * 1e18, + collateralArbed: 0.942823801231088711 * 1e18, + quoteTokenAmount: 14.999999999999999998 * 1e18, + bondChange: 0.227705098312484220 * 1e18, isReward: false, - lpAwardTaker: 1_085.822235391290531090 * 1e18, + lpAwardTaker: 1_404.198470330488271279 * 1e18, lpAwardKicker: 0 }); _assertAuction( AuctionParams({ borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.045342779771472726 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 4.858174346779663281 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 0.068831880837496785 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 5 hours, + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.068831880837496785 * 1e18, + auctionPrice: 15.909653511519124956 * 1e18, + debtInAuction: 4.876337367651467845 * 1e18, + thresholdPrice: 4.612606085276981381 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); _assertBucket({ index: _i1505_26, - lpBalance: 1_100.822235391290531090 * 1e18, - collateral: 0.731315193857015473 * 1e18, - deposit: 10, - exchangeRate: 1 * 1e18 + lpBalance: 1_419.198470330488271279 * 1e18, + collateral: 0.942823801231088711 * 1e18, + deposit: 0.000000000000000003 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6.163491979352977596 * 1e18, - borrowerCollateral: 1.268684806142984527 * 1e18, - borrowert0Np: 5.057793757429320966 * 1e18, - borrowerCollateralization: 2.001018319047304749 * 1e18 + borrowerDebt: 4.876337367651467845 * 1e18, + borrowerCollateral: 1.057176198768911289 * 1e18, + borrowert0Np: 5.240398686048708221 * 1e18, + borrowerCollateralization: 2.107549546895251001 * 1e18 }); _assertLenderLpBalance({ lender: _taker, index: _i1505_26, - lpBalance: 1_085.822235391290531090 * 1e18, + lpBalance: 1_404.198470330488271279 * 1e18, depositTime: block.timestamp }); _assertLenderLpBalance({ @@ -529,7 +526,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { } function testArbTakeGTNeutralPrice() external tearDown { - skip(3 hours); _addLiquidity({ @@ -564,23 +560,23 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 82.043967504018544800 * 1e18, - debtInAuction: 19.778761259189860404 * 1e18, - thresholdPrice: 9.889380629594930202 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 31.819307023038249912 * 1e18, + debtInAuction: 19.534579021422084350 * 1e18, + thresholdPrice: 9.767289510711042175 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.778761259189860404 * 1e18, + borrowerDebt: 19.534579021422084350 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.983003509435146965 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995291053303086302 * 1e18 }); _arbTake({ @@ -588,18 +584,18 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i10016, - collateralArbed: 0.257950403803869741 * 1e18, - quoteTokenAmount: 21.163274547333150632 * 1e18, - bondChange: 0.195342779771472726 * 1e18, + collateralArbed: 0.628227256535406044 * 1e18, + quoteTokenAmount: 19.989755955941097815 * 1e18, + bondChange: 0.296536979149981005 * 1e18, isReward: false, - lpAwardTaker: 2_562.597355112798042 * 1e18, + lpAwardTaker: 6_272.649557567888341455 * 1e18, lpAwardKicker: 0 }); _assertLenderLpBalance({ lender: _taker, index: _i10016, - lpBalance: 2_562.597355112798042 * 1e18, // arb taker was rewarded LPBs in arbed bucket + lpBalance: 6_272.649557567888341455 * 1e18, // arb taker was rewarded LPBs in arbed bucket depositTime: _startTime + 100 days + 3 hours }); _assertLenderLpBalance({ @@ -615,9 +611,9 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { }); _assertBucket({ index: _i10016, - lpBalance: 3_562.597355112798042 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker - collateral: 0.257950403803869741 * 1e18, // arbed collateral added to the arbed bucket - deposit: 978.836725452666849368 * 1e18, // quote token amount is diminished in arbed bucket + lpBalance: 7_272.649557567888341455 * 1e18, // LP balance in arbed bucket increased with LP awarded for arb taker + collateral: 0.628227256535406044 * 1e18, // arbed collateral added to the arbed bucket + deposit: 980.010244044058902179 * 1e18, // quote token amount is diminished in arbed bucket exchangeRate: 1.000000000000000001 * 1e18 }); _assertAuction( @@ -628,7 +624,7 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -639,13 +635,19 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.742049596196130259 * 1e18, + borrowerCollateral: 1.371772743464593956 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); } function testArbTakeReverts() external tearDown { + // should revert if taken from same block when kicked + _assertArbTakeAuctionNotTakeableRevert({ + from: _taker, + borrower: _borrower, + index: _i9_62 + }); // should revert if borrower not auctioned _assertArbTakeNoAuction({ @@ -654,13 +656,6 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { index: _i9_91 }); - // should revert if auction in grace period - _assertArbTakeAuctionInCooldownRevert({ - from: _lender, - borrower: _borrower, - index: _i9_91 - }); - skip(2.5 hours); _assertAuction( @@ -668,23 +663,29 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 2.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 116.027691555080513536 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889355228821139433 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 37.839746306253138192 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767264423527051292 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.778710457642278867 * 1e18, + borrowerDebt: 19.534528847054102585 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.983006034276170567 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995293609704622699 * 1e18 + }); + + // borrower cannot repay amidst auction + _assertRepayAuctionActiveRevert({ + from: _borrower, + maxAmount: 10 * 1e18 }); // should revert if bucket deposit is 0 @@ -714,5 +715,13 @@ contract ERC20PoolLiquidationsArbTakeTest is ERC20HelperContract { borrower: _borrower, index: _i9_91 }); + + // ensure zero bid reverts + skip(3 days); + _assertArbTakeZeroBidRevert({ + from: _taker, + borrower: _borrower, + index: _i9_52 + }); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol index 209be726c..3a5f7a027 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsDepositTake.t.sol @@ -109,14 +109,14 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ @@ -147,7 +147,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -159,17 +159,17 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.939819504377940339 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.975063576969429891 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 20.189067248182664594 * 1e18, + debt: 19.939819504377940339 * 1e18, collateral: 2 * 1e18, - bond: 0.199398195043779403 * 1e18, - transferAmount: 0.199398195043779403 * 1e18 + bond: 0.302693237371837952 * 1e18, + transferAmount: 0.302693237371837952 * 1e18 }); _assertAuction( @@ -177,21 +177,21 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 334.988967673549397664 * 1e18, - debtInAuction: 20.189067248182664594 * 1e18, - thresholdPrice: 10.094533624091332297 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 2_939.744240396328951808 * 1e18, + debtInAuction: 19.939819504377940339 * 1e18, + thresholdPrice: 9.969909752188970169 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.199398195043779403 * 1e18 + locked: 0.302693237371837952 * 1e18 }); } @@ -219,10 +219,10 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 20.189741380689676443 * 1e18, + borrowerDebt: 19.940485314261408832 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.962993599742653326 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.975031019739436493 * 1e18 }); // add liquidity to accrue interest and update reserves before deposit take @@ -231,7 +231,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { amount: 1 * 1e18, amountAdded: 0.999876712328767123 * 1e18, index: _i9_52, - lpAward: 0.999873479995558788 * 1e18, + lpAward: 0.999873480092787187 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -239,12 +239,12 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { index: _i9_91, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_026.352751434705402000 * 1e18, - exchangeRate: 1.013176375717352701 * 1e18 + deposit: 2_026.352751237661440000 * 1e18, + exchangeRate: 1.013176375618830720 * 1e18 }); _assertReserveAuction({ - reserves: 49.824849391649864824 * 1e18, - claimableReserves : 8.392639704106692236 * 1e18, + reserves: 49.575600446873147197 * 1e18, + claimableReserves : 8.144637039662123068 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -255,23 +255,23 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 7.402280333270247968 * 1e18, - debtInAuction: 20.189741380689676443 * 1e18, - thresholdPrice: 10.094870690344838221 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 9.656329662156355672 * 1e18, + debtInAuction: 19.940485314261408832 * 1e18, + thresholdPrice: 9.970242657130704416 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 20.189741380689676443 * 1e18, + borrowerDebt: 19.940485314261408832 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.962993599742653326 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.975031019739436493 * 1e18 }); // Amount is restricted by the collateral in the loan @@ -282,10 +282,10 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { index: _i9_91, collateralArbed: 2 * 1e18, quoteTokenAmount: 19.834369686871824148 * 1e18, - bondChange: 0.198343696868718241 * 1e18, + bondChange: 0.301092473301020371 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 0.195764233772511956 * 1e18 + lpAwardKicker: 0.297176760677150868 * 1e18 }); _assertLenderLpBalance({ @@ -297,20 +297,20 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender, index: _i9_91, - lpBalance: 2_000.195764233772511956 * 1e18, + lpBalance: 2_000.297176760677150868 * 1e18, depositTime: _startTime + 250 days + 6.5 hours }); _assertBucket({ index: _i9_91, - lpBalance: 2_000.195764233772511956 * 1e18, + lpBalance: 2_000.297176760677150868 * 1e18, collateral: 2 * 1e18, - deposit: 2_006.716725444702296094 * 1e18, - exchangeRate: 1.013176375717352702 * 1e18 + deposit: 2_006.819474024090636225 * 1e18, + exchangeRate: 1.013176375618830721 * 1e18 }); // reserves should remain the same after deposit take _assertReserveAuction({ - reserves: 51.238131288298142183 * 1e18, - claimableReserves : 9.897035340857769728 * 1e18, + reserves: 49.575600446873147192 * 1e18, + claimableReserves : 8.242303445263254296 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -320,22 +320,22 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 6.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 7.402280333270247968 * 1e18, - debtInAuction: 1.966997287334847889 * 1e18, + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 9.656329662156355672 * 1e18, + debtInAuction: 0.407208100690605057 * 1e18, thresholdPrice: 0, - neutralPrice: 10.468405239798418677 * 1e18 + neutralPrice: 11.483375939048159968 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 1.966997287334847889 * 1e18, + borrowerDebt: 0.407208100690605057 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); @@ -348,7 +348,6 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeDebtRestrict() external tearDown { - skip(5 hours); _assertAuction( @@ -356,15 +355,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 20.936810479596837344 * 1e18, - debtInAuction: 20.189067248182664594 * 1e18, - thresholdPrice: 10.094792904825850360 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 16.239945994830783896 * 1e18, + debtInAuction: 19.939819504377940339 * 1e18, + thresholdPrice: 9.970165831926765787 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); @@ -378,10 +377,10 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 20.189585809651700720 * 1e18, + borrowerDebt: 19.940331663853531575 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 149.112888462473727465 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 150.976799568254654687 * 1e18 }); _assertBucket({ index: _i1505_26, @@ -397,9 +396,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i1505_26, - collateralArbed: 0.014351542794629452 * 1e18, - quoteTokenAmount: 21.602856816327319770 * 1e18, - bondChange: 0.199398195043779403 * 1e18, + collateralArbed: 0.013555739562620698 * 1e18, + quoteTokenAmount: 20.404963076186087933 * 1e18, + bondChange: 0.302693237371837952 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -408,7 +407,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.985648457205370548 * 1e18, + borrowerCollateral: 1.986444260437379302 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -427,13 +426,13 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBucket({ index: _i1505_26, lpBalance: 25_000 * 1e18, - collateral: 0.014351542794629452 * 1e18, - deposit: 24_978.397143183672680230 * 1e18, + collateral: 0.013555739562620698 * 1e18, + deposit: 24_979.595036923813911959 * 1e18, exchangeRate: 1.000000000000000001 * 1e18 }); _assertReserveAuction({ - reserves: 51.428181523373734114 * 1e18, - claimableReserves : 10.097214040782253165 * 1e18, + reserves: 50.333588303732929197 * 1e18, + claimableReserves : 9.002620819943559986 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -441,7 +440,6 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeDepositRestrict() external tearDown { - skip(5 hours); _assertAuction( @@ -449,15 +447,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 20.936810479596837344 * 1e18, - debtInAuction: 20.189067248182664594 * 1e18, - thresholdPrice: 10.094792904825850360 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 16.239945994830783896 * 1e18, + debtInAuction: 19.939819504377940339 * 1e18, + thresholdPrice: 9.970165831926765787 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); @@ -471,10 +469,10 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 20.189585809651700720 * 1e18, + borrowerDebt: 19.940331663853531575 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.963001020098637267 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.975038532849870233 * 1e18 }); // Amount is restricted by the deposit in the bucket in the loan @@ -485,7 +483,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { index: _i1505_26, collateralArbed: 0.009965031187761219 * 1e18, quoteTokenAmount: 14.999999999999999995 * 1e18, - bondChange: 0.15 * 1e18, + bondChange: 0.227705098312484220 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -494,32 +492,32 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertAuction( AuctionParams({ borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.049398195043779403 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 3.317960196583009907 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 0.074988139059353732 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 5 hours, + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.074988139059353732 * 1e18, + auctionPrice: 16.239945994830783896 * 1e18, + debtInAuction: 5.281889311322257910 * 1e18, + thresholdPrice: 2.654169094563588010 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); _assertBucket({ index: _i1505_26, lpBalance: 15 * 1e18, collateral: 0.009965031187761219 * 1e18, - deposit: 5, + deposit: 0.000000000000000005 * 1e18, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 6.602856816327319776 * 1e18, + borrowerDebt: 5.281889311322257910 * 1e18, borrowerCollateral: 1.990034968812238781 * 1e18, - borrowert0Np: 3.384038787324199951 * 1e18, - borrowerCollateralization: 2.929901291475172996 * 1e18 + borrowert0Np: 2.954082977863112822 * 1e18, + borrowerCollateralization: 3.662651292618643252 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -536,7 +534,6 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { } function testDepositTakeGTNeutralPrice() external tearDown { - skip(3 hours); _addLiquidity({ @@ -571,23 +568,23 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 83.747241918387349408 * 1e18, - debtInAuction: 20.189378383465778991 * 1e18, - thresholdPrice: 10.094689191732889495 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 32.479891989661567792 * 1e18, + debtInAuction: 19.940126798484719991 * 1e18, + thresholdPrice: 9.970063399242359995 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 20.189378383465778991 * 1e18, + borrowerDebt: 19.940126798484719991 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.963010913995558897 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.975048550420503383 * 1e18 }); _depositTake({ @@ -595,9 +592,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, kicker: _lender, index: _i10016, - collateralArbed: 0.002156704581707556 * 1e18, - quoteTokenAmount: 21.602634870308383520 * 1e18, - bondChange: 0.199398195043779403 * 1e18, + collateralArbed: 0.002037113782225481 * 1e18, + quoteTokenAmount: 20.404753437231397559 * 1e18, + bondChange: 0.302693237371837952 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -624,9 +621,9 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBucket({ index: _i10016, lpBalance: 1_000 * 1e18, // LP balance in arbed bucket increased with LP awarded for deposit taker - collateral: 0.002156704581707556 * 1e18, // arbed collateral added to the arbed bucket - deposit: 978.397365129691616480 * 1e18, // quote token amount is diminished in arbed bucket - exchangeRate: 1 * 1e18 + collateral: 0.002037113782225481 * 1e18, // arbed collateral added to the arbed bucket + deposit: 979.595246562768594325 * 1e18, // quote token amount is diminished in arbed bucket + exchangeRate: 1.000000000000000001 * 1e18 }); _assertAuction( AuctionParams({ @@ -636,7 +633,7 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -647,19 +644,18 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.997843295418292444 * 1e18, + borrowerCollateral: 1.997962886217774519 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); } function testDepositTakeReverts() external tearDown { - - // should revert if auction in grace period - _assertDepositTakeAuctionInCooldownRevert({ - from: _lender, + // should revert if taken from same block when kicked + _assertDepositTakeAuctionNotTakeableRevert({ + from: _taker, borrower: _borrower, - index: _i9_91 + index: _i9_72 }); skip(2.5 hours); @@ -669,15 +665,15 @@ contract ERC20PoolLiquidationsDepositTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.199398195043779403 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.302693237371837952 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 2.5 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.199398195043779403 * 1e18, - auctionPrice: 118.436485332323967968 * 1e18, - debtInAuction: 20.189067248182664594 * 1e18, - thresholdPrice: 10.094663263626140338 * 1e18, - neutralPrice: 10.468405239798418677 * 1e18 + referencePrice: 11.483375939048159968 * 1e18, + totalBondEscrowed: 0.302693237371837952 * 1e18, + auctionPrice: 38.625318648625422832 * 1e18, + debtInAuction: 19.939819504377940339 * 1e18, + thresholdPrice: 9.970037791235694161 * 1e18, + neutralPrice: 11.483375939048159968 * 1e18 }) ); @@ -733,6 +729,7 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { _mintQuoteAndApproveTokens(actor4, type(uint256).max); _mintCollateralAndApproveTokens(actor4, type(uint256).max); + assertEq(_priceAt(2572), 2_697.999235705754194133 * 1e18); _addInitialLiquidity({ from: actor2, amount: 1_791_670_358_647.909977170293982862 * 1e18, @@ -764,17 +761,17 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { borrower: actor2, active: true, kicker: actor1, - bondSize: 9_090_645_929.673616432967467261 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 13_799_909_500.935435603423349661 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 2_697.999235705754194133 * 1e18, - totalBondEscrowed: 9_090_645_929.673616432967467261 * 1e18, + referencePrice: 3_137.845063437099084063 * 1e18, + totalBondEscrowed: 13_799_909_500.935435603423349661 * 1e18, auctionPrice: 0, - debtInAuction: 930_695_454_793.486423224879367583 * 1e18, - thresholdPrice: 2_789.112230632554291586 * 1e18, - neutralPrice: 2_860.503207254858101199 * 1e18 + debtInAuction: 920_341_611_662.285708998644615657 * 1e18, + thresholdPrice: 2_758.083788017359002804 * 1e18, + neutralPrice: 3_137.845063437099084063 * 1e18 // was 2_860.503207254858101199 }) - ); + ); // assert kicker balances in bucket before bucket take auction with auction price zero _assertLenderLpBalance({ @@ -784,15 +781,31 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { depositTime: 0 }); - ERC20Pool(address(_pool)).bucketTake(actor2, false, 2572); + ERC20Pool(address(_pool)).bucketTake(actor2, true, 2572); - // assert kicker balances in bucket after take - // deposit time should remain the same since auction price was zero / kicker reward is zero + // ensure some debt was covered by the take + _assertAuction( + AuctionParams({ + borrower: actor2, + active: true, + kicker: actor1, + bondSize: 13_799_909_500.935435603423349661 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: _startTime + 100 days, + referencePrice: 3_137.845063437099084063 * 1e18, + totalBondEscrowed: 13_799_909_500.935435603423349661 * 1e18, + auctionPrice: 0, + debtInAuction: 33_716_280_531.11637887639485531 * 1e18, + thresholdPrice: 0, + neutralPrice: 3_137.845063437099084063 * 1e18 // was 2_860.503207254858101199 + }) + ); + // ensure kicker was rewarded since bucket price taken was below the neutral price _assertLenderLpBalance({ lender: actor1, - index: 2572, - lpBalance: 0, - depositTime: 0 + index: 2572, // 2697.99923570534 + lpBalance: 13512526017.591065704389485704 * 1e18, + depositTime: _startTime + 200 days }); } @@ -833,7 +846,7 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { changePrank(actor2); _pool.updateInterest(); _pool.kick(actor0, 7388); - skip(5 days); + skip(70 hours); changePrank(actor3); _pool.updateInterest(); @@ -857,8 +870,11 @@ contract ERC20PoolLiquidationsDepositTakeRegressionTest is ERC20HelperContract { _pool.updateInterest(); // bucket take with bucket 2571 should revert as deposit of 3 cannot cover at least one unit of collateral - vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); - _pool.bucketTake(actor0, true, 2571); + _assertDepositTakeZeroBidRevert({ + from: actor2, + borrower: actor0, + index: 2571 + }); // assert bucket after take _assertBucket({ diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol index aee3f5358..689ff75c1 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsKick.t.sol @@ -111,14 +111,14 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ @@ -145,7 +145,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -157,7 +157,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.995306391810796636 * 1e18 }); @@ -170,10 +170,10 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 19.778456451861613481 * 1e18, + debt: 19.534277977147272573 * 1e18, collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 + bond: 0.296536979149981005 * 1e18, + transferAmount: 0.296536979149981005 * 1e18 }); /******************************/ @@ -186,11 +186,11 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 73_093.873009488594544000 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 835.035237319063220562 * 1e18, - poolDebt: 8_117.624599705640061722 * 1e18, + encumberedCollateral: 835.010119425512354679 * 1e18, + poolDebt: 8_117.380421230925720814 * 1e18, actualUtilization: 0.109684131322444679 * 1e18, targetUtilization: 0.822075127292417292 * 1e18, - minDebtAmount: 811.762459970564006172 * 1e18, + minDebtAmount: 811.738042123092572081* 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -199,45 +199,44 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.778456451861613481 * 1e18, + borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.983018658578564579 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.995306391810796636 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 8_097.846143253778448241 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.200479200648987171 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.804657220228527274 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.703463020850018995 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 328.175870016074179200 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889228225930806740 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 2_879.954914386826585856 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767138988573636287 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); - assertEq(_poolUtils.momp(address(_pool)), 9.818751856078723036 * 1e18); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.195342779771472726 * 1e18 + locked: 0.296536979149981005 * 1e18 }); _assertReserveAuction({ - reserves: 24.501590217045517722 * 1e18, + reserves: 24.257411742331176814 * 1e18, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, @@ -271,326 +270,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { }); } - function testKickAndSaveByRepay() external tearDown { - - // Skip to make borrower undercollateralized - skip(100 days); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, - neutralPrice: 0 - }) - ); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 - }); - - _kick({ - from: _lender, - borrower: _borrower, - debt: 19.778456451861613481 * 1e18, - collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: true, - kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 328.175870016074179200 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889228225930806740 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 - }) - ); - _assertKicker({ - kicker: _lender, - claimable: 0, - locked: 0.195342779771472726 * 1e18 - }); - - _repayAndSettleAuction({ - from: _borrower, - borrower: _borrower, - amount: 2 * 1e18, - repaid: 2 * 1e18, - collateral: 2 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 8.889228225930806741 * 1e18, - neutralPrice: 0 - }) - ); - _assertKicker({ - kicker: _lender, - claimable: 0.195342779771472726 * 1e18, - locked: 0 - }); - - // Skip to make borrower undercollateralized again - skip(750 days); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 19.500754673204780612 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 9.254718877190426163 * 1e18, - borrowerCollateralization: 0.997017400397270737 * 1e18 - }); - - // Kick method only emit Kick event and doesn't call transfer method when kicker has enough bond amount in claimable - _kick({ - from: _lender, - borrower: _borrower, - debt: 19.720138163278334394 * 1e18, - collateral: 2 * 1e18, - bond: 0.195007546732047806 * 1e18, - transferAmount: 0 - }); - - uint256 snapshot = vm.snapshot(); - - // kicker not saved if partial debt paid only - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 0.0001 * 1e18, - amountRepaid: 0.0001 * 1e18, - collateralToPull: 0, - newLup: 9.721295865031779605 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: true, - kicker: address(_lender), - bondSize: 0.195007546732047806 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: _startTime + 850 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 329.321295632797165408 * 1e18, - debtInAuction: 19.720038163278334394 * 1e18, - thresholdPrice: 9.860019081639167197 * 1e18, - neutralPrice: 10.291290488524911419 * 1e18 - }) - ); - - vm.revertTo(snapshot); - - // kicker saved if enough debt paid - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 10 * 1e18, - amountRepaid: 10 * 1e18, - collateralToPull: 0, - newLup: 9.721295865031779605 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 4.860069081639167197 * 1e18, - neutralPrice: 0 - }) - ); - - // kicker balance before withdraw auction bonds - assertEq(_quote.balanceOf(_lender), 46_999.804657220228527274 * 1e18); - - // should revert if user without claimable amount tries to withdraw bond - vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); - _pool.withdrawBonds(_withdrawRecipient, type(uint256).max); - - snapshot = vm.snapshot(); - - changePrank(_lender); - - // should revert if trying to withdraw 0 bond amount - vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); - _pool.withdrawBonds(_withdrawRecipient, 0); - - // kicker withdraws partial auction bonds and transfer to a different address - vm.expectEmit(true, true, false, true); - emit BondWithdrawn(_lender, _withdrawRecipient, 0.1 * 1e18); - _pool.withdrawBonds(_withdrawRecipient, 0.1 * 1e18); - - // kicker withdraws remaining auction bonds - vm.expectEmit(true, true, false, true); - emit BondWithdrawn(_lender, _lender, 0.095342779771472726 * 1e18); - _pool.withdrawBonds(_lender, type(uint256).max); - - assertEq(_quote.balanceOf(_withdrawRecipient), 0.1 * 1e18); - assertEq(_quote.balanceOf(_lender), 46_999.9 * 1e18); - - vm.revertTo(snapshot); - - // kicker withdraws entire auction bonds - vm.expectEmit(true, true, false, true); - emit BondWithdrawn(_lender, _lender, 0.195342779771472726 * 1e18); - _pool.withdrawBonds(_lender, type(uint256).max); - - assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); - - _assertKicker({ - kicker: _lender, - claimable: 0, - locked: 0 - }); - } - - function testKickAndSaveByPledgeCollateral() external tearDown { - - // Skip to make borrower undercollateralized - skip(100 days); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 9.767138988573636287 * 1e18, - neutralPrice: 0 - }) - ); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 19.534277977147272574 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.995306391810796636 * 1e18 - }); - - _kick({ - from: _lender, - borrower: _borrower, - debt: 19.778456451861613481 * 1e18, - collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: true, - kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 328.175870016074179200 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889228225930806740 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 - }) - ); - _assertKicker({ - kicker: _lender, - claimable: 0, - locked: 0.195342779771472726 * 1e18 - }); - - _pledgeCollateralAndSettleAuction({ - from: _borrower, - borrower: _borrower, - amount: 2 * 1e18, - collateral: 4 * 1e18 // collateral after auction settled = 2 new pledged + initial 2 collateral pledged - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 4.944614112965403370 * 1e18, - neutralPrice: 0 - }) - ); - _assertKicker({ - kicker: _lender, - claimable: 0.195342779771472726 * 1e18, - locked: 0 - }); - - // kicker withdraws his auction bonds - changePrank(_lender); - assertEq(_quote.balanceOf(_lender), 46_999.804657220228527274 * 1e18); - - _pool.withdrawBonds(_lender, type(uint256).max); - - assertEq(_quote.balanceOf(_lender), 47_000 * 1e18); - - _assertKicker({ - kicker: _lender, - claimable: 0, - locked: 0 - }); - } - function testKickActiveAuctionReverts() external tearDown { - // Skip to make borrower undercollateralized skip(100 days); @@ -602,7 +282,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -614,17 +294,17 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.995306391810796636 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.778456451861613481 * 1e18, + debt: 19.534277977147272573 * 1e18, collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 + bond: 0.296536979149981005 * 1e18, + transferAmount: 0.296536979149981005 * 1e18 }); _assertAuction( @@ -632,15 +312,15 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.195342779771472726 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.296536979149981005 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 0.195342779771472726 * 1e18, - auctionPrice: 328.175870016074179200 * 1e18, - debtInAuction: 19.778456451861613481 * 1e18, - thresholdPrice: 9.889228225930806740 * 1e18, - neutralPrice: 10.255495938002318100 * 1e18 + referencePrice: 11.249823884323541351 * 1e18, + totalBondEscrowed: 0.296536979149981005 * 1e18, + auctionPrice: 2_879.954914386826585856 * 1e18, + debtInAuction: 19.534277977147272574 * 1e18, + thresholdPrice: 9.767138988573636287 * 1e18, + neutralPrice: 11.249823884323541351 * 1e18 }) ); @@ -658,7 +338,6 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { } function testKickAuctionWithoutCollateralReverts() external tearDown { - // Skip to make borrower undercollateralized skip(100 days); @@ -670,7 +349,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -682,36 +361,36 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.995306391810796636 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.778456451861613481 * 1e18, + debt: 19.534277977147272573 * 1e18, collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 + bond: 0.296536979149981005 * 1e18, + transferAmount: 0.296536979149981005 * 1e18 }); - // skip enough time to take collateral at 0 price - skip(100 days); + // skip enough time to take collateral close to 0 price + skip(70 hours); _take({ from: _lender, borrower: _borrower, maxCollateral: 2 * 1e18, bondChange: 0, - givenAmount: 0, + givenAmount: 18, collateralTaken: 2 * 1e18, isReward: true }); // entire borrower collateral is taken but auction not settled as there's still bad debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 21.425476464349380091 * 1e18, + borrowerDebt: 19.541303552517827759 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); @@ -738,14 +417,14 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.534277977147272574 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.995306391810796636 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 11.194764859809874960 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertLoans({ @@ -758,10 +437,10 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertLoans({ @@ -774,10 +453,10 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 19.754038604390179389 * 1e18, + debt: 19.534277977147272573 * 1e18, collateral: 2 * 1e18, - bond: 0.195342779771472726 * 1e18, - transferAmount: 0.195342779771472726 * 1e18 + bond: 0.296536979149981005 * 1e18, + transferAmount: 0.296536979149981005 * 1e18 }); _assertLoans({ @@ -791,8 +470,8 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 73_114.174951097528944000 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_028.290450922889736704 * 1e18, - poolDebt: 9_996.315708608352095627 * 1e18, + encumberedCollateral: 1_015.597987863945504486 * 1e18, + poolDebt: 9_872.928519956368918240 * 1e18, actualUtilization: 0.541033613782051282 * 1e18, targetUtilization: 0.999781133426980224 * 1e18, minDebtAmount: 0, @@ -810,7 +489,7 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { from: _lender1, amount: 1 * 1e18, index: _i9_91, - lpAward: 0.993688287401017551 * 1e18, + lpAward: 0.993688394051845486 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -818,11 +497,11 @@ contract ERC20PoolLiquidationsKickTest is ERC20HelperContract { PoolParams({ htp: 0, lup: 9.721295865031779605 * 1e18, - poolSize: 73_115.810705342225439101 * 1e18, + poolSize: 73_115.802858058164606426 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_028.364405977643667984 * 1e18, - poolDebt: 9_997.034647576329686632 * 1e18, - actualUtilization: 0.100837784413285088 * 1e18, + encumberedCollateral: 1_015.671030071750751166 * 1e18, + poolDebt: 9_873.638584869078854771 * 1e18, + actualUtilization: 0.100677654461506314 * 1e18, targetUtilization: 0.999781133426980224 * 1e18, minDebtAmount: 0, loans: 0, @@ -930,3 +609,62 @@ contract ERC20PoolLiquidationKickFuzzyTest is ERC20FuzzyHelperContract { } } } + +contract ERC20PoolLiquidationKickHighThresholdPriceBorrower is ERC20HelperContract { + address internal _borrower; + address internal _lender; + + function setUp() external { + _startTest(); + + _borrower = makeAddr("borrower"); + _lender = makeAddr("lender"); + + _mintQuoteAndApproveTokens(_lender, 10_000_000 * 1e18); + _mintCollateralAndApproveTokens(_borrower, 4 * 1e18); + } + + function testKickHighThresholdPriceBorrower() external tearDown { + _addInitialLiquidity({ + from: _lender, + amount: 1_000 * 1e18, + index: 1 + }); + + _pledgeCollateral({ + from: _borrower, + borrower: _borrower, + amount: 0.00000105 * 1e18 + }); + + _borrow({ + from: _borrower, + amount: 999 * 1e18, + indexLimit: 7388, + newLup: _priceAt(1) + }); + + for (uint256 i = 0; i < 2000; i++) { + skip(13 hours); + _updateInterest(); + } + + uint256 htp = _poolUtils.htp(address(_pool)); + + // htp is greater than MAX_INFLATED_PRICE + assertTrue(htp > MAX_INFLATED_PRICE); + + // htp is greater than max uint96 value + assertTrue(htp > type(uint96).max); + + // Kick borrower + _kick({ + from: _lender, + borrower: _borrower, + debt: 102_216_005.616368048436296920 * 1e18, + collateral: 0.00000105 * 1e18, + bond: 1_551_673.707198968377320142 * 1e18, + transferAmount: 1_551_673.707198968377320142 * 1e18 + }); + } +} diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol index fc2b976c7..795bc719e 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsLenderKick.t.sol @@ -177,9 +177,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.8987273632000937560 * 1e18 }); /******************************/ @@ -192,11 +192,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { lup: 3_844.432207828138682757 * 1e18, poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.101746319376146305 * 1e18, - poolDebt: 100_346.394230769230815500 * 1e18, + encumberedCollateral: 26.036654682669472623 * 1e18, + poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 2_508.659855769230770388 * 1e18, + minDebtAmount: 2_502.403846153846155000 * 1e18, loans: 4, maxBorrower: address(_borrower5), interestRate: 0.05 * 1e18, @@ -205,8 +205,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - assertEq(_quote.balanceOf(address(_pool)), 17_005.769230769230772000 * 1e18); - assertEq(_quote.balanceOf(_lender1), 42_994.230769230769228000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 11_303.898727363200093756 * 1e18); + assertEq(_quote.balanceOf(_lender1), 48_696.101272636799906244 * 1e18); assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -239,7 +239,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertKicker({ kicker: _lender1, claimable: 0, - locked: 6_005.769230769230772000 * 1e18 + locked: 303.898727363200093756 * 1e18 }); // assert kicked auction _assertAuction( @@ -247,15 +247,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 6_005.769230769230772000 * 1e18, - auctionPrice: 123_636.939803752939029248 * 1e18, - debtInAuction: 20_269.471153846153855500 * 1e18, - thresholdPrice: 20.269471153846153855 * 1e18, - neutralPrice: 21.020192307692307702 * 1e18 + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 303.898727363200093756 * 1e18, + auctionPrice: 5_902.903818972869185792 * 1e18, + debtInAuction: 20_019.230769230769240000 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -267,7 +267,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { - bond auction is not covered entirely by removed deposit (bucket still contains LP), difference to cover bond is sent by lender */ - // borrower 1 draws more debt from pool, bond size will increase from 6_005.769230769230772000 in prev scenario to 8_708.365384615384619400 + // borrower 1 draws more debt from pool, bond size will increase from 303.8987273632000937560 in prev scenario to 440.653154676640135945 _drawDebt({ from: _borrower1, borrower: _borrower1, @@ -307,9 +307,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender3, index: 2500, borrower: _borrower1, - debt: 29_390.733173076923090475 * 1e18, + debt: 29_027.884615384615398000 * 1e18, collateral: 1_000 * 1e18, - bond: 8_708.365384615384619400 * 1e18 + bond: 440.653154676640135945 * 1e18 }); /******************************/ @@ -322,11 +322,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { lup: 3_844.432207828138682757 * 1e18, poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 28.474336477334401997 * 1e18, - poolDebt: 109_467.656250000000050475 * 1e18, + encumberedCollateral: 28.379953604109725159 * 1e18, + poolDebt: 109_104.807692307692358000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 2_736.691406250000001262 * 1e18, + minDebtAmount: 2_727.620192307692308950 * 1e18, loans: 4, maxBorrower: address(_borrower5), interestRate: 0.05 * 1e18, @@ -335,10 +335,10 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 10_708.365384615384619400 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 2_440.653154676640135945 * 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), 141_291.634615384615380600 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender3), 149_559.346845323359864055 * 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); @@ -370,7 +370,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertKicker({ kicker: _lender3, claimable: 0, - locked: 8_708.365384615384619400 * 1e18 + locked: 440.653154676640135945 * 1e18 }); // assert kicked auction _assertAuction( @@ -378,15 +378,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender3, - bondSize: 8_708.365384615384619400 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 440.653154676640135945 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 8_708.365384615384619400 * 1e18, - auctionPrice: 123_636.939803752939029248 * 1e18, - debtInAuction: 29_390.733173076923090475 * 1e18, - thresholdPrice: 29.390733173076923090 * 1e18, - neutralPrice: 30.631675240384615148 * 1e18 + referencePrice: 33.434416162151016873 * 1e18, + totalBondEscrowed: 440.653154676640135945 * 1e18, + auctionPrice: 8_559.210537510660319488 * 1e18, + debtInAuction: 29_027.884615384615398000 * 1e18, + thresholdPrice: 29.027884615384615398 * 1e18, + neutralPrice: 33.434416162151016873 * 1e18 }) ); } @@ -438,9 +438,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender2, index: 2499, borrower: _borrower1, - debt: 35_471.574519230769247125 * 1e18, + debt: 35_033.653846153846170000 * 1e18, collateral: 1_000 * 1e18, - bond: 10_510.096153846153851000 * 1e18 + bond: 531.8227728856001640720 * 1e18 }); /******************************/ @@ -453,11 +453,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { lup: 3_844.432207828138682757 * 1e18, poolSize: 121_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 30.056063249306572459 * 1e18, - poolDebt: 115_548.497596153846207125 * 1e18, + encumberedCollateral: 29.942152885069893516 * 1e18, + poolDebt: 115_110.576923076923130000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 2_888.712439903846155178 * 1e18, + minDebtAmount: 2_877.764423076923078250 * 1e18, loans: 4, maxBorrower: address(_borrower5), interestRate: 0.05 * 1e18, @@ -466,9 +466,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - assertEq(_quote.balanceOf(address(_pool)), 16_510.096153846153851000 * 1e18); // increased with the amount sent to cover bond + assertEq(_quote.balanceOf(address(_pool)), 6_531.822772885600164072 * 1e18); // increased with the amount sent to cover bond assertEq(_quote.balanceOf(_lender1), 49_000 * 1e18); - assertEq(_quote.balanceOf(_lender2), 119_489.903846153846149000 * 1e18); // decreased with the amount sent to cover bond + assertEq(_quote.balanceOf(_lender2), 129_468.177227114399835928 * 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); @@ -495,7 +495,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertKicker({ kicker: _lender2, claimable: 0, - locked: 10_510.096153846153851000 * 1e18 + locked: 531.822772885600164072 * 1e18 }); // assert kicked auction _assertAuction( @@ -503,15 +503,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender2, - bondSize: 10_510.096153846153851000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 531.822772885600164072 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 10_510.096153846153851000 * 1e18, - auctionPrice: 123_636.939803752939029248 * 1e18, - debtInAuction: 35_471.574519230769247125 * 1e18, - thresholdPrice: 35.471574519230769247 * 1e18, - neutralPrice: 36.969263221153845869 * 1e18 + referencePrice: 40.351881575009847950 * 1e18, + totalBondEscrowed: 531.822772885600164072 * 1e18, + auctionPrice: 10_330.081683202521075200 * 1e18, + debtInAuction: 35_033.653846153846170000 * 1e18, + thresholdPrice: 35.033653846153846170 * 1e18, + neutralPrice: 40.351881575009847950 * 1e18 }) ); } @@ -556,9 +556,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); /******************************/ @@ -571,11 +571,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { lup: 3_844.432207828138682757 * 1e18, poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.101746319376146305 * 1e18, - poolDebt: 100_346.394230769230815500 * 1e18, + encumberedCollateral: 26.036654682669472623 * 1e18, + poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, - minDebtAmount: 2_508.659855769230770388 * 1e18, + minDebtAmount: 2_502.403846153846155000 * 1e18, loans: 4, maxBorrower: address(_borrower5), interestRate: 0.05 * 1e18, @@ -584,8 +584,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { ); // assert balances - no change, bond was covered from deposit - 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(address(_pool)), 11_303.898727363200093756 * 1e18); // increased by amount used to cover auction bond + assertEq(_quote.balanceOf(_lender1), 48_696.101272636799906244 * 1e18); // reduced by amount used to cover auction bond assertEq(_quote.balanceOf(_lender2), 140_000 * 1e18); assertEq(_quote.balanceOf(_borrower1), 20_000 * 1e18); assertEq(_quote.balanceOf(_borrower2), 20_000 * 1e18); @@ -618,7 +618,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { _assertKicker({ kicker: _lender1, claimable: 0, - locked: 6_005.769230769230772000 * 1e18 + locked: 303.898727363200093756 * 1e18 }); // assert kicked auction _assertAuction( @@ -626,15 +626,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 6_005.769230769230772000 * 1e18, - auctionPrice: 123_636.939803752939029248 * 1e18, - debtInAuction: 20_269.471153846153855500 * 1e18, - thresholdPrice: 20.269471153846153855 * 1e18, - neutralPrice: 21.020192307692307702 * 1e18 + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 303.898727363200093756 * 1e18, + auctionPrice: 5_902.903818972869185792 * 1e18, + debtInAuction: 20_019.230769230769240000 * 1e18, + thresholdPrice: 20.019230769230769240 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -665,9 +665,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower1, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -689,9 +689,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { address head; address next; address prev; - (, , , , , , head, next, prev, ) = _pool.auctionInfo(address(0)); + (, , , , , , head, next, prev) = _pool.auctionInfo(address(0)); assertEq(head, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -701,9 +701,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower5, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -722,11 +722,11 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { assertEq(borrower, address(0)); assertEq(thresholdPrice, 0); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower1); @@ -736,9 +736,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower4, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -757,15 +757,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { assertEq(borrower, address(0)); assertEq(thresholdPrice, 0); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower5); @@ -775,9 +775,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower3, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -796,19 +796,19 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { assertEq(borrower, address(0)); assertEq(thresholdPrice, 0); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower4); @@ -818,9 +818,9 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, index: 2500, borrower: _borrower2, - debt: 20_269.471153846153855500 * 1e18, + debt: 20_019.230769230769240000 * 1e18, collateral: 1_000 * 1e18, - bond: 6_005.769230769230772000 * 1e18 + bond: 303.898727363200093756 * 1e18 }); (borrower, thresholdPrice) = _pool.loanInfo(1); @@ -839,23 +839,23 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { assertEq(borrower, address(0)); assertEq(thresholdPrice, 0); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, _borrower2); assertEq(prev, _borrower4); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower3); @@ -867,8 +867,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { lup: 3_844.432207828138682757 * 1e18, poolSize: 111_000 * 1e18, pledgedCollateral: 5_000 * 1e18, - encumberedCollateral: 26.362112866202841031 * 1e18, - poolDebt: 101_347.355769230769277500 * 1e18, + encumberedCollateral: 26.036654682669472623 * 1e18, + poolDebt: 100_096.153846153846200000 * 1e18, actualUtilization: 0, targetUtilization: 1e18, minDebtAmount: 0, @@ -888,15 +888,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 101_347.355769230769277500 * 1e18, - thresholdPrice: 20.278728733568272609 * 1e18, - neutralPrice: 21.020192307692307702 * 1e18 + debtInAuction: 100_096.153846153846200000 * 1e18, + thresholdPrice: 20.028374057845207515 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -904,7 +904,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower2, maxDepth: 1, - settledDebt: 20_269.471153846153855500 * 1e18 + settledDebt: 20_019.230769230769240000 * 1e18 }); _assertAuction( @@ -915,32 +915,32 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 81_114.914934273090436936 * 1e18, + debtInAuction: 80_113.496231380830061171 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower4); assertEq(prev, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower5); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower4); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -951,15 +951,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower4, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 81_114.914934273090436936 * 1e18, - thresholdPrice: 20.278728733568272609 * 1e18, - neutralPrice: 21.125293269230769068 * 1e18 + debtInAuction: 80_113.496231380830061171 * 1e18, + thresholdPrice: 20.028374057845207515 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -967,7 +967,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower4, maxDepth: 5, - settledDebt: 20_269.471153846153855500 * 1e18 + settledDebt: 20_019.230769230769240000 * 1e18 }); _assertAuction( @@ -978,32 +978,32 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 60_836.186200704817827702 * 1e18, + debtInAuction: 60_085.122173535622545879 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower1); assertEq(next, _borrower5); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower1); assertEq(next, _borrower3); assertEq(prev, _borrower1); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, _borrower5); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower1); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1014,15 +1014,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower1, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 60_836.186200704817827702 * 1e18, - thresholdPrice: 20.278728733568272609 * 1e18, - neutralPrice: 21.020192307692307702 * 1e18 + debtInAuction: 60_085.122173535622545879 * 1e18, + thresholdPrice: 20.028374057845207515 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -1030,7 +1030,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower1, maxDepth: 5, - settledDebt: 20_269.471153846153855500 * 1e18 + settledDebt: 20_019.230769230769240000 * 1e18 }); _assertAuction( @@ -1041,32 +1041,32 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 40_557.457467136545218468 * 1e18, + debtInAuction: 40_056.748115690415030586 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower5); assertEq(next, _borrower3); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, _borrower5); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower5); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1077,15 +1077,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower5, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 40_557.457467136545218468 * 1e18, - thresholdPrice: 20.278728733568272609 * 1e18, - neutralPrice: 21.230919735576922742 * 1e18 + debtInAuction: 40_056.748115690415030586 * 1e18, + thresholdPrice: 20.028374057845207515 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -1093,7 +1093,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower5, maxDepth: 5, - settledDebt: 20_269.471153846153855500 * 1e18 + settledDebt: 20_019.230769230769240000 * 1e18 }); _assertAuction( @@ -1104,32 +1104,32 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 20_278.728733568272609234 * 1e18, + debtInAuction: 20_028.374057845207515293 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) ); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, _borrower3); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1140,15 +1140,15 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { borrower: _borrower3, active: true, kicker: _lender1, - bondSize: 6_005.769230769230772000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 303.898727363200093756 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 23.058218042862770257 * 1e18, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, - debtInAuction: 20_278.728733568272609234 * 1e18, - thresholdPrice: 20.278728733568272609 * 1e18, - neutralPrice: 21.125293269230769068 * 1e18 + debtInAuction: 20_028.374057845207515293 * 1e18, + thresholdPrice: 20.028374057845207515 * 1e18, + neutralPrice: 23.058218042862770257 * 1e18 }) ); @@ -1158,7 +1158,7 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { from: _lender1, borrower: _borrower3, maxDepth: 5, - settledDebt: 20_269.471153846153855500 * 1e18 + settledDebt: 20_019.230769230769240000 * 1e18 }); _assertAuction( @@ -1169,8 +1169,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 30_028.846153846153860000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 1_519.493636816000468780 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1178,23 +1178,23 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { }) ); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower1); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower1); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower5); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower5); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower4); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower4); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower3); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower3); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); - (, , , , , , head, next, prev, ) = _pool.auctionInfo(_borrower2); + (, , , , , , head, next, prev) = _pool.auctionInfo(_borrower2); assertEq(head, address(0)); assertEq(next, address(0)); assertEq(prev, address(0)); @@ -1204,8 +1204,8 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 9_645.701045977641587831 * 1e18, - pledgedCollateral: 4_973.703521110015138686 * 1e18, + poolSize: 10_896.988687385325019536 * 1e18, + pledgedCollateral: 4_974.029127598743052356 * 1e18, encumberedCollateral: 0, poolDebt: 0, actualUtilization: 0, @@ -1227,43 +1227,43 @@ contract ERC20PoolLiquidationsLenderKickAuctionTest is ERC20HelperContract { // assert lender1 as a kicker _assertKicker({ kicker: _lender1, - claimable: 30_028.846153846153860000 * 1e18, + claimable: 1_519.493636816000468780 * 1e18, locked: 0 }); // assert borrowers after settle _assertBorrower({ borrower: _borrower1, borrowerDebt: 0, - borrowerCollateral: 994.750357720674222924 * 1e18, - borrowert0Np: 21.020192307692307702 * 1e18, + borrowerCollateral: 994.816126720381654072 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 994.751412316543869246 * 1e18, - borrowert0Np: 21.020192307692307702 * 1e18, + borrowerCollateral: 994.816209695351969626 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower3, borrowerDebt: 0, - borrowerCollateral: 994.725169378126588635 * 1e18, - borrowert0Np: 21.125293269230769068 * 1e18, + borrowerCollateral: 994.790290743828729516 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower4, borrowerDebt: 0, - borrowerCollateral: 994.751412316543869246 * 1e18, - borrowert0Np: 21.125293269230769068 * 1e18, + borrowerCollateral: 994.816209695351969626 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower5, borrowerDebt: 0, - borrowerCollateral: 994.725169378126588635 * 1e18, - borrowert0Np: 21.230919735576922742 * 1e18, + borrowerCollateral: 994.790290743828729516 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol index 4298bcb0f..bf934eace 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsMisc.t.sol @@ -106,14 +106,14 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ @@ -186,7 +186,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -198,17 +198,17 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.272843317722413899 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.998794730435100100 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.489662805046791054 * 1e18, + debt: 19.272843317722413898 * 1e18, collateral: 2 * 1e18, - bond: 0.192728433177224139 * 1e18, - transferAmount: 0.192728433177224139 * 1e18 + bond: 0.292568312161539120 * 1e18, + transferAmount: 0.292568312161539120 * 1e18 }); _assertBucket({ @@ -223,15 +223,15 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.192728433177224139 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.292568312161539120 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.721295865031779605 * 1e18, - totalBondEscrowed: 0.192728433177224139 * 1e18, - auctionPrice: 323.783767737736553472 * 1e18, - debtInAuction: 19.489662805046791055 * 1e18, - thresholdPrice: 9.744831402523395527 * 1e18, - neutralPrice: 10.118242741804267296 * 1e18 + referencePrice: 11.099263219668902589 * 1e18, + totalBondEscrowed: 0.292568312161539120 * 1e18, + auctionPrice: 2_841.411384235239062784 * 1e18, + debtInAuction: 19.272843317722413899 * 1e18, + thresholdPrice: 9.636421658861206949 * 1e18, + neutralPrice: 11.099263219668902589 * 1e18 }) ); @@ -275,32 +275,32 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.192728433177224139 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.292568312161539120 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 3 hours, - kickMomp: 9.721295865031779605 * 1e18, - totalBondEscrowed: 0.192728433177224139 * 1e18, - auctionPrice: 80.945941934434138368 * 1e18, - debtInAuction: 19.489662805046791055 * 1e18, - thresholdPrice: 9.744966562937366149 * 1e18, - neutralPrice: 10.118242741804267296 * 1e18 + referencePrice: 11.099263219668902589 * 1e18, + totalBondEscrowed: 0.292568312161539120 * 1e18, + auctionPrice: 31.393457155209254668 * 1e18, + debtInAuction: 19.272843317722413899 * 1e18, + thresholdPrice: 9.636555315636456019 * 1e18, + neutralPrice: 11.099263219668902589 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.489933125874732299 * 1e18, + borrowerDebt: 19.273110631272912039 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, - borrowerCollateralization: 0.987669594447545452 * 1e18 + borrowert0Np: 11.096767433127708186 * 1e18, + borrowerCollateralization: 0.998780877385080338 * 1e18 }); _take({ from: _lender, borrower: _borrower, maxCollateral: 2.0 * 1e18, - bondChange: 0.192728433177224139 * 1e18, - givenAmount: 20.854228444685963559 * 1e18, - collateralTaken: 0.257631549479994909 * 1e18, + bondChange: 0.292568312161539120 * 1e18, + givenAmount: 19.722195067961733839 * 1e18, + collateralTaken: 0.628226288377708765 * 1e18, isReward: false }); @@ -313,7 +313,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -324,7 +324,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower, borrowerDebt: 0, - borrowerCollateral: 1.742368450520005091 * 1e18, + borrowerCollateral: 1.371773711622291235 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -332,11 +332,11 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 7.989580407145861718 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 63_008.829558890303235305 * 1e18, - pledgedCollateral: 1_001.742368450520005091 * 1e18, + poolSize: 63_008.829556315248414267 * 1e18, + pledgedCollateral: 1_001.371773711622291235 * 1e18, encumberedCollateral: 821.863722498661263922 * 1e18, poolDebt: 7_989.580407145861717463 * 1e18, - actualUtilization: 0.121389301029167552 * 1e18, + actualUtilization: 0.121389232097000537 * 1e18, targetUtilization: 0.822758145478171949 * 1e18, minDebtAmount: 798.958040714586171746 * 1e18, loans: 1, @@ -348,7 +348,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _removeLiquidity({ from: _lender, - amount: 8_008.368802555852473042 * 1e18, + amount: 8_008.368802228565193289 * 1e18, index: _i9_72, newLup: 9.624807173121239337 * 1e18, lpRedeem: 8_007.361474606956967924 * 1e18 @@ -364,7 +364,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _removeLiquidity({ from: _lender, - amount: 25_000.037740139097750000 * 1e18, + amount: 25_000.037739117392250000 * 1e18, index: _i9_62, newLup: 9.529276179422528643 * 1e18, lpRedeem: 25_000.000000000000000000 * 1e18 @@ -383,15 +383,15 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { amount: 22_000 * 1e18, index: _i9_52, newLup: 9.529276179422528643 * 1e18, - lpRedeem: 21_999.966788727729901404 * 1e18 + lpRedeem: 21_999.966789626828026872 * 1e18 }); _assertBucket({ index: _i9_52, - lpBalance: 8_000.033211272270098596 * 1e18, + lpBalance: 8_000.033210373171973128 * 1e18, collateral: 0, - deposit: 8_000.045288166917300000 * 1e18, - exchangeRate: 1.000001509605563911 * 1e18 + deposit: 8_000.045286940870700000 * 1e18, + exchangeRate: 1.000001509564695691 * 1e18 }); _assertRemoveAllLiquidityLupBelowHtpRevert({ @@ -405,11 +405,11 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 7.989580407145861718 * 1e18, lup: 9.529276179422528643 * 1e18, - poolSize: 8_000.423016195353009887 * 1e18, - pledgedCollateral: 1_001.742368450520005091 * 1e18, + poolSize: 8_000.423014969290972838 * 1e18, + pledgedCollateral: 1_001.371773711622291235 * 1e18, encumberedCollateral: 838.521600516187410670 * 1e18, poolDebt: 7_990.503913730158190391 * 1e18, - actualUtilization: 0.121389301029167552 * 1e18, + actualUtilization: 0.121389232097000537 * 1e18, targetUtilization: 0.822758145478171949 * 1e18, minDebtAmount: 799.050391373015819039 * 1e18, loans: 1, @@ -422,7 +422,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 7_990.503913730158190391 * 1e18, borrowerCollateral: 1_000.00 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.192575121957988603 * 1e18 }); @@ -433,11 +433,11 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 7.990503913730158191 * 1e18, lup: 9.529276179422528643 * 1e18, - poolSize: 8_001.213845441144339172 * 1e18, - pledgedCollateral: 1_001.742368450520005091 * 1e18, + poolSize: 8_001.213844211612533894 * 1e18, + pledgedCollateral: 1_001.371773711622291235 * 1e18, encumberedCollateral: 838.521600516187410670 * 1e18, poolDebt: 7_990.503913730158190391 * 1e18, - actualUtilization: 0.383638008977773077 * 1e18, + actualUtilization: 0.383637856267925676 * 1e18, targetUtilization: 0.829403289225492236 * 1e18, minDebtAmount: 799.050391373015819039 * 1e18, loans: 1, @@ -453,7 +453,7 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 8_084.412285638162564830 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 0.000000012349231999 * 1e18 }); @@ -465,11 +465,11 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { PoolParams({ htp: 0, lup: 0.000000099836282890 * 1e18, - poolSize: 8_083.134379679494060567 * 1e18, - pledgedCollateral: 1_001.742368450520005091 * 1e18, - encumberedCollateral: 81_714_595_700.439346767851204401 * 1e18, - poolDebt: 8_158.081492591040321202 * 1e18, - actualUtilization: 0.998661461633463484 * 1e18, + poolSize: 8_083.134377459926771461 * 1e18, + pledgedCollateral: 1_001.371773711622291235 * 1e18, + encumberedCollateral: 80_976_695_562.129442225570824234 * 1e18, + poolDebt: 8_084.412285638162564830 * 1e18, + actualUtilization: 0.998661461786925952 * 1e18, targetUtilization: 0.838521600515840801 * 1e18, minDebtAmount: 0, loans: 0, @@ -492,31 +492,31 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 80.844122856381625648 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 122.724126286659537773 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 0.000000099836282890 * 1e18, - totalBondEscrowed: 80.844122856381625648 * 1e18, - auctionPrice: 0.535858215296360576 * 1e18, - debtInAuction: 8_158.081492591040321202 * 1e18, - thresholdPrice: 8.158454900996626324 * 1e18, - neutralPrice: 8.573731444741769263 * 1e18 + referencePrice: 9.311653548504757974 * 1e18, + totalBondEscrowed: 122.724126286659537773 * 1e18, + auctionPrice: 2.327913387126189492 * 1e18, + debtInAuction: 8_084.412285638162564830 * 1e18, + thresholdPrice: 8.084782322086612071 * 1e18, + neutralPrice: 9.311653548504757974 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_158.454900996626324182 * 1e18, + borrowerDebt: 8_084.782322086612071679 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, - borrowerCollateralization: 0.000000012237155699 * 1e18 + borrowert0Np: 9.200228999102245332 * 1e18, + borrowerCollateralization: 0.000000012348666781 * 1e18 }); _take({ from: _lender, borrower: _borrower2, maxCollateral: 1_000.0 * 1e18, - bondChange: 5.358582152963605760 * 1e18, //TODO: review - givenAmount: 535.858215296360576000 * 1e18, + bondChange: 35.338516445234474376 * 1e18, + givenAmount: 2_327.913387126189492000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -524,12 +524,12 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { _assertPool( PoolParams({ htp: 0, - lup: 0.000000099836282890 * 1e18, - poolSize: 8_083.501615236504132602 * 1e18, - pledgedCollateral: 1.742368450520005091 * 1e18, - encumberedCollateral: 82_124_923_660.837160770168974387 * 1e18, - poolDebt: 8_199.047110922993196875 * 1e18, - actualUtilization: 0.998661461633463484 * 1e18, + lup: 9.529276179422528643 * 1e18, + poolSize: 8_083.498296802166583218 * 1e18, + pledgedCollateral: 1.371773711622291235 * 1e18, + encumberedCollateral: 607.832887025912931068 * 1e18, + poolDebt: 5_792.207451405657054680 * 1e18, + actualUtilization: 0.998661461786925952 * 1e18, targetUtilization: 0.838521600515840801 * 1e18, minDebtAmount: 0, loans: 0, @@ -540,9 +540,9 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_199.047110922993196875 * 1e18, + borrowerDebt: 5_792.207451405657054680 * 1e18, borrowerCollateral: 0, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); @@ -556,18 +556,18 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 8_100.565390045132587717 * 1e18 + settledDebt: 5_722.635152359337569948 * 1e18 }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 551.311957051027493010 * 1e18, - pledgedCollateral: 1.742368450520005091 * 1e18, + poolSize: 2_312.355002439841726602 * 1e18, + pledgedCollateral: 1.371773711622291235 * 1e18, encumberedCollateral: 0, poolDebt: 0, - actualUtilization: 0.998661461633463484 * 1e18, + actualUtilization: 0.998661461786925952 * 1e18, targetUtilization: 0.838521600515840801 * 1e18, minDebtAmount: 0, loans: 0, @@ -606,10 +606,10 @@ contract ERC20PoolLiquidationsMiscTest is ERC20HelperContract { }); _assertBucket({ index: _i9_52, - lpBalance: 8_000.033211272270098596 * 1e18, + lpBalance: 8_000.033210373171973128 * 1e18, collateral: 0, - deposit: 551.311957051027493215 * 1e18, - exchangeRate: 0.068913708542386244 * 1e18 + deposit: 2_312.355002439841725846 * 1e18, + exchangeRate: 0.289043175401015481 * 1e18 }); } } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol index 093c90a3c..f6416a7b4 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsScaled.t.sol @@ -127,7 +127,6 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint8 quotePrecisionDecimals_, uint16 startBucketId_ ) external tearDown { - uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 6, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 1, 18); uint256 startBucketId = bound(uint256(startBucketId_), 2000, 5388); @@ -217,7 +216,6 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { if (bucketQuote != 0) _pool.removeQuoteToken(type(uint256).max, startBucketId + i); } - // check bond transfer amount with rounding (uint256 claimableBond, ) = _pool.kickerInfo(_bidder); uint256 bondTransferAmount = claimableBond / _pool.quoteTokenScale(); @@ -238,7 +236,6 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint8 quotePrecisionDecimals_, uint16 startBucketId_ ) external tearDown { - uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 12, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 1, 18); uint256 startBucketId = bound(uint256(startBucketId_), 1, 7388 - BUCKETS_WITH_DEPOSIT); @@ -316,23 +313,20 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 auctionBondFactor, uint256 auctionBondSize, uint256 auctionKickTime, - uint256 auctionKickMomp, + uint256 auctionReferencePrice, uint256 auctionNeutralPrice, , , - , ) = _pool.auctionInfo(_borrower); - assertEq(auctionKicker, kicker); - assertGe(auctionBondFactor, 0.01 * 1e18); - assertLe(auctionBondFactor, 0.3 * 1e18); - assertGt(auctionBondSize, 0); - assertLt(auctionBondSize, _pool.depositSize()); - assertEq(auctionKickTime, _startTime + timeSinceStart); - assertGt(auctionKickMomp, _priceAt(_startBucketId + BUCKETS_WITH_DEPOSIT)); - assertLt(auctionKickMomp, _priceAt(_startBucketId)); - assertGt(auctionNeutralPrice, _priceAt(_startBucketId)); - assertLt(auctionNeutralPrice, Maths.wmul(_priceAt(_startBucketId), 1.1 * 1e18)); + assertEq(auctionKicker, kicker); + assertGe(auctionBondFactor, 0.01 * 1e18); + assertLe(auctionBondFactor, 0.3 * 1e18); + assertGt(auctionBondSize, 0); + assertLt(auctionBondSize, _pool.depositSize()); + assertEq(auctionKickTime, _startTime + timeSinceStart); + assertGt(auctionReferencePrice, _priceAt(_startBucketId + BUCKETS_WITH_DEPOSIT)); + assertGt(auctionNeutralPrice, _priceAt(_startBucketId)); } function _take(uint256 collateralToTake, address bidder) internal { @@ -376,8 +370,8 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } // confirm LP were awarded to the kicker - (address kicker, , , uint256 kickTime, uint256 kickMomp, uint256 neutralPrice, , , , ) = _pool.auctionInfo(_borrower); - uint256 auctionPrice = _auctionPrice(kickMomp, neutralPrice, kickTime); + (address kicker, , , uint256 kickTime, uint256 referencePrice, uint256 neutralPrice, , ,) = _pool.auctionInfo(_borrower); + uint256 auctionPrice = _auctionPrice(referencePrice, kickTime); if (auctionPrice < neutralPrice) { uint256 kickerLP = _kickerLP(bucketId); assertGt(kickerLP, lastKickerLP); @@ -447,12 +441,12 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { uint256 auctionDebt_, uint256 auctionCollateral_ ){ - (, , , uint256 kickTime, uint256 kickMomp, uint256 neutralPrice, , , , ) = _pool.auctionInfo(_borrower); - uint256 lastAuctionPrice = _auctionPrice(kickMomp, neutralPrice, kickTime); + (, , , uint256 kickTime, uint256 referencePrice, , , , ) = _pool.auctionInfo(_borrower); + uint256 lastAuctionPrice = _auctionPrice(referencePrice, kickTime); (uint256 lastAuctionDebt, uint256 lastAuctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); if (secondsToSkip != 0) { skip(secondsToSkip); - auctionPrice_ = _auctionPrice(kickMomp, neutralPrice, kickTime); + auctionPrice_ = _auctionPrice(referencePrice, kickTime); (uint256 auctionDebt, uint256 auctionCollateral, ) = _poolUtils.borrowerInfo(address(_pool), _borrower); // ensure auction price decreases and auction debt increases as time passes assertLt(auctionPrice_, lastAuctionPrice); @@ -473,7 +467,7 @@ contract ERC20PoolLiquidationsScaledTest is ERC20DSTestPlus { } function _kickerLP(uint256 bucketId) internal view returns (uint256) { - (address kicker, , , , , , , , , ) = _pool.auctionInfo(_borrower); + (address kicker, , , , , , , , ) = _pool.auctionInfo(_borrower); (uint256 kickerLP, ) = _pool.lenderInfo(bucketId, kicker); return kickerLP; } diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol index 296769888..9ad4e9a1c 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsSettle.t.sol @@ -27,7 +27,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _mintQuoteAndApproveTokens(_lender1, 120_000 * 1e18); _mintCollateralAndApproveTokens(_borrower, 4 * 1e18); - _mintCollateralAndApproveTokens(_borrower2, 1_000 * 1e18); + _mintCollateralAndApproveTokens(_borrower2, 1_001 * 1e18); _mintCollateralAndApproveTokens(_lender1, 4 * 1e18); // Lender adds Quote token accross 5 prices @@ -108,14 +108,14 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ @@ -150,7 +150,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -162,17 +162,17 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 11.194764859809874960 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -180,23 +180,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertBucket({ index: _i9_91, @@ -235,23 +235,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.977074177773911990 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853900422492752583 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_977.074177773911990382 * 1e18, + borrowerDebt: 9_853.900422492752583093 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974363394700228467 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986542937133981323 * 1e18 }); // take partial 800 collateral @@ -259,8 +259,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 800 * 1e18, - bondChange: 5.224891622608908288 * 1e18, - givenAmount: 522.489162260890828800 * 1e18, + bondChange: 34.456860650725712362 * 1e18, + givenAmount: 2_269.834595673383616 * 1e18, collateralTaken: 800 * 1e18, isReward: true }); @@ -270,44 +270,44 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 103.758834042401124745 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 184.034734289495351885 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 103.758834042401124745 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 10_158.205099579803908909 * 1e18, - thresholdPrice: 50.791025497899019544 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 184.034734289495351885 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 7_618.522687470094679893 * 1e18, + thresholdPrice: 38.092613437350473399 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_158.205099579803908909 * 1e18, + borrowerDebt: 7_618.522687470094679893 * 1e18, borrowerCollateral: 200 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.191397904841159446 * 1e18 + borrowert0Np: 43.276046239860018335 * 1e18, + borrowerCollateralization: 0.255201599150450493 * 1e18 }); _assertBucket({ index: _i9_91, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_012.736560735960384000 * 1e18, - exchangeRate: 1.006368280367980192 * 1e18 + deposit: 2_012.735939051273346000 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _assertBucket({ index: _i9_81, lpBalance: 5_000 * 1e18, collateral: 0, - deposit: 5_031.841401839900960000 * 1e18, - exchangeRate: 1.006368280367980192 * 1e18 + deposit: 5_031.839847628183365000 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _assertBucket({ index: _i9_72, lpBalance: 11_000 * 1e18, collateral: 0, - deposit: 11_070.051084047782112000 * 1e18, - exchangeRate: 1.006368280367980192 * 1e18 + deposit: 11_070.047664782003403000 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _assertBucket({ index: _i9_62, @@ -322,24 +322,24 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_162.015140830231868754 * 1e18, + borrowerDebt: 7_621.380169222238377339 * 1e18, borrowerCollateral: 200 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.191326144082827145 * 1e18 + borrowert0Np: 43.276046239860018335 * 1e18, + borrowerCollateralization: 0.255105916492388742 * 1e18 }); _assertBucket({ index: _i9_91, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_012.736560735960384000 * 1e18, - exchangeRate: 1.006368280367980192 * 1e18 + deposit: 2_012.735939051273346000 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 10_019.485661146575724663 * 1e18 + settledDebt: 7_514.484899441934449285 * 1e18 }); _assertAuction( @@ -350,8 +350,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 103.758834042401124745 * 1e18, + referencePrice: 0, + totalBondEscrowed: 184.034734289495351885 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -362,7 +362,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBucket({ @@ -383,8 +383,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { index: _i9_72, lpBalance: 11_000 * 1e18, collateral: 0, - deposit: 8_807.556808084119380150 * 1e18, - exchangeRate: 0.800686982553101762 * 1e18 + deposit: 10_525.670272469343333339 * 1e18, + exchangeRate: 0.956879115679031213 * 1e18 }); _assertBucket({ index: _i9_62, @@ -397,7 +397,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { PoolParams({ htp: 9.771304290202671377 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 63_807.556808084119380150 * 1e18, + poolSize: 65_525.670272469343333339 * 1e18, pledgedCollateral: 2 * 1e18, encumberedCollateral: 2.010288427770370775 * 1e18, poolDebt: 19.542608580405342754 * 1e18, @@ -432,7 +432,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -444,17 +444,17 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 11.194764859809874960 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -462,23 +462,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertBucket({ index: _i9_91, @@ -518,30 +518,30 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 73 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, auctionPrice: 0, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.980303582194898667 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.857089957723356708 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_980.303582194898667002 * 1e18, + borrowerDebt: 9_857.089957723356708150 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974048112361512224 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986223713766031127 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_840.828245192307696845 * 1e18 + settledDebt: 9_719.336538461538466020 * 1e18 }); _assertAuction( @@ -552,8 +552,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 98.533942419792216457 * 1e18, + referencePrice: 0, + totalBondEscrowed: 149.577873638769639523 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -564,29 +564,29 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBucket({ index: _i9_91, lpBalance: 2_000 * 1e18, - collateral: 202.986484470302055715 * 1e18, + collateral: 202.986026776638220827 * 1e18, deposit: 0, - exchangeRate: 1.006527243605609346 * 1e18 + exchangeRate: 1.006524974089276386 * 1e18 }); _assertBucket({ index: _i9_81, lpBalance: 5_000 * 1e18, - collateral: 512.553559942792076265 * 1e18, + collateral: 512.552404237685039184 * 1e18, deposit: 0, - exchangeRate: 1.006527243605609346 * 1e18 + exchangeRate: 1.006524974089276386 * 1e18 }); _assertBucket({ index: _i9_72, lpBalance: 11_000 * 1e18, - collateral: 284.459955586905868020 * 1e18, - deposit: 8_290.291541398584037503 * 1e18, - exchangeRate: 1.005055539219335976 * 1e18 + collateral: 284.461568985676739989 * 1e18, + deposit: 8_290.291541398624686508 * 1e18, + exchangeRate: 1.005056965067230573 * 1e18 }); _assertBucket({ index: _i9_62, @@ -595,9 +595,19 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { deposit: 25_000 * 1e18, exchangeRate: 1 * 1e18 }); + + // borrower can re-open a loan once their previous loan is fully settled + _drawDebt({ + from: _borrower2, + borrower: _borrower2, + amountToBorrow: 5 * 1e18, + limitIndex: _i9_72, + collateralToPledge: 1 * 1e18, + newLup: 9.721295865031779605 * 1e18 + }); } - function testSettleAuctionReverts() external tearDown { + function testSettleAuctionReverts() external { // Borrower2 borrows _borrow({ from: _borrower2, @@ -619,10 +629,10 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -630,23 +640,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: kickTime, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); // settle should revert on an kicked auction but 72 hours not passed (there's still debt to settle and collateral to be auctioned) @@ -656,30 +666,30 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { }); // skip ahead so take can be called on the loan - skip(10 hours); + skip(12.5 hours); _assertAuction( AuctionParams({ borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: kickTime, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.977074177773911990 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 1.192934859200383004 * 1e18, + debtInAuction: 9853.394241979221645667 * 1e18, + thresholdPrice: 9.854026971684066190 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_977.074177773911990382 * 1e18, + borrowerDebt: 9_854.026971684066190794 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974363394700228467 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986530267571451282 * 1e18 }); _addLiquidityWithPenalty({ @@ -690,12 +700,12 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lpAward: 99.987671232876712300 * 1e18, newLup: 9.721295865031779605 * 1e18 }); - + _addLiquidity({ from: _lender1, amount: 100 * 1e18, index: _i9_91, - lpAward: 99.367201799558744044 * 1e18, + lpAward: 99.366617416827728755 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -704,8 +714,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 18.109156626307515503 * 1e18, + givenAmount: 1_192.934859200383004000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -738,32 +748,33 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.367201799558744044 * 1e18, - depositTime: _startTime + 100 days + 10 hours + lpBalance: 99.366617416827728755 * 1e18, + depositTime: _startTime + 100 days + 12.5 hours }); // settle to make buckets insolvent // settle should work because there is still debt to settle but no collateral left to auction (even if 72 hours didn't pass from kick) _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_028.889031920233428709 * 1e18, + borrowerDebt: 8679.201269109990702794 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, 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 vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(_i9_91, 2_099.367201799558744044 * 1e18); + emit BucketBankruptcy(_i9_91, 2_099.366617416827728755 * 1e18); vm.expectEmit(true, true, false, true); emit BucketBankruptcy(_i9_81, 5_000 * 1e18); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 8_560.569020353099739628 * 1e18 }); // bucket is insolvent, balances are resetted @@ -785,7 +796,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lender: _lender1, index: _i9_91, lpBalance: 0, - depositTime: _startTime + 100 days + 10 hours + depositTime: _startTime + 100 days + 12.5 hours }); // cannot add liquidity in same block when bucket marked insolvent @@ -830,7 +841,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lender: _lender1, index: _i9_91, lpBalance: 149.668739373743648296 * 1e18, - depositTime: _startTime + 100 days + 10 hours + 1 hours + depositTime: _startTime + 100 days + 12.5 hours + 1 hours }); // bucket is healthy again _assertBucket({ @@ -856,7 +867,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lender: _lender, index: _i9_91, lpBalance: 1_000 * 1e18, - 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) + depositTime: _startTime + 100 days + 12.5 hours + 1 // _i9_91 bucket insolvency time + 1 (since deposit in _i9_52 from bucket was done before _i9_91 target bucket become insolvent) }); _pool.addQuoteToken(1_000 * 1e18, _i9_52, block.timestamp + 1 minutes, false); @@ -866,7 +877,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { lender: _lender, index: _i9_91, lpBalance: 2_000 * 1e18, - depositTime: _startTime + 100 days + 10 hours + 1 hours // time of deposit in _i9_52 from bucket (since deposit in _i9_52 from bucket was done after _i9_91 target bucket become insolvent) + depositTime: _startTime + 100 days + 12.5 hours + 1 hours // time of deposit in _i9_52 from bucket (since deposit in _i9_52 from bucket was done after _i9_91 target bucket become insolvent) }); // ensure bucket bankruptcy when moving amounts from an unbalanced bucket leave bucket healthy @@ -874,8 +885,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { index: _i9_72, lpBalance: 11_000 * 1e18, collateral: 0 * 1e18, - deposit: 9_036.877963971180232637 * 1e18, - exchangeRate: 0.821534360361016385 * 1e18 + deposit: 9_565.123570257669797761 * 1e18, + exchangeRate: 0.869556688205242709 * 1e18 }); _pool.moveQuoteToken(10000000000 * 1e18, _i9_72, _i9_91, type(uint256).max, false); @@ -905,16 +916,16 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2 }); - + uint256 kickTime = _startTime + 100 days; _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -922,23 +933,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: kickTime, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); // skip ahead so take can be called on the loan @@ -949,23 +960,23 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: kickTime, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.977074177773911990 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853900422492752583 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_977.074177773911990382 * 1e18, + borrowerDebt: 9_853.900422492752583093 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974363394700228467 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986542937133981323 * 1e18 }); // add liquidity in same block should be possible as debt was not yet settled / bucket is not yet insolvent @@ -973,7 +984,7 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender1, amount: 100 * 1e18, index: _i9_91, - lpAward: 99.367201799558744044 * 1e18, + lpAward: 99.367232491646341844 * 1e18, newLup: 9.721295865031779605 * 1e18 }); @@ -982,8 +993,8 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 43.071075813407140453 * 1e18, + givenAmount: 2_837.29324459172952 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -991,34 +1002,34 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { _assertLenderLpBalance({ lender: _lender1, index: _i9_91, - lpBalance: 99.367201799558744044 * 1e18, + lpBalance: 99.367232491646341844 * 1e18, depositTime: _startTime + 100 days + 10 hours }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_028.889031920233428709 * 1e18, + borrowerDebt: 7_059.678253714430204093 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertBucket({ index: _i9_91, - lpBalance: 2_099.367201799558744044 * 1e18, + lpBalance: 2_099.367232491646341844 * 1e18, collateral: 0, - deposit: 2_112.736560735960384000 * 1e18, - exchangeRate: 1.006368280367980193 * 1e18 + deposit: 2_112.735939051273346000 * 1e18, + exchangeRate: 1.006367969525636674 * 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); + emit BucketBankruptcy(_i9_91, 2_099.367232491646341844 * 1e18); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 6_963.271989687033445101 * 1e18 }); // bucket is insolvent, balances are resetted @@ -1029,7 +1040,6 @@ contract ERC20PoolLiquidationsSettleTest is ERC20HelperContract { deposit: 0, exchangeRate: 1 * 1e18 }); - } } @@ -1075,62 +1085,50 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { _mintCollateralAndApproveTokens(actor8, type(uint256).max); } - function testSettleAndBankruptcyOnHPBWithTinyDeposit() external { + function test_regression_bankruptcy_on_hpb_with_tiny_deposit() external { + // add liquidity to bucket 2572 changePrank(actor6); _pool.addQuoteToken(2_000_000 * 1e18, 2572, block.timestamp + 100, false); skip(100 days); - ERC20Pool(address(_pool)).drawDebt(actor6, 1000000 * 1e18, 7388, 372.489032271806320214 * 1e18); + + // borrower 6 draws debt and becomes undercollateralized due to interest accrual + ERC20Pool(address(_pool)).drawDebt(actor6, 1_000_000 * 1e18, 7388, 372.489032271806320214 * 1e18); skip(100 days); + // borrower 1 kicks borrower 6 and draws debt before auction 6 is settled changePrank(actor1); - _pool.updateInterest(); _pool.kick(actor6, 7388); skip(100 hours); - ERC20Pool(address(_pool)).drawDebt(actor1, 1000000 * 1e18, 7388, 10066231386838.450530455239517417 * 1e18); + ERC20Pool(address(_pool)).drawDebt(actor1, 1_000_000 * 1e18, 7388, 10_066_231_386_838.450530455239517417 * 1e18); skip(100 days); + // another actor kicks borrower 1 changePrank(actor2); - _pool.updateInterest(); _pool.kick(actor1, 7388); skip(10 days); + // attempt to deposit tiny amount into bucket 2571, creating new HPB changePrank(actor3); + vm.expectRevert(abi.encodeWithSignature('AuctionNotCleared()')); _pool.addQuoteToken(2, 2571, block.timestamp + 100, false); - (uint256 bucketLps, uint256 collateral, , uint256 deposit, ) = _pool.bucketInfo(2571); - assertEq(bucketLps, 2); - assertEq(collateral, 0); - assertEq(deposit, 2); - (uint256 borrowerDebt, uint256 borrowerCollateral, ) = _pool.borrowerInfo(actor1); - assertEq(borrowerDebt, 985_735.245058880968054979 * 1e18); - assertEq(borrowerCollateral, 10066231386838.450530455239517417 * 1e18); - - changePrank(actor8); - _pool.updateInterest(); - vm.expectEmit(true, true, false, true); - emit BucketBankruptcy(2571, 2); - ERC20Pool(address(_pool)).settle(actor1, 1); - - (bucketLps, collateral, , deposit, ) = _pool.bucketInfo(2571); - assertEq(bucketLps, 0); // entire LP removed from bucket 2571 - assertEq(collateral, 0); // no collateral added in bucket 2571 - assertEq(deposit, 0); // entire deposit from bucket 2571 used to settle - (borrowerDebt, borrowerCollateral, ) = _pool.borrowerInfo(actor1); - assertEq(borrowerDebt, 985_735.245058880968054978 * 1e18); // decreased with 1 - assertEq(borrowerCollateral, 10066231386838.450530455239517417 * 1e18); // same as before settle + // Previous test added quote token successfully, then settled auction 1, bankrupting bucket 2571. + // This is not possible because we prevent depositing into bucket when an uncleared auction exists. } - function testSettleWithReserves() external tearDown { + function test_regression_settle_with_reserves() external tearDown { changePrank(actor2); - - ERC20Pool(address(_pool)).updateInterest(); _addInitialLiquidity({ from: actor2, amount: 112_807_891_516.8015826259279868 * 1e18, index: 2572 }); - ERC20Pool(address(_pool)).updateInterest(); + // no reserves + (uint256 reserves, uint256 claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 0); + assertEq(claimableReserves, 0); + _drawDebtNoLupCheck({ from: actor2, borrower: actor2, @@ -1139,34 +1137,35 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { collateralToPledge: 21_009_851.171858165566322122 * 1e18 }); + // origination fee goes to reserves + (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 54_234_563.229231556141209574 * 1e18); + assertEq(claimableReserves, 0); + // skip some time to make actor2 undercollateralized skip(200 days); + ERC20Pool(address(_pool)).updateInterest(); + // check reserves after interest accrual + (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 289_462_063.392449001089942144 * 1e18); + assertEq(claimableReserves, 0); + // kick actor2 changePrank(actor4); - - ERC20Pool(address(_pool)).updateInterest(); _kick({ from: actor4, borrower: actor2, - debt: 58_679_160_247.182050965227801655 * 1e18, + debt: 58_026_363_656.051471906282127718 * 1e18, collateral: 21_009_851.171858165566322122 * 1e18, - bond: 580_263_636.560514719062821277 * 1e18, - transferAmount: 580_263_636.560514719062821277 * 1e18 - }); - - changePrank(actor1); - - ERC20Pool(address(_pool)).updateInterest(); - _kickReserveAuction({ - from: actor1, - remainingReserves: 642_374_111.754807749608166225 * 1e18, - price: 1_000_000_000 * 1e18, - epoch: 1 + bond: 880_859_922.734477445997454079 * 1e18, + transferAmount: 880_859_922.734477445997454079 * 1e18 }); + // ensure reserves did not increase as result of kick + (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 289_462_063.392449001089942144 * 1e18); + assertEq(claimableReserves, 0); changePrank(actor7); - - ERC20Pool(address(_pool)).updateInterest(); _drawDebtNoLupCheck({ from: actor7, borrower: actor7, @@ -1177,28 +1176,27 @@ contract ERC20PoolLiquidationsSettleRegressionTest is ERC20HelperContract { // skip some time to make actor7 undercollateralized skip(200 days); - - changePrank(actor6); - - ERC20Pool(address(_pool)).updateInterest(); - (uint256 borrowerDebt, , ) = _poolUtils.borrowerInfo(address(_pool), actor2); - assertEq(borrowerDebt, 60_144_029_463.415046012797744619 * 1e18); - - (uint256 reserves, , , ,) = _poolUtils.poolReservesInfo(address(_pool)); - assertEq(reserves, 467_743_959.189518118524102933 * 1e18); + assertEq(borrowerDebt, 59_474_936_428.593370593619524964 * 1e18); + // reserves increase slightly due to interest accrual + (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 289_462_928.777064385704942145 * 1e18); + assertEq(claimableReserves, 0); + // settle auction with reserves + changePrank(actor6); _settle({ from: actor6, borrower: actor2, maxDepth: 2, - settledDebt: 57_093_334_850.248360626382636508 * 1e18 + settledDebt: 56_458_180_321.630022869105202974 * 1e18 }); - (reserves, , , ,) = _poolUtils.poolReservesInfo(address(_pool)); - - assertEq(reserves, 58.746831970548518322 * 1e18); + // almost all the reserves are used to settle debt + (reserves, claimableReserves, , ,) = _poolUtils.poolReservesInfo(address(_pool)); + assertEq(reserves, 58.732475079196632424 * 1e18); + assertEq(claimableReserves, 0); } } @@ -1253,7 +1251,7 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { borrower: _borrower, borrowerDebt: 290_278.84615384615398 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 3_047.92788461538461679 * 1e18, + borrowert0Np: 3_343.441616215101687356 * 1e18, borrowerCollateralization: 1.026946145846449373 * 1e18 }); @@ -1263,12 +1261,11 @@ contract ERC20PoolLiquidationSettleFuzzyTest is ERC20FuzzyHelperContract { _kick({ from: _kicker, borrower: _borrower, - debt: 310_461.23296586145968703 * 1e18, + debt: 306_628.378237887861419289 * 1e18, collateral: 100 * 1e18, - bond: 3_066.283782378878614193 * 1e18, - transferAmount: 3_066.283782378878614193 * 1e18 + bond: 4_654.723000803723493401 * 1e18, + transferAmount: 4_654.723000803723493401 * 1e18 }); - } function testSettleWithDepositFuzzy(uint256 quoteAmount, uint256 bucketIndex) external { diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol index b7606efa8..568f5dff9 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolLiquidationsTake.t.sol @@ -105,14 +105,14 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.268509615384615394 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 1.009034539679184679 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 7_987.673076923076926760 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 8.471136974495192174 * 1e18, + borrowert0Np: 9.200228999102245332 * 1e18, borrowerCollateralization: 1.217037273735858713 * 1e18 }); _assertReserveAuction({ @@ -133,51 +133,6 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); } - function testTakeCoolDownPeriod() external tearDown { - - // should revert if there's no auction started - _assertTakeNoAuctionRevert({ - from: _lender, - borrower: _borrower, - maxCollateral: 10 * 1e18 - }); - - /********************/ - /*** Kick Auction ***/ - /********************/ - - _borrow({ - from: _borrower2, - amount: 1_700.0 * 1e18, - indexLimit: _i9_72, - newLup: _p9_72 - }); - - skip(100 days); - - _kick({ - from: _lender, - borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, - collateral: 1_000 * 1e18, - bond: 98.229512113654856365 * 1e18, - transferAmount: 98.229512113654856365 * 1e18 - }); - - /********************/ - /*** Take Auction ***/ - /********************/ - - skip(30 minutes); - - // should revert if still in cool down period - _assertTakeAuctionInCooldownRevert({ - from: _lender, - borrower: _borrower2, - maxCollateral: 10 * 1e18 - }); - } - function testTakeLoanColConstraintBpfPosNoResidual() external tearDown { // Increase neutralPrice so it exceeds TP @@ -230,7 +185,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -261,7 +216,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -273,34 +228,34 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 2_946.885363409645690939 * 1e18, - transferAmount: 2_946.885363409645690939 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 2_946.885363409645690939 * 1e18 + locked: 149.115738086847591203 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.738101507554206919 * 1e18, + borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977433325291186371 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 179.552281242188325468 * 1e18, - claimableReserves : 83.959813435773714795 * 1e18, + reserves: 56.765391100119755012 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -314,11 +269,11 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 83_219.674636105806588000 * 1e18, pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_966.791200431324241706 * 1e18, - poolDebt: 19_119.759164133922414841 * 1e18, + encumberedCollateral: 1_954.159641123343178119 * 1e18, + poolDebt: 18_996.964038864342413928 * 1e18, actualUtilization: 0.225749991311399444 * 1e18, targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_911.975916413392241484 * 1e18, + minDebtAmount: 1_899.696403886434241393 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -330,23 +285,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 2_946.885363409645690939 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 47000 seconds, - kickMomp: 1505.263728469068226832 * 1e18, - totalBondEscrowed: 2_946.885363409645690939 * 1e18, - auctionPrice: 12.005655124053999200 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.946405146835980073 * 1e18, - neutralPrice: 1_597.054445085392479852 * 1e18 + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 0.980964776869723804 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.823610021566400073 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_946.405146835980073930 * 1e18, + borrowerDebt: 9_823.610021566400073017 * 1e18, borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977367774740624830 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989584871924882640 * 1e18 }); // BPF Positive, Loan Col constraint @@ -354,8 +309,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_001 * 1e18, - bondChange: 3_598.602058071496018124 * 1e18, - givenAmount: 12_005.655124053999200000 * 1e18, + bondChange: 14.891378730546973678 * 1e18, + givenAmount: 980.964776869723804000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -366,93 +321,43 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: address(0xb012341CA6E91C00A290F658fbaA5211F2559fB1), - bondSize: 6_545.487421481141709063 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 164.007116817394564881 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 47000 seconds, - kickMomp: 1_505.263728469068226832 * 1e18, - totalBondEscrowed: 6_545.487421481141709063 * 1e18, - auctionPrice: 12.005655124053999200 * 1e18, - debtInAuction: 2_235.600441131995497105 * 1e18, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 164.007116817394564881 * 1e18, + auctionPrice: 0.980964776869723804 * 1e18, + debtInAuction: 8_857.536623427223243018 * 1e18, thresholdPrice: 0, - neutralPrice: 1_597.054445085392479852 * 1e18 + neutralPrice: 11.314108592233961587 * 1e18 }) ); // Bad debt remains _assertBorrower({ borrower: _borrower2, - borrowerDebt: 2_235.600441131995497105 * 1e18, + borrowerDebt: 8_857.536623427223243018 * 1e18, borrowerCollateral: 0, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertPool( PoolParams({ htp: 9.155043929439064212 * 1e18, - lup: 9.917184843435912074 * 1e18, - poolSize: 83_220.780269640882398489 * 1e18, + lup: 9.721295865031779605 * 1e18, + poolSize: 83_220.773168797860489236 * 1e18, pledgedCollateral: 1_002.0 * 1e18, - encumberedCollateral: 1_150.422689356386608344 * 1e18, - poolDebt: 11_408.954458429937838016 * 1e18, - actualUtilization: 0.175622917264332252 * 1e18, + encumberedCollateral: 1_854.782622714283711888 * 1e18, + poolDebt: 18_030.890640725165583929 * 1e18, + actualUtilization: 0.175476347926803679 * 1e18, targetUtilization: 0.962794543732489691 * 1e18, - minDebtAmount: 1_140.895445842993783802 * 1e18, + minDebtAmount: 1_803.089064072516558393 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.0405 * 1e18, interestRateUpdate: block.timestamp }) ); - - // borrower recollateralizes themselves by pleding collateral - _pledgeCollateral({ - from: _borrower2, - borrower: _borrower2, - amount: 1_000 * 1e18 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower2, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 6_545.487421481141709063 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 2.235600441131995497 * 1e18, - neutralPrice: 0 - }) - ); - - _assertBorrower({ - borrower: _borrower2, - borrowerDebt: 2_235.600441131995497105 * 1e18, - borrowerCollateral: 1_000.0 * 1e18, - borrowert0Np: 348.242758284751090878 * 1e18, - borrowerCollateralization: 4.436027413921223336 * 1e18 - }); - - _assertPool( - PoolParams({ - htp: 9.155043929439064212 * 1e18, - lup: 9.917184843435912074 * 1e18, - poolSize: 83_220.780269640882398489 * 1e18, - pledgedCollateral: 2_002.0 * 1e18, - encumberedCollateral: 1_150.422689356386608344 * 1e18, - poolDebt: 11_408.954458429937838016 * 1e18, - actualUtilization: 0.175622917264332252 * 1e18, - targetUtilization: 0.962794543732489691 * 1e18, - minDebtAmount: 570.447722921496891901 * 1e18, - loans: 2, - maxBorrower: address(_borrower), - interestRate: 0.0405 * 1e18, - interestRateUpdate: block.timestamp - }) - ); } function testTakeCallerColConstraintBpfPosNoResidual() external tearDown { @@ -507,7 +412,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_689.307692307692312160 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -538,7 +443,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -550,34 +455,34 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 2_946.885363409645690939 * 1e18, - transferAmount: 2_946.885363409645690939 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 2_946.885363409645690939 * 1e18 + locked: 149.115738086847591203 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.738101507554206919 * 1e18, + borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977433325291186371 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 179.552281242188325468 * 1e18, - claimableReserves : 83.959813435773714795 * 1e18, + reserves: 56.765391100119755012 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -591,11 +496,11 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 83_219.674636105806588000 * 1e18, pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_966.779974486190376300 * 1e18, - poolDebt: 19_119.650033399911495437 * 1e18, + encumberedCollateral: 1_954.148487275944809732 * 1e18, + poolDebt: 18_996.855609013749459851 * 1e18, actualUtilization: 0.225749991311399444 * 1e18, targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_911.965003339991149544 * 1e18, + minDebtAmount: 1_899.685560901374945985 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, @@ -607,23 +512,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 2_946.885363409645690939 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 43000 seconds, - kickMomp: 1505.263728469068226832 * 1e18, - totalBondEscrowed: 2_946.885363409645690939 * 1e18, - auctionPrice: 25.933649477033750336 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.946348375279124882 * 1e18, - neutralPrice: 1_597.054445085392479852 * 1e18 + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 1.441757768272869640 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.823553950892962846 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_946.348375279124882461 * 1e18, + borrowerDebt: 9_823.553950892962846875 * 1e18, borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977373353339734632 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989590520256481315 * 1e18 }); // BPF Positive, caller collateral is constraint @@ -631,8 +536,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 10 * 1e18, - bondChange: 77.051043093949465946 * 1e18, - givenAmount: 259.336494770337503360 * 1e18, + bondChange: 0.218863729578241083 * 1e18, + givenAmount: 14.417577682728696400 * 1e18, collateralTaken: 10.0 * 1e18, isReward: true }); @@ -643,28 +548,27 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: address(0xb012341CA6E91C00A290F658fbaA5211F2559fB1), - bondSize: 3_023.936406503595156885 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 149.334601816425832286 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 43000 seconds, - kickMomp: 1_505.263728469068226832 * 1e18, - totalBondEscrowed: 3_023.936406503595156885 * 1e18, - auctionPrice: 25.933649477033750336 * 1e18, - debtInAuction: 10_460.307309872275586823 * 1e18, - thresholdPrice: 10.565966979668965239 * 1e18, - neutralPrice: 1_597.054445085392479852 * 1e18 + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.334601816425832286 * 1e18, + auctionPrice: 1.441757768272869640 * 1e18, + debtInAuction: 9_809.355236939812391565 * 1e18, + thresholdPrice: 9.908439633272537769 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_460.307309872275586823 * 1e18, + borrowerDebt: 9_809.355236939812391565 * 1e18, borrowerCollateral: 990 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.920057377023560467 * 1e18 + borrowert0Np: 11.256613027484040114 * 1e18, + borrowerCollateralization: 0.981112690275436564 * 1e18 }); } - function testTakeCallerColConstraintBpfPosResidual () external tearDown { - + function testTakeCallerColConstraintBpfPosResidual () external tearDown { // Increase neutralPrice so it exceeds TP _addLiquidity({ from: _lender, @@ -715,7 +619,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -746,7 +650,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -758,40 +662,40 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 2_946.885363409645690939 * 1e18, - transferAmount: 2_946.885363409645690939 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 2_946.885363409645690939 * 1e18 + locked: 149.115738086847591203 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.738101507554206919 * 1e18, + borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977433325291186371 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 179.552281242188325468 * 1e18, - claimableReserves : 83.959813435773714795 * 1e18, + reserves: 56.765391100119755012 * 1e18, + claimableReserves : 0.000000000000000000 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - skip(43000 seconds); // 11.94 hrs + skip(22000 seconds); _assertPool( PoolParams({ @@ -799,15 +703,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 83_219.674636105806588000 * 1e18, pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_966.779974486190376300 * 1e18, - poolDebt: 19_119.650033399911495437 * 1e18, + encumberedCollateral: 1_954.089930621571444937 * 1e18, + poolDebt: 18_996.286362451719573593 * 1e18, actualUtilization: 0.225749991311399444 * 1e18, targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_911.965003339991149544 * 1e18, + minDebtAmount: 1_899.628636245171957359 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, - interestRateUpdate: block.timestamp - 43000 seconds + interestRateUpdate: block.timestamp - 22000 seconds }) ); _assertAuction( @@ -815,23 +719,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 2_946.885363409645690939 * 1e18, - bondFactor: 0.3 * 1e18, - kickTime: block.timestamp - 43000 seconds, - kickMomp: 1505.263728469068226832 * 1e18, - totalBondEscrowed: 2_946.885363409645690939 * 1e18, - auctionPrice: 25.933649477033750336 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.946348375279124882 * 1e18, - neutralPrice: 1_597.054445085392479852 * 1e18 + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 22000 seconds, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 10.886704980656377540 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.823259585107984853 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_946.348375279124882461 * 1e18, + borrowerDebt: 9_823.259585107984853687 * 1e18, borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977373353339734632 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989620174526306750 * 1e18 }); // BPF Positive, Caller Col constraint @@ -839,37 +743,36 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 577 * 1e18, - bondChange: 4_445.845186520884185062 * 1e18, - givenAmount: 14_963.715748248473943872 * 1e18, + bondChange: 27.337468146252670459 * 1e18, + givenAmount: 6_281.628773838729840580 * 1e18, collateralTaken: 577 * 1e18, isReward: true }); - // Residual is collateralized, auction is not active + // Residual is collateralized, auction remains active. _assertAuction( AuctionParams({ borrower: _borrower2, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 7_392.730549930529876001 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 0.294851536220032779 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 176.453206233100261662 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 22000 seconds, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 176.453206233100261662 * 1e18, + auctionPrice: 10.886704980656377540 * 1e18, + debtInAuction: 3_653.993019025148320626 * 1e18, + thresholdPrice: 8.638281368853778535 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 124.722199821073865675 * 1e18, + borrowerDebt: 3_653.993019025148320626 * 1e18, borrowerCollateral: 423.000000000000000000 * 1e18, - borrowert0Np: 0.303909165615512483 * 1e18, - borrowerCollateralization: 5_105.158167959369510853 * 1e18 + borrowert0Np: 9.813927120521769770 * 1e18, + borrowerCollateralization: 1.136655711572588218 * 1e18 }); - } function testTakeCallerColConstraintBpfNegResidual () external tearDown { @@ -902,7 +805,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_689.307692307692312160 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.275765152019230606 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -911,10 +814,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 98.229512113654856365 * 1e18, - transferAmount: 98.229512113654856365 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); _assertAuction( @@ -922,38 +825,38 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.229512113654856365 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.229512113654856365 * 1e18, - auctionPrice: 333.359923587916662112 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.945738101507554206 * 1e18, - neutralPrice: 10.417497612122395691 * 1e18 + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 2_896.411799611894166272 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.822951211365485636 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.229512113654856365 * 1e18 + locked: 149.115738086847591203 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.738101507554206919 * 1e18, + borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.275765152019230606 * 1e18, - borrowerCollateralization: 0.977433325291186371 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 152.199485178078897492 * 1e18, - claimableReserves : 102.373050166832495788 * 1e18, + reserves: 29.412595036010327036 * 1e18, + claimableReserves : 0 * 1e18, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - skip(2 hours); + skip(80 minutes); _assertPool( PoolParams({ @@ -961,15 +864,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 73_113.822894306622582000 * 1e18, pledgedCollateral: 1_002 * 1e18, - encumberedCollateral: 1_025.107650389722106875 * 1e18, - poolDebt: 9_965.374762946048672277 * 1e18, + encumberedCollateral: 1_012.473341055493309162 * 1e18, + poolDebt: 9_842.552903857677844743 * 1e18, actualUtilization: 0.539365344551282052 * 1e18, targetUtilization: 0.996698234880015451 * 1e18, - minDebtAmount: 996.537476294604867228 * 1e18, + minDebtAmount: 984.255290385767784474 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, - interestRateUpdate: block.timestamp - 2 hours + interestRateUpdate: block.timestamp - 80 minutes }) ); _assertAuction( @@ -977,23 +880,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.229512113654856365 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp - 2 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.229512113654856365 * 1e18, - auctionPrice: 166.679961793958331072 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.945840284273233679 * 1e18, - neutralPrice: 10.417497612122395691 * 1e18 + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 80 minutes, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 181.025737475743385344 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.823018492083647863 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.840284273233679079 * 1e18, + borrowerDebt: 9_823.018492083647863197 * 1e18, borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 10.275765152019230606 * 1e18, - borrowerCollateralization: 0.977423283219567398 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989644463447376554 * 1e18 }); // BPF Negative, Caller collateral constraint @@ -1001,54 +904,53 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 10.0 * 1e18, - bondChange: 16.667996179395833107 * 1e18, - givenAmount: 1_666.799617939583310720 * 1e18, + bondChange: 27.480322232669404372 * 1e18, + givenAmount: 1_810.257374757433853440 * 1e18, collateralTaken: 10.0 * 1e18, isReward: false }); _assertPool( PoolParams({ - htp: 9.767239336407496599 * 1e18, + htp: 9.767205887014990773 * 1e18, lup: 9.721295865031779605 * 1e18, - poolSize: 73_113.913417169507608000 * 1e18, + poolSize: 73_113.882499196138656000 * 1e18, pledgedCollateral: 992.0 * 1e18, - encumberedCollateral: 925.265940856763249328 * 1e18, - poolDebt: 8_994.783964905591719093 * 1e18, - actualUtilization: 0.539426554958980321 * 1e18, - targetUtilization: 0.996698499658312393 * 1e18, - minDebtAmount: 449.739198245279585955 * 1e18, - loans: 2, + encumberedCollateral: 830.497921731842609849 * 1e18, + poolDebt: 8_073.516012449248097864 * 1e18, + actualUtilization: 0.539405362783948025 * 1e18, + targetUtilization: 0.996698410914855915 * 1e18, + minDebtAmount: 807.351601244924809786 * 1e18, + loans: 1, // TODO: is this test still relevant like this? maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, - interestRateUpdate: block.timestamp - 2 hours + interestRateUpdate: block.timestamp - 80 minutes }) ); - // Residual is collateralized, auction is not active + // take recollateralized borrower however once in auction, always in auction... _assertAuction( AuctionParams({ borrower: _borrower2, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 81.561515934259023258 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 9.065908571952299723 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 121.635415854178186831 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 80 minutes, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 121.635415854178186831 * 1e18, + auctionPrice: 181.025737475743385344 * 1e18, + debtInAuction: 8_053.981600675218116317 * 1e18, + thresholdPrice: 8.135334950176987996 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 8_975.249486232776725895 * 1e18, + borrowerDebt: 8_053.981600675218116317 * 1e18, borrowerCollateral: 990.000000000000000000 * 1e18, - borrowert0Np: 9.438566662973887791 * 1e18, - borrowerCollateralization: 1.072291407736791833 * 1e18 + borrowert0Np: 9.242757957291237631 * 1e18, + borrowerCollateralization: 1.194947217854906920 * 1e18 }); - } function testTakeLoanDebtConstraintBpfPosResidual() external tearDown { @@ -1103,7 +1005,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_689.307692307692312160* 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 1.003301388885552947 * 1e18 }); @@ -1134,7 +1036,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -1146,40 +1048,40 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, + borrowert0Np: 11.160177532745580804 * 1e18, borrowerCollateralization: 0.989651241857326201 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 2_946.885363409645690939 * 1e18, - transferAmount: 2_946.885363409645690939 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 2_946.885363409645690939 * 1e18 + locked: 149.115738086847591203 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_945.738101507554206919 * 1e18, + borrowerDebt: 9_822.951211365485636463 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977433325291186371 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989651241857326201 * 1e18 }); _assertReserveAuction({ - reserves: 179.552281242188325468 * 1e18, - claimableReserves : 83.959813435773714795 * 1e18, + reserves: 56.765391100119755012 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 }); - skip(43000 seconds); // 11.94 hrs + skip(22000 seconds); // 6.11s hrs _assertPool( PoolParams({ @@ -1187,15 +1089,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lup: 9.721295865031779605 * 1e18, poolSize: 83_219.674636105806588000 * 1e18, pledgedCollateral: 2_002.000000000000000000 * 1e18, - encumberedCollateral: 1_966.779974486190376300 * 1e18, - poolDebt: 19_119.650033399911495437 * 1e18, + encumberedCollateral: 1_954.089930621571444937 * 1e18, + poolDebt: 18_996.286362451719573593 * 1e18, actualUtilization: 0.225749991311399444 * 1e18, targetUtilization: 0.963953858271529038 * 1e18, - minDebtAmount: 1_911.965003339991149544 * 1e18, + minDebtAmount: 1_899.628636245171957359 * 1e18, loans: 1, maxBorrower: address(_borrower), interestRate: 0.045 * 1e18, - interestRateUpdate: block.timestamp - 43000 seconds + interestRateUpdate: block.timestamp - 22000 seconds }) ); _assertAuction( @@ -1203,23 +1105,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 2_946.885363409645690939 * 1e18, - bondFactor: 0.3 * 1e18, - kickTime: block.timestamp - 43000 seconds, - kickMomp: 1505.263728469068226832 * 1e18, - totalBondEscrowed: 2_946.885363409645690939 * 1e18, - auctionPrice: 25.933649477033750336 * 1e18, - debtInAuction: 9_945.738101507554206919 * 1e18, - thresholdPrice: 9.946348375279124882 * 1e18, - neutralPrice: 1_597.054445085392479852 * 1e18 + bondSize: 149.115738086847591203 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 22000 seconds, + referencePrice: 11.314108592233961587 * 1e18, + totalBondEscrowed: 149.115738086847591203 * 1e18, + auctionPrice: 10.886704980656377540 * 1e18, + debtInAuction: 9_822.951211365485636463 * 1e18, + thresholdPrice: 9.823259585107984853 * 1e18, + neutralPrice: 11.314108592233961587 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_946.348375279124882461 * 1e18, + borrowerDebt: 9_823.259585107984853687 * 1e18, borrowerCollateral: 1_000.000000000000000 * 1e18, - borrowert0Np: 1_575.326150647652569911 * 1e18, - borrowerCollateralization: 0.977373353339734632 * 1e18 + borrowert0Np: 11.160177532745580804 * 1e18, + borrowerCollateralization: 0.989620174526306750 * 1e18 }); // BPF Positive, Loan Debt constraint @@ -1227,9 +1129,9 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_001 * 1e18, - bondChange: 4_498.564564314381167419 * 1e18, - givenAmount: 15_141.157325863044791651 * 1e18, - collateralTaken: 583.842136806534270091 * 1e18, + bondChange: 43.529168844258845077 * 1e18, + givenAmount: 10_002.172770738542860841 * 1e18, + collateralTaken: 918.751154597329341626 * 1e18, isReward: true }); @@ -1242,8 +1144,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 7_445.449927724026858358 * 1e18, + referencePrice: 0, + totalBondEscrowed: 192.644906931106436280 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1253,7 +1155,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, - borrowerCollateral: 416.157863193465729909 * 1e18, + borrowerCollateral: 81.248845402670658374 * 1e18, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -1276,17 +1178,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 11.194764859809874960 * 1e18, borrowerCollateralization: 0.986593617011217057 * 1e18 }); _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -1294,32 +1196,32 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.533942419792216457 * 1e18 + locked: 149.577873638769639523 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertReserveAuction({ - reserves: 152.670996883580244810 * 1e18, - claimableReserves : 102.690444029499747768 * 1e18, + reserves: 29.503568858839974240 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1327,38 +1229,38 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { uint256 preTakeSnapshot = vm.snapshot(); - skip(364 minutes); + skip(500 minutes); _assertAuction( AuctionParams({ borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp - 364 minutes, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 9.977887794379977376 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976872588243234769 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 500 minutes, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 5.055481829190032044 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853816057268096589 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.872588243234769567 * 1e18, + borrowerDebt: 9_853.816057268096589430 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974383082378677738 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986551383599395369 * 1e18 }); _take({ from: _lender, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 99.778877943799773760 * 1e18, - givenAmount: 9_977.887794379977376000 * 1e18, + bondChange: 76.743932462179586888 * 1e18, + givenAmount: 5_055.481829190032044 * 1e18, collateralTaken: 1000.0 * 1e18, isReward: true }); @@ -1368,28 +1270,28 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 198.312820363591990217 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp - 364 minutes, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 198.312820363591990217 * 1e18, - auctionPrice: 9.977887794379977376 * 1e18, - debtInAuction: 797.144752984083601437 * 1e18, + bondSize: 226.321806100949226411 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 500 minutes, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 226.321806100949226411 * 1e18, + auctionPrice: 5.055481829190032044 * 1e18, + debtInAuction: 4_875.078160540244132430 * 1e18, thresholdPrice: 0, - neutralPrice: 10.449783245217816340 * 1e18 + neutralPrice: 11.34917297836691808 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 797.144752984083601437 * 1e18, + borrowerDebt: 4_875.078160540244132430 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 198.312820363591990217 * 1e18 + locked: 226.321806100949226411 * 1e18 }); vm.revertTo(preTakeSnapshot); @@ -1402,23 +1304,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.977074177773911990 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.34917297836691808 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853900422492752583 * 1e18, + neutralPrice: 11.34917297836691808 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_977.074177773911990382 * 1e18, + borrowerDebt: 9_853.900422492752583093 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974363394700228467 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986542937133981323 * 1e18 }); // partial take for 20 collateral @@ -1427,8 +1329,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 20 * 1e18, - bondChange: 0.130622290565222707 * 1e18, - givenAmount: 13.062229056522270720 * 1e18, + bondChange: 0.861421516268142809 * 1e18, + givenAmount: 56.745864891834590400 * 1e18, collateralTaken: 20 * 1e18, isReward: true }); @@ -1438,33 +1340,33 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.664564710357439164 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 150.439295155037782332 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.664564710357439164 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 10_662.537763452128781688 * 1e18, - thresholdPrice: 10.880140574951151818 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 150.439295155037782332 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 9_798.015979117186135514 * 1e18, + thresholdPrice: 9.997975488895087893 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_662.537763452128781688 * 1e18, + borrowerDebt: 9_798.015979117186135514 * 1e18, borrowerCollateral: 980 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.893489913853932440 * 1e18 + borrowert0Np: 11.358444866850947120 * 1e18, + borrowerCollateralization: 0.972326435069717785 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.664564710357439164 * 1e18 // locked bond + reward, auction is not yet finished + locked: 150.439295155037782332 * 1e18 // locked bond + reward, auction is not yet finished }); // reserves should increase after take action _assertReserveAuction({ - reserves: 851.125605070547985156 * 1e18, - claimableReserves : 797.715166731277766566 * 1e18, + reserves: 29.562252507398080560 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1475,8 +1377,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 981 * 1e18, - bondChange: 6.400492237695912653 * 1e18, - givenAmount: 640.049223769591265280 * 1e18, + bondChange: 42.209654297138997644 * 1e18, + givenAmount: 2_780.547379699894929600 * 1e18, collateralTaken: 980 * 1e18, isReward: true }); @@ -1486,33 +1388,33 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 105.065056948053351817 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 192.648949452176779976 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 105.065056948053351817 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 10_028.889031920233428709 * 1e18, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 192.648949452176779976 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 7_059.678253714430204094 * 1e18, thresholdPrice: 0, - neutralPrice: 10.449783245217816340 * 1e18 + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 10_028.889031920233428709 * 1e18, + borrowerDebt: 7_059.678253714430204094 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 105.065056948053351817 * 1e18 // locked bond + reward, auction is not yet finalized + locked: 192.648949452176779976 * 1e18 // locked bond + reward, auction is not yet finalized }); // reserves should increase after take action _assertReserveAuction({ - reserves: 851.125605070547984804 * 1e18, - claimableReserves : 800.883410388937242979 * 1e18, + reserves: 29.562252507398081096 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1532,15 +1434,15 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { index: 3_696, lpBalance: 2_000 * 1e18, collateral: 0, - deposit: 2_012.736560735960384000 * 1e18, - exchangeRate: 1.006368280367980192 * 1e18 + deposit: 2_012.735939051273346000 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _settle({ from: _lender, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 6_963.271989687033445102 * 1e18 }); _assertAuction( @@ -1551,8 +1453,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 105.065056948053351817 * 1e18, + referencePrice: 0, + totalBondEscrowed: 192.648949452176779976 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1563,12 +1465,12 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertKicker({ kicker: _lender, - claimable: 105.065056948053351817 * 1e18, + claimable: 192.648949452176779976 * 1e18, locked: 0 }); _assertBucket({ @@ -1586,23 +1488,23 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); _assertBucket({ index: _i9_81, - lpBalance: 0, // bucket is bankrupt + lpBalance: 5_000 * 1e18, collateral: 0, - deposit: 0, - exchangeRate: 1 * 1e18 + deposit: 14.459712357801136539 * 1e18, + exchangeRate: 0.002891942471560228 * 1e18 }); _assertLenderLpBalance({ lender: _lender, index: _i9_81, - lpBalance: 0, // bucket is bankrupt + lpBalance: 5_000 * 1e18, depositTime: _startTime }); _assertBucket({ index: _i9_72, lpBalance: 11_000 * 1e18, collateral: 0, - deposit: 8_936.865546659328965469 * 1e18, - exchangeRate: 0.812442322423575361 * 1e18 + deposit: 11_070.047664782003403 * 1e18, + exchangeRate: 1.006367969525636673 * 1e18 }); _assertLenderLpBalance({ lender: _lender, @@ -1636,12 +1538,13 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { lpBalance: 30_000 * 1e18, depositTime: _startTime }); + // done vm.revertTo(postTakeSnapshot); _assertReserveAuction({ - reserves: 851.125605070547984804 * 1e18, - claimableReserves : 800.883410388937242979 * 1e18, + reserves: 29.562252507398081096 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1651,10 +1554,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 0, - settledDebt: 839.502646350469647166 * 1e18 + settledDebt: 29.158481211449497738 * 1e18 }); _assertReserveAuction({ - reserves: 0.000073114629046626 * 1e18, + reserves: 0.000073114623451463 * 1e18, claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, @@ -1666,7 +1569,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 1_985.250830463506159498 * 1e18 + settledDebt: 1_985.25021726848337055 * 1e18 }); _assertAuction( @@ -1674,28 +1577,28 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 105.065056948053351817 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 192.648949452176779976 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime + 100 days, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 105.065056948053351817 * 1e18, - auctionPrice: 0.653111452826113536 * 1e18, - debtInAuction: 7_165.026939228354106531 * 1e18, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 192.648949452176779976 * 1e18, + auctionPrice: 2.837293244591729520 * 1e18, + debtInAuction: 5_017.380135270382228461 * 1e18, thresholdPrice: 0, - neutralPrice: 10.449783245217816340 * 1e18 + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 7_165.026939228354106531 * 1e18, + borrowerDebt: 5_017.380135270382228461 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 105.065056948053351817 * 1e18 // locked bond + reward, auction is not yet finalized + locked: 192.648949452176779976 * 1e18 // locked bond + reward, auction is not yet finalized }); // clear remaining debt @@ -1703,7 +1606,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxDepth: 5, - settledDebt: 7_067.182044030301540259 * 1e18 + settledDebt: 4_948.863291207100576814 * 1e18 }); _assertAuction( @@ -1714,8 +1617,8 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 105.065056948053351817 * 1e18, + referencePrice: 0, + totalBondEscrowed: 192.648949452176779976 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1726,21 +1629,21 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 10.307611531622595991 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertKicker({ kicker: _lender, - claimable: 105.065056948053351817 * 1e18, + claimable: 192.648949452176779976 * 1e18, locked: 0 }); // kicker withdraws his auction bonds - assertEq(_quote.balanceOf(_lender), 46_248.354604754094247543 * 1e18); + assertEq(_quote.balanceOf(_lender), 44_013.128881769500840477 * 1e18); _pool.withdrawBonds(_lender, type(uint256).max); - assertEq(_quote.balanceOf(_lender), 46_353.419661702147599360 * 1e18); + assertEq(_quote.balanceOf(_lender), 44_205.777831221677620453 * 1e18); _assertKicker({ kicker: _lender, @@ -1765,10 +1668,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); _assertAuction( @@ -1776,32 +1679,32 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.533942419792216457 * 1e18 + locked: 149.577873638769639523 * 1e18 }); _assertReserveAuction({ - reserves: 152.670996883580244810 * 1e18, - claimableReserves : 102.690444029499747768 * 1e18, + reserves: 29.503568858839974240 * 1e18, + claimableReserves : 0, claimableReservesRemaining: 0, auctionPrice: 0, timeRemaining: 0 @@ -1818,10 +1721,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 98.533942419792216457 * 1e18, + referencePrice: 0, + totalBondEscrowed: 149.577873638769639523 * 1e18, auctionPrice: 0, - debtInAuction: 9_976.561670003961916237 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, thresholdPrice: 9.888301125810259647 * 1e18, neutralPrice: 0 }) @@ -1830,17 +1733,17 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 19.776602251620519295 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.115967548076923081 * 1e18, + borrowert0Np: 11.096767433127708186 * 1e18, borrowerCollateralization: 0.983110823724556080 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 19.999089026951250136 * 1e18, + debt: 19.776602251620519294 * 1e18, collateral: 2 * 1e18, - bond: 0.197766022516205193 * 1e18, - transferAmount: 0.197766022516205193 * 1e18 + bond: 0.300215543999476476 * 1e18, + transferAmount: 0.300215543999476476 * 1e18 }); _assertAuction( @@ -1848,21 +1751,21 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.197766022516205193 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.300215543999476476 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.731708442308421650 * 1e18, - auctionPrice: 332.246917827224724128 * 1e18, - debtInAuction: 10_120.320801313999710974 * 1e18, - thresholdPrice: 9.999544513475625068 * 1e18, - neutralPrice: 10.382716182100772629 * 1e18 + referencePrice: 11.389378845807642064 * 1e18, + totalBondEscrowed: 149.878089182769115999 * 1e18, + auctionPrice: 2_915.680984526756368384 * 1e18, + debtInAuction: 9_995.402984757347394196 * 1e18, + thresholdPrice: 9.888301125810259647 * 1e18, + neutralPrice: 11.389378845807642064 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.731708442308421650 * 1e18 + locked: 149.878089182769115999 * 1e18 }); skip(2 hours); @@ -1880,62 +1783,7 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { }); } - function testTakeAfterSettleReverts() external tearDown { - // Borrower draws debt - _borrow({ - from: _borrower2, - amount: 1_730 * 1e18, - indexLimit: _i9_72, - newLup: 9.721295865031779605 * 1e18 - }); - - // Skip to make borrower undercollateralized and kick auction - skip(100 days); - _kick({ - from: _lender, - borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, - collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 - }); - - // Take everything - skip(10 hours); - _take({ - from: _lender, - borrower: _borrower2, - maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.1114528261135360 * 1e18, - collateralTaken: 1_000 * 1e18, - isReward: true - }); - - // Partially settle the auction, such that it is not removed from queue - _settle({ - from: _lender, - borrower: _borrower2, - maxDepth: 1, - settledDebt: 2_824.753476813975806664 * 1e18 - }); - - // Borrower draws more debt - _drawDebt({ - from: _borrower2, - borrower: _borrower2, - amountToBorrow: 1_000 * 1e18, - limitIndex: _i9_72, - collateralToPledge: 1_000 * 1e18, - newLup: 9.721295865031779605 * 1e18 - }); - - // Take should revert - _assertTakeNoAuctionRevert(_borrower2, _borrower2, 1_000 * 1e18); - } - function testTakeAuctionPriceLtNeutralPrice() external tearDown { - _addLiquidity({ from: _lender1, amount: 1 * 1e18, @@ -1958,68 +1806,96 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); - _assertAuction( AuctionParams({ borrower: _borrower2, active: true, kicker: _lender, - bondSize: 98.533942419792216457 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.818751856078723036 * 1e18, - totalBondEscrowed: 98.533942419792216457 * 1e18, - auctionPrice: 334.393063846970122880 * 1e18, - debtInAuction: 9_976.561670003961916237 * 1e18, - thresholdPrice: 9.976561670003961916 * 1e18, - neutralPrice: 10.449783245217816340 * 1e18 + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 2_905.388282461931028480 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853394241979221645 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 }) ); - assertEq(_poolUtils.momp(address(_pool)), 9.818751856078723036 * 1e18); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 9_976.561670003961916237 * 1e18, + borrowerDebt: 9_853.394241979221645667 * 1e18, borrowerCollateral: 1_000 * 1e18, - borrowert0Np: 10.307611531622595991 * 1e18, - borrowerCollateralization: 0.974413448899967463 * 1e18 + borrowert0Np: 11.194764859809874960 * 1e18, + borrowerCollateralization: 0.986593617011217057 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 98.533942419792216457 * 1e18 + locked: 149.577873638769639523 * 1e18 }); - skip(3 hours); + // after 6 hours, auction price should equal neutral price + skip(6 hours); + _assertAuction( + AuctionParams({ + borrower: _borrower2, + active: true, + kicker: _lender, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 6 hours, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 11.349172978366918080 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853697947167044034 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 + }) + ); - _assertBucket({ - index: _i9_91, - lpBalance: 2_001 * 1e18, - collateral: 0, - deposit: 2_013.691743633473441469 * 1e18, - exchangeRate: 1.006342700466503469 * 1e18 - }); + // skip another hour, and then take auction below neutral price + skip(1 hours); + _assertAuction( + AuctionParams({ + borrower: _borrower2, + active: true, + kicker: _lender, + bondSize: 149.577873638769639523 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 7 hours, + referencePrice: 11.349172978366918080 * 1e18, + totalBondEscrowed: 149.577873638769639523 * 1e18, + auctionPrice: 8.025077173862374200 * 1e18, + debtInAuction: 9_853.394241979221645667 * 1e18, + thresholdPrice: 9.853748565608429470 * 1e18, + neutralPrice: 11.349172978366918080 * 1e18 + }) + ); + // confirm kicker is rewarded _take({ from: _lender, borrower: _borrower2, maxCollateral: 1_001 * 1e18, - bondChange: 98.533942419792216457 * 1e18, - givenAmount: 10_675.085498940513902727 * 1e18, - collateralTaken: 127.695058936100465256 * 1e18, - isReward: false + bondChange: 121.823399122640329123 * 1e18, + givenAmount: 8_025.0771738623742 * 1e18, + collateralTaken: 1_000 * 1e18, + isReward: true }); + // borrower left with bad debt to be settled _assertBorrower({ borrower: _borrower2, - borrowerDebt: 0, - borrowerCollateral: 872.304941063899534744 * 1e18, + borrowerDebt: 1950.49479086869560036 * 1e18, + borrowerCollateral: 0, borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 + borrowerCollateralization: 0 }); } @@ -2058,10 +1934,10 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { _kick({ from: _lender, borrower: _borrower2, - debt: 9_945.738101507554206918 * 1e18, + debt: 9_822.951211365485636462 * 1e18, collateral: 1_000 * 1e18, - bond: 2_946.885363409645690939 * 1e18, - transferAmount: 2_946.885363409645690939 * 1e18 + bond: 149.115738086847591203 * 1e18, + transferAmount: 149.115738086847591203 * 1e18 }); skip(43000 seconds); // 11.94 hrs @@ -2069,8 +1945,6 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { // force pool state update _updateInterest(); - (uint256 borrowerDebt, ,) = _poolUtils.borrowerInfo(address(_pool), _borrower2); - (uint256 reservesBeforeTake, , , , ) = _poolUtils.poolReservesInfo(address(_pool)); // BPF Positive, Loan Debt constraint @@ -2078,16 +1952,115 @@ contract ERC20PoolLiquidationsTakeTest is ERC20HelperContract { from: _lender, borrower: _borrower2, maxCollateral: 1_001 * 1e18, - bondChange: 4_498.564564314381167419 * 1e18, - givenAmount: 15_141.157325863044791651 * 1e18, - collateralTaken: 583.842136806534270091 * 1e18, + bondChange: 21.886372957824108251 * 1e18, + givenAmount: 1_441.75776827286964 * 1e18, + collateralTaken: 1000 * 1e18, isReward: true }); (uint256 reservesAfterTake, , , , ) = _poolUtils.poolReservesInfo(address(_pool)); - // reserves should only increase by 7% of the borrower debt on first take and settle auction - assertEq(reservesAfterTake, reservesBeforeTake + Maths.floorWmul(borrowerDebt, 0.07 * 1e18)); + // reserves should increase by borrower take penalty + assertGt(reservesAfterTake, reservesBeforeTake); + } +} + +contract ERC20PoolLiquidationsLowPriceCollateralTest is ERC20HelperContract { + + address internal _lender; + address internal _borrower; + uint256 internal _p0_00016 = 0.000016088121329146 * 1e18; + uint256 internal _i0_00016 = 6369; + + function setUp() external { + assertEq(_priceAt(_i0_00016), _p0_00016); + _startTest(); + + _lender = makeAddr("lender"); + _borrower = makeAddr("borrower"); + + _mintQuoteAndApproveTokens(_lender, 1_000_000 * 1e18); + _mintQuoteAndApproveTokens(_borrower, 1_000_000 * 1e18); + + _mintCollateralAndApproveTokens(_borrower, 50_000_000 * 1e18); + + _addInitialLiquidity({ + from: _lender, + amount: 1_000 * 1e18, + index: _i0_00016 + }); + } + + function testTakeRevertsOnZeroPrice() external tearDown { + // Borrower borrows + _drawDebt({ + from: _borrower, + borrower: _borrower, + amountToBorrow: 750 * 1e18, + limitIndex: _i0_00016+1, + collateralToPledge: Maths.wmul(Maths.wdiv(750 * 1e18, _p0_00016), 1.01 * 1e18), + newLup: _p0_00016 + }); + + // Skip to make borrower undercollateralized + skip(100 days); + + _kick({ + from: _lender, + borrower: _borrower, + debt: 761.075765343400230098 * 1e18, + collateral: 47_084_428.598115880943744161 * 1e18, + bond: 11.553388798051207996 * 1e18, + transferAmount: 11.553388798051207996 * 1e18 + }); + + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: _lender, + bondSize: 11.553388798051207996 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp, + referencePrice: 0.000018617825030991 * 1e18, + totalBondEscrowed: 11.553388798051207996 * 1e18, + auctionPrice: 0.004766163207933696 * 1e18, + debtInAuction: 761.075765343400230098 * 1e18, + thresholdPrice: 0.000016164065021144 * 1e18, + neutralPrice: 0.000018617825030991 * 1e18 + }) + ); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 761.075765343400230098 * 1e18, + borrowerCollateral: 47_084_428.598115880943744161 * 1e18, + borrowert0Np: 0.000018364525223142 * 1e18, + borrowerCollateralization: 0.995301695959551634 * 1e18 + }); + + // should revert if take occurs at 0 price + skip(71 hours); + _assertAuction( + AuctionParams({ + borrower: _borrower, + active: true, + kicker: _lender, + bondSize: 11.553388798051207996 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: _startTime + 100 days, + referencePrice: 0.000018617825030991 * 1e18, + totalBondEscrowed: 11.553388798051207996 * 1e18, + auctionPrice: 0 * 1e18, + debtInAuction: 761.075765343400230098 * 1e18, + thresholdPrice: 0.000016169961551610 * 1e18, + neutralPrice: 0.000018617825030991 * 1e18 + }) + ); + _assertTakeZeroBidRevert({ + from: _lender, + borrower: _borrower, + maxCollateral: 2_000_0000 * 1e18 + }); } } @@ -2160,24 +2133,24 @@ contract ERC20PoolLiquidationsTakeAndRepayAllDebtInPoolTest is ERC20HelperContra _kick({ from: _kicker, borrower: _borrower, - debt: 104.162540773774892916 * 1e18, + debt: 102.876583480271499176 * 1e18, collateral: 0.067433366047580170 * 1e18, - bond: 1.028765834802714992 * 1e18, - transferAmount: 1.028765834802714992 * 1e18 + bond: 1.561701503695180782 * 1e18, + transferAmount: 1.561701503695180782 * 1e18 }); skip(964); skip(3600 * 3); - + // the calculated repaid amount is with 1 WAD greater than the pool debt // check that take works and doesn't overflow _take({ from: _taker, borrower: _borrower, maxCollateral: 0.067433366047580170 * 1e18, - bondChange: 1.028765834802714992 * 1e18, - givenAmount: 111.455789568155429077 * 1e18, - collateralTaken: 0.010471063560951988 * 1e18, + bondChange: 1.561701503695180782 * 1e18, + givenAmount: 105.275486946083517714 * 1e18, + collateralTaken: 0.023241640918094312 * 1e18, isReward: false }); @@ -2228,7 +2201,7 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { borrower: _borrower, borrowerDebt: 290_278.84615384615398 * 1e18, borrowerCollateral: 100 * 1e18, - borrowert0Np: 3_047.92788461538461679 * 1e18, + borrowert0Np: 3_343.441616215101687356 * 1e18, borrowerCollateralization: 1.026946145846449373 * 1e18 }); @@ -2238,23 +2211,31 @@ contract ERC20PoolLiquidationTakeFuzzyTest is ERC20FuzzyHelperContract { _kick({ from: _taker, borrower: _borrower, - debt: 310_461.23296586145968703 * 1e18, + debt: 306_628.378237887861419289 * 1e18, collateral: 100 * 1e18, - bond: 3_066.283782378878614193 * 1e18, - transferAmount: 3_066.283782378878614193 * 1e18 + bond: 4_654.723000803723493401 * 1e18, + transferAmount: 4_654.723000803723493401 * 1e18 }); } function testTakeCollateralFuzzy(uint256 takeAmount, uint256 skipTimeToTake) external tearDown { - takeAmount = bound(takeAmount, 1, 100 * 1e18); skipTimeToTake = bound(skipTimeToTake, 1.1 hours, 71 hours); // skip some time to make auction takeable skip(skipTimeToTake); + (,,,, uint256 auctionPrice, ) = _poolUtils.auctionStatus(address(_pool), _borrower); + + uint256 minCollateralTakeAmount = Maths.max(Maths.wdiv(1, auctionPrice), 1); + + takeAmount = bound(takeAmount, minCollateralTakeAmount, 100 * 1e18); + + uint256 quoteTokenRequired = Maths.ceilWmul(auctionPrice, takeAmount); + + // return when collateral price is too low and quote token required to take that collateral is 0 + if (quoteTokenRequired == 0) return; // calculate and mint quote tokens to buy collateral - (,,,, uint256 auctionPrice, ) = _poolUtils.auctionStatus(address(_pool), _borrower); - _mintQuoteAndApproveTokens(_taker, auctionPrice * takeAmount); + _mintQuoteAndApproveTokens(_taker, quoteTokenRequired); uint256 beforeTakerQuoteBalance = _quote.balanceOf(_taker); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol index 94bf7becc..607ed97f2 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolPrecision.t.sol @@ -241,7 +241,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { function testBorrowRepayPrecision( uint8 collateralPrecisionDecimals_, uint8 quotePrecisionDecimals_ - ) external tearDown { + ) external { // setup fuzzy bounds and initialize the pool uint256 boundColPrecision = bound(uint256(collateralPrecisionDecimals_), 1, 18); uint256 boundQuotePrecision = bound(uint256(quotePrecisionDecimals_), 1, 18); @@ -329,11 +329,12 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { uint256 debt = 10_008.653846153846150000 * 1e18; uint256 col = 50 * 1e18; + // 50 collateral @ 3025.9 = 151295, so borrower is 15_116% collateralized _assertBorrower({ borrower: _borrower, borrowerDebt: debt, borrowerCollateral: col, - borrowert0Np: 209.180865384615384535 * 1e18, + borrowert0Np: 229.411561015492614726 * 1e18, borrowerCollateralization: 15.116650694597107214 * 1e18 }); _assertPoolPrices({ @@ -395,7 +396,7 @@ contract ERC20PoolPrecisionTest is ERC20DSTestPlus { borrower: _borrower, borrowerDebt: debt, borrowerCollateral: col, - borrowert0Np: 209.180865384615384535 * 1e18, + borrowert0Np: 114.804959297694401926 * 1e18, borrowerCollateralization: 30.207183159927296805 * 1e18 }); _assertPoolPrices({ diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol index 6ecfb0a3b..75a129d05 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolQuoteToken.t.sol @@ -979,7 +979,7 @@ contract ERC20PoolQuoteTokenTest is ERC20HelperContract { borrower: _borrower, borrowerDebt: 89_085.576923076923118000 * 1e18, borrowerCollateral: 30.0 * 1e18, - borrowert0Np: 3_117.995192307692309130 * 1e18, + borrowert0Np: 3_420.302343024644254882 * 1e18, borrowerCollateralization: 1.008888047888587643 * 1e18 }); diff --git a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol index 456c49a76..6d68900b4 100644 --- a/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC20Pool/ERC20PoolReserveAuction.t.sol @@ -88,7 +88,7 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 1.411317956425859163 * 1e18, + remainingReserves: 1.425573693359453700 * 1e18, price: 1000000000 * 1e18, epoch: 1 }); @@ -96,22 +96,75 @@ contract ERC20PoolReserveAuctionTest is ERC20HelperContract { skip(60 hours); _assertReserveAuction({ - reserves: 0.000001743377232837 * 1e18, - claimableReserves : 0.000000736933594537 * 1e18, - claimableReservesRemaining: 1.411317956425859163 * 1e18, + reserves: 0.000001006443638300 * 1e18, + claimableReserves : 0, + claimableReservesRemaining: 1.425573693359453700 * 1e18, auctionPrice: 0.000000000867361737 * 1e18, timeRemaining: 43200 }); - assertEq(USDC.balanceOf(address(_pool)), 1_007.854958 * 1e6); - assertEq(USDC.balanceOf(address(_bidder)), 0.014255 * 1e6); // kicker reward - assertEq(AJNA.balanceOf(address(_bidder)), 10 * 1e18); + // taking 0 amount forbidden + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.takeReserves(0); + // take all reserves + assertEq(USDC.balanceOf(address(_pool)), 1_007.869213 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 10 * 1e18); _pool.takeReserves(10 * 1e18); + assertEq(USDC.balanceOf(address(_pool)), 1_006.443640 * 1e6); + assertEq(USDC.balanceOf(address(_bidder)), 1.425573 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999998763511925 * 1e18); + } - assertEq(USDC.balanceOf(address(_pool)), 1_006.443641 * 1e6); - assertEq(USDC.balanceOf(address(_bidder)), 1.425572 * 1e6); - assertEq(AJNA.balanceOf(address(_bidder)), 9.999999998775876805 * 1e18); + function testZeroBid() external { + // mint into the pool to simulate reserves + deal(address(USDC), address(_pool), 1_000_000 * 1e6); + _assertReserveAuction({ + reserves: 999_300.2884615384615386 * 1e18, + claimableReserves : 999_298.787018230769230907 * 1e18, + claimableReservesRemaining: 0, + auctionPrice: 0, + timeRemaining: 0 + }); + + // kick off a new auction + _kickReserveAuction({ + from: _bidder, + remainingReserves: 999_298.787018230769230907 * 1e18, + price: 1_000_000_000 * 1e18, + epoch: 1 + }); + + // price cannot hit zero, but wait for it to be reasonably small + skip(71 hours); + _assertReserveAuction({ + reserves: 1.501443307692307693 * 1e18, + claimableReserves : 0, + claimableReservesRemaining: 999_298.787018230769230907 * 1e18, + auctionPrice: 0.000000000000423516 * 1e18, + timeRemaining: 1 hours + }); + + // try to take the smallest amount of USDC possible + assertEq(USDC.balanceOf(address(_bidder)), 0); + assertEq(AJNA.balanceOf(address(_bidder)), 10 * 1e18); + _pool.takeReserves(1 * 1e6); + // bidder got nothing, but burned 1wei of AJNA + assertEq(USDC.balanceOf(address(_bidder)), 0); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999999999 * 1e18); + + // try to take a smaller-than-possible amount of USDC + _pool.takeReserves(1); + // bidder got nothing, but burned another 1wei of AJNA + assertEq(USDC.balanceOf(address(_bidder)), 0); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999999999998 * 1e18); + + // take a reasonable amount of USDC + assertEq(USDC.balanceOf(address(_bidder)), 0); + _pool.takeReserves(100 * 1e18); + // bidder burned some AJNA + assertEq(USDC.balanceOf(address(_bidder)), 100 * 1e6); + assertEq(AJNA.balanceOf(address(_bidder)), 9.999999999957648398 * 1e18); } } @@ -150,14 +203,10 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { // pool balance is amount added minus new debt assertEq(_quote.balanceOf(address(pool)), 98903); - vm.warp(block.timestamp + 17280000); + vm.warp(block.timestamp + 17_280_000); changePrank(_actor9); pool.updateInterest(); - pool.kick(_actor3, 7388); - // pool balance increased by kick bond - assertEq(_quote.balanceOf(address(pool)), 99920); - // available quote token does not account the kick bond assertEq(_availableQuoteToken(), 98903); vm.warp(block.timestamp + 86400); @@ -168,21 +217,23 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); pool.drawDebt(_actor7, 99266, 7388, 999234524847); - pool.drawDebt(_actor7, 98903, 7388, 999234524847); + // actor 7 draws almost all available quote token + pool.drawDebt(_actor7, 98703, 7388, 999234524847); // pool balance decreased by new debt - assertEq(_quote.balanceOf(address(pool)), 1017); + assertEq(_quote.balanceOf(address(pool)), 200); // available quote token decreased with new debt - assertEq(_availableQuoteToken(), 0); + assertEq(_availableQuoteToken(), 200); vm.warp(block.timestamp + 86400); + // attempt to kick reserves and verify pool balance is unchanged changePrank(_actor2); pool.updateInterest(); vm.expectRevert(IPoolErrors.NoReserves.selector); pool.kickReserveAuction(); + assertEq(_quote.balanceOf(address(pool)), 200); - // pool balance remains the same - assertEq(_quote.balanceOf(address(pool)), 1017); + vm.warp(block.timestamp + 86400); changePrank(_actor3); pool.updateInterest(); @@ -192,26 +243,21 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { // repay debt to have enough balance to kick new reserves auction ERC20Pool(address(_pool)).repayDebt(_actor3, type(uint256).max, 0, _actor3, MAX_FENWICK_INDEX); + ERC20Pool(address(_pool)).repayDebt(_actor7, type(uint256).max, 0, _actor7, MAX_FENWICK_INDEX); - uint256 initialPoolBalance = 103934; - uint256 initialAvailableAmount = 102917; + uint256 initialPoolBalance = 200784; + uint256 initialAvailableAmount = 200784; assertEq(_quote.balanceOf(address(pool)), initialPoolBalance); assertEq(_availableQuoteToken(), initialAvailableAmount); pool.kickReserveAuction(); - uint256 kickerReward = 12; - uint256 claimableTokens = 1229; + uint256 claimableTokens = 591; ( , , 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 @@ -221,9 +267,9 @@ contract ERC20PoolReserveAuctionNoFundsTest is ERC20HelperContract { pool.takeReserves(claimableTokens); // quote token balance diminished by quote token taken from reserve auction - assertEq(_quote.balanceOf(address(pool)), initialPoolBalance - kickerReward - claimableTokens); + assertEq(_quote.balanceOf(address(pool)), initialPoolBalance - claimableTokens); // available quote token (available to remove / draw debt from) is not modified - assertEq(_availableQuoteToken(), initialAvailableAmount - (kickerReward + claimableTokens)); + assertEq(_availableQuoteToken(), initialAvailableAmount - claimableTokens); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol index 543a2b857..ac5dadf09 100644 --- a/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol +++ b/tests/forge/unit/ERC721Pool/ERC721DSTestPlus.sol @@ -41,6 +41,13 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { address borrower ) internal { changePrank(borrower); + + // settle borrower if borrower is kicked + (uint256 kickTime, , , , , ) = _poolUtils.auctionStatus(address(_pool), borrower); + if (kickTime != 0) { + _pool.settle(borrower, bucketsUsed.length()); + } + uint256 borrowerT0debt; uint256 borrowerCollateral; (borrowerT0debt, borrowerCollateral, ) = _pool.borrowerInfo(borrower); @@ -140,16 +147,33 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { assertEq(collateral, 0); } ( , uint256 loansCount, , , ) = _poolUtils.poolLoansInfo(address(_pool)); - (uint256 debt, , ,) = _pool.debtInfo(); + (uint256 debt, , uint256 t0DebtInAuction,) = _pool.debtInfo(); assertEq(debt, 0); + assertEq(t0DebtInAuction, 0); assertEq(loansCount, 0); assertEq(_pool.pledgedCollateral(), 0); } modifier tearDown { _; + + // Skip time to make all auctioned borrowers settleable + skip(73 hours); + for (uint i = 0; i < borrowers.length(); i++) { - repayDebt(borrowers.at(i)); + address borrower = borrowers.at(i); + (,,, uint256 kickTime,,,,,) = _pool.auctionInfo(borrower); + if (kickTime != 0) { + changePrank(borrower); + _pool.settle(borrower, bucketsUsed.length() + 1); + + // Settle again if not settled, this can happen when less reserves calculated with DEPOSIT_BUFFER and borrower is not fully settled + (,,, kickTime,,,,,) = _pool.auctionInfo(borrower); + if (kickTime != 0) { + _pool.settle(borrower, bucketsUsed.length() + 1); + } + } + repayDebt(borrower); } for (uint i = 0; i < lenders.length(); i++) { @@ -637,6 +661,15 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { ERC721Pool(address(_pool)).repayDebt(from, 0, amount, from, indexLimit); } + function _assertRepayAuctionActiveRevert( + address from, + uint256 maxAmount + ) internal override { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionActive.selector); + ERC721Pool(address(_pool)).repayDebt(from, maxAmount, 0, from, MAX_FENWICK_INDEX); + } + function _assertRepayLimitIndexRevert( address from, uint256 amount, @@ -686,6 +719,25 @@ abstract contract ERC721DSTestPlus is DSTestPlus, IERC721PoolEvents { vm.expectRevert(IPoolErrors.InsufficientLP.selector); _pool.removeCollateral(amount, index); } + + function _assertRepayDebtAuctionActiveRevert( + address from, + address borrower, + uint256 amount + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionActive.selector); + ERC721Pool(address(_pool)).repayDebt(borrower, amount, 0, borrower, MAX_FENWICK_INDEX); + } + + function _assertPledgeCollateralAuctionActiveRevert( + address from, + uint256[] memory tokenIds + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionActive.selector); + ERC721Pool(address(_pool)).drawDebt(from, 0, 0, tokenIds); + } } abstract contract ERC721HelperContract is ERC721DSTestPlus { diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol index 3a63580db..b8b41c6d2 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolBorrow.t.sol @@ -248,7 +248,7 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, borrowerDebt: 3_002.884615384615386000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 1_152.910902143138512881 * 1e18, borrowerCollateralization: 3.007999714779824033 * 1e18 }); // pass time to allow interest to accumulate @@ -289,7 +289,6 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { interestRateUpdate: _startTime + 10 days }) ); - assertEq(_poolUtils.momp(address(_pool)), 3_010.892022197881557845 * 1e18); // check bucket state after partial repay _assertBucket({ index: 2550, @@ -303,7 +302,7 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, borrowerDebt: 1_507.000974734143274062 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 577.797569043003579568 * 1e18, borrowerCollateralization: 5.993809040625961846 * 1e18 }); @@ -315,7 +314,7 @@ contract ERC721SubsetPoolBorrowTest is ERC721PoolBorrowTest { borrower: _borrower, borrowerDebt: 1_508.860066921599065132 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 577.797569043003579568 * 1e18, borrowerCollateralization: 5.986423966420065589 * 1e18 }); @@ -826,7 +825,7 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra borrower: _borrower, borrowerDebt: 3_002.884615384615386000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 1_152.910902143138512881 * 1e18, borrowerCollateralization: 3.007999714779824033 * 1e18 }); // pass time to allow interest to accumulate @@ -868,7 +867,6 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra interestRateUpdate: _startTime + 10 days }) ); - assertEq(_poolUtils.momp(address(_pool)), 3_010.892022197881557845 * 1e18); // check bucket state after partial repay _assertBucket({ index: 2550, @@ -882,7 +880,7 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra borrower: _borrower, borrowerDebt: 1_507.000974734143274062 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 577.797569043003579568 * 1e18, borrowerCollateralization: 5.993809040625961846 * 1e18 }); @@ -894,7 +892,7 @@ contract ERC721ScaledQuoteTokenBorrowAndRepayTest is ERC721NDecimalsHelperContra borrower: _borrower, borrowerDebt: 1_508.860066921599065132 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_051.009615384615385100 * 1e18, + borrowert0Np: 577.797569043003579568 * 1e18, borrowerCollateralization: 5.986423966420065589 * 1e18 }); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol index 7e55c866c..d4f1015fd 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolCollateral.t.sol @@ -657,7 +657,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 150.144230769230769300 * 1e18, borrowerCollateral: 2.0 * 1e18, - borrowert0Np: 78.825721153846153882 * 1e18, + borrowert0Np: 86.468317660735388466 * 1e18, borrowerCollateralization: 3.043424968161510485 * 1e18, tokenIds: borrowerTokenIds }); @@ -693,10 +693,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 598.174133241016922932 * 1e18, + debt: 590.789267398535232526 * 1e18, collateral: 2.0 * 1e18, - bond: 5.907892673985352325 * 1e18, - transferAmount: 5.907892673985352325 * 1e18 + bond: 8.968381880996266239 * 1e18, + transferAmount: 8.968381880996266239 * 1e18 }); skip(32 hours); @@ -706,15 +706,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 5.907892673985352325 * 1e18, - bondFactor: 0.010 * 1e18, + bondSize: 8.968381880996266239 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 32 hours, - kickMomp: 0.000000099836282890 * 1e18, - totalBondEscrowed: 5.907892673985352325 * 1e18, - auctionPrice: 0.000004621809202112 * 1e18, - debtInAuction: 598.174133241016922932 * 1e18, - thresholdPrice: 299.147163209604307694 * 1e18, - neutralPrice: 310.164365384230997074 * 1e18 + referencePrice: 340.236543104248948639 * 1e18, + totalBondEscrowed: 8.968381880996266239 * 1e18, + auctionPrice: 0.000081118713165342 * 1e18, + debtInAuction: 590.789267398535232527 * 1e18, + thresholdPrice: 295.453988355164748340 * 1e18, + neutralPrice: 340.236543104248948639 * 1e18 }) ); @@ -724,8 +724,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { lup: 99836282890, poolSize: 574.548281134908793200 * 1e18, pledgedCollateral: 2 * 1e18, - encumberedCollateral: 5_992_754_428.551908353085520210 * 1e18, - poolDebt: 598.294326419208615388 * 1e18, + encumberedCollateral: 5_918_769_805.977193435161155568 * 1e18, + poolDebt: 590.907976710329496681 * 1e18, actualUtilization: 0.750721153846153847 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, @@ -742,80 +742,80 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { index: 3060, lpBalance: 20 * 1e18, collateral: 0.0000000000000000000 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3061, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3062, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3063, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3064, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3065, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3066, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3067, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3068, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ index: 3069, lpBalance: 20.0 * 1e18, collateral: 0.0 * 1e18, - deposit: 57.465712770068876500 * 1e18, - exchangeRate: 2.873285638503443825 * 1e18 + deposit: 57.465578391592604940 * 1e18, + exchangeRate: 2.873278919579630247 * 1e18 }); _assertBucket({ @@ -841,18 +841,18 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3060, - lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.245340879650286415 * 1e18, - deposit: 0, - exchangeRate: 2.873285638503443827 * 1e18 + lpBalance: 20.308286694556134654 * 1e18, + collateral: 0.246630842904997686 * 1e18, + deposit: 0.000000000000000144 * 1e18, + exchangeRate: 2.873278919579630248 * 1e18 }); _assertBucket({ index: 3061, - lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.246567584048537845 * 1e18, - deposit: 0, - exchangeRate: 2.873285638503443827 * 1e18 + lpBalance: 20.308286694556134655 * 1e18, + collateral: 0.247863997119522673 * 1e18, + deposit: 0.000000000000000006 * 1e18, + exchangeRate: 2.873278919579630248 * 1e18 }); _assertBucket({ @@ -868,15 +868,15 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 5.907892673985352325 * 1e18, - bondFactor: 0.010 * 1e18, + bondSize: 8.968381880996266239 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 32 hours, - kickMomp: 0.000000099836282890 * 1e18, - totalBondEscrowed: 5.907892673985352325 * 1e18, - auctionPrice: 0.000004621809202112 * 1e18, - debtInAuction: 467.777790958346588935 * 1e18, - thresholdPrice: 371.166459589091918644 * 1e18, - neutralPrice: 310.164365384230997074 * 1e18 + referencePrice: 340.236543104248948639 * 1e18, + totalBondEscrowed: 8.968381880996266239 * 1e18, + auctionPrice: 0.000081118713165342 * 1e18, + debtInAuction: 418.511241535551682100 * 1e18, + thresholdPrice: 333.103014700636165105 * 1e18, + neutralPrice: 340.236543104248948639 * 1e18 }) ); @@ -884,10 +884,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: 99836282890, - poolSize: 402.259989390482135517 * 1e18, - pledgedCollateral: 1.260291114332395208 * 1e18, - encumberedCollateral: 4_685_448_790.934513817364339575 * 1e18, - poolDebt: 467.777790958346588935 * 1e18, + poolSize: 402.259048741148234756 * 1e18, + pledgedCollateral: 1.256401842870359357 * 1e18, + encumberedCollateral: 4_191_975_396.326293274519167147 * 1e18, + poolDebt: 418.511241535551682100 * 1e18, actualUtilization: 0.750721153846153847 * 1e18, targetUtilization: 0.328577182109433013 * 1e18, minDebtAmount: 0, @@ -904,10 +904,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 467.777790958346588935 * 1e18, - borrowerCollateral: 1.260291114332395208 * 1e18, - borrowert0Np: 78.825721153846153882 * 1e18, - borrowerCollateralization: 0.000000000268979808 * 1e18, + borrowerDebt: 418.511241535551682100 * 1e18, + borrowerCollateral: 1.256401842870359357 * 1e18, + borrowert0Np: 97.486777718699640528 * 1e18, + borrowerCollateralization: 0.000000000299715939 * 1e18, tokenIds: borrowerTokenIds }); @@ -919,8 +919,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2 * 1e18, - bondChange: 0.000000046218092021 * 1e18, - givenAmount: 0.000004621809202112 * 1e18, + bondChange: 0.000001231409637086 * 1e18, + givenAmount: 0.000081118713165342 * 1e18, collateralTaken: 1 * 1e18, isReward: true }); @@ -930,10 +930,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 467.777786382755478845 * 1e18, - borrowerCollateral: 0.260291114332395208 * 1e18, - borrowert0Np: 78.825721153846153882 * 1e18, - borrowerCollateralization: 0.000000000055553081 * 1e18, + borrowerDebt: 418.511161648248153847 * 1e18, + borrowerCollateral: 0.256401842870359357 * 1e18, + borrowert0Np: 477.697595423190347016 * 1e18, + borrowerCollateralization: 0.000000000061164932 * 1e18, tokenIds: borrowerTokenIds }); @@ -956,30 +956,30 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: address(_lender), - bondSize: 5.907892720203444346 * 1e18, - bondFactor: 0.010 * 1e18, + bondSize: 8.968383112405903325 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - (32 hours + 4210 minutes), - kickMomp: 0.000000099836282890 * 1e18, - totalBondEscrowed: 5.907892720203444346 * 1e18, + referencePrice: 340.236543104248948639 * 1e18, + totalBondEscrowed: 8.968383112405903325 * 1e18, auctionPrice: 0, - debtInAuction: 467.777786382755478845 * 1e18, - thresholdPrice: 1_798.004234437087055097 * 1e18, - neutralPrice: 310.164365384230997074 * 1e18 + debtInAuction: 418.511161648248153847 * 1e18, + thresholdPrice: 1_633.038265299714540882 * 1e18, + neutralPrice: 340.236543104248948639 * 1e18 }) ); _settle({ from: _lender, borrower: _borrower, - maxDepth: 10, - settledDebt: 118.857992573354662400 * 1e18 + maxDepth: 11, + settledDebt: 106.339800629932799697 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 78.825721153846153882 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1.0 * 1e18, tokenIds: borrowerTokenIds }); @@ -996,8 +996,8 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 5.907892720203444346 * 1e18, + referencePrice: 0, + totalBondEscrowed: 8.968383112405903325 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1007,10 +1007,10 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { _assertBucket({ index: 3060, - lpBalance: 20.202020202020202020 * 1e18, - collateral: 0.245340879650286415 * 1e18, + lpBalance: 20.308286694556134654 * 1e18, + collateral: 0.246630842904997687 * 1e18, deposit: 0, - exchangeRate: 2.873285638503443827 * 1e18 + exchangeRate: 2.873278919579630252 * 1e18 }); _assertLenderLpBalance({ lender: _borrower, @@ -1169,7 +1169,7 @@ contract ERC721PoolCollateralTest is ERC721HelperContract { PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 50.000004233778718162 * 1e18, + poolSize: 50.000079544611684526 * 1e18, pledgedCollateral: 0, encumberedCollateral: 0, poolDebt: 0, diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol index d07ff3ac0..c46c23e4c 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolInterest.t.sol @@ -103,7 +103,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_743.173878205128204457 * 1e18, + borrowert0Np: 1_911.763008462438456052 * 1e18, borrowerCollateralization: 1.804973217265326249 * 1e18 }); @@ -127,7 +127,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 4 * 1e18, - borrowert0Np: 1_743.173878205128204457 * 1e18, + borrowert0Np: 1_433.822256346828842039 * 1e18, borrowerCollateralization: 2.403665705362551645 * 1e18 }); @@ -152,7 +152,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_735.667387820512819845 * 1e18, + borrowert0Np: 1_902.683561057818747541 * 1e18, borrowerCollateralization: 1.800750077529217167 * 1e18 }); @@ -176,7 +176,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_073.483875782488916529 * 1e18, + borrowert0Np: 2_271.558482861789242177 * 1e18, borrowerCollateralization: 1.500002057800446964 * 1e18 }); @@ -204,7 +204,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_073.483875782488916529 * 1e18, + borrowert0Np: 0.000000000000000000 * 1e18, borrowerCollateralization: 1 * 1e18 }); } @@ -259,7 +259,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_802.692307692307693600 * 1e18, + borrowert0Np: 3_074.429072381702701017 * 1e18, borrowerCollateralization: 1.127999893042434013 * 1e18 }); @@ -292,14 +292,14 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_802.692307692307693600 * 1e18, + borrowert0Np: 3_074.429072381702701017 * 1e18, borrowerCollateralization: 1.122362328272840838 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_904.661507289418461412 * 1e18, + borrowert0Np: 3_170.432595761480458330 * 1e18, borrowerCollateralization: 1.088376197116173336 * 1e18 }); @@ -336,21 +336,21 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_802.692307692307693600 * 1e18, + borrowert0Np: 3_074.429072381702701017 * 1e18, borrowerCollateralization: 1.122336703854666979 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_904.661507289418461412 * 1e18, + borrowert0Np: 3_170.432595761480458330 * 1e18, borrowerCollateralization: 1.088351348628209297 * 1e18 }); _assertBorrower({ borrower: _borrower3, borrowerDebt: expectedBorrower3Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_640.541083248800813687 * 1e18, + borrowert0Np: 2_882.145647529036115605 * 1e18, borrowerCollateralization: 1.197213816827790670 * 1e18 }); @@ -382,7 +382,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedBorrower1Debt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_802.692307692307693600 * 1e18, + borrowert0Np: 3_074.429072381702701017 * 1e18, borrowerCollateralization: 1.122311080021518821 * 1e18 }); @@ -392,7 +392,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower2, borrowerDebt: expectedBorrower2Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_904.661507289418461412 * 1e18, + borrowert0Np: 3_170.432595761480458330 * 1e18, borrowerCollateralization: 1.088326500707555859 * 1e18 }); @@ -402,7 +402,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower3, borrowerDebt: expectedBorrower3Debt, borrowerCollateral: 1 * 1e18, - borrowert0Np: 2_640.541083248800813687 * 1e18, + borrowert0Np: 2_882.145647529036115605 * 1e18, borrowerCollateralization: 1.197186483491030227 * 1e18 }); @@ -466,7 +466,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_743.173878205128204457 * 1e18, + borrowert0Np: 1_911.763008462438456052 * 1e18, borrowerCollateralization: 1.804973217265326249 * 1e18 }); @@ -481,7 +481,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_743.173878205128204457 * 1e18, + borrowert0Np: 1_911.763008462438456052 * 1e18, borrowerCollateralization: 1.798309619615464420 * 1e18 }); @@ -507,7 +507,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_743.173878205128204457 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -529,7 +529,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_726.979669209494250313 * 1e18, + borrowert0Np: 1_893.159858820699522954 * 1e18, borrowerCollateralization: 1.805129295309881815 * 1e18 }); @@ -554,7 +554,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 4 * 1e18, - borrowert0Np: 1_726.979669209494250313 * 1e18, + borrowert0Np: 1_419.869894115524642215 * 1e18, borrowerCollateralization: 2.404169939255701731 * 1e18 }); @@ -579,7 +579,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_720.257643586910442803 * 1e18, + borrowert0Np: 1_884.589452870960229897 * 1e18, borrowerCollateralization: 1.801327695821111558 * 1e18 }); @@ -603,7 +603,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: expectedDebt, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_055.969470907112040316 * 1e18, + borrowert0Np: 2_250.568493913377606760 * 1e18, borrowerCollateralization: 1.500545633513497515 * 1e18 }); @@ -631,7 +631,7 @@ contract ERC721PoolSubsetInterestTest is ERC721PoolInterestTest { borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 3 * 1e18, - borrowert0Np: 2_055.969470907112040316 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol index 0d31ea0b4..94c574fa8 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsDepositTake.t.sol @@ -128,14 +128,14 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 19.819038461538461548 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 1.000773560501591181 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.981531649793150539 * 1e18 }); @@ -147,10 +147,10 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); /******************************/ @@ -163,11 +163,11 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { lup: 9.917184843435912074 * 1e18, poolSize: 73_004.346887619919714000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.056751649452525709 * 1e18, - poolDebt: 40.231555971534224232 * 1e18, + encumberedCollateral: 4.028103499563389533 * 1e18, + poolDebt: 39.947446973661202747 * 1e18, actualUtilization: 0.000477170706006322 * 1e18, targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 4.023155597153422423 * 1e18, + minDebtAmount: 3.994744697366120275 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -176,41 +176,39 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.727860269914713433 * 1e18 }); } function testDepositTakeNFTAndSettleAuction() external { - - skip(5 hours); + skip(6 hours); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, - kickTime: block.timestamp - 5 hours, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 23.865155821333804736 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506709959118993145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 6 hours, + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 13.089508376044532180 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364710191686173217 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); - assertEq(_poolUtils.momp(address(_pool)), 9.917184843435912074 * 1e18); _addLiquidity({ from: _lender, @@ -222,10 +220,10 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.013419918237986290 * 1e18, + borrowerDebt: 22.729420383372346434 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861861025320848319 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872629805438488447 * 1e18 }); // before deposit take: NFTs pledged by auctioned borrower are owned by the pool @@ -239,8 +237,8 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { index: _i1505_26, collateralArbed: 0.009965031187761219 * 1e18, quoteTokenAmount: 14.999999999999999995 * 1e18, - bondChange: 0.15 * 1e18, - isReward: false, + bondChange: 0, + isReward: true, lpAwardTaker: 0, lpAwardKicker: 0 }); @@ -248,39 +246,39 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { _assertAuction( AuctionParams({ borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.077287198298417188 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 9.624359312514645335 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 6 hours, + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 13.089508376044532180 * 1e18, + debtInAuction: 8.014051756262951713 * 1e18, + thresholdPrice: 4.027090921445553358 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); // borrower is compensated LP for fractional collateral _assertLenderLpBalance({ lender: _borrower, index: 3519, - lpBalance: 23.737330323739529015 * 1e18, - depositTime: block.timestamp + lpBalance: 0 * 1e18, + depositTime: 0 }); _assertBucket({ index: _i1505_26, lpBalance: 15 * 1e18, collateral: 0.009965031187761219 * 1e18, - deposit: 5, + deposit: 0.000000000000000005 * 1e18, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9.624359312514645335 * 1e18, - borrowerCollateral: 1 * 1e18, - borrowert0Np: 8.769696613728507382 * 1e18, - borrowerCollateralization: 1.030425457052554443 * 1e18 + borrowerDebt: 8.014051756262951713 * 1e18, + borrowerCollateral: 1.990034968812238781 * 1e18, + borrowert0Np: 4.044492274291511923 * 1e18, + borrowerCollateralization: 2.462617566100560496 * 1e18 }); _assertLenderLpBalance({ lender: _taker, @@ -295,17 +293,26 @@ contract ERC721PoolLiquidationsDepositTakeTest is ERC721HelperContract { depositTime: block.timestamp }); - // borrower should be able to repay and pull collateral from the pool - _repayDebtNoLupCheck({ - from: _borrower, - borrower: _borrower, - amountToRepay: 10 * 1e18, - amountRepaid: 10 * 1e18, - collateralToPull: 1 + // borrower cannot repay amidst auction + _assertRepayAuctionActiveRevert({ + from: _borrower, + maxAmount: 4 * 1e18 }); - // after deposit take and pull: NFT taken remains in pool, the pulled one goes to borrower - assertEq(_collateral.ownerOf(3), address(_pool)); - assertEq(_collateral.ownerOf(1), _borrower); + // ensure borrower is not left with fraction of NFT upon settlement + skip(72 hours); + _settle({ + from: _lender, + borrower: _borrower, + maxDepth: 5, + settledDebt: 6.987894865384582852 * 1e18 + }); + _assertBorrower({ + borrower: _borrower, + borrowerDebt: 0 * 1e18, + borrowerCollateral: 1 * 1e18, + borrowert0Np: 0 * 1e18, + borrowerCollateralization: 1 * 1e18 + }); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol index abc8f1d3e..6b7e1d1bb 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsKick.t.sol @@ -121,14 +121,14 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 19.819038461538461548 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 1.000773560501591181 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.981531649793150539 * 1e18 }); @@ -148,7 +148,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -160,17 +160,17 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 0.872656701977127996 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); /******************************/ @@ -183,11 +183,11 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { lup: 9.917184843435912074 * 1e18, poolSize: 73_004.346887619919714000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.056751649452525709 * 1e18, - poolDebt: 40.231555971534224232 * 1e18, + encumberedCollateral: 4.028103499563389533 * 1e18, + poolDebt: 39.947446973661202747 * 1e18, actualUtilization: 0.000477170706006322 * 1e18, targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 4.023155597153422423 * 1e18, + minDebtAmount: 3.994744697366120275 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -199,38 +199,38 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 381.842493141340875904 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506414413857370145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3_350.914144267400237568 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364359914920859402 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.727860269914713433 * 1e18 }); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.227287198298417188 * 1e18 + locked: 0.345029692224734546 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.772712801701582812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); // kick should fail if borrower in liquidation _assertKickAuctionActiveRevert({ @@ -259,7 +259,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { }); } - function testKickSubsetPoolAndSettleByRepayAndPledge() external tearDown { + function testKickSubsetPoolRepayAndPledgeReverts() external tearDown { // Skip to make borrower undercollateralized skip(1000 days); @@ -271,7 +271,7 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -283,17 +283,17 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 0.872656701977127996 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); _assertAuction( @@ -301,96 +301,34 @@ contract ERC721PoolLiquidationsKickTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 381.842493141340875904 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506414413857370145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3_350.914144267400237568 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364359914920859402 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); - assertEq(_poolUtils.momp(address(_pool)), 9.917184843435912074 * 1e18); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 - }); - - uint256 snapshot = vm.snapshot(); - - // borrower repays debt in order to exit from auction - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 25 * 1e18, - amountRepaid: 23.012828827714740290 * 1e18, - collateralToPull: 0, - newLup: _priceAt(3696) - }); - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 0, - neutralPrice: 0 - }) - ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 0, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); - vm.revertTo(snapshot); - - // borrower pledge one more NFT to exit from auction uint256[] memory tokenIdsToAdd = new uint256[](1); tokenIdsToAdd[0] = 5; - _pledgeCollateral({ - from: _borrower, - borrower: _borrower, - tokenIds: tokenIdsToAdd - }); - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 7.670942942571580096 * 1e18, - neutralPrice: 0 - }) - ); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, - borrowerCollateral: 3 * 1e18, - borrowert0Np: 6.989927127403846156 * 1e18, - borrowerCollateralization: 1.292824743669819254 * 1e18 - }); + // should revert if borrower tries to pledge collateral when in auction + _assertPledgeCollateralAuctionActiveRevert(_borrower, tokenIdsToAdd); + + // should revert if borrower tries to repay debt when in auction + _assertRepayDebtAuctionActiveRevert(_borrower, _borrower, type(uint256).max); } } \ No newline at end of file diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol index c9bcd5b5b..c57f03711 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettle.t.sol @@ -99,14 +99,14 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 5_004.807692307692310000 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 2_882.277255357846282204 * 1e18, borrowerCollateralization: 1.543977154129479546 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 5_004.807692307692310000 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_751.682692307692308500 * 1e18, + borrowert0Np: 1_921.518170238564188136 * 1e18, borrowerCollateralization: 2.315965731194219318 * 1e18 }); @@ -124,18 +124,18 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, index: 2500, borrower: _borrower, - debt: 5_067.367788461538463875 * 1e18, + debt: 5_004.80769230769231 * 1e18, collateral: 2 * 1e18, - bond: 1_501.442307692307693000 * 1e18 + bond: 75.974681840800023439 * 1e18 }); _lenderKick({ from: _lender, index: 2500, borrower: _borrower2, - debt: 5_067.367788461538463875 * 1e18, + debt: 5_004.80769230769231 * 1e18, collateral: 3 * 1e18, - bond: 1_501.442307692307693000 * 1e18 + bond: 75.974681840800023439 * 1e18 }); // skip to make loans clearable @@ -146,8 +146,8 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { lup: 3_863.654368867279344664 * 1e18, poolSize: 16_000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 2.624293841728065377 * 1e18, - poolDebt: 10_139.364366784136304617 * 1e18, + encumberedCollateral: 2.591895152324015187 * 1e18, + poolDebt: 10_014.187028922603757647 * 1e18, actualUtilization: 0, targetUtilization: 1e18, minDebtAmount: 0, @@ -159,21 +159,21 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_069.682183392068152309 * 1e18, + borrowerDebt: 5_007.093514461301878824 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 1.524219558190194493 * 1e18 + borrowert0Np: 2_882.277255357846282204 * 1e18, + borrowerCollateralization: 1.543272302667571924 * 1e18 }); _assertBorrower({ borrower: _borrower2, - borrowerDebt: 5_069.682183392068152309 * 1e18, + borrowerDebt: 5_007.093514461301878824 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 1_751.682692307692308500 * 1e18, - borrowerCollateralization: 2.286329337285291739 * 1e18 + borrowert0Np: 1_921.518170238564188136 * 1e18, + borrowerCollateralization: 2.314908454001357886 * 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(address(_pool)), 6_151.949363681600046878 * 1e18); // increased by bonds size + assertEq(_quote.balanceOf(_lender), 103_848.050636318399953122 * 1e18); // decreased by bonds size assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); } @@ -185,15 +185,15 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower2, active: true, kicker: _lender, - bondSize: 1_501.442307692307693000 * 1e18, - bondFactor: 0.3 * 1e18, + bondSize: 75.974681840800023439 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: _startTime, - kickMomp: 3_863.654368867279344664 * 1e18, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + referencePrice: 1_921.518170238564188136 * 1e18, + totalBondEscrowed: 151.949363681600046878 * 1e18, auctionPrice: 0, - debtInAuction: 10_134.735576923076927750 * 1e18, - thresholdPrice: 1_689.894061130689384103 * 1e18, - neutralPrice: 1_751.682692307692308500 * 1e18 + debtInAuction: 10_009.615384615384620000 * 1e18, + thresholdPrice: 1_669.031171487100626274 * 1e18, + neutralPrice: 1_921.518170238564188136 * 1e18 }) ); @@ -209,7 +209,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 5_067.367788461538463875 * 1e18 + settledDebt: 5_004.807692307692310000 * 1e18 }); _assertAuction( @@ -220,10 +220,10 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 151.949363681600046878 * 1e18, auctionPrice: 0, - debtInAuction: 5_069.682183392068152309 * 1e18, + debtInAuction: 5_007.093514461301878824 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) @@ -242,14 +242,14 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 5_067.367788461538463875 * 1e18 + settledDebt: 5_004.807692307692310000 * 1e18 }); _assertPool( PoolParams({ htp: 0, lup: MAX_PRICE, - poolSize: 5_864.570104597764159383 * 1e18, + poolSize: 5_989.698868738532498354 * 1e18, pledgedCollateral: 1 * 1e18, encumberedCollateral: 0, poolDebt: 0, @@ -270,8 +270,8 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, + referencePrice: 0, + totalBondEscrowed: 151.949363681600046878 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -282,27 +282,27 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 1 * 1e18, - borrowert0Np: 1_751.682692307692308500 * 1e18, + borrowert0Np: 0 * 1e18, borrowerCollateralization: 1 * 1e18 }); // assert bucket used for settle _assertBucket({ index: MAX_FENWICK_INDEX, - lpBalance: 0.000000137345389190 * 1e18, - collateral: 1.375706158271934622 * 1e18, + lpBalance: 0.000000140579953912 * 1e18, + collateral: 1.408104847675984812 * 1e18, deposit: 0, - exchangeRate: 1.000000000005475091 * 1e18 + exchangeRate: 0.999999999995447280 * 1e18 }); - assertEq(_quote.balanceOf(address(_pool)), 9_002.884615384615386000 * 1e18); - assertEq(_quote.balanceOf(_lender), 100_997.115384615384614000 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 6_151.949363681600046878 * 1e18); + assertEq(_quote.balanceOf(_lender), 103_848.050636318399953122 * 1e18); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); assertEq(_quote.balanceOf(_borrower2), 13_000 * 1e18); @@ -311,7 +311,7 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { from: _lender, amount: 100 * 1e18, index: MAX_FENWICK_INDEX, - lpAward: 99.999999999452490925 * 1e18, + lpAward: 100.000000000455272058 * 1e18, newLup: MAX_PRICE }); @@ -365,96 +365,11 @@ contract ERC721PoolLiquidationsSettleTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 4_863.128335182565063307 * 1e18, + lpBalance: 4_988.244512154526666083 * 1e18, collateral: 0, - deposit: 4_864.324200136395380383 * 1e18, - exchangeRate: 1.000245904461368780 * 1e18 - }); - } - - function testKickAndSettleSubsetPoolByRepay() external tearDown { - // before auction settle: NFTs pledged by auctioned borrower are owned by the pool - assertEq(_collateral.ownerOf(51), address(_pool)); - assertEq(_collateral.ownerOf(53), address(_pool)); - assertEq(_collateral.ownerOf(73), address(_pool)); - - // borrower 2 repays debt and settles auction - _repayDebtNoLupCheck({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 6_000 * 1e18, - amountRepaid: 0, - collateralToPull: 3 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower2, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, - auctionPrice: 0, - debtInAuction: 5_069.682183392068152309 * 1e18, - thresholdPrice: 0, - neutralPrice: 0 - }) - ); - _assertBorrower({ - borrower: _borrower2, - borrowerDebt: 0, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 + deposit: 4_989.456000134711482354 * 1e18, + exchangeRate: 1.000242868603821017 * 1e18 }); - - // after settle: NFTs pledged by auctioned borrower are owned by the borrower - assertEq(_collateral.ownerOf(51), address(_borrower2)); - assertEq(_collateral.ownerOf(53), address(_borrower2)); - assertEq(_collateral.ownerOf(73), address(_borrower2)); - - // before auction settle: NFTs pledged by auctioned borrower are owned by the pool - assertEq(_collateral.ownerOf(1), address(_pool)); - assertEq(_collateral.ownerOf(3), address(_pool)); - - // borrower repays debt and settles auction - _repayDebtNoLupCheck({ - from: _borrower, - borrower: _borrower, - amountToRepay: 6_000 * 1e18, - amountRepaid: 0, - collateralToPull: 2 - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 3_002.884615384615386000 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 0, - neutralPrice: 0 - }) - ); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 0, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 - }); - - // after settle: NFTs pledged by auctioned borrower are owned by the borrower - assertEq(_collateral.ownerOf(1), address(_borrower)); - assertEq(_collateral.ownerOf(3), address(_borrower)); } + } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol index 453ce67fa..f03a1350a 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsSettleAuction.t.sol @@ -97,17 +97,17 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, index: 2500, borrower: _borrower, - debt: 10_190.456508610307854461 * 1e18, + debt: 10_064.648403565736152554 * 1e18, collateral: 2 * 1e18, - bond: 100.646484035657361526 * 1e18 + bond: 152.784783614301553735 * 1e18 }); _lenderKick({ from: _lender, index: 2500, borrower: _borrower2, - debt: 10_203.037319114765024653 * 1e18, + debt: 10_064.648403565736152554 * 1e18, collateral: 3 * 1e18, - bond: 1_325.327386341314188042 * 1e18 + bond: 152.784783614301553735 * 1e18 }); } @@ -149,10 +149,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 10_195.576288428866513838 * 1e18, + borrowerDebt: 10_069.704976226041001321 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.757907990596315111 * 1e18 + borrowert0Np: 2_882.277255357846282204 * 1e18, + borrowerCollateralization: 0.767381840478769050 * 1e18 }); // first settle call settles partial borrower debt @@ -160,24 +160,24 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_485.576684127234225434 * 1e18 + settledDebt: 2_485.570270210405357279 * 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.287929788232333535 * 1e18, + collateral: 1.287926464788484107 * 1e18, deposit: 0, - exchangeRate: 1.000199226172731231 * 1e18 + exchangeRate: 1.000196645204423177 * 1e18 }); // partial borrower debt is settled, borrower collateral decreased with the amount used to settle debt _assertBorrower({ borrower: _borrower, - borrowerDebt: 5_194.580157565210366847 * 1e18, - borrowerCollateral: 0.712070211767666465 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.529627631336027971 * 1e18 + borrowerDebt: 5_068.721750203925124024 * 1e18, + borrowerCollateral: 0.712073535211515893 * 1e18, + borrowert0Np: 4_074.953051699645482676 * 1e18, + borrowerCollateralization: 0.542781032548108438 * 1e18 }); _assertCollateralInvariants(); @@ -199,7 +199,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 1, - settledDebt: 2_258.399659496838434005 * 1e18 + settledDebt: 2_127.089747762669017517 * 1e18 }); // no token id left in borrower token ids array @@ -212,15 +212,15 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, lpBalance: 20_036.073477395793018984 * 1e18, - collateral: 0.712070211767666465 * 1e18, - deposit: 30_548.811547417239049073 * 1e18, - exchangeRate: 1.662002526074875972 * 1e18 + collateral: 0.712073535211515893 * 1e18, + deposit: 30_548.712777641352242710 * 1e18, + exchangeRate: 1.661998237353453822 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 650.665648223383091746 * 1e18, + borrowerDebt: 789.003620205433623214 * 1e18, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); @@ -228,14 +228,14 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 5, - settledDebt: 323.391444837465804436 * 1e18 + settledDebt: 392.147674334617935204 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1.0 * 1e18 }); @@ -245,36 +245,36 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { from: _lender, borrower: _borrower2, maxDepth: 1, - settledDebt: 5_073.623798076923079263 * 1e18 + settledDebt: 5_004.807692307692310000 * 1e18 }); _assertBucket({ index: 2500, lpBalance: 20_036.073477395793018984 * 1e18, - collateral: 3.354170784195916811 * 1e18, - deposit: 19_689.982479544706885705 * 1e18, - exchangeRate: 1.629527817447087792 * 1e18 + collateral: 3.318337971638889847 * 1e18, + deposit: 19_690.004181209877611641 * 1e18, + exchangeRate: 1.622619083494012841 * 1e18 }); _assertBucket({ index: 2499, lpBalance: 5_000 * 1e18, - collateral: 1.287929788232333535 * 1e18, + collateral: 1.287926464788484107 * 1e18, deposit: 0, - exchangeRate: 1.000199226172731231 * 1e18 + exchangeRate: 1.000196645204423177 * 1e18 }); _assertBucket({ index: 7388, - lpBalance: 99.984931542573546395 * 1e18, - collateral: 0.357899427571749654 * 1e18, - deposit: 100.004851122084218862 * 1e18, - exchangeRate: 1.000199226172731231 * 1e18 + lpBalance: 99.984931546150681783 * 1e18, + collateral: 0.393735563572626046 * 1e18, + deposit: 100.004593064144716734 * 1e18, + exchangeRate: 1.000196645204423177 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 1_769.243311298076895206 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -314,10 +314,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2500, - lpBalance: 15_976.708867181974059418 * 1e18, - collateral: 1.642100572428250346 * 1e18, - deposit: 19_689.982479544706885705 * 1e18, - exchangeRate: 1.629527817447087792 * 1e18 + lpBalance: 15_959.417125063160793398 * 1e18, + collateral: 1.606264436427373954 * 1e18, + deposit: 19_690.004181209877611641 * 1e18, + exchangeRate: 1.622619083494012841 * 1e18 }); _assertBucket({ index: 2499, @@ -328,23 +328,23 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBucket({ index: MAX_FENWICK_INDEX, - lpBalance: 99.984931542573546395 * 1e18, - collateral: 0.357899427571749654 * 1e18, - deposit: 100.004851122084218862 * 1e18, - exchangeRate: 1.000199226172731231 * 1e18 + lpBalance: 99.984931546150681783 * 1e18, + collateral: 0.393735563572626046 * 1e18, + deposit: 100.004593064144716734 * 1e18, + exchangeRate: 1.000196645204423177 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 1_769.243311298076895206 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); @@ -365,7 +365,6 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { } function testDepositTakeAndSettleSubsetPool() external tearDown { - // the 2 token ids are owned by borrower before settle assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 3); @@ -379,10 +378,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 10_190.456508610307854462 * 1e18, + borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.747027241552026434 * 1e18 + borrowert0Np: 2_882.277255357846282204 * 1e18, + borrowerCollateralization: 0.756365082071426765 * 1e18 }); skip(32 hours); @@ -400,419 +399,103 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBucket({ index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 + lpBalance: 3_863.757250427550337858 * 1e18, + collateral: 1.678659796633077181 * 1e18, + deposit: 0.000000000000002754 * 1e18, + exchangeRate: 1.661954009450878778 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 4_582.063964428011899646 * 1e18, - borrowerCollateral: 0.330122111965997525 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.276978254692862222 * 1e18 + borrowerDebt: 3_742.762708953482933471 * 1e18, + borrowerCollateral: 0.321340203366922819 * 1e18, + borrowert0Np: 6_669.712537943716399889 * 1e18, + borrowerCollateralization: 0.330069182462081655 * 1e18 }); _assertCollateralInvariants(); - // borrower tries to repay remaining debt - _repayDebtNoLupCheck({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 1000 * 1e18, - amountRepaid: 0, - collateralToPull: 0 - }); - skip(80 hours); + // settle auction 1 _settle({ from: _lender, borrower: _borrower, maxDepth: 2, - settledDebt: 2_278.046992473852091989 * 1e18 + settledDebt: 1_860.774838340588348583 * 1e18 }); - _assertBucket({ index: 2500, lpBalance: 8_000 * 1e18, - collateral: 0.330122111965997525 * 1e18, - deposit: 11_222.172625306604949654 * 1e18, - exchangeRate: 1.562206295682965556 * 1e18 + collateral: 0.321340203366922819 * 1e18, + deposit: 11_084.202409928441579151 * 1e18, + exchangeRate: 1.540718736319969120 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 + lpBalance: 3_863.757250427550337858 * 1e18, + collateral: 1.678659796633077181 * 1e18, + deposit: 0.000000000000002755 * 1e18, + exchangeRate: 1.661954009450878778 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, 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 merge / removes the other 2 NFTs - uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2500; - removalIndexes[1] = 2502; - _mergeOrRemoveCollateral({ - from: _lender, - toIndex: 2502, - noOfNFTsToRemove: 2, - collateralMerged: 2 * 1e18, - removeCollateralAtIndex: removalIndexes, - toIndexLps: 0 - }); - - // the 2 NFTs claimed from pool are owned by lender - assertEq(_collateral.ownerOf(1), _lender); - assertEq(_collateral.ownerOf(3), _lender); - - _assertCollateralInvariants(); - } - - function testDepositTakeAndSettleByPledgeSubsetPool() external tearDown { - - // 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); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 10_190.456508610307854462 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.747027241552026434 * 1e18 - }); - - skip(32 hours); - _addLiquidityNoEventCheck({ - from: _lender, - amount: 3_000 * 1e18, - index: 2502 - }); - - _depositTake({ - from: _lender, - borrower: _borrower, - kicker: _lender, - index: 2502, - collateralArbed: 1.669877888034002475 * 1e18, - quoteTokenAmount: 6_387.793369052686121698 * 1e18, - bondChange: 63.877933690526861217 * 1e18, - isReward: true, - lpAwardTaker: 0, - lpAwardKicker: 38.435354287866834063 * 1e18 - }); - - // after bucket take, token id 3 is moved to pool claimable array (the most recent pledged) - assertEq(ERC721Pool(address(_pool)).totalBorrowerTokens(_borrower), 1); - assertEq(ERC721Pool(address(_pool)).totalBucketTokens(), 1); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); - - _assertBucket({ - index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 - }); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 4_582.063964428011899646 * 1e18, - borrowerCollateral: 0.330122111965997525 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.276978254692862222 * 1e18 - }); - - _assertCollateralInvariants(); - - // borrower 2 repays entire debt and pulls collateral - _repayDebt({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 11_000 * 1e18, - amountRepaid: 10_205.087450363250041380 * 1e18, - collateralToPull: 3, - newLup: 3_863.654368867279344664 * 1e18 - }); - - // borrower exits from auction by pledging more collateral - uint256[] memory tokenIdsToAdd = new uint256[](3); - tokenIdsToAdd[0] = 2; - tokenIdsToAdd[1] = 4; - tokenIdsToAdd[2] = 5; - _drawDebtNoLupCheck({ - from: _borrower, - borrower: _borrower, - amountToBorrow: 0, - limitIndex: 0, - tokenIds: tokenIdsToAdd - }); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 4_582.063964428011899646 * 1e18, - borrowerCollateral: 3 * 1e18, - borrowert0Np: 801.113192353304652349 * 1e18, - borrowerCollateralization: 2.529637996454456058 * 1e18 - }); - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 1_425.973870376971549568 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 1_527.354654809337299882 * 1e18, - neutralPrice: 0 - }) - ); - - _assertCollateralInvariants(); - - // after settle borrower has 3 token ids (token id 1 saved from auction + pledged token ids 2 and 4) - // most recent token pledged 5 is used to settle the auction hence in pool claimable array - assertEq(ERC721Pool(address(_pool)).totalBorrowerTokens(_borrower), 3); - assertEq(ERC721Pool(address(_pool)).totalBucketTokens(), 2); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 0), 1); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 1), 2); - assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower, 2), 4); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 3); - assertEq(ERC721Pool(address(_pool)).bucketTokenIds(1), 5); - - _assertBucket({ - index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 - }); - _assertBucket({ - index: 6051, - lpBalance: 0.000025941052120484 * 1e18, - collateral: 0.330122111965997525 * 1e18, - deposit: 0, - exchangeRate: 0.999999999999991014 * 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] = 2502; - removalIndexes[1] = 6051; - _mergeOrRemoveCollateral({ - from: _lender, - toIndex: 6051, - noOfNFTsToRemove: 2, - collateralMerged: 2 * 1e18, - removeCollateralAtIndex: removalIndexes, - toIndexLps: 0 - }); - - // borrower repays entire debt and pulls collateral - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 5_000 * 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.000025941052120483 * 1e18, - index: 6051, - newLup: MAX_PRICE, - lpRedeem: 0.000025941052120484 * 1e18 + // settle auction 2 to enable mergeOrRemoveCollateral + _settle({ + from: _lender, + borrower: _borrower2, + maxDepth: 2, + settledDebt: 5_004.80769230769231 * 1e18 }); - - // the 3 NFTs pulled from pool are owned by borrower - assertEq(_collateral.ownerOf(1), _borrower); - assertEq(_collateral.ownerOf(2), _borrower); - assertEq(_collateral.ownerOf(4), _borrower); - // the 2 NFTs claimed from pool are owned by lender - assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(5), _lender); - _assertCollateralInvariants(); - } - - function testDepositTakeAndSettleByRepaySubsetPool() external tearDown { - // 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); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 10_190.456508610307854462 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.747027241552026434 * 1e18 - }); + // collateral in buckets: + // 2500 - 2.928128325437681102 + // 2502 - 1.678659796633077182 + // 7388 - 0.393211877929241716 - skip(32 hours); + // lender deposits quote token into 7388 to merge from that bucket _addLiquidityNoEventCheck({ from: _lender, - amount: 3_000 * 1e18, - index: 2502 - }); - - _depositTake({ - from: _lender, - borrower: _borrower, - kicker: _lender, - index: 2502, - collateralArbed: 1.669877888034002475 * 1e18, - quoteTokenAmount: 6_387.793369052686121698 * 1e18, - bondChange: 63.877933690526861217 * 1e18, - isReward: true, - lpAwardTaker: 0, - lpAwardKicker: 38.435354287866834063 * 1e18 + amount: 1 * 1e18, + index: 7388 }); - _assertBucket({ - index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 - }); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 4_582.063964428011899646 * 1e18, - borrowerCollateral: 0.330122111965997525 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.276978254692862222 * 1e18 - }); - - _assertCollateralInvariants(); - - // borrower 2 repays entire debt and pulls collateral - _repayDebt({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 11_000 * 1e18, - amountRepaid: 10_205.087450363250041380 * 1e18, - collateralToPull: 3, - newLup: 3_863.654368867279344664 * 1e18 - }); - // borrower exits from auction by repaying the debt - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 5_000 * 1e18, - amountRepaid: 4_582.063964428011899646 * 1e18, - collateralToPull: 0, - newLup: MAX_PRICE - }); - - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 0, - borrowerCollateral: 0, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 - }); - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 1_425.973870376971549568 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 0, - neutralPrice: 0 - }) - ); - - _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); - - _assertBucket({ - index: 2502, - lpBalance: 3_843.535428786683406029 * 1e18, - collateral: 1.669877888034002475 * 1e18, - deposit: 0, - exchangeRate: 1.661957717681079631 * 1e18 - }); - _assertBucket({ - index: 6051, - lpBalance: 0.000025941052120484 * 1e18, - collateral: 0.330122111965997525 * 1e18, - deposit: 0, - exchangeRate: 0.999999999999991014 * 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] = 2502; - removalIndexes[1] = 6051; + // lender merge / removes available NFTs + uint256[] memory removalIndexes = new uint256[](3); + removalIndexes[0] = 2500; + removalIndexes[1] = 2502; + removalIndexes[2] = 7388; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 6051, - noOfNFTsToRemove: 2, - collateralMerged: 2 * 1e18, + toIndex: 7388, + noOfNFTsToRemove: 5, + collateralMerged: 5 * 1e18, removeCollateralAtIndex: removalIndexes, toIndexLps: 0 }); - // the 2 NFTs claimed from pool are owned by lender - assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(1), _lender); + // NFTs claimed from pool are owned by lender + assertEq(_collateral.ownerOf(1), _lender); + assertEq(_collateral.ownerOf(51), _lender); + assertEq(_collateral.ownerOf(53), _lender); + assertEq(_collateral.ownerOf(73), _lender); _assertCollateralInvariants(); - - // borrower removes tokens from auction price bucket for compensated collateral fraction - _removeAllLiquidity({ - from: _borrower, - amount: 0.000025941052120483 * 1e18, - index: 6051, - newLup: MAX_PRICE, - lpRedeem: 0.000025941052120484 * 1e18 - }); - } function testDepositTakeAndSettleByRegularTakeSubsetPool() external tearDown { - // 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); @@ -826,10 +509,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 10_190.456508610307854462 * 1e18, + borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.747027241552026434 * 1e18 + borrowert0Np: 2_882.277255357846282204 * 1e18, + borrowerCollateralization: 0.756365082071426765 * 1e18 }); skip(4 hours); @@ -845,8 +528,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { kicker: _lender, index: 2000, collateralArbed: 0.021378186081598093 * 1e18, - quoteTokenAmount: 999.9999999999999908 * 1e18, - bondChange: 9.999999999999999908 * 1e18, + quoteTokenAmount: 999.999999999999990800 * 1e18, + bondChange: 15.180339887498947860 * 1e18, isReward: false, lpAwardTaker: 0, lpAwardKicker: 0 @@ -856,45 +539,35 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 9203, + deposit: 0.000000000000009201 * 1e18, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 9_904.062307087997104829 * 1e18, + borrowerDebt: 9_087.671681713557968897 * 1e18, borrowerCollateral: 1.978621813918401907 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.760412964078541435 * 1e18 + borrowert0Np: 2_630.547032872719470290 * 1e18, + borrowerCollateralization: 0.832868255733566506 * 1e18 }); _assertCollateralInvariants(); assertEq(_quote.balanceOf(_borrower), 5_100 * 1e18); - assertEq(_quote.balanceOf(address(_pool)), 5_425.973870376971549568 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 4_305.569567228603107470 * 1e18); // borrower exits from auction by regular take _take({ from: _lender, borrower: _borrower, - maxCollateral: 1, - bondChange: 90.646484035657361618 * 1e18, - givenAmount: 9_904.062307087997104828 * 1e18, - collateralTaken: 0.468592638026133319 * 1e18, + maxCollateral: 2, + bondChange: 137.604443726802605875 * 1e18, + givenAmount: 9_299.424314491640485936 * 1e18, + collateralTaken: 0.802193429456335794 * 1e18, isReward: false }); - 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({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 11_000 * 1e18, - amountRepaid: 10_203.293562995691294053 * 1e18, - collateralToPull: 3, - newLup: MAX_PRICE - }); + assertEq(_quote.balanceOf(_borrower), 7_393.071925217111242444 * 1e18); + assertEq(_quote.balanceOf(address(_pool)), 13_604.993881720243593406 * 1e18); _assertBorrower({ borrower: _borrower, @@ -903,6 +576,7 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); + // auction 2 still ongoing _assertAuction( AuctionParams({ borrower: _borrower, @@ -911,10 +585,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 1_325.327386341314188042 * 1e18, + referencePrice: 0, + totalBondEscrowed: 152.784783614301553735 * 1e18, auctionPrice: 0, - debtInAuction: 0, + debtInAuction: 10064.901171882309537906 * 1e18, thresholdPrice: 0, neutralPrice: 0 }) @@ -925,26 +599,29 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { // remaining token is moved to pool claimable array assertEq(ERC721Pool(address(_pool)).bucketTokenIds(0), 1); + // buckets with collateral + // 2000 - 0.021876321065491412 + // 2279 - 0.978123678934508588 _assertBucket({ index: 2000, lpBalance: 1_000 * 1e18, collateral: 0.021378186081598093 * 1e18, - deposit: 9203, + deposit: 0.000000000000009201 * 1e18, exchangeRate: 1.000000000000000001 * 1e18 }); _assertBucket({ - index: 2159, - lpBalance: 20_712.867160884608174886 * 1e18, + index: 2279, + lpBalance: 11_384.469793445698921143 * 1e18, collateral: 0.978621813918401907 * 1e18, deposit: 0, - exchangeRate: 1.000000000000000001 * 1e18 + exchangeRate: 1 * 1e18 }); // lender adds liquidity in bucket 2159 and merge / removes remaining NFTs _addLiquidityNoEventCheck({ from: _lender, amount: 40_000 * 1e18, - index: 2159 + index: 2279 }); _addLiquidityNoEventCheck({ from: _lender, @@ -953,10 +630,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }); uint256[] memory removalIndexes = new uint256[](2); removalIndexes[0] = 2000; - removalIndexes[1] = 2159; + removalIndexes[1] = 2279; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 2159, + toIndex: 2279, noOfNFTsToRemove: 1, collateralMerged: 1 * 1e18, removeCollateralAtIndex: removalIndexes, @@ -967,108 +644,64 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { assertEq(_collateral.ownerOf(3), _lender); assertEq(_collateral.ownerOf(1), _lender); - _assertCollateralInvariants(); - - // borrower removes tokens from auction price bucket for compensated collateral fraction - _removeAllLiquidity({ - from: _borrower, - amount: 20_712.867160884608174886 * 1e18, - index: 2159, - newLup: MAX_PRICE, - 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); - + // ensure no collateral in buckets _assertBucket({ - index: 2502, - lpBalance: 2_000 * 1e18, + index: 2000, + lpBalance: 40_000.000000000000009178 * 1e18, collateral: 0, - 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.747027241552026434 * 1e18 - }); - - skip(32 hours); - - _depositTake({ - from: _lender, - borrower: _borrower, - kicker: _lender, - index: 2502, - collateralArbed: 0.877705109111459100 * 1e18, - quoteTokenAmount: 3_357.490338749655817817 * 1e18, - bondChange: 33.574903387496558178 * 1e18, - isReward: true, - lpAwardTaker: 0, - lpAwardKicker: 20.202020202020202017 * 1e18 + deposit: 40_000.000000000000009201 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 }); - _assertBucket({ - index: 2502, - lpBalance: 2_020.202020202020202017 * 1e18, - collateral: 0.877705109111459100 * 1e18, - deposit: 362, - exchangeRate: 1.661957717681079631 * 1e18 - }); - _assertBorrower({ - borrower: _borrower, - borrowerDebt: 7_582.063964428011900489 * 1e18, - borrowerCollateral: 1.122294890888540900 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.563403610033938441 * 1e18 + index: 2279, + lpBalance: 40_000.000000000000000001 * 1e18, + collateral: 0, + deposit: 40_000.000000000000000000 * 1e18, + exchangeRate: 1 * 1e18 }); _assertCollateralInvariants(); - // borrower 2 repays entire debt and pulls collateral - _repayDebt({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 11_000 * 1e18, - amountRepaid: 10_205.087450363250041380 * 1e18, - collateralToPull: 3, - newLup: 3_863.654368867279344664 * 1e18 + // borrower removes tokens from auction price bucket for compensated collateral fraction + _removeAllLiquidity({ + from: _borrower, + amount: 11_384.469793445698921142 * 1e18, + index: 2279, + newLup: _priceAt(2000), + lpRedeem: 11_384.469793445698921143 * 1e18 }); - // borrower exits from auction by bucket take: lender adds quote token at a higher priced bucket and calls deposit take - _addLiquidityNoEventCheck({ - from: _lender, - amount: 40_000 * 1e18, - index: 2000 + // borrower2 exits from auction by deposit take + skip(3 hours); + _assertBucket({ + index: 2500, + lpBalance: 8_000.000000000000000000 * 1e18, + collateral: 0 * 1e18, + deposit: 13_293.654327999447280000 * 1e18, + exchangeRate: 1.661706790999930910 * 1e18 }); _depositTake({ from: _lender, - borrower: _borrower, + borrower: _borrower2, kicker: _lender, - index: 2000, - collateralArbed: 0.163728054862748873 * 1e18, - quoteTokenAmount: 7_658.650469119203939887 * 1e18, - bondChange: 76.586504691192039399 * 1e18, + index: 2500, + collateralArbed: 2.645225595891871889 * 1e18, + quoteTokenAmount: 10_220.237430207183199580 * 1e18, + bondChange: 155.146677921483848824 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 76.586504691192039399 * 1e18 + lpAwardKicker: 93.365678971373374698 * 1e18 }); - + _assertCollateralInvariants(); _assertBorrower({ - borrower: _borrower, + borrower: _borrower2, borrowerDebt: 0, borrowerCollateral: 0, borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); + _assertAuction( AuctionParams({ borrower: _borrower, @@ -1077,8 +710,8 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 1_425.973870376971549568 * 1e18, + referencePrice: 0, + totalBondEscrowed: 152.784783614301553735 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -1086,68 +719,68 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { }) ); - _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); - - _assertBucket({ - index: 2000, - lpBalance: 40_076.586504691192039399 * 1e18, - collateral: 0.163728054862748873 * 1e18, - deposit: 32_417.936035571988099513 * 1e18, - exchangeRate: 1.000000000000000001 * 1e18 - }); + // lender removes collateral _assertBucket({ - index: 6051, - lpBalance: 0.000075324346213057 * 1e18, - collateral: 0.958566836025792027 * 1e18, - deposit: 0, - exchangeRate: 0.999999999999996900 * 1e18 + index: 2500, + lpBalance: 8_093.365678971373374698 * 1e18, + collateral: 2.645225595891871889 * 1e18, + deposit: 3_228.588863672794087920 * 1e18, + exchangeRate: 1.661709951994811681 * 1e18 }); - - // lender adds liquidity in bucket 6051 and merge / removes the other 2 NFTs _addLiquidityNoEventCheck({ from: _lender, - amount: 1_000 * 1e18, - index: 6051 + amount: 10_000 * 1e18, + index: 2569 }); - uint256[] memory removalIndexes = new uint256[](3); - removalIndexes[0] = 2000; - removalIndexes[1] = 2502; - removalIndexes[2] = 6051; + _assertBucket({ + index: 2569, + lpBalance: 10_971.610695426638179656 * 1e18, + collateral: 0.354774404108128111 * 1e18, + deposit: 10_000.000000000000000000 * 1e18, + exchangeRate: 1 * 1e18 + }); + removalIndexes[0] = 2500; + removalIndexes[1] = 2569; _mergeOrRemoveCollateral({ from: _lender, - toIndex: 6051, - noOfNFTsToRemove: 2, - collateralMerged: 2 * 1e18, + toIndex: 2569, + noOfNFTsToRemove: 3, + collateralMerged: 3 * 1e18, removeCollateralAtIndex: removalIndexes, toIndexLps: 0 }); - - // the 2 NFTs claimed from pool are owned by lender - assertEq(_collateral.ownerOf(3), _lender); - assertEq(_collateral.ownerOf(1), _lender); - - _assertCollateralInvariants(); - - // borrower removes tokens from auction price bucket for compensated collateral fraction + _assertBucket({ + index: 2500, + lpBalance: 1_942.931652901886597757 * 1e18, + collateral: 0, + deposit: 3_228.588863672794087920 * 1e18, + exchangeRate: 1.661709951994811681 * 1e18 + }); + _assertBucket({ + index: 2569, + lpBalance: 10_000.000000000000000004 * 1e18, + collateral: 0, + deposit: 10_000.000000000000000000 * 1e18, + exchangeRate: 1 * 1e18 + }); + // borrower 2 redeems LP for quote token _removeAllLiquidity({ - from: _borrower, - amount: 0.000075324346213056 * 1e18, - index: 6051, + from: _borrower2, + amount: 971.610695426638179651 * 1e18, + index: 2569, newLup: MAX_PRICE, - lpRedeem: 0.000075324346213057 * 1e18 + lpRedeem: 971.610695426638179652 * 1e18 }); } - function testDepositTakeAndSettleBySettleSubsetPool() external tearDown { - + 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); + // 1 token id is owned by borrower 2 before settle + assertEq(ERC721Pool(address(_pool)).borrowerTokenIds(_borrower2, 2), 73); + _assertBucket({ index: 2502, lpBalance: 2_000 * 1e18, @@ -1158,10 +791,10 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 10_190.456508610307854462 * 1e18, + borrowerDebt: 10_064.648403565736152555 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.747027241552026434 * 1e18 + borrowert0Np: 2_882.277255357846282204 * 1e18, + borrowerCollateralization: 0.756365082071426765 * 1e18 }); skip(32 hours); @@ -1171,56 +804,57 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { borrower: _borrower, kicker: _lender, index: 2502, - collateralArbed: 0.877705109111459100 * 1e18, - quoteTokenAmount: 3_357.490338749655817817 * 1e18, - bondChange: 33.574903387496558178 * 1e18, + collateralArbed: 0.882320037286956004 * 1e18, + quoteTokenAmount: 3_375.143849709550192592 * 1e18, + bondChange: 51.235830807792639427 * 1e18, isReward: true, lpAwardTaker: 0, - lpAwardKicker: 20.202020202020202017 * 1e18 + lpAwardKicker: 30.828669455613465562 * 1e18 }); _assertBucket({ index: 2502, - lpBalance: 2_020.202020202020202017 * 1e18, - collateral: 0.877705109111459100 * 1e18, - deposit: 362, - exchangeRate: 1.661957717681079631 * 1e18 + lpBalance: 2_030.828669455613465562 * 1e18, + collateral: 0.882320037286956004 * 1e18, + deposit: 0.000000000000000834 * 1e18, + exchangeRate: 1.661954009450878778 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 7_582.063964428011900489 * 1e18, - borrowerCollateral: 1.122294890888540900 * 1e18, - borrowert0Np: 2_627.524038461538462750 * 1e18, - borrowerCollateralization: 0.563403610033938441 * 1e18 + borrowerDebt: 6_742.762708953482931550 * 1e18, + borrowerCollateral: 1.117679962713043996 * 1e18, + borrowert0Np: 3_454.620119359940588354 * 1e18, + borrowerCollateralization: 0.630927812552385529 * 1e18 }); _assertCollateralInvariants(); - // borrower 2 repays entire debt and pulls collateral - _repayDebt({ - from: _borrower2, - borrower: _borrower2, - amountToRepay: 11_000 * 1e18, - amountRepaid: 10_205.087450363250041380 * 1e18, - collateralToPull: 3, - newLup: 3_863.654368867279344664 * 1e18 + // borrowers exits from auction by bucket take: lender adds quote token at a higher priced bucket and calls deposit take + _addLiquidityNoEventCheck({ + from: _lender, + amount: 60_000 * 1e18, + index: 2000 }); - skip(72 hours); - - // borrower exits from auction by pool debt settle - _settle({ - from: _lender, - borrower: _borrower, - maxDepth: 10, - settledDebt: 3_769.545371910961412793 * 1e18 + // bucket take on borrower + _depositTake({ + from: _lender, + borrower: _borrower, + kicker: _lender, + index: 2000, + collateralArbed: 0.146369981971725896 * 1e18, + quoteTokenAmount: 6_846.697910339464805069 * 1e18, + bondChange: 103.935201385981873520 * 1e18, + isReward: true, + lpAwardTaker: 0, + lpAwardKicker: 103.935201385981873519 * 1e18 }); _assertBorrower({ borrower: _borrower, borrowerDebt: 0, borrowerCollateral: 0, - borrowert0Np: 2_627.524038461538462750 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 1 * 1e18 }); _assertAuction( @@ -1231,53 +865,130 @@ contract ERC721PoolLiquidationsSettleAuctionTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 1_425.973870376971549568 * 1e18, + referencePrice: 0, + totalBondEscrowed: 305.569567228603107470 * 1e18, + auctionPrice: 0, + debtInAuction: 10_066.670727855240484714 * 1e18, + thresholdPrice: 0, + neutralPrice: 0 + }) + ); + _assertBucket({ + index: 5476, + lpBalance: 0.001343248402621047 * 1e18, + collateral: 0.971309980741318100 * 1e18, + deposit: 0, + exchangeRate: 1.000000000000000249 * 1e18 + }); + + // bucket take on borrower 2 + _depositTake({ + from: _lender, + borrower: _borrower2, + kicker: _lender, + index: 2000, + collateralArbed: 0.218524435242978009 * 1e18, + quoteTokenAmount: 10_221.841760049014997661 * 1e18, + bondChange: 155.171032193774512947 * 1e18, + isReward: true, + lpAwardTaker: 0, + lpAwardKicker: 155.171032193774512946 * 1e18 + }); + + _assertBorrower({ + borrower: _borrower2, + borrowerDebt: 0, + borrowerCollateral: 2 * 1e18, + borrowert0Np: 0, + borrowerCollateralization: 1 * 1e18 + }); + _assertAuction( + AuctionParams({ + borrower: _borrower2, + active: false, + kicker: address(0), + bondSize: 0, + bondFactor: 0, + kickTime: 0, + referencePrice: 0, + totalBondEscrowed: 305.569567228603107470 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, neutralPrice: 0 }) ); + _assertBucket({ + index: 5557, + lpBalance: 0.000721544103807183 * 1e18, + collateral: 0.781475564757021991 * 1e18, + deposit: 0, + exchangeRate: 0.999999999999999669 * 1e18 + }); _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); + assertEq(ERC721Pool(address(_pool)).bucketTokenIds(2), 73); _assertBucket({ - index: 2500, - lpBalance: 8_000 * 1e18, - collateral: 1.122294890888540900 * 1e18, - deposit: 8_218.389542394611030535 * 1e18, - exchangeRate: 1.569318637591693583 * 1e18 - }); - _assertBucket({ - index: 2502, - lpBalance: 2_020.202020202020202017 * 1e18, - collateral: 0.877705109111459100 * 1e18, - deposit: 362, - exchangeRate: 1.661957717681079631 * 1e18 + index: 2000, + lpBalance: 60_259.106233579756386465 * 1e18, + collateral: 0.364894417214703905 * 1e18, + deposit: 43_190.566563191276548531 * 1e18, + exchangeRate: 1.000000000000000001 * 1e18 }); - // lender merge / removes the other 2 NFTs - uint256[] memory removalIndexes = new uint256[](2); - removalIndexes[0] = 2500; + // lender adds liquidity in bucket 6171 and 6252 and merge / removes the other 3 NFTs + _addLiquidityNoEventCheck({ + from: _lender, + amount: 1_000 * 1e18, + index: 5476 + }); + _addLiquidityNoEventCheck({ + from: _lender, + amount: 1_000 * 1e18, + index: 5557 + }); + uint256[] memory removalIndexes = new uint256[](4); + removalIndexes[0] = 2000; removalIndexes[1] = 2502; + removalIndexes[2] = 5476; + removalIndexes[3] = 5557; + _mergeOrRemoveCollateral({ from: _lender, - toIndex: 2502, - noOfNFTsToRemove: 2, - collateralMerged: 2 * 1e18, + toIndex: 6252, + noOfNFTsToRemove: 3, + collateralMerged: 3 * 1e18, removeCollateralAtIndex: removalIndexes, toIndexLps: 0 }); - // the 2 NFTs claimed from pool are owned by lender + // the 3 NFTs claimed from pool are owned by lender assertEq(_collateral.ownerOf(3), _lender); assertEq(_collateral.ownerOf(1), _lender); + assertEq(_collateral.ownerOf(73), _lender); _assertCollateralInvariants(); + + // remove lps for both borrower and borrower 2 + _removeAllLiquidity({ + from: _borrower, + amount: 0.001343248402621047 * 1e18, + index: 5476, + newLup: MAX_PRICE, + lpRedeem: 0.001343248402621047 * 1e18 + }); + + _removeAllLiquidity({ + from: _borrower2, + amount: 0.000721544103807182 * 1e18, + index: 5557, + newLup: MAX_PRICE, + lpRedeem: 0.000721544103807183 * 1e18 + }); } } diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol index 2ad9744f3..3bdd8b0f1 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolLiquidationsTake.t.sol @@ -126,14 +126,14 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 19.819038461538461548 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 1.000773560501591181 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 15.014423076923076930 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.981531649793150539 * 1e18 }); @@ -141,7 +141,6 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { } function testTakeCollateralSubsetPool() external tearDown { - // Skip to make borrower undercollateralized skip(1000 days); @@ -153,7 +152,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -166,17 +165,17 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 0.872656701977127996 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); /******************************/ @@ -189,11 +188,11 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { lup: 9.917184843435912074 * 1e18, poolSize: 73_004.346887619919714000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.056751649452525709 * 1e18, - poolDebt: 40.231555971534224232 * 1e18, + encumberedCollateral: 4.028103499563389533 * 1e18, + poolDebt: 39.947446973661202747 * 1e18, actualUtilization: 0.000477170706006322 * 1e18, targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 4.023155597153422423 * 1e18, + minDebtAmount: 3.994744697366120275 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -202,41 +201,41 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.727860269914713433 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.772712801701582812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 381.842493141340875904 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506414413857370145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3350.914144267400237568 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364359914920859402 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.227287198298417188 * 1e18 + locked: 0.345029692224734546 * 1e18 }); skip(5.5 hours); @@ -246,32 +245,33 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // before take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_999.772712801701582812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); assertEq(_quote.balanceOf(_borrower), 119.8 * 1e18); + // threshold price increases slightly due to interest _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 5.5 hours, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 16.875213515338743424 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506739514062665877 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 15.566136492679870612 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364681001543373706 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.013479028125331754 * 1e18, + borrowerDebt: 22.729362003086747412 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861858811639550854 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872632046785045240 * 1e18 }); uint256 snapshot = vm.snapshot(); @@ -284,25 +284,26 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 1, - bondChange: 0.168752135153387434 * 1e18, - givenAmount: 16.875213515338743424 * 1e18, + bondChange: 0.236299242694081216 * 1e18, + givenAmount: 15.566136492679870612 * 1e18, collateralTaken: 1.0 * 1e18, isReward: false }); + // borrower still under liquidation _assertPool( PoolParams({ - htp: 7.749209044755361553 * 1e18, + htp: 5.739737879567360457 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.347853838043123634 * 1e18, + poolSize: 73_004.347847014760830891 * 1e18, pledgedCollateral: 4 * 1e18, - encumberedCollateral: 2.517692578855560848 * 1e18, - poolDebt: 24.968422683457442926 * 1e18, - actualUtilization: 0.000411524519658268 * 1e18, + encumberedCollateral: 2.494345764818852289 * 1e18, + poolDebt: 24.736888013150079997 * 1e18, + actualUtilization: 0.000411524083711660 * 1e18, targetUtilization: 0.781984313351887130 * 1e18, - minDebtAmount: 1.248421134172872146 * 1e18, - loans: 2, - maxBorrower: address(_borrower), + minDebtAmount: 2.473688801315008000 * 1e18, + loans: 1, + maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, interestRateUpdate: block.timestamp - 5.5 hours }) @@ -310,26 +311,26 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _assertBorrower({ borrower: _borrower, - borrowerDebt: 7.749209044755361554 * 1e18, + borrowerDebt: 7.517674374447998626 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 7.061045370627448275 * 1e18, - borrowerCollateralization: 1.279767365438131935 * 1e18 + borrowert0Np: 7.550178184893434284 * 1e18, + borrowerCollateralization: 1.319182548946741612 * 1e18 }); _assertAuction( AuctionParams({ borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.058535063145029754 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 7.749209044755361554 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 0.108730449530653330 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 5.5 hours, + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.108730449530653330 * 1e18, + auctionPrice: 15.566136492679870612 * 1e18, + debtInAuction: 7.517674374447998626 * 1e18, + thresholdPrice: 7.517674374447998626 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertKicker({ @@ -343,7 +344,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // after take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_982.897499286362839388 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_984.088833815095394842 * 1e18); assertEq(_quote.balanceOf(_borrower), 119.8 * 1e18); // no additional tokens as there is no rounding of collateral taken (1) vm.revertTo(snapshot); @@ -356,9 +357,9 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 0.227287198298417188 * 1e18, - givenAmount: 24.624422560094104976 * 1e18, - collateralTaken: 1.459206577606363895 * 1e18, // not a rounded collateral, difference of 2 - 1.16 collateral should go to borrower in quote tokens at auction price + bondChange: 0.345029692224734546 * 1e18, + givenAmount: 23.258980855317575086 * 1e18, + collateralTaken: 1.494203835759460320 * 1e18, // not a rounded collateral, difference of 2 - 1.49 collateral should go to borrower in quote tokens at auction price isReward: false }); @@ -366,11 +367,11 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { PoolParams({ htp: 5.739737879567360457 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.347853838043123634 * 1e18, + poolSize: 73_004.347847014760830891 * 1e18, pledgedCollateral: 3.0 * 1e18, encumberedCollateral: 1.736300564176668638 * 1e18, poolDebt: 17.219213638702081372 * 1e18, - actualUtilization: 0.000411524519658268 * 1e18, + actualUtilization: 0.000411524083711660 * 1e18, targetUtilization: 0.781984313351887130 * 1e18, minDebtAmount: 1.721921363870208137 * 1e18, loans: 1, @@ -396,7 +397,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -415,12 +416,11 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), _lender); // after take: check quote token balances of taker and borrower - assertEq(_quote.balanceOf(_lender), 46_966.022285771024095971 * 1e18); - assertEq(_quote.balanceOf(_borrower), 128.926004470583381865 * 1e18); // borrower gets quote tokens from the difference of rounded collateral (2) and needed collateral (1.16) at auction price (19.8) = 16.6 additional tokens + assertEq(_quote.balanceOf(_lender), 46_968.522697322415524242 * 1e18); + assertEq(_quote.balanceOf(_borrower), 127.673292130042166126 * 1e18); // borrower gets quote tokens from the difference of rounded collateral (2) and needed collateral (1.49) at auction price (15.5) = 7.9 additional tokens } function testTakeCollateralAndSettleSubsetPool() external tearDown { - // Skip to make borrower undercollateralized skip(1000 days); @@ -432,7 +432,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -444,17 +444,17 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 0.872656701977127996 * 1e18 }); _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); /******************************/ @@ -467,11 +467,11 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { lup: 9.917184843435912074 * 1e18, poolSize: 73_004.346887619919714000 * 1e18, pledgedCollateral: 5 * 1e18, - encumberedCollateral: 4.056751649452525709 * 1e18, - poolDebt: 40.231555971534224232 * 1e18, + encumberedCollateral: 4.028103499563389533 * 1e18, + poolDebt: 39.947446973661202747 * 1e18, actualUtilization: 0.000477170706006322 * 1e18, targetUtilization: 0.786051641950380194 * 1e18, - minDebtAmount: 4.023155597153422423 * 1e18, + minDebtAmount: 3.994744697366120275 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -480,41 +480,41 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); _assertBorrower({ borrower: _borrower2, borrowerDebt: 17.218727143819483943 * 1e18, borrowerCollateral: 3 * 1e18, - borrowert0Np: 5.255048076923076925 * 1e18, + borrowert0Np: 5.764554510715692564 * 1e18, borrowerCollateralization: 1.727860269914713433 * 1e18 }); - assertEq(_quote.balanceOf(_lender), 46_999.772712801701582812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 381.842493141340875904 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506414413857370145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3_350.914144267400237568 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364359914920859402 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.227287198298417188 * 1e18 + locked: 0.345029692224734546 * 1e18 }); skip(10 hours); @@ -524,30 +524,30 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(1), address(_pool)); // before take: check quote token balances of taker - assertEq(_quote.balanceOf(_lender), 46_999.772712801701582812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_999.654970307775265454 * 1e18); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 0.745786119416681408 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.507005511971773436 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3.272377094011133044 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364943715527677468 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.014011023943546872 * 1e18, + borrowerDebt: 22.729887431055354936 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861838888763733724 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872611874873280395 * 1e18 }); /**************************************/ @@ -558,8 +558,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 2, - bondChange: 0.014915722388333628 * 1e18, - givenAmount: 1.491572238833362816 * 1e18, + bondChange: 0.099351593054310196 * 1e18, + givenAmount: 6.544754188022266088 * 1e18, collateralTaken: 2 * 1e18, isReward: true }); @@ -568,20 +568,20 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { assertEq(_collateral.ownerOf(3), _lender); assertEq(_collateral.ownerOf(1), _lender); - // after take : Taker quote token used for buying collateral - assertEq(_quote.balanceOf(_lender), 46_998.281140562868219996 * 1e18); + // after take: Taker quote token used for buying collateral + assertEq(_quote.balanceOf(_lender), 46_993.110216119752999366 * 1e18); _assertPool( PoolParams({ htp: 5.739870563397816903 * 1e18, lup: 9.917184843435912074 * 1e18, - poolSize: 73_004.348644400449318457 * 1e18, + poolSize: 73_004.348631994338166115 * 1e18, pledgedCollateral: 3 * 1e18, - encumberedCollateral: 4.070504644882883983 * 1e18, - poolDebt: 40.367946969368016673 * 1e18, - actualUtilization: 0.000371338408811493 * 1e18, + encumberedCollateral: 3.378387824288349781 * 1e18, + poolDebt: 33.504096526280849753 * 1e18, + actualUtilization: 0.000371337774626592 * 1e18, targetUtilization: 0.778640404875432888 * 1e18, - minDebtAmount: 4.036794696936801667 * 1e18, + minDebtAmount: 3.350409652628084975 * 1e18, loans: 1, maxBorrower: address(_borrower2), interestRate: 0.045 * 1e18, @@ -592,9 +592,9 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // Borrower collateral is 0 and some debt is still to be paid _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.148335279174565965 * 1e18, + borrowerDebt: 16.284484836087399045 * 1e18, borrowerCollateral: 0, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 0, borrowerCollateralization: 0 }); _assertAuction( @@ -602,22 +602,22 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.242202920686750816 * 1e18, - bondFactor: 0.010000000000000000 * 1e18, + bondSize: 0.444381285279044742 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 10 hours, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.242202920686750816 * 1e18, - auctionPrice: 0.745786119416681408 * 1e18, - debtInAuction: 23.148335279174565965 * 1e18, + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.444381285279044742 * 1e18, + auctionPrice: 3.272377094011133044 * 1e18, + debtInAuction: 16.284484836087399045 * 1e18, thresholdPrice: 0, - neutralPrice: 11.932577910666902372 * 1e18 + neutralPrice: 13.089508376044532178 * 1e18 }) ); // kicker bond is locked as auction is not cleared _assertKicker({ kicker: _lender, claimable: 0, - locked: 0.242202920686750816 * 1e18 + locked: 0.444381285279044742 * 1e18 }); // settle auction @@ -625,7 +625,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxDepth: 10, - settledDebt: 20.183898781290497858 * 1e18 + settledDebt: 14.199051019135248430 * 1e18 }); _assertAuction( @@ -636,8 +636,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.242202920686750816 * 1e18, + referencePrice: 0, + totalBondEscrowed: 0.444381285279044742 * 1e18, auctionPrice: 0, debtInAuction: 0, thresholdPrice: 0, @@ -646,7 +646,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { ); _assertKicker({ kicker: _lender, - claimable: 0.242202920686750816 * 1e18, + claimable: 0.444381285279044742 * 1e18, locked: 0 }); @@ -658,10 +658,10 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { // Kicker claims remaining bond + reward to his own address _pool.withdrawBonds(_lender, type(uint256).max); - assertEq(_quote.balanceOf(_lender), 46_998.423343483554970812 * 1e18); + assertEq(_quote.balanceOf(_lender), 46_993.454597405032044108 * 1e18); } - function testTakeCollateralSubsetPoolAndSettleByRepayAndPledge() external tearDown { + function testTakeCollateralSubsetPoolAndSettleWithDebt() external tearDown { // Skip to make borrower undercollateralized skip(1000 days); @@ -673,7 +673,7 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { bondSize: 0, bondFactor: 0, kickTime: 0, - kickMomp: 0, + referencePrice: 0, totalBondEscrowed: 0, auctionPrice: 0, debtInAuction: 0, @@ -685,40 +685,40 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, + borrowert0Np: 11.413817931217071277 * 1e18, borrowerCollateralization: 0.872656701977127996 * 1e18 - }); + }); _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); _assertBorrower({ borrower: _borrower, - borrowerDebt: 23.012828827714740290 * 1e18, + borrowerDebt: 22.728719829841718805 * 1e18, borrowerCollateral: 2 * 1e18, - borrowert0Np: 10.404995192307692312 * 1e18, - borrowerCollateralization: 0.861883162446546169 * 1e18 + borrowert0Np: 11.413817931217071277 * 1e18, + borrowerCollateralization: 0.872656701977127996 * 1e18 }); _assertAuction( AuctionParams({ borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298417188 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224734546 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298417188 * 1e18, - auctionPrice: 381.842493141340875904 * 1e18, - debtInAuction: 23.012828827714740290 * 1e18, - thresholdPrice: 11.506414413857370145 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224734546 * 1e18, + auctionPrice: 3_350.914144267400237568 * 1e18, + debtInAuction: 22.728719829841718805 * 1e18, + thresholdPrice: 11.364359914920859402 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); @@ -729,8 +729,8 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { from: _lender, borrower: _borrower, maxCollateral: 1, - bondChange: 0.000000000000006781 * 1e18, - givenAmount: 0.000000000000678144 * 1e18, + bondChange: 0.000000000000180719 * 1e18, + givenAmount: 0.000000000011904838 * 1e18, collateralTaken: 1 * 1e18, isReward: true }); @@ -740,107 +740,66 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { borrower: _borrower, active: true, kicker: _lender, - bondSize: 0.227287198298423969 * 1e18, - bondFactor: 0.01 * 1e18, + bondSize: 0.345029692224915265 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, kickTime: block.timestamp - 50 hours, - kickMomp: 9.917184843435912074 * 1e18, - totalBondEscrowed: 0.227287198298423969 * 1e18, - auctionPrice: 0.000000000000678144 * 1e18, - debtInAuction: 24.630052245331353429 * 1e18, - thresholdPrice: 24.630052245331353429 * 1e18, - neutralPrice: 11.932577910666902372 * 1e18 - }) - ); - - uint256 snapshot = vm.snapshot(); - // borrower repays debt in order to exit from auction - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 25 * 1e18, - amountRepaid: 24.630052245331353429 * 1e18, - collateralToPull: 0, - newLup: _priceAt(3696) - }); - - _assertAuction( - AuctionParams({ - borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.227287198298423969 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 0, - neutralPrice: 0 + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224915265 * 1e18, + auctionPrice: 0.000000000011904838 * 1e18, + debtInAuction: 22.734558435739539104 * 1e18, + thresholdPrice: 22.734558435739539104 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 0, + borrowerDebt: 22.734558435739539104 * 1e18, borrowerCollateral: 1 * 1e18, - borrowert0Np: 0, - borrowerCollateralization: 1 * 1e18 - }); - - // borrower should be able to pull collateral from the pool - _repayDebtNoLupCheck({ - from: _borrower, - borrower: _borrower, - amountToRepay: 0, - amountRepaid: 0, - collateralToPull: 1 + borrowert0Np: 22.827635862422370438 * 1e18, + borrowerCollateralization: 0.436216294742093726 * 1e18 }); - vm.revertTo(snapshot); - - // borrower repays part of debt, but not enough to exit from auction - _repayDebt({ - from: _borrower, - borrower: _borrower, - amountToRepay: 5 * 1e18, - amountRepaid: 5 * 1e18, - collateralToPull: 0, - newLup: _priceAt(3696) - }); + // confirm borrower cannot repay while in liquidation + _assertRepayAuctionActiveRevert(_borrower, 25 * 1e18); - // borrower pledge one more NFT to exit from auction + // confirm borrower cannot recollateralize while in liquidation uint256[] memory tokenIdsToAdd = new uint256[](1); tokenIdsToAdd[0] = 5; - _pledgeCollateral({ - from: _borrower, - borrower: _borrower, - tokenIds: tokenIdsToAdd - }); + _assertPledgeCollateralAuctionActiveRevert(_borrower, tokenIdsToAdd); + // ensure auction state did not change _assertAuction( AuctionParams({ borrower: _borrower, - active: false, - kicker: address(0), - bondSize: 0, - bondFactor: 0, - kickTime: 0, - kickMomp: 0, - totalBondEscrowed: 0.227287198298423969 * 1e18, - auctionPrice: 0, - debtInAuction: 0, - thresholdPrice: 9.815026122665676715 * 1e18, - neutralPrice: 0 + active: true, + kicker: _lender, + bondSize: 0.345029692224915265 * 1e18, + bondFactor: 0.015180339887498948 * 1e18, + kickTime: block.timestamp - 50 hours, + referencePrice: 13.089508376044532178 * 1e18, + totalBondEscrowed: 0.345029692224915265 * 1e18, + auctionPrice: 0.000000000011904838 * 1e18, + debtInAuction: 22.734558435739539104 * 1e18, + thresholdPrice: 22.734558435739539104 * 1e18, + neutralPrice: 13.089508376044532178 * 1e18 }) ); _assertBorrower({ borrower: _borrower, - borrowerDebt: 19.630052245331353430 * 1e18, - borrowerCollateral: 2 * 1e18, - borrowert0Np: 8.902861174861655549 * 1e18, - borrowerCollateralization: 1.010408400292926569 * 1e18 + borrowerDebt: 22.734558435739539104 * 1e18, + borrowerCollateral: 1 * 1e18, + borrowert0Np: 22.827635862422370438 * 1e18, + borrowerCollateralization: 0.436216294742093726 * 1e18 }); + // settle the auction with debt + skip(22 hours + 1); + _settle({ + from: _lender, + borrower: _borrower, + maxDepth: 10, + settledDebt: 19.819038461528240952 * 1e18 + }); } function testTakeCollateralWithAtomicSwapSubsetPool() external tearDown { @@ -850,10 +809,10 @@ contract ERC721PoolLiquidationsTakeTest is ERC721HelperContract { _kick({ from: _lender, borrower: _borrower, - debt: 23.012828827714740289 * 1e18, + debt: 22.728719829841718804 * 1e18, collateral: 2 * 1e18, - bond: 0.227287198298417188 * 1e18, - transferAmount: 0.227287198298417188 * 1e18 + bond: 0.345029692224734546 * 1e18, + transferAmount: 0.345029692224734546 * 1e18 }); skip(5.5 hours); diff --git a/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol b/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol index 1959705bc..9e579ef35 100644 --- a/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol +++ b/tests/forge/unit/ERC721Pool/ERC721PoolReserveAuction.t.sol @@ -122,7 +122,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 823.268887039816613726 * 1e18, + remainingReserves: 831.584734383653145178 * 1e18, price: 1_000_000_000 * 1e18, epoch: 1 }); @@ -193,7 +193,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction _kickReserveAuction({ from: _bidder, - remainingReserves: 823.268887039816613726 * 1e18, + remainingReserves: 831.584734383653145178 * 1e18, price: 1_000_000_000 * 1e18, epoch: 1 }); @@ -248,10 +248,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction uint256 expectedPrice = 1_000_000_000 * 1e18; - - uint256 kickAward = Maths.wmul(claimableReserves, 0.01 * 1e18); - uint256 expectedQuoteBalance = _quote.balanceOf(_bidder) + kickAward; - expectedReserves -= kickAward; + uint256 expectedQuoteBalance = _quote.balanceOf(_bidder); _kickReserveAuction({ from: _bidder, @@ -267,14 +264,14 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { timeRemaining: 3 days }); assertEq(_quote.balanceOf(_bidder), expectedQuoteBalance); - + // bid once the price becomes attractive skip(24 hours); expectedPrice = 59.604644775390625 * 1e18; _assertReserveAuction({ reserves: 0.000203758789008448 * 1e18, claimableReserves : 0, - claimableReservesRemaining: 823.268887039816613726 * 1e18, + claimableReservesRemaining: 831.584734383653145178 * 1e18, auctionPrice: expectedPrice, timeRemaining: 2 days }); @@ -282,7 +279,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { _takeReserves({ from: _bidder, amount: 300 * 1e18, - remainingReserves: 523.268887039816613726 * 1e18, + remainingReserves: 531.584734383653145178 * 1e18, price: expectedPrice, epoch: 1 }); @@ -319,7 +316,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { }); expectedQuoteBalance += expectedReserves; assertEq(_quote.balanceOf(_bidder), expectedQuoteBalance); - assertEq(_ajnaToken.balanceOf(_bidder), 32_679.868870829247225792 * 1e18); + assertEq(_ajnaToken.balanceOf(_bidder), 32_212.025177571105194476 * 1e18); expectedReserves = 0; _assertReserveAuction({ @@ -369,8 +366,6 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // kick off a new auction uint256 expectedPrice = 1_000_000_000 * 1e18; uint256 expectedReserves = claimableReserves; - uint256 kickAward = Maths.wmul(expectedReserves, 0.01 * 1e18); - expectedReserves -= kickAward; _kickReserveAuction({ from: _bidder, @@ -445,8 +440,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { timeRemaining: 0 }); expectedPrice = 1_000_000_000 * 1e18; - kickAward = Maths.wmul(newClaimableReserves, 0.01 * 1e18); - expectedReserves += newClaimableReserves - kickAward; + expectedReserves += newClaimableReserves; _kickReserveAuction({ from: _bidder, remainingReserves: expectedReserves, @@ -460,7 +454,7 @@ contract ERC721PoolReserveAuctionTest is ERC721HelperContract { // ensure entire reserves can still be taken skip(28 hours); - assertEq(expectedReserves, 751.769002239424117961 * 1e18); + assertEq(expectedReserves, 760.372729534771836324 * 1e18); expectedPrice = 3.725290298461914062 * 1e18; _assertReserveAuction({ reserves: 0.000204114705960104 * 1e18, diff --git a/tests/forge/unit/Positions/CodearenaReports.t.sol b/tests/forge/unit/Positions/CodearenaReports.t.sol index 6bfe61eea..d582c4ff5 100644 --- a/tests/forge/unit/Positions/CodearenaReports.t.sol +++ b/tests/forge/unit/Positions/CodearenaReports.t.sol @@ -139,22 +139,22 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); // skip ahead so take can be called on the loan - skip(10 hours); + skip(9 hours); // take entire collateral _take({ from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 60.911699561320164197 * 1e18, + givenAmount: 4_012.538586931187076 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -163,7 +163,7 @@ contract PositionManagerCodeArenaTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 5_821.65265251164695163 * 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 71f307a05..0f27ee230 100644 --- a/tests/forge/unit/Positions/PositionManager.t.sol +++ b/tests/forge/unit/Positions/PositionManager.t.sol @@ -918,22 +918,22 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); // skip ahead so take can be called on the loan - skip(10 hours); + skip(9 hours); // take entire collateral _take({ from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 60.911699561320164197 * 1e18, + givenAmount: 4012.538586931187076000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -942,7 +942,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 5_821.652652511646951630 * 1e18 }); // bucket is insolvent, balances are reset @@ -2807,22 +2807,22 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _kick({ from: testMinter, borrower: testBorrowerTwo, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); // skip ahead so take can be called on the loan - skip(10 hours); + skip(14 hours); // take entire collateral _take({ from: testMinter, borrower: testBorrowerTwo, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 10.767768953351785113 * 1e18, + givenAmount: 709.323311147932380000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -2831,7 +2831,7 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract from: testMinter, borrower: testBorrowerTwo, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 9_030.334558988288428680 * 1e18 }); // bucket is insolvent, balances are reset @@ -2855,8 +2855,8 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract index: _i9_72, lpBalance: 11_000 * 1e18, collateral: 0, - deposit: 8_936.865546659328965469 * 1e18, - exchangeRate: 0.812442322423575361 * 1e18 + deposit: 8_988.841151969900795435 * 1e18, + exchangeRate: 0.817167377451809164 * 1e18 }); assertTrue(_positionManager.isPositionBucketBankrupt(tokenId, testIndex)); @@ -2900,9 +2900,9 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract _assertBucketAssets({ index: _i9_91, - lpBalance: 18_936.867676658332708016 * 1e18, + lpBalance: 18_988.843069038537201221 * 1e18, collateral: 0, - deposit: 18_936.867676658332708016 * 1e18, + deposit: 18_988.843069038537201221 * 1e18, exchangeRate: 1.0 * 1e18 }); @@ -2925,10 +2925,10 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract // minter one should only be able to withdraw what they moved _removeAllLiquidity({ from: testMinter, - amount: 8_936.867676658332708016 * 1e18, + amount: 8_988.843069038537201221 * 1e18, index: _i9_91, newLup: _p9_91, - lpRedeem: 8_936.867676658332708016 * 1e18 + lpRedeem: 8_988.843069038537201221 * 1e18 }); // minter2 has remaining liquidity in _i9_91 @@ -2940,7 +2940,6 @@ contract PositionManagerERC20PoolTest is PositionManagerERC20PoolHelperContract exchangeRate: 1.0 * 1e18 }); } - } abstract contract PositionManagerERC721PoolHelperContract is ERC721HelperContract { diff --git a/tests/forge/unit/Rewards/ClaimRewards.t.sol b/tests/forge/unit/Rewards/ClaimRewards.t.sol index a54811626..b9d629a83 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.798787696449835897 * 1e18, + tokensToBurn: 82.625038077222056449 * 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.089939384822486675 * 1e18); + assertEq(minterTwoBalance, 4.131251903861097650 * 1e18); vm.revertTo(stakeSnapshot); @@ -164,11 +164,11 @@ contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089939384822486675 * 1e18 + reward: 4.131251903861097650 * 1e18 }); uint256 updaterBalance = _ajnaToken.balanceOf(_updater); - assertEq(updaterBalance, 4.089939384822486675 * 1e18); + assertEq(updaterBalance, 4.131251903861097650 * 1e18); vm.revertTo(updateSnapshot); @@ -181,7 +181,7 @@ contract ClaimRewardsOnExchangeRateUpdateTest is ClaimRewardsOnStakeTest { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089939384822486675 * 1e18 + reward: 4.131251903861097650 * 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.089939384822486675 * 1e18 + reward: 4.131251903861097650 * 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.539636308934920041 * 1e18, + reward: 24.787511423166585895 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.539636308934920041 * 1e18); + assertEq(minterOneBalance, 24.787511423166585895 * 1e18); vm.revertTo(claimSnapshot); @@ -253,7 +253,7 @@ contract ClaimRewardsTest is ClaimRewardsOnStakeTest { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 5 * 1e18, - reward: 24.539636308934920041 * 1e18, + reward: 24.787511423166585895 * 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.539636308934920041 * 1e18, + reward: 24.787511423166585895 * 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.539636308934920041 * 1e18, + reward: 24.787511423166585895 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 4.089939384822486675 * 1e18 + updateExchangeRatesReward: 4.131251903861097650 * 1e18 }); uint256 minterOneBalance = _ajnaToken.balanceOf(_minterOne); - assertEq(minterOneBalance, 24.539636308934920041 * 1e18); + assertEq(minterOneBalance, 24.787511423166585895 * 1e18); } function testClaimOnUnstakeWithInsufficientFunds() external { diff --git a/tests/forge/unit/Rewards/RewardsManager.t.sol b/tests/forge/unit/Rewards/RewardsManager.t.sol index 4edecdc05..08c0996f2 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.799082739441061020 * 1e18 + tokensToBurn: 82.625336100445516170 * 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.089954136972052373 * 1e18 + reward: 4.131266805022275123 * 1e18 }); // check only deposit owner can claim rewards @@ -370,7 +370,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenId, minAmountToReceive: 0, - reward: 40.899541369720523724 * 1e18, + reward: 41.312668050222751231 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); @@ -387,13 +387,13 @@ contract RewardsManagerTest is RewardsHelperContract { burnEvent: 1, rewardsEarned: 0 }); - assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720523724 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 41.312668050222751231 * 1e18); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.799082739441061020 * 1e18, + burned: 82.625336100445516170 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); @@ -412,7 +412,6 @@ contract RewardsManagerTest is RewardsHelperContract { vm.expectEmit(true, true, true, true); emit Unstake(_minterOne, address(_pool), tokenId); _rewardsManager.unstake(tokenId); - } function testWithdrawAndClaimRewardsNoExchangeRateUpdate() external { @@ -443,7 +442,7 @@ contract RewardsManagerTest is RewardsHelperContract { // first reserve auction happens successfully -> epoch 1 uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2_555, pool: address(_pool) @@ -454,37 +453,36 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972057005 * 1e18 + reward: 4.131266805022279800 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.799082739441179038 * 1e18, + burned: 82.625336100445635379 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); - // second reserve auction happens successfully -> epoch 2 tokensToBurn += _triggerReserveAuctions({ borrower: _borrower, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool), - tokensToBurn: 150.531225765096169950 * 1e18 + tokensToBurn: 152.051743197066838325 * 1e18 }); - + // check owner can withdraw the NFT and rewards will be automatically claimed _unstakeToken({ owner: _minterOne, pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(2, 0), - reward: 78.702220033830793321 * 1e18, + reward: 79.497191953364437697 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 3.436607151282747570 * 1e18 + updateExchangeRatesReward: 3.471320354831058155 * 1e18 }); } @@ -519,7 +517,7 @@ contract RewardsManagerTest is RewardsHelperContract { // first reserve auction happens successfully Staker should receive rewards epoch 0 - 1 uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -530,7 +528,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972057005 * 1e18 + reward: 4.131266805022279800 * 1e18 }); skip(2 weeks); @@ -547,7 +545,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), epoch: 1, timestamp: block.timestamp - (2 weeks + 26 weeks + 24 hours), - burned: 81.799082739441179038 * 1e18, + burned: 82.625336100445635379 * 1e18, tokensToBurn: tokensToBurn, interest: 6.443638300196908069 * 1e18 }); @@ -687,22 +685,22 @@ contract RewardsManagerTest is RewardsHelperContract { _kick({ from: _minterTwo, borrower: _borrower2, - debt: 9_976.561670003961916237 * 1e18, + debt: 9_853.394241979221645666 * 1e18, collateral: 1_000 * 1e18, - bond: 98.533942419792216457 * 1e18, - transferAmount: 98.533942419792216457 * 1e18 + bond: 149.577873638769639523 * 1e18, + transferAmount: 149.577873638769639523 * 1e18 }); // skip ahead so take can be called on the loan - skip(10 hours); + skip(9 hours); // take entire collateral _take({ from: _minterTwo, borrower: _borrower2, maxCollateral: 1_000 * 1e18, - bondChange: 6.531114528261135360 * 1e18, - givenAmount: 653.111452826113536000 * 1e18, + bondChange: 60.911699561320164197 * 1e18, + givenAmount: 4012.538586931187076000 * 1e18, collateralTaken: 1_000 * 1e18, isReward: true }); @@ -711,7 +709,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterTwo, borrower: _borrower2, maxDepth: 10, - settledDebt: 9_891.935520844277346923 * 1e18 + settledDebt: 5_821.652652511646951630 * 1e18 }); // bucket is insolvent, balances are reset @@ -728,8 +726,8 @@ contract RewardsManagerTest is RewardsHelperContract { index: _i9_81, lpBalance: 10_000 * 1e18, collateral: 0, - deposit: 4_886.628561176422153760 * 1e18, - exchangeRate: 0.488662856117642216 * 1e18 + deposit: 8_191.675009896270870814 * 1e18, + exchangeRate: 0.819167500989627088 * 1e18 }); /***********************/ @@ -876,15 +874,15 @@ contract RewardsManagerTest is RewardsHelperContract { }); (,, 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 + reward: 0.007146561992635801 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 0.007075096372721386 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 0.007146561992635801 * 1e18); _assertBurn({ pool: address(_pool), @@ -899,7 +897,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 0.283003854923906684 * 1e18, + burned: 0.285862479721117855 * 1e18, interest: 0.000048562908902619 * 1e18, tokensToBurn: tokensBurned }); @@ -923,13 +921,13 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndex2, - reward: 0.021225289119669282 * 1e18 + reward: 0.021439685979475985 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), .021225289119669282 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 0.021439685979475985 * 1e18); // assert minterOne has rewards to be claimed uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 0.226403083939125347 * 1e18); + assertEq(rewardsEarned, 0.228689983776894284 * 1e18); _assertBucket({ index: 2770, @@ -1013,16 +1011,16 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndex1, - reward: 3.511985000906831402 * 1e18 + reward: 3.547459596875587275 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 3.519060097279552788 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 3.554606158868223076 * 1e18); _assertBurn({ pool: address(_pool), epoch: 2, timestamp: block.timestamp - 24 hours, - burned: 140.762403891199659050 * 1e18, + burned: 142.184246354747130336 * 1e18, interest: 2.566194585267388219 * 1e18, tokensToBurn: tokensBurned }); @@ -1046,13 +1044,13 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndex2, - reward: 3.160572158484729706 * 1e18 + reward: 3.192497129782555259 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 3.181797447604398988 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 3.213936815762031244 * 1e18); // assert minterOne has more rewards to be claimed rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 66.951974677854736430 * 1e18); + assertEq(rewardsEarned, 67.628257250358319615 * 1e18); // QT is adeed to a bucket deal(address(_quote), _minterOne, 100 * 1e18 * depositIndexes.length + 6_000.0 * 1e18); @@ -1092,17 +1090,17 @@ contract RewardsManagerTest is RewardsHelperContract { borrower: _borrower, borrowerDebt: 25656.385808102176964640 * 1e18, borrowerCollateral: 25.921751033498703620 * 1e18, - borrowert0Np: 1_004.264567230919901856 * 1e18, + borrowert0Np: 1_101.390902162019364514 * 1e18, borrowerCollateralization: 0.990376081445383032 * 1e18 }); _kick({ from: _minterTwo, borrower: _borrower, - debt: 25_945.020148443326455492 * 1e18, + debt: 25_656.385808102176964640 * 1e18, collateral: 25.921751033498703620 * 1e18, - bond: 256.563858081021769646 * 1e18, - transferAmount: 256.563858081021769646 * 1e18 + bond: 374.752609017118925592 * 1e18, + transferAmount: 374.752609017118925592 * 1e18 }); // skip ahead so take can be called on the loan @@ -1113,8 +1111,8 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterTwo, borrower: _borrower, maxCollateral: 100.0 * 1e18, - bondChange: 0 * 1e18, - givenAmount: 0 * 1e18, + bondChange: 80, + givenAmount: 5495, collateralTaken: 25.921751033498703620 * 1e18, isReward: true }); @@ -1123,7 +1121,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterTwo, borrower: _borrower, maxDepth: 10, - settledDebt: 26_954.947917202244023854 * 1e18 + settledDebt: 24_911.288118205001229802 * 1e18 }); // bucket is insolvent, balances are reset @@ -1256,9 +1254,9 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndex1, - reward: 0.007075096372721386 * 1e18 + reward: 0.007146561992635801 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 0.007075096372721386 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 0.007146561992635801 * 1e18); _assertBurn({ pool: address(_pool), @@ -1273,7 +1271,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 0.283003854923906684 * 1e18, + burned: 0.285862479721117855 * 1e18, interest: 0.000048562908902619 * 1e18, tokensToBurn: tokensBurned }); @@ -1297,10 +1295,9 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndex2, - reward: 0.021225289119669282 * 1e18 + reward: 0.021439685979475985 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 0.021225289119669282 * 1e18); - + assertEq(_ajnaToken.balanceOf(_updater2), 0.021439685979475985 * 1e18); /*******************************************/ /*** Lender Withdraws And Claims Rewards ***/ @@ -1312,7 +1309,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 0.226403083939125347 * 1e18, + reward: 0.228689983776894284 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); @@ -1445,16 +1442,16 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndex1, - reward: 0.007075096372721386 * 1e18 + reward: 0.007146561992635801 * 1e18 }); _updateExchangeRates({ updater: _updater, pool: address(_poolTwo), indexes: depositIndex1, - reward: 0.007075096372721386 * 1e18 + reward: 0.007146561992635801 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 2 * 0.007075096372721386 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 2 * 0.007146561992635801 * 1e18); _assertBurn({ pool: address(_pool), @@ -1478,7 +1475,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 0.283003854923906684 * 1e18, + burned: 0.285862479721117855 * 1e18, interest: 0.000048562908902619 * 1e18, tokensToBurn: tokensBurned }); @@ -1487,7 +1484,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_poolTwo), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 0.283003854923906684 * 1e18, + burned: 0.285862479721117855 * 1e18, interest: 0.000048562908902619 * 1e18, tokensToBurn: tokensBurned }); @@ -1515,16 +1512,16 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndex2, - reward: 0.021225289119669282 * 1e18 + reward: 0.021439685979475985 * 1e18 }); _updateExchangeRates({ updater: _updater2, pool: address(_poolTwo), indexes: depositIndex2, - reward: 0.021225289119669282 * 1e18 + reward: 0.021439685979475985 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 2 * 0.021225289119669282 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 2 * 0.021439685979475985 * 1e18); /*******************************************/ @@ -1537,7 +1534,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 0.226403083939125347 * 1e18, + reward: 0.228689983776894284 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); @@ -1547,7 +1544,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_poolTwo), tokenId: tokenIdTwo, claimedArray: _epochsClaimedArray(1, 0), - reward: 0.226403083939125347 * 1e18, + reward: 0.228689983776894284 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); @@ -1580,7 +1577,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1591,7 +1588,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972057005 * 1e18 + reward: 4.131266805022279800 * 1e18 }); // burn rewards manager tokens and leave only 5 tokens available @@ -1599,7 +1596,7 @@ contract RewardsManagerTest is RewardsHelperContract { IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 4.999999999999993052 * 1e18); + assertEq(managerBalance, 4.958687331949770257 * 1e18); // check reward generated are more than manager token balance uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1614,7 +1611,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 40.899541369720570039 * 1e18, + reward: 41.312668050222798013 * 1e18, epochsClaimed: _epochsClaimedArray(1,0) }); @@ -1663,7 +1660,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 408.996298826180042327 * 1e18, + tokensToBurn: 413.127574571899032653 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6000, pool: address(_pool) @@ -1674,12 +1671,12 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 20.449814941309000626 * 1e18 + reward: 20.656378728594950130 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 20.449814941309000626 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 20.656378728594950130 * 1e18); uint256 rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 204.498149413090006279 * 1e18); + assertEq(rewardsEarned, 206.563787285949501291 * 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); /******************************/ @@ -1688,7 +1685,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079404058517 * 1e18, + tokensToBurn: 757.513427352933392466 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1699,13 +1696,13 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661199616 * 1e18 + reward: 17.219292639051716786 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 37.496914653970200242 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 37.875671367646666916 * 1e18); // check available rewards rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 374.969146539702002449 * 1e18); + assertEq(rewardsEarned, 378.756713676466669152 * 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); /*****************************/ @@ -1715,7 +1712,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger third reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_030.321595435443883599 * 1e18, + tokensToBurn: 1_040.728884278226145090 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1723,7 +1720,7 @@ contract RewardsManagerTest is RewardsHelperContract { // skip updating exchange rates and check available rewards uint256 rewardsEarnedNoUpdate = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedNoUpdate, 374.969146539702002449* 1e18); + assertEq(rewardsEarnedNoUpdate, 378.756713676466669152* 1e18); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); // snapshot calling update exchange rate @@ -1734,10 +1731,10 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndexes, - reward: 14.019165117801987582 * 1e18 + reward: 14.160772846264633918 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 14.019165117801987582 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 14.160772846264633918 * 1e18); // check available rewards rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -1754,7 +1751,7 @@ contract RewardsManagerTest is RewardsHelperContract { // triger fourth reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_285.690028219559780957 * 1e18, + tokensToBurn: 1_298.676796181373516144 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1762,7 +1759,7 @@ contract RewardsManagerTest is RewardsHelperContract { // check rewards earned rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 374.969146539702002449 * 1e18); + assertEq(rewardsEarned, 378.756713676466669152 * 1e18); // call update exchange rate _updateExchangeRates({ @@ -1775,7 +1772,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.969146539702002449 * 1e18); + assertEq(rewardsEarned, 378.756713676466669152 * 1e18); /*****************************/ /*** Fifth Reserve Auction ***/ @@ -1784,7 +1781,7 @@ contract RewardsManagerTest is RewardsHelperContract { // triger fifth reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 1_518.007030973479132952 * 1e18, + tokensToBurn: 1_533.340435326746598961 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -1795,12 +1792,12 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater2, pool: address(_pool), indexes: depositIndexes, - reward: 11.615850137695967876 * 1e18 + reward: 11.733181957268654420 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater2), 11.615850137695967876 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater2), 11.733181957268654420 * 1e18); rewardsEarned = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarned, 491.127647916661681237 * 1e18); + assertEq(rewardsEarned, 496.088533249153213379 * 1e18); // claim all rewards accrued since deposit _claimRewards({ @@ -1809,7 +1806,7 @@ contract RewardsManagerTest is RewardsHelperContract { tokenId: tokenIdOne, minAmountToReceive: 0, epochsClaimed: _epochsClaimedArray(5,0), - reward: 491.127647916661681237 * 1e18 + reward: 496.088533249153213379 * 1e18 }); assertEq(_ajnaToken.balanceOf(_minterOne), rewardsEarned); assertLt(rewardsEarned, Maths.wmul(totalTokensBurned, 0.800000000000000000 * 1e18)); @@ -1887,7 +1884,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 133.010720463154931188 * 1e18, + tokensToBurn: 134.354263094095890105 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -1899,24 +1896,24 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdTwo, claimedArray: _epochsClaimedArray(1, 0), - reward: 39.908147491580588274 * 1e18, + reward: 40.311260092505644727 * 1e18, indexes: depositIndexes, - updateExchangeRatesReward: 6.651023502439564179 * 1e18 + updateExchangeRatesReward: 6.718205558019761798 * 1e18 }); uint256 minterTwoBalance = _ajnaToken.balanceOf(_minterTwo); - assertEq(minterTwoBalance, 39.908147491580588274 * 1e18); + assertEq(minterTwoBalance, 40.311260092505644727 * 1e18); _unstakeToken({ owner: _minterThree, pool: address(_pool), tokenId: tokenIdThree, claimedArray: _epochsClaimedArray(1, 0), - reward: 33.248236242436447412 * 1e18, + reward: 33.584077012562068097 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); uint256 minterThreeBalance = _ajnaToken.balanceOf(_minterThree); - assertEq(minterThreeBalance, 33.248236242436447412 * 1e18); + assertEq(minterThreeBalance, 33.584077012562068097 * 1e18); assertGt(minterTwoBalance, minterThreeBalance); } @@ -1959,7 +1956,7 @@ contract RewardsManagerTest is RewardsHelperContract { // borrower takes actions providing reserves enabling reserve auctions uint256 firstTokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441061020 * 1e18, + tokensToBurn: 82.625336100445516170 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -1983,7 +1980,7 @@ contract RewardsManagerTest is RewardsHelperContract { owner: _minterTwo, tokenId: tokenIdTwo }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 8.171892378490154686 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterTwo), 8.254436745949651197 * 1e18); // calculate rewards earned since exchange rates have been updated uint256 idOneRewardsAtOne = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -2007,7 +2004,7 @@ contract RewardsManagerTest is RewardsHelperContract { // conduct second reserve auction uint256 secondTokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 175.885944654845768512 * 1e18, + tokensToBurn: 177.662570358430069210 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -2039,11 +2036,11 @@ contract RewardsManagerTest is RewardsHelperContract { uint256 idOneRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); assertLt(idOneRewardsAtTwo, secondTokensToBurn); assertGt(idOneRewardsAtTwo, 0); - assertEq(idOneRewardsAtTwo, 23.539670861841372334 * 1e18); + assertEq(idOneRewardsAtTwo, 23.777445314991285190 * 1e18); uint256 idTwoRewardsAtTwo = _rewardsManager.calculateRewards(tokenIdTwo, _pool.currentBurnEpoch()); assertLt(idOneRewardsAtTwo + idTwoRewardsAtTwo, secondTokensToBurn); - assertEq(idTwoRewardsAtTwo, 23.507224958013738649 * 1e18); + assertEq(idTwoRewardsAtTwo, 23.744671674761352175 * 1e18); assertGt(idTwoRewardsAtTwo, 0); // minter one claims rewards accrued after second auction @@ -2053,7 +2050,7 @@ contract RewardsManagerTest is RewardsHelperContract { tokenId: tokenIdOne, minAmountToReceive: 0, epochsClaimed: _epochsClaimedArray(1,1), - reward: 23.539670861841372334 * 1e18 + reward: 23.777445314991285190 * 1e18 }); assertEq(_ajnaToken.balanceOf(_minterOne), idOneRewardsAtOne + idOneRewardsAtTwo); @@ -2067,7 +2064,7 @@ contract RewardsManagerTest is RewardsHelperContract { epochsClaimed: _epochsClaimedArray(1,1), reward: idTwoRewardsAtTwo }); - assertEq(_ajnaToken.balanceOf(_minterTwo), 31.679117336503893335 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterTwo), 31.999108420711003372 * 1e18); // check there are no remaining rewards available after claiming uint256 remainingRewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -2139,7 +2136,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction one uint256 tokensToBurnE1 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.797607524484463335 * 1e18, + tokensToBurn: 82.623845984327740729 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2149,14 +2146,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089880376224205350 * 1e18 + reward: 4.131192299216369040 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 1, timestamp: block.timestamp - 24 hours, - burned: 81.797607524484463335 * 1e18, + burned: 82.623845984327740729 * 1e18, tokensToBurn: tokensToBurnE1, interest: 6.443638300196908069 * 1e18 }); @@ -2164,7 +2161,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction two uint256 tokensToBurnE2 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 308.522250520128650190 * 1e18, + tokensToBurn: 311.638636889018838585 * 1e18, borrowAmount: 1_000 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2174,14 +2171,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 11.336232149782168987 * 1e18 + reward: 11.450739545234514130 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 2, timestamp: block.timestamp - 24 hours, - burned: 308.522250520128650190 * 1e18, + burned: 311.638636889018838585 * 1e18, tokensToBurn: tokensToBurnE2, interest: 23.938554041534910348 * 1e18 }); @@ -2189,7 +2186,7 @@ contract RewardsManagerTest is RewardsHelperContract { // auction three uint256 tokensToBurnE3 = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 676.508959571631757977 * 1e18, + tokensToBurn: 683.342383405688644410 * 1e18, borrowAmount: 2_000 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2199,14 +2196,14 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 18.399335452575176310 * 1e18 + reward: 18.585187325833511425 * 1e18 }); _assertBurn({ pool: address(_pool), epoch: 3, timestamp: block.timestamp - 24 hours, - burned: 676.508959571631757977 * 1e18, + burned: 683.342383405688644410 * 1e18, tokensToBurn: tokensToBurnE3, interest: 52.423541260157607958 * 1e18 }); @@ -2217,7 +2214,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(3, 0), - reward: 56.375746630969251081 * 1e18, + reward: 56.945198617140657657 * 1e18, indexes: firstIndexes, updateExchangeRatesReward: 0 }); @@ -2227,7 +2224,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdTwo, claimedArray: _epochsClaimedArray(3, 0), - reward: 281.878733154846255411 * 1e18, + reward: 284.725993085703288290 * 1e18, indexes: secondIndexes, updateExchangeRatesReward: 0 }); @@ -2260,7 +2257,7 @@ contract RewardsManagerTest is RewardsHelperContract { _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2271,7 +2268,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972057005 * 1e18 + reward: 4.131266805022279800 * 1e18 }); // _minterOne unstakes staked position @@ -2280,7 +2277,7 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 40.899541369720570039 * 1e18, + reward: 41.312668050222798013 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); @@ -2347,7 +2344,6 @@ contract RewardsManagerTest is RewardsHelperContract { }); } - function testWithdrawAndClaimRewards() external { skip(10); @@ -2375,7 +2371,7 @@ contract RewardsManagerTest is RewardsHelperContract { uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2386,7 +2382,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 4.089954136972057005 * 1e18 + reward: 4.131266805022279800 * 1e18 }); // check owner can withdraw the NFT and rewards will be automatically claimed @@ -2400,7 +2396,7 @@ contract RewardsManagerTest is RewardsHelperContract { IERC20Token(address(_ajnaToken)).burn(99_999_990.910045863027949943 * 1e18); uint256 managerBalance = _ajnaToken.balanceOf(address(_rewardsManager)); - assertEq(managerBalance, 4.999999999999993052 * 1e18); + assertEq(managerBalance, 4.958687331949770257 * 1e18); // check reward generated are more than manager token balance uint256 rewards = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); @@ -2418,13 +2414,13 @@ contract RewardsManagerTest is RewardsHelperContract { pool: address(_pool), tokenId: tokenIdOne, claimedArray: _epochsClaimedArray(1, 0), - reward: 40.899541369720570039 * 1e18, + reward: 41.312668050222798013 * 1e18, indexes: depositIndexes, updateExchangeRatesReward: 0 }); assertEq(PositionManager(address(_positionManager)).ownerOf(tokenIdOne), _minterOne); - assertEq(_ajnaToken.balanceOf(_minterOne), 40.899541369720570039 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 41.312668050222798013 * 1e18); assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); // check can't claim rewards twice @@ -2462,7 +2458,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger ajna burns _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441179038 * 1e18, + tokensToBurn: 82.625336100445635379 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 2555, pool: address(_pool) @@ -2474,7 +2470,7 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 44.989495506692627044 * 1e18, + reward: 45.443934855245077813 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); @@ -2533,7 +2529,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned uint256 tokensToBurn = _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 81.799082739441061020 * 1e18, + tokensToBurn: 82.625336100445516170 * 1e18, borrowAmount: 300 * 1e18, limitIndex: 3, pool: address(_pool) @@ -2562,9 +2558,9 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _minterOne, pool: address(_pool), indexes: firstIndexes, - reward: 4.089954136972052373 * 1e18 + reward: 4.131266805022275123 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_minterOne), 4.089954136972052373 * 1e18); + assertEq(_ajnaToken.balanceOf(_minterOne), 4.131266805022275123 * 1e18); // check owner in pool with accrued interest can properly claim rewards _claimRewards({ @@ -2572,11 +2568,10 @@ contract RewardsManagerTest is RewardsHelperContract { from: _minterOne, tokenId: tokenIdOne, minAmountToReceive: 0, - reward: 40.899541369720523724 * 1e18, + reward: 41.312668050222751231 * 1e18, epochsClaimed: _epochsClaimedArray(1, 0) }); assertLt(_ajnaToken.balanceOf(_minterOne), tokensToBurn); - } function testMultipleUnstakeInSameEpoch() external { @@ -2620,7 +2615,7 @@ contract RewardsManagerTest is RewardsHelperContract { // bidder takes reserve auctions by providing ajna tokens to be burned totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 408.996298826180042327 * 1e18, + tokensToBurn: 413.127574571899032653 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6000, pool: address(_pool) @@ -2631,14 +2626,12 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 20.449814941309000626 * 1e18 + reward: 20.656378728594950130 * 1e18 }); - assertEq(_ajnaToken.balanceOf(_updater), 20.449814941309000626 * 1e18); + assertEq(_ajnaToken.balanceOf(_updater), 20.656378728594950130 * 1e18); uint256 rewardsEarnedFirstEpoch = _rewardsManager.calculateRewards(tokenIdOne, _pool.currentBurnEpoch()); - assertEq(rewardsEarnedFirstEpoch, 204.498149413090006279 * 1e18); - - uint256 totalRewardEarned = 374.969146539702002449 * 1e18; + assertEq(rewardsEarnedFirstEpoch, 206.563787285949501291 * 1e18); uint256 snapshot = vm.snapshot(); @@ -2681,7 +2674,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079404058517 * 1e18, + tokensToBurn: 757.513427352933392466 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -2692,10 +2685,11 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661199616 * 1e18 + reward: 17.219292639051716786 * 1e18 }); - uint256 newRewardsEarned = totalRewardEarned - rewardsEarnedFirstEpoch; + uint256 totalRewardEarned = 378.756713676466669152 * 1e18; + uint256 newRewardsEarned = totalRewardEarned - rewardsEarnedFirstEpoch; // 172.192926390517167861 // claim rewards for second epoch _claimRewards({ @@ -2720,7 +2714,7 @@ contract RewardsManagerTest is RewardsHelperContract { // trigger second reserve auction totalTokensBurned += _triggerReserveAuctions({ borrower: _borrower, - tokensToBurn: 749.938293079404058517 * 1e18, + tokensToBurn: 757.513427352933392466 * 1e18, borrowAmount: 1_500 * 1e18, limitIndex: 6_000, pool: address(_pool) @@ -2731,7 +2725,7 @@ contract RewardsManagerTest is RewardsHelperContract { updater: _updater, pool: address(_pool), indexes: depositIndexes, - reward: 17.047099712661199616 * 1e18 + reward: 17.219292639051716786 * 1e18 }); // check available rewards @@ -2750,7 +2744,6 @@ contract RewardsManagerTest is RewardsHelperContract { // ensure total rewards earned are same with and without unstake between epochs assertEq(_ajnaToken.balanceOf(_minterOne), totalRewardEarned); - } /********************/ diff --git a/tests/forge/utils/DSTestPlus.sol b/tests/forge/utils/DSTestPlus.sol index ef8eaa9df..d5b945159 100644 --- a/tests/forge/utils/DSTestPlus.sol +++ b/tests/forge/utils/DSTestPlus.sol @@ -78,7 +78,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 bondSize; uint256 bondFactor; uint256 kickTime; - uint256 kickMomp; + uint256 referencePrice; uint256 totalBondEscrowed; uint256 auctionPrice; uint256 debtInAuction; @@ -433,7 +433,7 @@ abstract contract DSTestPlus is Test, IPoolEvents { uint256 auctionBondFactor; uint256 auctionBondSize; uint256 auctionKickTime; - uint256 auctionKickMomp; + uint256 auctionReferencePrice; uint256 auctionNeutralPrice; uint256 auctionTotalBondEscrowed; uint256 auctionDebtInAuction; @@ -447,11 +447,10 @@ abstract contract DSTestPlus is Test, IPoolEvents { vars.auctionBondFactor, vars.auctionBondSize, vars.auctionKickTime, - vars.auctionKickMomp, + vars.auctionReferencePrice, vars.auctionNeutralPrice, , , - , ) = _pool.auctionInfo(state_.borrower); (uint256 borrowerDebt, uint256 borrowerCollateral , ) = _poolUtils.borrowerInfo(address(_pool), state_.borrower); @@ -466,11 +465,10 @@ abstract contract DSTestPlus is Test, IPoolEvents { assertEq(vars.auctionBondSize, state_.bondSize); assertEq(vars.auctionBondFactor, state_.bondFactor); assertEq(vars.auctionKickTime, state_.kickTime); - assertEq(vars.auctionKickMomp, state_.kickMomp); + assertEq(vars.auctionReferencePrice, state_.referencePrice); assertEq(vars.auctionTotalBondEscrowed, state_.totalBondEscrowed); assertEq(_auctionPrice( - vars.auctionKickMomp, - vars.auctionNeutralPrice, + vars.auctionReferencePrice, vars.auctionKickTime), state_.auctionPrice); assertEq(vars.auctionDebtInAuction, state_.debtInAuction); assertEq(vars.auctionNeutralPrice, state_.neutralPrice); @@ -662,8 +660,8 @@ abstract contract DSTestPlus is Test, IPoolEvents { assertEq(t0Np, borrowert0Np); assertEq( _collateralization( - borrowerDebt, - borrowerCollateral, + debt, + col, lup ), borrowerCollateralization @@ -844,24 +842,24 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.bucketTake(borrower, false, index); } - function _assertArbTakeAuctionInCooldownRevert( + function _assertArbTakeAuctionInsufficientLiquidityRevert( address from, address borrower, uint256 index ) internal { changePrank(from); - vm.expectRevert(abi.encodeWithSignature('TakeNotPastCooldown()')); - _pool.bucketTake(borrower, false, index); + vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); + _pool.bucketTake(borrower,false, index); } - function _assertArbTakeAuctionInsufficientLiquidityRevert( + function _assertArbTakeAuctionNotTakeableRevert( address from, address borrower, uint256 index ) internal { changePrank(from); - vm.expectRevert(IPoolErrors.InsufficientLiquidity.selector); - _pool.bucketTake(borrower,false, index); + vm.expectRevert(IPoolErrors.AuctionNotTakeable.selector); + _pool.bucketTake(borrower, false, index); } function _assertArbTakeAuctionPriceGreaterThanBucketPriceRevert( @@ -904,14 +902,14 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.bucketTake(borrower, false, index); } - function _assertDepositTakeAuctionInCooldownRevert( + function _assertArbTakeZeroBidRevert( address from, address borrower, uint256 index ) internal { changePrank(from); - vm.expectRevert(abi.encodeWithSignature('TakeNotPastCooldown()')); - _pool.bucketTake(borrower, true, index); + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.bucketTake(borrower, false, index); } function _assertDepositTakeAuctionInsufficientLiquidityRevert( @@ -924,6 +922,16 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.bucketTake(borrower, true, index); } + function _assertDepositTakeAuctionNotTakeableRevert( + address from, + address borrower, + uint256 index + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.AuctionNotTakeable.selector); + _pool.bucketTake(borrower, true, index); + } + function _assertDepositTakeAuctionPriceGreaterThanBucketPriceRevert( address from, address borrower, @@ -964,6 +972,16 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.bucketTake(borrower, true, index); } + function _assertDepositTakeZeroBidRevert( + address from, + address borrower, + uint256 index + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.bucketTake(borrower, true, index); + } + function _assertStampLoanAuctionActiveRevert( address borrower ) internal { @@ -1326,14 +1344,11 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.moveQuoteToken(amount, fromIndex, toIndex, type(uint256).max, true); } - function _assertTakeAuctionInCooldownRevert( + function _assertRepayAuctionActiveRevert( address from, - address borrower, - uint256 maxCollateral - ) internal { - changePrank(from); - vm.expectRevert(abi.encodeWithSignature('TakeNotPastCooldown()')); - _pool.take(borrower, maxCollateral, from, new bytes(0)); + uint256 maxAmount + ) internal virtual { + // to be overidden by ERC20/ERC721DSTestPlus } function _assertTakeDebtUnderMinPoolDebtRevert( @@ -1378,6 +1393,16 @@ abstract contract DSTestPlus is Test, IPoolEvents { _pool.kickReserveAuction(); } + function _assertTakeZeroBidRevert( + address from, + address borrower, + uint256 maxCollateral + ) internal { + changePrank(from); + vm.expectRevert(IPoolErrors.InvalidAmount.selector); + _pool.take(borrower, maxCollateral, from, new bytes(0)); + } + function _lup() internal view returns (uint256 lup_) { ( , , , , lup_, ) = _poolUtils.poolPricesInfo(address(_pool)); }