diff --git a/README.md b/README.md index f726d5365..6d7b9d190 100644 --- a/README.md +++ b/README.md @@ -621,7 +621,7 @@ Hints allow cheaper CDP operations for the user, at the expense of a slightly lo const EBTCRepayment = toBN(toWei('230')) // borrower wants to repay 230 eBTC // Get CDP's current debt and coll - const {0: debt, 1: coll} = await cdpManager.getDebtAndCollShares(borrower) + const {0: debt, 1: coll} = await cdpManager.getSyncedDebtAndCollShares(borrower) const newDebt = debt.sub(EBTCRepayment) const newColl = coll.add(collIncrease) diff --git a/packages/contracts/contracts/ActivePool.sol b/packages/contracts/contracts/ActivePool.sol index 2f9f1b1fd..bf237f26c 100644 --- a/packages/contracts/contracts/ActivePool.sol +++ b/packages/contracts/contracts/ActivePool.sol @@ -30,7 +30,7 @@ contract ActivePool is IActivePool, ERC3156FlashLender, ReentrancyGuard, BaseMat uint256 internal systemCollShares; // deposited collateral tracker uint256 internal systemDebt; uint256 internal feeRecipientCollShares; // coll shares claimable by fee recipient - ICollateralToken public collateral; + ICollateralToken public immutable collateral; // --- Contract setters --- diff --git a/packages/contracts/contracts/BorrowerOperations.sol b/packages/contracts/contracts/BorrowerOperations.sol index ff34e9507..3491337dc 100644 --- a/packages/contracts/contracts/BorrowerOperations.sol +++ b/packages/contracts/contracts/BorrowerOperations.sol @@ -66,40 +66,38 @@ contract BorrowerOperations is Used to hold, return and assign variables inside a function, in order to avoid the error: "CompilerError: Stack too deep". */ - struct LocalVariables_adjustCdp { + struct AdjustCdpLocals { uint256 price; - uint256 collChange; + uint256 collSharesChange; uint256 netDebtChange; bool isCollIncrease; uint256 debt; - uint256 coll; + uint256 collShares; uint256 oldICR; uint256 newICR; uint256 newTCR; uint256 newDebt; - uint256 newColl; + uint256 newCollShares; uint256 stake; } - struct LocalVariables_openCdp { + struct OpenCdpLocals { uint256 price; uint256 debt; - uint256 totalColl; - uint256 netColl; + uint256 netStEthBalance; uint256 ICR; uint256 NICR; uint256 stake; uint256 arrayIndex; } - struct LocalVariables_moveTokens { + struct MoveTokensParams { address user; - uint256 collChange; + uint256 collSharesChange; uint256 collAddUnderlying; // ONLY for isCollIncrease=true bool isCollIncrease; - uint256 EBTCChange; - bool isDebtIncrease; uint256 netDebtChange; + bool isDebtIncrease; } // --- Dependency setters --- @@ -290,16 +288,15 @@ contract BorrowerOperations is ) internal { // Confirm the operation is the borrower or approved position manager adjusting its own cdp address _borrower = sortedCdps.getOwnerAddress(_cdpId); - _requireBorrowerOrPositionManagerAndUpdate(_borrower); + _requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower); _requireCdpisActive(cdpManager, _cdpId); cdpManager.syncAccounting(_cdpId); - LocalVariables_adjustCdp memory vars; + AdjustCdpLocals memory vars; vars.price = priceFeed.fetchPrice(); - bool isRecoveryMode = _checkRecoveryModeForTCR(_getTCR(vars.price)); if (_isDebtIncrease) { _requireNonZeroDebtChange(_debtChange); @@ -307,8 +304,8 @@ contract BorrowerOperations is _requireSingularCollChange(_stEthBalanceIncrease, _stEthBalanceDecrease); _requireNonZeroAdjustment(_stEthBalanceIncrease, _stEthBalanceDecrease, _debtChange); - // Get the collChange based on the collateral value transferred in the transaction - (vars.collChange, vars.isCollIncrease) = _getCollSharesChangeFromStEthChange( + // Get the collSharesChange based on the collateral value transferred in the transaction + (vars.collSharesChange, vars.isCollIncrease) = _getCollSharesChangeFromStEthChange( _stEthBalanceIncrease, _stEthBalanceDecrease ); @@ -316,19 +313,19 @@ contract BorrowerOperations is vars.netDebtChange = _debtChange; vars.debt = cdpManager.getCdpDebt(_cdpId); - vars.coll = cdpManager.getCdpCollShares(_cdpId); + vars.collShares = cdpManager.getCdpCollShares(_cdpId); // Get the cdp's old ICR before the adjustment, and what its new ICR will be after the adjustment - uint256 _cdpStEthBalance = collateral.getPooledEthByShares(vars.coll); + uint256 _cdpStEthBalance = collateral.getPooledEthByShares(vars.collShares); require( _stEthBalanceDecrease <= _cdpStEthBalance, "BorrowerOperations: withdraw more collateral than CDP has!" ); vars.oldICR = EbtcMath._computeCR(_cdpStEthBalance, vars.debt, vars.price); vars.newICR = _getNewICRFromCdpChange( - vars.coll, + vars.collShares, vars.debt, - vars.collChange, + vars.collSharesChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease, @@ -336,6 +333,7 @@ contract BorrowerOperations is ); // Check the adjustment satisfies all conditions for the current system mode + bool isRecoveryMode = _checkRecoveryModeForTCR(_getTCR(vars.price)); _requireValidAdjustmentInCurrentMode( isRecoveryMode, _stEthBalanceDecrease, @@ -346,22 +344,29 @@ contract BorrowerOperations is // When the adjustment is a debt repayment, check it's a valid amount, that the caller has enough EBTC, and that the resulting debt is >0 if (!_isDebtIncrease && _debtChange > 0) { _requireValidDebtRepayment(vars.debt, vars.netDebtChange); - _requireSufficientEbtcBalance(msg.sender, vars.netDebtChange); + _requireSufficientEbtcTokenBalance(msg.sender, vars.netDebtChange); _requireNonZeroDebt(vars.debt - vars.netDebtChange); } - (vars.newColl, vars.newDebt) = _getNewCdpAmounts( - vars.coll, + (vars.newCollShares, vars.newDebt) = _getNewCdpAmounts( + vars.collShares, vars.debt, - vars.collChange, + vars.collSharesChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease ); - _requireAtLeastMinNetStEthBalance(collateral.getPooledEthByShares(vars.newColl)); + _requireAtLeastMinNetStEthBalance(collateral.getPooledEthByShares(vars.newCollShares)); - cdpManager.updateCdp(_cdpId, _borrower, vars.coll, vars.debt, vars.newColl, vars.newDebt); + cdpManager.updateCdp( + _cdpId, + _borrower, + vars.collShares, + vars.debt, + vars.newCollShares, + vars.newDebt + ); // Re-insert cdp in to the sorted list { @@ -369,16 +374,15 @@ contract BorrowerOperations is sortedCdps.reInsert(_cdpId, newNICR, _upperHint, _lowerHint); } - // Use the unmodified _debtChange here, as we don't send the fee to the user + // CEI: Process token movements { - LocalVariables_moveTokens memory _varMvTokens = LocalVariables_moveTokens( + MoveTokensParams memory _varMvTokens = MoveTokensParams( msg.sender, - vars.collChange, + vars.collSharesChange, (vars.isCollIncrease ? _stEthBalanceIncrease : 0), vars.isCollIncrease, _debtChange, - _isDebtIncrease, - vars.netDebtChange + _isDebtIncrease ); _processTokenMovesFromAdjustment(_varMvTokens); } @@ -392,32 +396,29 @@ contract BorrowerOperations is address _borrower ) internal returns (bytes32) { _requireNonZeroDebt(_debt); - _requireBorrowerOrPositionManagerAndUpdate(_borrower); + _requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower); - LocalVariables_openCdp memory vars; + OpenCdpLocals memory vars; - // ICR is based on the net coll, i.e. the requested coll amount - fixed liquidator incentive gas comp. - vars.netColl = _getNetColl(_stEthBalance); + // ICR is based on the net stEth balance, i.e. the specified stEth balance amount - fixed liquidator incentive gas comp. + vars.netStEthBalance = _calcNetStEthBalance(_stEthBalance); - // will revert if _stEthBalance is less than MIN_NET_COLL + LIQUIDATOR_REWARD - _requireAtLeastMinNetStEthBalance(vars.netColl); + _requireAtLeastMinNetStEthBalance(vars.netStEthBalance); // Update global pending index before any operations cdpManager.syncGlobalAccounting(); vars.price = priceFeed.fetchPrice(); - bool isRecoveryMode = _checkRecoveryModeForTCR(_getTCR(vars.price)); - vars.debt = _debt; // Sanity check - require(vars.netColl > 0, "BorrowerOperations: zero collateral for openCdp()!"); + require(vars.netStEthBalance > 0, "BorrowerOperations: zero collateral for openCdp()!"); - uint256 _netCollAsShares = collateral.getSharesByPooledEth(vars.netColl); + uint256 _netCollAsShares = collateral.getSharesByPooledEth(vars.netStEthBalance); uint256 _liquidatorRewardShares = collateral.getSharesByPooledEth(LIQUIDATOR_REWARD); // ICR is based on the net coll, i.e. the requested coll amount - fixed liquidator incentive gas comp. - vars.ICR = EbtcMath._computeCR(vars.netColl, vars.debt, vars.price); + vars.ICR = EbtcMath._computeCR(vars.netStEthBalance, vars.debt, vars.price); // NICR uses shares to normalize NICR across CDPs opened at different pooled ETH / shares ratios vars.NICR = EbtcMath._computeNominalCR(_netCollAsShares, vars.debt); @@ -429,7 +430,14 @@ contract BorrowerOperations is In normal mode, ICR must be greater thatn MCR Additionally, the new system TCR after the CDPs addition must be >CCR */ - uint256 newTCR = _getNewTCRFromCdpChange(vars.netColl, true, vars.debt, true, vars.price); + bool isRecoveryMode = _checkRecoveryModeForTCR(_getTCR(vars.price)); + uint256 newTCR = _getNewTCRFromCdpChange( + vars.netStEthBalance, + true, + vars.debt, + true, + vars.price + ); if (isRecoveryMode) { _requireICRisNotBelowCCR(vars.ICR); @@ -469,21 +477,21 @@ contract BorrowerOperations is _borrower ); - // Mint the full debt amount, in eBTC tokens, to the caller - _withdrawDebt(msg.sender, _debt, _debt); + // CEI: Mint the full debt amount, in eBTC tokens, to the caller + _withdrawDebt(msg.sender, _debt); /** - Note that only NET coll (as shares) is considered part of the CDP. + Note that only NET stEth balance (as shares) is considered part of the CDP. The static liqudiation incentive is stored in the gas pool and can be considered a deposit / voucher to be returned upon CDP close, to the closer. The close can happen from the borrower closing their own CDP, a full liquidation, or a redemption. */ - // CEI: Move the net collateral and liquidator gas compensation to the Active Pool. Track only net collateral shares for TCR purposes. + // CEI: Move the collateral and liquidator gas compensation to the Active Pool. Track only net collateral for TCR purposes. _activePoolAddColl(_stEthBalance, _netCollAsShares); // Invariant check require( - vars.netColl + LIQUIDATOR_REWARD == _stEthBalance, + vars.netStEthBalance + LIQUIDATOR_REWARD == _stEthBalance, "BorrowerOperations: deposited collateral mismatch!" ); @@ -495,7 +503,7 @@ contract BorrowerOperations is */ function closeCdp(bytes32 _cdpId) external override { address _borrower = sortedCdps.getOwnerAddress(_cdpId); - _requireBorrowerOrPositionManagerAndUpdate(_borrower); + _requireBorrowerOrPositionManagerAndUpdateManagerApproval(_borrower); _requireCdpisActive(cdpManager, _cdpId); @@ -504,14 +512,14 @@ contract BorrowerOperations is uint256 price = priceFeed.fetchPrice(); _requireNotInRecoveryMode(_getTCR(price)); - uint256 coll = cdpManager.getCdpCollShares(_cdpId); + uint256 collShares = cdpManager.getCdpCollShares(_cdpId); uint256 debt = cdpManager.getCdpDebt(_cdpId); uint256 liquidatorRewardShares = cdpManager.getCdpLiquidatorRewardShares(_cdpId); - _requireSufficientEbtcBalance(msg.sender, debt); + _requireSufficientEbtcTokenBalance(msg.sender, debt); uint256 newTCR = _getNewTCRFromCdpChange( - collateral.getPooledEthByShares(coll), + collateral.getPooledEthByShares(collShares), false, debt, false, @@ -523,7 +531,7 @@ contract BorrowerOperations is // By definition we are not in RM, notify CDPManager to ensure "Glass is on" cdpManager.notifyEndGracePeriod(newTCR); - cdpManager.closeCdp(_cdpId, _borrower, debt, coll); + cdpManager.closeCdp(_cdpId, _borrower, debt, collShares); // Burn the repaid EBTC from the user's balance _repayDebt(msg.sender, debt); @@ -531,7 +539,7 @@ contract BorrowerOperations is // CEI: Send the collateral and liquidator reward shares back to the user activePool.transferSystemCollSharesAndLiquidatorReward( msg.sender, - coll, + collShares, liquidatorRewardShares ); } @@ -665,12 +673,12 @@ contract BorrowerOperations is function _getCollSharesChangeFromStEthChange( uint256 _collReceived, uint256 _requestedCollWithdrawal - ) internal view returns (uint256 collChange, bool isCollIncrease) { + ) internal view returns (uint256 collSharesChange, bool isCollIncrease) { if (_collReceived != 0) { - collChange = collateral.getSharesByPooledEth(_collReceived); + collSharesChange = collateral.getSharesByPooledEth(_collReceived); isCollIncrease = true; } else { - collChange = collateral.getSharesByPooledEth(_requestedCollWithdrawal); + collSharesChange = collateral.getSharesByPooledEth(_requestedCollWithdrawal); } } @@ -678,23 +686,21 @@ contract BorrowerOperations is @notice Process the token movements required by a CDP adjustment. @notice Handles the cases of a debt increase / decrease, and/or a collateral increase / decrease. */ - function _processTokenMovesFromAdjustment( - LocalVariables_moveTokens memory _varMvTokens - ) internal { + function _processTokenMovesFromAdjustment(MoveTokensParams memory _varMvTokens) internal { // Debt increase: mint change value of new eBTC to user, increment ActivePool eBTC internal accounting if (_varMvTokens.isDebtIncrease) { - _withdrawDebt(_varMvTokens.user, _varMvTokens.EBTCChange, _varMvTokens.netDebtChange); + _withdrawDebt(_varMvTokens.user, _varMvTokens.netDebtChange); } else { // Debt decrease: burn change value of eBTC from user, decrement ActivePool eBTC internal accounting - _repayDebt(_varMvTokens.user, _varMvTokens.EBTCChange); + _repayDebt(_varMvTokens.user, _varMvTokens.netDebtChange); } if (_varMvTokens.isCollIncrease) { // Coll increase: send change value of stETH to Active Pool, increment ActivePool stETH internal accounting - _activePoolAddColl(_varMvTokens.collAddUnderlying, _varMvTokens.collChange); + _activePoolAddColl(_varMvTokens.collAddUnderlying, _varMvTokens.collSharesChange); } else { // Coll decrease: send change value of stETH to user, decrement ActivePool stETH internal accounting - activePool.transferSystemCollShares(_varMvTokens.user, _varMvTokens.collChange); + activePool.transferSystemCollShares(_varMvTokens.user, _varMvTokens.collSharesChange); } } @@ -710,8 +716,8 @@ contract BorrowerOperations is } /// @dev Mint specified debt tokens to account and change global debt accounting accordingly - function _withdrawDebt(address _account, uint256 _debt, uint256 _netDebtIncrease) internal { - activePool.increaseSystemDebt(_netDebtIncrease); + function _withdrawDebt(address _account, uint256 _debt) internal { + activePool.increaseSystemDebt(_debt); ebtcToken.mint(_account, _debt); } @@ -776,7 +782,7 @@ contract BorrowerOperations is bool _isRecoveryMode, uint256 _stEthBalanceDecrease, bool _isDebtIncrease, - LocalVariables_adjustCdp memory _vars + AdjustCdpLocals memory _vars ) internal { /* *In Recovery Mode, only allow: @@ -794,7 +800,7 @@ contract BorrowerOperations is */ _vars.newTCR = _getNewTCRFromCdpChange( - collateral.getPooledEthByShares(_vars.collChange), + collateral.getPooledEthByShares(_vars.collSharesChange), _vars.isCollIncrease, _vars.netDebtChange, _isDebtIncrease, @@ -859,10 +865,10 @@ contract BorrowerOperations is require(_debt > 0, "BorrowerOperations: Debt must be non-zero"); } - function _requireAtLeastMinNetStEthBalance(uint256 _coll) internal pure { + function _requireAtLeastMinNetStEthBalance(uint256 _stEthBalance) internal pure { require( - _coll >= MIN_NET_COLL, - "BorrowerOperations: Cdp's net coll must not fall below minimum" + _stEthBalance >= MIN_NET_STETH_BALANCE, + "BorrowerOperations: Cdp's net stEth balance must not fall below minimum" ); } @@ -873,14 +879,17 @@ contract BorrowerOperations is ); } - function _requireSufficientEbtcBalance(address _account, uint256 _debtRepayment) internal view { + function _requireSufficientEbtcTokenBalance( + address _account, + uint256 _debtRepayment + ) internal view { require( ebtcToken.balanceOf(_account) >= _debtRepayment, "BorrowerOperations: Caller doesnt have enough eBTC to make repayment" ); } - function _requireBorrowerOrPositionManagerAndUpdate(address _borrower) internal { + function _requireBorrowerOrPositionManagerAndUpdateManagerApproval(address _borrower) internal { if (_borrower == msg.sender) { return; // Early return, no delegation } @@ -894,7 +903,7 @@ contract BorrowerOperations is // Conditional Adjustment /// @dev If this is a position manager operation with a one-time approval, clear that approval - /// @dev If the PositionManagerApproval was none, we should have failed with the check in _requireBorrowerOrPositionManagerAndUpdate + /// @dev If the PositionManagerApproval was none, we should have failed with the check in _requireBorrowerOrPositionManagerAndUpdateManagerApproval if (_approval == PositionManagerApproval.OneTime) { _setPositionManagerApproval(_borrower, msg.sender, PositionManagerApproval.None); } @@ -904,43 +913,43 @@ contract BorrowerOperations is // Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards. function _getNewNominalICRFromCdpChange( - LocalVariables_adjustCdp memory vars, + AdjustCdpLocals memory vars, bool _isDebtIncrease ) internal pure returns (uint256) { - (uint256 newColl, uint256 newDebt) = _getNewCdpAmounts( - vars.coll, + (uint256 newCollShares, uint256 newDebt) = _getNewCdpAmounts( + vars.collShares, vars.debt, - vars.collChange, + vars.collSharesChange, vars.isCollIncrease, vars.netDebtChange, _isDebtIncrease ); - uint256 newNICR = EbtcMath._computeNominalCR(newColl, newDebt); + uint256 newNICR = EbtcMath._computeNominalCR(newCollShares, newDebt); return newNICR; } // Compute the new collateral ratio, considering the change in coll and debt. Assumes 0 pending rewards. function _getNewICRFromCdpChange( - uint256 _coll, + uint256 _collShares, uint256 _debt, - uint256 _collChange, + uint256 _collSharesChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease, uint256 _price ) internal view returns (uint256) { - (uint256 newColl, uint256 newDebt) = _getNewCdpAmounts( - _coll, + (uint256 newCollShares, uint256 newDebt) = _getNewCdpAmounts( + _collShares, _debt, - _collChange, + _collSharesChange, _isCollIncrease, _debtChange, _isDebtIncrease ); uint256 newICR = EbtcMath._computeCR( - collateral.getPooledEthByShares(newColl), + collateral.getPooledEthByShares(newCollShares), newDebt, _price ); @@ -948,37 +957,41 @@ contract BorrowerOperations is } function _getNewCdpAmounts( - uint256 _coll, + uint256 _collShares, uint256 _debt, - uint256 _collChange, + uint256 _collSharesChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease ) internal pure returns (uint256, uint256) { - uint256 newColl = _coll; + uint256 newCollShares = _collShares; uint256 newDebt = _debt; - newColl = _isCollIncrease ? _coll + _collChange : _coll - _collChange; + newCollShares = _isCollIncrease + ? _collShares + _collSharesChange + : _collShares - _collSharesChange; newDebt = _isDebtIncrease ? _debt + _debtChange : _debt - _debtChange; - return (newColl, newDebt); + return (newCollShares, newDebt); } function _getNewTCRFromCdpChange( - uint256 _collChange, + uint256 _stEthBalanceChange, bool _isCollIncrease, uint256 _debtChange, bool _isDebtIncrease, uint256 _price ) internal view returns (uint256) { - uint256 _shareColl = getSystemCollShares(); - uint256 totalColl = collateral.getPooledEthByShares(_shareColl); - uint256 totalDebt = _getSystemDebt(); + uint256 _systemCollShares = getSystemCollShares(); + uint256 systemStEthBalance = collateral.getPooledEthByShares(_systemCollShares); + uint256 systemDebt = _getSystemDebt(); - totalColl = _isCollIncrease ? totalColl + _collChange : totalColl - _collChange; - totalDebt = _isDebtIncrease ? totalDebt + _debtChange : totalDebt - _debtChange; + systemStEthBalance = _isCollIncrease + ? systemStEthBalance + _stEthBalanceChange + : systemStEthBalance - _stEthBalanceChange; + systemDebt = _isDebtIncrease ? systemDebt + _debtChange : systemDebt - _debtChange; - uint256 newTCR = EbtcMath._computeCR(totalColl, totalDebt, _price); + uint256 newTCR = EbtcMath._computeCR(systemStEthBalance, systemDebt, _price); return newTCR; } diff --git a/packages/contracts/contracts/CdpManager.sol b/packages/contracts/contracts/CdpManager.sol index 124a56cdb..1037c2701 100644 --- a/packages/contracts/contracts/CdpManager.sol +++ b/packages/contracts/contracts/CdpManager.sol @@ -153,13 +153,12 @@ contract CdpManager is CdpManagerStorage, ICdpManager, Proxy { // Repurposing this struct here to avoid stack too deep. CdpDebtAndCollShares memory _oldDebtAndColl = CdpDebtAndCollShares( Cdps[_redeemColFromCdp.cdpId].debt, - Cdps[_redeemColFromCdp.cdpId].coll, - 0 + Cdps[_redeemColFromCdp.cdpId].coll ); // Decrease the debt and collateral of the current Cdp according to the EBTC lot and corresponding ETH to send - uint256 newDebt = _oldDebtAndColl.entireDebt - singleRedemption.debtToRedeem; - uint256 newColl = _oldDebtAndColl.entireColl - singleRedemption.collSharesDrawn; + uint256 newDebt = _oldDebtAndColl.debt - singleRedemption.debtToRedeem; + uint256 newColl = _oldDebtAndColl.collShares - singleRedemption.collSharesDrawn; if (newDebt == 0) { // No debt remains, close CDP @@ -185,8 +184,8 @@ contract CdpManager is CdpManagerStorage, ICdpManager, Proxy { _redeemColFromCdp.cdpId, _borrower, msg.sender, - _oldDebtAndColl.entireDebt, - _oldDebtAndColl.entireColl, + _oldDebtAndColl.debt, + _oldDebtAndColl.collShares, 0, 0, 0, @@ -205,7 +204,7 @@ contract CdpManager is CdpManagerStorage, ICdpManager, Proxy { */ if ( newNICR != _redeemColFromCdp.partialRedemptionHintNICR || - collateral.getPooledEthByShares(newColl) < MIN_NET_COLL + collateral.getPooledEthByShares(newColl) < MIN_NET_STETH_BALANCE ) { singleRedemption.cancelledPartial = true; return singleRedemption; @@ -226,8 +225,8 @@ contract CdpManager is CdpManagerStorage, ICdpManager, Proxy { _redeemColFromCdp.cdpId, ISortedCdps(sortedCdps).getOwnerAddress(_redeemColFromCdp.cdpId), msg.sender, - _oldDebtAndColl.entireDebt, - _oldDebtAndColl.entireColl, + _oldDebtAndColl.debt, + _oldDebtAndColl.collShares, newDebt, newColl, Cdps[_redeemColFromCdp.cdpId].stake, @@ -514,7 +513,7 @@ contract CdpManager is CdpManagerStorage, ICdpManager, Proxy { } function syncAccounting(bytes32 _cdpId) external override { - // _requireCallerIsBorrowerOperations(); /// @audit Please check this and let us know if opening this creates issues | TODO: See Stermi Partial Liq + // _requireCallerIsBorrowerOperations(); /// @audit Opening can cause invalid reordering of Cdps due to changing values without reInserting into sortedCdps return _syncAccounting(_cdpId); } diff --git a/packages/contracts/contracts/CdpManagerStorage.sol b/packages/contracts/contracts/CdpManagerStorage.sol index 4b0a783e9..670757dce 100644 --- a/packages/contracts/contracts/CdpManagerStorage.sol +++ b/packages/contracts/contracts/CdpManagerStorage.sol @@ -644,7 +644,7 @@ contract CdpManagerStorage is EbtcBase, ReentrancyGuard, ICdpManagerData, AuthNo /// @notice Return the nominal collateral ratio (ICR) of a given Cdp, without the price. /// @dev Takes a cdp's pending coll and debt rewards from redistributions into account. function getNominalICR(bytes32 _cdpId) external view returns (uint256) { - (uint256 currentEBTCDebt, uint256 currentCollShares, ) = getDebtAndCollShares(_cdpId); + (uint256 currentEBTCDebt, uint256 currentCollShares) = getSyncedDebtAndCollShares(_cdpId); uint256 NICR = EbtcMath._computeNominalCR(currentCollShares, currentEBTCDebt); return NICR; @@ -668,7 +668,7 @@ contract CdpManagerStorage is EbtcBase, ReentrancyGuard, ICdpManagerData, AuthNo // Return the current collateral ratio (ICR) of a given Cdp. //Takes a cdp's pending coll and debt rewards from redistributions into account. function getICR(bytes32 _cdpId, uint256 _price) public view returns (uint256) { - (uint256 currentEBTCDebt, uint256 currentCollShares, ) = getDebtAndCollShares(_cdpId); + (uint256 currentEBTCDebt, uint256 currentCollShares) = getSyncedDebtAndCollShares(_cdpId); uint256 ICR = _calculateCR(currentCollShares, currentEBTCDebt, _price); return ICR; } @@ -696,28 +696,25 @@ contract CdpManagerStorage is EbtcBase, ReentrancyGuard, ICdpManagerData, AuthNo } // Return the Cdps entire debt and coll struct - function _getDebtAndCollShares( + function _getSyncedDebtAndCollShares( bytes32 _cdpId ) internal view returns (CdpDebtAndCollShares memory) { - (uint256 entireDebt, uint256 entireColl, uint256 pendingDebtReward) = getDebtAndCollShares( - _cdpId - ); - return CdpDebtAndCollShares(entireDebt, entireColl, pendingDebtReward); + (uint256 entireDebt, uint256 entireColl) = getSyncedDebtAndCollShares(_cdpId); + return CdpDebtAndCollShares(entireDebt, entireColl); } // Return the Cdps entire debt and coll, including pending rewards from redistributions and collateral reduction from split fee. /// @notice pending rewards are included in the debt and coll totals returned. - function getDebtAndCollShares( + function getSyncedDebtAndCollShares( bytes32 _cdpId - ) public view returns (uint256 debt, uint256 coll, uint256 pendingEBTCDebtReward) { - (uint256 _newColl, uint256 _newDebt, , uint256 _pendingDebt) = _calcSyncedAccounting( + ) public view returns (uint256 debt, uint256 coll) { + (uint256 _newColl, uint256 _newDebt, , ) = _calcSyncedAccounting( _cdpId, cdpStEthFeePerUnitIndex[_cdpId], systemStEthFeePerUnitIndex ); coll = _newColl; debt = _newDebt; - pendingEBTCDebtReward = _pendingDebt; } /// @dev calculate pending global state change to be applied: diff --git a/packages/contracts/contracts/Dependencies/EbtcBase.sol b/packages/contracts/contracts/Dependencies/EbtcBase.sol index 834bae69c..cd08b1cd2 100644 --- a/packages/contracts/contracts/Dependencies/EbtcBase.sol +++ b/packages/contracts/contracts/Dependencies/EbtcBase.sol @@ -28,7 +28,7 @@ contract EbtcBase is BaseMath, IEbtcBase { uint256 public constant LIQUIDATOR_REWARD = 2e17; // Minimum amount of stETH collateral a CDP must have - uint256 public constant MIN_NET_COLL = 2e18; + uint256 public constant MIN_NET_STETH_BALANCE = 2e18; uint256 public constant PERCENT_DIVISOR = 200; // dividing by 200 yields 0.5% @@ -53,8 +53,8 @@ contract EbtcBase is BaseMath, IEbtcBase { // --- Gas compensation functions --- - function _getNetColl(uint256 _coll) internal pure returns (uint256) { - return _coll - LIQUIDATOR_REWARD; + function _calcNetStEthBalance(uint256 _stEthBalance) internal pure returns (uint256) { + return _stEthBalance - LIQUIDATOR_REWARD; } /** diff --git a/packages/contracts/contracts/HintHelpers.sol b/packages/contracts/contracts/HintHelpers.sol index c942dde71..3ff1b78da 100644 --- a/packages/contracts/contracts/HintHelpers.sol +++ b/packages/contracts/contracts/HintHelpers.sol @@ -100,7 +100,10 @@ contract HintHelpers is EbtcBase { // If the partial redemption would leave the CDP with less than the minimum allowed coll, bail out of partial redemption and return only the fully redeemable // TODO: This seems to return the original coll? why? - if (collateral.getPooledEthByShares(partialRedemptionNewColl) < MIN_NET_COLL) { + if ( + collateral.getPooledEthByShares(partialRedemptionNewColl) < + MIN_NET_STETH_BALANCE + ) { partialRedemptionHintNICR = 0; //reset to 0 as there is no partial redemption in this case partialRedemptionNewColl = 0; vars.remainingEbtcToRedeem = _cachedEbtcToRedeem; @@ -148,7 +151,7 @@ contract HintHelpers is EbtcBase { _oldIndex ); } else { - (, newCollShare, ) = cdpManager.getDebtAndCollShares(vars.currentCdpId); + (, newCollShare) = cdpManager.getSyncedDebtAndCollShares(vars.currentCdpId); } vars.remainingEbtcToRedeem = vars.remainingEbtcToRedeem - maxRedeemableEBTC; diff --git a/packages/contracts/contracts/Interfaces/ICdpManagerData.sol b/packages/contracts/contracts/Interfaces/ICdpManagerData.sol index 9291df141..922d0d01f 100644 --- a/packages/contracts/contracts/Interfaces/ICdpManagerData.sol +++ b/packages/contracts/contracts/Interfaces/ICdpManagerData.sol @@ -111,9 +111,8 @@ interface ICdpManagerData is IRecoveryModeGracePeriod { **/ struct CdpDebtAndCollShares { - uint256 entireDebt; - uint256 entireColl; - uint256 pendingDebtReward; + uint256 debt; + uint256 collShares; } struct LiquidationLocals { @@ -255,9 +254,9 @@ interface ICdpManagerData is IRecoveryModeGracePeriod { function hasPendingRedistributedDebt(bytes32 _cdpId) external view returns (bool); - function getDebtAndCollShares( + function getSyncedDebtAndCollShares( bytes32 _cdpId - ) external view returns (uint256 debt, uint256 coll, uint256 pendingEBTCDebtReward); + ) external view returns (uint256 debt, uint256 collShares); function canLiquidateRecoveryMode(uint256 icr, uint256 tcr) external view returns (bool); } diff --git a/packages/contracts/contracts/LiquidationLibrary.sol b/packages/contracts/contracts/LiquidationLibrary.sol index d5ff1452d..23e69834f 100644 --- a/packages/contracts/contracts/LiquidationLibrary.sol +++ b/packages/contracts/contracts/LiquidationLibrary.sol @@ -374,7 +374,7 @@ contract LiquidationLibrary is CdpManagerStorage { // without emmiting events function _closeCdpByLiquidation(bytes32 _cdpId) private returns (uint256, uint256, uint256) { // calculate entire debt to repay - (uint256 entireDebt, uint256 entireColl, ) = getDebtAndCollShares(_cdpId); + (uint256 entireDebt, uint256 entireColl) = getSyncedDebtAndCollShares(_cdpId); // housekeeping after liquidation by closing the CDP uint256 _liquidatorReward = Cdps[_cdpId].liquidatorRewardShares; @@ -392,16 +392,16 @@ contract LiquidationLibrary is CdpManagerStorage { uint256 _partialDebt = _partialState.partialAmount; // calculate entire debt to repay - CdpDebtAndCollShares memory _debtAndColl = _getDebtAndCollShares(_cdpId); - _requirePartialLiqDebtSize(_partialDebt, _debtAndColl.entireDebt, _partialState.price); - uint256 newDebt = _debtAndColl.entireDebt - _partialDebt; + CdpDebtAndCollShares memory _debtAndColl = _getSyncedDebtAndCollShares(_cdpId); + _requirePartialLiqDebtSize(_partialDebt, _debtAndColl.debt, _partialState.price); + uint256 newDebt = _debtAndColl.debt - _partialDebt; // credit to https://arxiv.org/pdf/2212.07306.pdf for details (uint256 _partialColl, uint256 newColl, ) = _calculatePartialLiquidationSurplusAndCap( _partialState.ICR, _partialState.price, _partialDebt, - _debtAndColl.entireColl + _debtAndColl.collShares ); // early return: if new collateral is zero, we have a full liqudiation @@ -420,8 +420,8 @@ contract LiquidationLibrary is CdpManagerStorage { _reInsertPartialLiquidation( _partialState, EbtcMath._computeNominalCR(newColl, newDebt), - _debtAndColl.entireDebt, - _debtAndColl.entireColl + _debtAndColl.debt, + _debtAndColl.collShares ); uint _debtToColl = (_partialDebt * DECIMAL_PRECISION) / _partialState.price; uint _cappedColl = collateral.getPooledEthByShares(_partialColl); @@ -891,14 +891,15 @@ contract LiquidationLibrary is CdpManagerStorage { uint256 _price ) internal view { require( - (_partialDebt + _convertDebtDenominationToBtc(MIN_NET_COLL, _price)) <= _entireDebt, + (_partialDebt + _convertDebtDenominationToBtc(MIN_NET_STETH_BALANCE, _price)) <= + _entireDebt, "LiquidationLibrary: Partial debt liquidated must be less than total debt" ); } function _requirePartialLiqCollSize(uint256 _entireColl) internal pure { require( - _entireColl >= MIN_NET_COLL, + _entireColl >= MIN_NET_STETH_BALANCE, "LiquidationLibrary: Coll remaining in partially liquidated CDP must be >= minimum" ); } diff --git a/packages/contracts/contracts/TestContracts/invariants/BeforeAfter.sol b/packages/contracts/contracts/TestContracts/invariants/BeforeAfter.sol index ea1d393f4..83625482d 100644 --- a/packages/contracts/contracts/TestContracts/invariants/BeforeAfter.sol +++ b/packages/contracts/contracts/TestContracts/invariants/BeforeAfter.sol @@ -77,7 +77,7 @@ abstract contract BeforeAfter is BaseStorageVariables { function _before(bytes32 _cdpId) internal { vars.priceBefore = priceFeedMock.fetchPrice(); - (uint256 debtBefore, , ) = cdpManager.getDebtAndCollShares(_cdpId); + (uint256 debtBefore, ) = cdpManager.getSyncedDebtAndCollShares(_cdpId); vars.nicrBefore = _cdpId != bytes32(0) ? crLens.quoteRealNICR(_cdpId) : 0; vars.icrBefore = _cdpId != bytes32(0) ? cdpManager.getICR(_cdpId, vars.priceBefore) : 0; diff --git a/packages/contracts/contracts/TestContracts/invariants/Properties.sol b/packages/contracts/contracts/TestContracts/invariants/Properties.sol index ef0b709c3..bcc3dfda9 100644 --- a/packages/contracts/contracts/TestContracts/invariants/Properties.sol +++ b/packages/contracts/contracts/TestContracts/invariants/Properties.sol @@ -49,7 +49,7 @@ abstract contract Properties is BeforeAfter, PropertiesDescriptions, Asserts, Pr uint256 _cdpCount = cdpManager.getActiveCdpsCount(); uint256 _sum; for (uint256 i = 0; i < _cdpCount; ++i) { - (, uint256 _coll, ) = cdpManager.getDebtAndCollShares(cdpManager.CdpIds(i)); + (, uint256 _coll) = cdpManager.getSyncedDebtAndCollShares(cdpManager.CdpIds(i)); _sum += _coll; } uint256 _activeColl = activePool.getSystemCollShares(); @@ -64,7 +64,7 @@ abstract contract Properties is BeforeAfter, PropertiesDescriptions, Asserts, Pr uint256 _cdpCount = cdpManager.getActiveCdpsCount(); uint256 _sum; for (uint256 i = 0; i < _cdpCount; ++i) { - (uint256 _debt, , ) = cdpManager.getDebtAndCollShares(cdpManager.CdpIds(i)); + (uint256 _debt, ) = cdpManager.getSyncedDebtAndCollShares(cdpManager.CdpIds(i)); _sum += _debt; } @@ -296,7 +296,9 @@ abstract contract Properties is BeforeAfter, PropertiesDescriptions, Asserts, Pr bytes32 currentCdp = sortedCdps.getFirst(); uint256 cdpsBalance; while (currentCdp != bytes32(0)) { - (uint256 entireDebt, , ) = cdpManager.getDebtAndCollShares(currentCdp); + (uint256 entireDebt, uint256 entireColl) = cdpManager.getSyncedDebtAndCollShares( + currentCdp + ); cdpsBalance += entireDebt; currentCdp = sortedCdps.getNext(currentCdp); } diff --git a/packages/contracts/contracts/TestContracts/invariants/Simulator.sol b/packages/contracts/contracts/TestContracts/invariants/Simulator.sol index 8c21f7909..6a287be63 100644 --- a/packages/contracts/contracts/TestContracts/invariants/Simulator.sol +++ b/packages/contracts/contracts/TestContracts/invariants/Simulator.sol @@ -32,7 +32,7 @@ contract Simulator { bytes32 currentCdp = sortedCdps.getFirst(); while (currentCdp != bytes32(0) && sortedCdps.getSize() > 1) { Actor actor = Actor(payable(sortedCdps.getOwnerAddress(currentCdp))); - (uint256 entireDebt, , ) = cdpManager.getDebtAndCollShares(currentCdp); + (uint256 entireDebt, ) = cdpManager.getSyncedDebtAndCollShares(currentCdp); (success, ) = actor.proxy( address(borrowerOperations), diff --git a/packages/contracts/contracts/TestContracts/invariants/TargetFunctions.sol b/packages/contracts/contracts/TestContracts/invariants/TargetFunctions.sol index 01740dd4b..84af3eed4 100644 --- a/packages/contracts/contracts/TestContracts/invariants/TargetFunctions.sol +++ b/packages/contracts/contracts/TestContracts/invariants/TargetFunctions.sol @@ -212,7 +212,7 @@ abstract contract TargetFunctions is Properties { bytes32 _cdpId = _getRandomCdp(_i); - (uint256 entireDebt, , ) = cdpManager.getDebtAndCollShares(_cdpId); + (uint256 entireDebt, ) = cdpManager.getSyncedDebtAndCollShares(_cdpId); require(entireDebt > 0, "CDP must have debt"); _before(_cdpId); @@ -283,7 +283,7 @@ abstract contract TargetFunctions is Properties { bytes32 _cdpId = _getRandomCdp(_i); - (uint256 entireDebt, , ) = cdpManager.getDebtAndCollShares(_cdpId); + (uint256 entireDebt, ) = cdpManager.getSyncedDebtAndCollShares(_cdpId); require(entireDebt > 0, "CDP must have debt"); _partialAmount = between(_partialAmount, 0, entireDebt); @@ -330,7 +330,7 @@ abstract contract TargetFunctions is Properties { // CDP was not fully liquidated gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); } @@ -650,7 +650,7 @@ abstract contract TargetFunctions is Properties { uint256 requiredCollAmount = (_EBTCAmount * cdpManager.CCR()) / (price); uint256 minCollAmount = max( - cdpManager.MIN_NET_COLL() + borrowerOperations.LIQUIDATOR_REWARD(), + cdpManager.MIN_NET_STETH_BALANCE() + borrowerOperations.LIQUIDATOR_REWARD(), requiredCollAmount ); uint256 maxCollAmount = min(2 * minCollAmount, INITIAL_COLL_BALANCE / 10); @@ -693,7 +693,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); eq( @@ -799,7 +799,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); @@ -875,7 +875,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); @@ -949,7 +949,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); @@ -989,7 +989,7 @@ abstract contract TargetFunctions is Properties { bytes32 _cdpId = sortedCdps.cdpOfOwnerByIndex(address(actor), _i); t(_cdpId != bytes32(0), "CDP ID must not be null if the index is valid"); - (uint256 entireDebt, , ) = cdpManager.getDebtAndCollShares(_cdpId); + (uint256 entireDebt, ) = cdpManager.getSyncedDebtAndCollShares(_cdpId); _amount = between(_amount, 0, entireDebt); _before(_cdpId); @@ -1021,7 +1021,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); @@ -1148,7 +1148,7 @@ abstract contract TargetFunctions is Properties { bytes32 _cdpId = sortedCdps.cdpOfOwnerByIndex(address(actor), _i); t(_cdpId != bytes32(0), "CDP ID must not be null if the index is valid"); - (uint256 entireDebt, uint256 entireColl, ) = cdpManager.getDebtAndCollShares(_cdpId); + (uint256 entireDebt, uint256 entireColl) = cdpManager.getSyncedDebtAndCollShares(_cdpId); _collWithdrawal = between(_collWithdrawal, 0, entireColl); _EBTCChange = between(_EBTCChange, 0, entireDebt); @@ -1179,7 +1179,7 @@ abstract contract TargetFunctions is Properties { // https://github.com/Badger-Finance/ebtc-fuzz-review/issues/4 gte( collateral.getPooledEthByShares(cdpManager.getCdpCollShares(_cdpId)), - borrowerOperations.MIN_NET_COLL(), + borrowerOperations.MIN_NET_STETH_BALANCE(), GENERAL_10 ); diff --git a/packages/contracts/foundry_test/BaseFixture.sol b/packages/contracts/foundry_test/BaseFixture.sol index e9f4d234a..effd04b0d 100644 --- a/packages/contracts/foundry_test/BaseFixture.sol +++ b/packages/contracts/foundry_test/BaseFixture.sol @@ -114,7 +114,6 @@ contract eBTCBaseFixture is struct CdpState { uint256 debt; uint256 coll; - uint256 pendingEBTCDebtReward; } /* setUp() - basic function to call when setting up new Foundry test suite @@ -406,10 +405,9 @@ contract eBTCBaseFixture is // Helper functions //////////////////////////////////////////////////////////////////////////// - function _getDebtAndCollShares(bytes32 cdpId) internal view returns (CdpState memory) { - (uint256 debt, uint256 coll, uint256 pendingEBTCDebtReward) = cdpManager - .getDebtAndCollShares(cdpId); - return CdpState(debt, coll, pendingEBTCDebtReward); + function _getSyncedDebtAndCollShares(bytes32 cdpId) internal view returns (CdpState memory) { + (uint256 debt, uint256 coll) = cdpManager.getSyncedDebtAndCollShares(cdpId); + return CdpState(debt, coll); } function dealCollateral(address _recipient, uint256 _amount) public virtual returns (uint256) { diff --git a/packages/contracts/foundry_test/BorrowerOperations.collOps.t.sol b/packages/contracts/foundry_test/BorrowerOperations.collOps.t.sol index 5029327ce..e5466c16d 100644 --- a/packages/contracts/foundry_test/BorrowerOperations.collOps.t.sol +++ b/packages/contracts/foundry_test/BorrowerOperations.collOps.t.sol @@ -106,8 +106,10 @@ contract CDPOpsTest is eBTCBaseFixture { ); // In case borrowedAmount is less than MIN_NET_DEBT - expect revert - if (collAmount < borrowerOperations.MIN_NET_COLL()) { - vm.expectRevert(bytes("BorrowerOperations: Cdp's net coll must not fall below minimum")); + if (collAmount < borrowerOperations.MIN_NET_STETH_BALANCE()) { + vm.expectRevert( + bytes("BorrowerOperations: Cdp's net stEth balance must not fall below minimum") + ); borrowerOperations.openCdp(borrowedAmount, "hint", "hint", collAmount); return; } diff --git a/packages/contracts/foundry_test/BorrowerOperations.openCloseCdp.t.sol b/packages/contracts/foundry_test/BorrowerOperations.openCloseCdp.t.sol index 40fb0e018..9833e402f 100644 --- a/packages/contracts/foundry_test/BorrowerOperations.openCloseCdp.t.sol +++ b/packages/contracts/foundry_test/BorrowerOperations.openCloseCdp.t.sol @@ -117,7 +117,7 @@ contract OpenCloseCdpTest is eBTCBaseInvariants { // @dev Attempt to open a CDP with net coll below the minimum allowed and ensure it fails // @dev The collateral value passed into the openCdp function is interpretted as netColl + liqudiatorReward. The fixed liqudiator reward is taken out before netColl is checked function testMinCollTooLow(uint256 netColl) public { - netColl = bound(netColl, 0, borrowerOperations.MIN_NET_COLL() - 1); + netColl = bound(netColl, 0, borrowerOperations.MIN_NET_STETH_BALANCE() - 1); uint256 collPlusLiquidatorReward = netColl + borrowerOperations.LIQUIDATOR_REWARD(); @@ -130,7 +130,9 @@ contract OpenCloseCdpTest is eBTCBaseInvariants { assert(sortedCdps.getLast() == ""); vm.startPrank(user); - vm.expectRevert(bytes("BorrowerOperations: Cdp's net coll must not fall below minimum")); + vm.expectRevert( + bytes("BorrowerOperations: Cdp's net stEth balance must not fall below minimum") + ); borrowerOperations.openCdp(1, "hint", "hint", collPlusLiquidatorReward); vm.stopPrank(); } diff --git a/packages/contracts/foundry_test/CDPManager.redemptions.t.sol b/packages/contracts/foundry_test/CDPManager.redemptions.t.sol index 9173e93c9..6cf8aa697 100644 --- a/packages/contracts/foundry_test/CDPManager.redemptions.t.sol +++ b/packages/contracts/foundry_test/CDPManager.redemptions.t.sol @@ -118,7 +118,7 @@ contract CDPManagerRedemptionsTest is eBTCBaseInvariants { uint256 _redeemNumber = _utils.generateRandomNumber(1, _cdpNumber - 1, _redeemer); uint256 _redeemDebt; for (uint256 i = 0; i < _redeemNumber; ++i) { - CdpState memory _state = _getDebtAndCollShares(_cdpIds[i]); + CdpState memory _state = _getSyncedDebtAndCollShares(_cdpIds[i]); _redeemDebt += _state.debt; address _owner = sortedCdps.getOwnerAddress(_cdpIds[i]); uint256 _sugar = eBTCToken.balanceOf(_owner); @@ -364,7 +364,7 @@ contract CDPManagerRedemptionsTest is eBTCBaseInvariants { function _singleCdpSetupWithICR(address _usr, uint256 _icr) internal returns (address, bytes32) { uint256 _price = priceFeedMock.fetchPrice(); - uint256 _coll = cdpManager.MIN_NET_COLL() * 2; + uint256 _coll = cdpManager.MIN_NET_STETH_BALANCE() * 2; uint256 _debt = (_coll * _price) / _icr; bytes32 _cdpId = _openTestCDP(_usr, _coll + cdpManager.LIQUIDATOR_REWARD(), _debt); uint256 _cdpICR = cdpManager.getICR(_cdpId, _price); diff --git a/packages/contracts/foundry_test/CdpManager.Liquidation.t.sol b/packages/contracts/foundry_test/CdpManager.Liquidation.t.sol index 7e1873127..36be8b261 100644 --- a/packages/contracts/foundry_test/CdpManager.Liquidation.t.sol +++ b/packages/contracts/foundry_test/CdpManager.Liquidation.t.sol @@ -81,7 +81,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { bytes32 cdpId1 = _openTestCDP(users[0], coll1, debtAmt); // get original debt upon CDP open - CdpState memory _cdpState0 = _getDebtAndCollShares(cdpId1); + CdpState memory _cdpState0 = _getSyncedDebtAndCollShares(cdpId1); // Price falls priceFeedMock.setPrice(price); @@ -91,7 +91,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { // Liquidate cdp1 bool _availableToLiq1 = _checkAvailableToLiq(cdpId1, price); if (_availableToLiq1) { - CdpState memory _cdpState = _getDebtAndCollShares(cdpId1); + CdpState memory _cdpState = _getSyncedDebtAndCollShares(cdpId1); assertEq(_cdpState.debt, _cdpState0.debt, "!interest should not accrue"); uint256 _ICR = cdpManager.getICR(cdpId1, price); @@ -156,7 +156,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { bytes32 cdpId1 = _openTestCDP(users[0], coll1, debtAmt); // get original debt upon CDP open - CdpState memory _cdpState0 = _getDebtAndCollShares(cdpId1); + CdpState memory _cdpState0 = _getSyncedDebtAndCollShares(cdpId1); // Price falls uint256 _newPrice = _curPrice / 2; @@ -167,18 +167,18 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { // Partially Liquidate cdp1 bool _availableToLiq1 = _checkAvailableToLiq(cdpId1, _newPrice); if (_availableToLiq1) { - CdpState memory _cdpState = _getDebtAndCollShares(cdpId1); + CdpState memory _cdpState = _getSyncedDebtAndCollShares(cdpId1); assertEq(_cdpState.debt, _cdpState0.debt, "!interest should not accrue"); LocalVar_PartialLiq memory _partialLiq; _partialLiq._ratio = _icrGtLICR ? cdpManager.MCR() : cdpManager.LICR(); _partialLiq._repaidDebt = (_cdpState.debt * partialRatioBps) / 10000; if ( - (_cdpState.coll - cdpManager.MIN_NET_COLL()) <= + (_cdpState.coll - cdpManager.MIN_NET_STETH_BALANCE()) <= ((_partialLiq._repaidDebt * _partialLiq._ratio) / _newPrice) ) { _partialLiq._repaidDebt = - ((_cdpState.coll - cdpManager.MIN_NET_COLL() * 3) * _newPrice) / + ((_cdpState.coll - cdpManager.MIN_NET_STETH_BALANCE() * 3) * _newPrice) / _partialLiq._ratio; if (_partialLiq._repaidDebt >= 2) { _partialLiq._repaidDebt = _partialLiq._repaidDebt - 1; @@ -281,7 +281,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { // calc debt in system by summing up all CDPs debt uint256 _leftTotalDebt; for (uint256 i = 0; i < cdpManager.getActiveCdpsCount(); ++i) { - (uint256 _cdpDebt, , ) = cdpManager.getDebtAndCollShares(cdpManager.CdpIds(i)); + (uint256 _cdpDebt, ) = cdpManager.getSyncedDebtAndCollShares(cdpManager.CdpIds(i)); _leftTotalDebt = (_leftTotalDebt + _cdpDebt); _cdpLeftActive[cdpManager.CdpIds(i)] = true; } @@ -340,8 +340,8 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { bool _availableToLiq2 = _checkAvailableToLiq(cdpId2, price); if (_availableToLiq1 || _availableToLiq2) { // get original debt - CdpState memory _cdpState1 = _getDebtAndCollShares(cdpId1); - CdpState memory _cdpState2 = _getDebtAndCollShares(cdpId2); + CdpState memory _cdpState1 = _getSyncedDebtAndCollShares(cdpId1); + CdpState memory _cdpState2 = _getSyncedDebtAndCollShares(cdpId2); bytes32[] memory _emptyCdps; _multipleCDPsLiq(2, _emptyCdps, users[0]); @@ -390,8 +390,8 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { bool _availableToLiq2 = _checkAvailableToLiq(cdpId2, price); if (_availableToLiq1 || _availableToLiq2) { // get original debt - CdpState memory _cdpState1 = _getDebtAndCollShares(cdpId1); - CdpState memory _cdpState2 = _getDebtAndCollShares(cdpId2); + CdpState memory _cdpState1 = _getSyncedDebtAndCollShares(cdpId1); + CdpState memory _cdpState2 = _getSyncedDebtAndCollShares(cdpId2); bytes32[] memory _cdps = new bytes32[](2); _cdps[0] = cdpId1; @@ -904,7 +904,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { function _singleCdpSetup(address _usr, uint256 _icr) internal returns (address, bytes32) { uint256 _price = priceFeedMock.fetchPrice(); - uint256 _coll = cdpManager.MIN_NET_COLL() * 2; + uint256 _coll = cdpManager.MIN_NET_STETH_BALANCE() * 2; uint256 _debt = (_coll * _price) / _icr; bytes32 _cdpId = _openTestCDP(_usr, _coll + cdpManager.LIQUIDATOR_REWARD(), _debt); uint256 _cdpICR = cdpManager.getICR(_cdpId, _price); diff --git a/packages/contracts/foundry_test/CdpManager.StakingSplitFee.t.sol b/packages/contracts/foundry_test/CdpManager.StakingSplitFee.t.sol index 798afcef7..436fd35d8 100644 --- a/packages/contracts/foundry_test/CdpManager.StakingSplitFee.t.sol +++ b/packages/contracts/foundry_test/CdpManager.StakingSplitFee.t.sol @@ -47,7 +47,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { function _assert_cdp_manager_invariant_fee3(LocalFeeSplitVar memory _var) internal { uint256 _cdpCount = cdpManager.getActiveCdpsCount(); for (uint256 i = 0; i < _cdpCount; ++i) { - CdpState memory _cdpState = _getDebtAndCollShares(cdpManager.CdpIds(i)); + CdpState memory _cdpState = _getSyncedDebtAndCollShares(cdpManager.CdpIds(i)); assertGt( collateral.getPooledEthByShares(_cdpState.coll), _targetCdpPrevCollUnderlyings[cdpManager.CdpIds(i)], @@ -59,7 +59,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { function _assert_cdp_manager_invariant_fee4(LocalFeeSplitVar memory _var) internal view { uint256 _cdpCount = cdpManager.getActiveCdpsCount(); for (uint256 i = 0; i < _cdpCount; ++i) { - CdpState memory _cdpState = _getDebtAndCollShares(cdpManager.CdpIds(i)); + CdpState memory _cdpState = _getSyncedDebtAndCollShares(cdpManager.CdpIds(i)); uint256 _diffColl = _targetCdpPrevColls[cdpManager.CdpIds(i)] - _cdpState.coll; require( @@ -183,7 +183,7 @@ contract CdpManagerLiquidationTest is eBTCBaseInvariants { } function _populateCdpStatus(bytes32 _cdpId) internal { - CdpState memory _cdpState = _getDebtAndCollShares(_cdpId); + CdpState memory _cdpState = _getSyncedDebtAndCollShares(_cdpId); _targetCdpPrevColls[_cdpId] = _cdpState.coll; _targetCdpPrevCollUnderlyings[_cdpId] = collateral.getPooledEthByShares(_cdpState.coll); } diff --git a/packages/contracts/foundry_test/EchidnaToFoundry.t.sol b/packages/contracts/foundry_test/EchidnaToFoundry.t.sol index ce0aba002..2fcf6a99c 100644 --- a/packages/contracts/foundry_test/EchidnaToFoundry.t.sol +++ b/packages/contracts/foundry_test/EchidnaToFoundry.t.sol @@ -406,7 +406,9 @@ contract EToFoundry is bytes32 currentCdp = sortedCdps.getFirst(); while (currentCdp != bytes32(0)) { - (uint256 debtBefore, uint256 collBefore, ) = cdpManager.getDebtAndCollShares(currentCdp); + (uint256 debtBefore, uint256 collBefore) = cdpManager.getSyncedDebtAndCollShares( + currentCdp + ); console2.log("debtBefore", debtBefore); console2.log("collBefore", collBefore); @@ -439,7 +441,9 @@ contract EToFoundry is currentCdp = sortedCdps.getFirst(); while (currentCdp != bytes32(0)) { - (uint256 debtBefore, uint256 collBefore, ) = cdpManager.getDebtAndCollShares(currentCdp); + (uint256 debtBefore, uint256 collBefore) = cdpManager.getSyncedDebtAndCollShares( + currentCdp + ); console2.log("debtBefore", debtBefore); console2.log("collBefore", collBefore); diff --git a/packages/contracts/foundry_test/PositionManagers.t.sol b/packages/contracts/foundry_test/PositionManagers.t.sol index a4ad7b8c1..48d2d4683 100644 --- a/packages/contracts/foundry_test/PositionManagers.t.sol +++ b/packages/contracts/foundry_test/PositionManagers.t.sol @@ -197,7 +197,7 @@ contract PositionManagersTest is eBTCBaseInvariants { collToWithdraw = bound( collToWithdraw, 1, - _getCdpStEthBalance(userCdpId) - cdpManager.MIN_NET_COLL() - 1 + _getCdpStEthBalance(userCdpId) - cdpManager.MIN_NET_STETH_BALANCE() - 1 ); uint price = priceFeedMock.fetchPrice(); diff --git a/packages/contracts/foundry_test/Proxy.leverage.t.sol b/packages/contracts/foundry_test/Proxy.leverage.t.sol index a1c6d45f3..ad49eb7fb 100644 --- a/packages/contracts/foundry_test/Proxy.leverage.t.sol +++ b/packages/contracts/foundry_test/Proxy.leverage.t.sol @@ -194,7 +194,7 @@ contract ProxyLeverageTest is eBTCBaseInvariants { uint256 netColl, uint256 adjustBps ) internal returns (uint256 _netColl, uint256 _adjustBps) { - _netColl = bound(netColl, cdpManager.MIN_NET_COLL() * 2 + 1, INITITAL_COLL * 5 - 1); + _netColl = bound(netColl, cdpManager.MIN_NET_STETH_BALANCE() * 2 + 1, INITITAL_COLL * 5 - 1); _adjustBps = bound(adjustBps, 100 + 1, (MAX_SLIPPAGE / 2) - 1); } @@ -291,7 +291,7 @@ contract ProxyLeverageTest is eBTCBaseInvariants { // prepare operation data { - (uint256 _debt, uint256 _totalColl, ) = cdpManager.getDebtAndCollShares(cdpId); + (uint256 _debt, uint256 _totalColl) = cdpManager.getSyncedDebtAndCollShares(cdpId); _totalDebt = _debt; uint256 _flDebt = _getTotalAmountForFlashLoan(_totalDebt, true); LeverageMacroBase.CloseCdpOperation memory _opData = LeverageMacroBase.CloseCdpOperation( @@ -361,7 +361,7 @@ contract ProxyLeverageTest is eBTCBaseInvariants { LeverageMacroBase.SwapOperation[] memory _levSwapsBefore; LeverageMacroBase.SwapOperation[] memory _levSwapsAfter; LocalVar_AdjustCdp memory _adjustVars; - (uint256 _debt, uint256 _totalColl, ) = cdpManager.getDebtAndCollShares(cdpId); + (uint256 _debt, uint256 _totalColl) = cdpManager.getSyncedDebtAndCollShares(cdpId); // prepare operation data { _adjustVars = _increaseCdpSize(cdpId, _totalColl, _collAdded, _debt); @@ -416,15 +416,15 @@ contract ProxyLeverageTest is eBTCBaseInvariants { LeverageMacroBase.SwapOperation[] memory _levSwapsBefore; LeverageMacroBase.SwapOperation[] memory _levSwapsAfter; LocalVar_AdjustCdp memory _adjustVars; - (uint256 _debt, uint256 _totalColl, ) = cdpManager.getDebtAndCollShares(cdpId); + (uint256 _debt, uint256 _totalColl) = cdpManager.getSyncedDebtAndCollShares(cdpId); // prepare operation data { if ( collateral.getPooledEthByShares(_totalColl - _collRemoved) <= - cdpManager.MIN_NET_COLL() + cdpManager.MIN_NET_STETH_BALANCE() ) { uint256 _minShare = collateral.getSharesByPooledEth( - cdpManager.MIN_NET_COLL() + 123456789 + cdpManager.MIN_NET_STETH_BALANCE() + 123456789 ); require(_totalColl > _minShare, "!CDP is too small to decrease size"); _collRemoved = _totalColl - _minShare; diff --git a/packages/contracts/foundry_test/SortedCdps.t.sol b/packages/contracts/foundry_test/SortedCdps.t.sol index 0c152a69d..b3f033815 100644 --- a/packages/contracts/foundry_test/SortedCdps.t.sol +++ b/packages/contracts/foundry_test/SortedCdps.t.sol @@ -138,7 +138,7 @@ contract CDPOpsTest is eBTCBaseFixture, Properties { } function testSortedCdpsICRgteTCRInvariant() public { - uint256 coll = borrowerOperations.MIN_NET_COLL() + + uint256 coll = borrowerOperations.MIN_NET_STETH_BALANCE() + borrowerOperations.LIQUIDATOR_REWARD() + 16; diff --git a/packages/contracts/fuzzTests/PoolManager_AllDepositorsCanWithdrawTest.js b/packages/contracts/fuzzTests/PoolManager_AllDepositorsCanWithdrawTest.js index b442cb738..e1b56e3b2 100644 --- a/packages/contracts/fuzzTests/PoolManager_AllDepositorsCanWithdrawTest.js +++ b/packages/contracts/fuzzTests/PoolManager_AllDepositorsCanWithdrawTest.js @@ -120,7 +120,7 @@ contract("PoolManager - random liquidations/deposits, then check all depositors for (let i = 0; i < n; i++) { const ICR = await cdpManager.getICR(cdp, price) - const debt = ICR.lt(toBN(dec(110, 16))) ? (await cdpManager.getDebtAndCollShares(cdp))[0] : ZERO + const debt = ICR.lt(toBN(dec(110, 16))) ? (await cdpManager.getSyncedDebtAndCollShares(cdp))[0] : ZERO totalDebt = totalDebt.add(debt) cdp = await sortedCdps.getPrev(cdp) @@ -146,7 +146,7 @@ contract("PoolManager - random liquidations/deposits, then check all depositors */ while(await systemContainsCdpUnder100(price) && await cdpManager.checkRecoveryMode()) { const lowestCdp = await sortedCdps.getLast() - const lastCdpDebt = (await cdpManager.getDebtAndCollShares(cdp))[0] + const lastCdpDebt = (await cdpManager.getSyncedDebtAndCollShares(cdp))[0] await borrowerOperations.adjustCdp(0, lastCdpDebt, true, whale, {from: whale}) await ebtcToken.transfer(lowestCdp, lowestCdpDebt, {from: whale}) await borrowerOperations.closeCdp({from: lowestCdp}) diff --git a/packages/contracts/gasTest/gasCalc.js b/packages/contracts/gasTest/gasCalc.js index 70ee9c077..8b3abad02 100644 --- a/packages/contracts/gasTest/gasCalc.js +++ b/packages/contracts/gasTest/gasCalc.js @@ -967,7 +967,7 @@ contract('Gas cost tests', async accounts => { await th.fastForwardTime(timeValues.SECONDS_IN_ONE_MONTH, web3.currentProvider) let _first = await sortedCdps.getFirst(); - let _firstDebtAndColl = await cdpManager.getDebtAndCollShares(_first); + let _firstDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_first); const gas = await th.redeemCollateral(_liquidator, contracts, _firstDebtAndColl[0]) th.logGas(gas, message) diff --git a/packages/contracts/test/BorrowerOperationsTest.js b/packages/contracts/test/BorrowerOperationsTest.js index f4567a7e9..682efc66e 100644 --- a/packages/contracts/test/BorrowerOperationsTest.js +++ b/packages/contracts/test/BorrowerOperationsTest.js @@ -106,7 +106,7 @@ contract('BorrowerOperations', async accounts => { feeRecipient = contracts.feeRecipient - MIN_NET_DEBT = await borrowerOperations.MIN_NET_COLL() + MIN_NET_DEBT = await borrowerOperations.MIN_NET_STETH_BALANCE() BORROWING_FEE_FLOOR = await borrowerOperations.BORROWING_FEE_FLOOR() ownerSigner = await ethers.provider.getSigner(owner); @@ -678,7 +678,7 @@ contract('BorrowerOperations', async accounts => { const aliceIndex = await sortedCdps.cdpOfOwnerByIndex(alice,0) const bobIndex = await sortedCdps.cdpOfOwnerByIndex(bob,0) - const aliceColl = (await cdpManager.getDebtAndCollShares(aliceIndex))[1] + const aliceColl = (await cdpManager.getSyncedDebtAndCollShares(aliceIndex))[1] // Check Cdp is active const alice_Cdp_Before = await cdpManager.Cdps(aliceIndex) @@ -2561,7 +2561,7 @@ contract('BorrowerOperations', async accounts => { const bobIndex = await sortedCdps.cdpOfOwnerByIndex(bob,0) const carolIndex = await sortedCdps.cdpOfOwnerByIndex(carol,0) - let _carolDebtColl = await cdpManager.getDebtAndCollShares(carolIndex) + let _carolDebtColl = await cdpManager.getSyncedDebtAndCollShares(carolIndex) let _carolDebt = _carolDebtColl[0] let _carolColl = _carolDebtColl[1] @@ -3767,11 +3767,11 @@ contract('BorrowerOperations', async accounts => { await priceFeed.setPrice(_newPrice) let _aliceCdpId = await sortedCdps.cdpOfOwnerByIndex(alice, 0); - let _aliceDebtAndColl = await cdpManager.getDebtAndCollShares(_aliceCdpId); + let _aliceDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId); let _aliceDebt = _aliceDebtAndColl[0]; let _aliceColl = _aliceDebtAndColl[1]; let _bobCdpId = await sortedCdps.cdpOfOwnerByIndex(bob, 0); - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -3811,11 +3811,11 @@ contract('BorrowerOperations', async accounts => { await borrowerOperations.openCdp(cdpEBTCAmount, th.DUMMY_BYTES32, th.DUMMY_BYTES32, cdpColl, { from: bob }) let _aliceCdpId = await sortedCdps.cdpOfOwnerByIndex(alice, 0); - let _aliceDebtAndColl = await cdpManager.getDebtAndCollShares(_aliceCdpId); + let _aliceDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId); let _aliceDebt = _aliceDebtAndColl[0]; let _aliceColl = _aliceDebtAndColl[1]; let _bobCdpId = await sortedCdps.cdpOfOwnerByIndex(bob, 0); - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -3857,11 +3857,11 @@ contract('BorrowerOperations', async accounts => { await borrowerOperations.openCdp(cdpEBTCAmount, th.DUMMY_BYTES32, th.DUMMY_BYTES32, cdpColl, { from: bob }) let _aliceCdpId = await sortedCdps.cdpOfOwnerByIndex(alice, 0); - let _aliceDebtAndColl = await cdpManager.getDebtAndCollShares(_aliceCdpId); + let _aliceDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId); let _aliceDebt = _aliceDebtAndColl[0]; let _aliceColl = _aliceDebtAndColl[1]; let _bobCdpId = await sortedCdps.cdpOfOwnerByIndex(bob, 0); - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -3902,11 +3902,11 @@ contract('BorrowerOperations', async accounts => { await borrowerOperations.openCdp(cdpEBTCAmount, th.DUMMY_BYTES32, th.DUMMY_BYTES32, cdpColl, { from: bob }) let _aliceCdpId = await sortedCdps.cdpOfOwnerByIndex(alice, 0); - let _aliceDebtAndColl = await cdpManager.getDebtAndCollShares(_aliceCdpId); + let _aliceDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId); let _aliceDebt = _aliceDebtAndColl[0]; let _aliceColl = _aliceDebtAndColl[1]; let _bobCdpId = await sortedCdps.cdpOfOwnerByIndex(bob, 0); - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -3946,11 +3946,11 @@ contract('BorrowerOperations', async accounts => { await borrowerOperations.openCdp(cdpEBTCAmount, th.DUMMY_BYTES32, th.DUMMY_BYTES32, cdpColl, { from: alice }) await borrowerOperations.openCdp(cdpEBTCAmount, th.DUMMY_BYTES32, th.DUMMY_BYTES32, cdpColl, { from: bob }) let _aliceCdpId = await sortedCdps.cdpOfOwnerByIndex(alice, 0); - let _aliceDebtAndColl = await cdpManager.getDebtAndCollShares(_aliceCdpId); + let _aliceDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId); let _aliceDebt = _aliceDebtAndColl[0]; let _aliceColl = _aliceDebtAndColl[1]; let _bobCdpId = await sortedCdps.cdpOfOwnerByIndex(bob, 0); - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; diff --git a/packages/contracts/test/CdpManagerTest.js b/packages/contracts/test/CdpManagerTest.js index 25426e201..518f4018a 100644 --- a/packages/contracts/test/CdpManagerTest.js +++ b/packages/contracts/test/CdpManagerTest.js @@ -80,7 +80,7 @@ contract('CdpManager', async accounts => { hintHelpers = contracts.hintHelpers debtToken = ebtcToken; LICR = await cdpManager.LICR() - MIN_CDP_SIZE = await cdpManager.MIN_NET_COLL() + MIN_CDP_SIZE = await cdpManager.MIN_NET_STETH_BALANCE() collToken = contracts.collateral; liqReward = await contracts.borrowerOperations.LIQUIDATOR_REWARD(); @@ -355,7 +355,7 @@ contract('CdpManager', async accounts => { // Bob now withdraws EBTC, bringing his ICR to 1.11 const { increasedTotalDebt: B_increasedTotalDebt } = await withdrawDebt({_cdpId: _bobCdpId, ICR: toBN(dec(111, 16)), extraParams: { from: bob } }) - let _bobTotalDebt = (await cdpManager.getDebtAndCollShares(_bobCdpId))[0] + let _bobTotalDebt = (await cdpManager.getSyncedDebtAndCollShares(_bobCdpId))[0] // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); @@ -4861,7 +4861,7 @@ contract('CdpManager', async accounts => { const _leftColl = MIN_CDP_SIZE.mul(toBN("10001")).div(toBN("10000")) assert.isTrue((await collToken.getSharesByPooledEth(_leftColl)).lt(MIN_CDP_SIZE)); - let _aColl = (await cdpManager.getDebtAndCollShares(_aCdpID))[1] + let _aColl = (await cdpManager.getSyncedDebtAndCollShares(_aCdpID))[1] const _partialRedeem_EBTC = (_aColl).sub(_leftColl).mul(price).div(mv._1e18BN) let firstRedemptionHint diff --git a/packages/contracts/test/CdpManager_LiquidationRewardsTest.js b/packages/contracts/test/CdpManager_LiquidationRewardsTest.js index c4794cb8c..42849913b 100644 --- a/packages/contracts/test/CdpManager_LiquidationRewardsTest.js +++ b/packages/contracts/test/CdpManager_LiquidationRewardsTest.js @@ -553,7 +553,7 @@ contract('CdpManager - Redistribution reward calculations', async accounts => { // Price drops to 100 $/E await priceFeed.setPrice(_newPrice) - let _aliceTotalDebt = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[0]; + let _aliceTotalDebt = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[0]; // Liquidate Alice await debtToken.transfer(owner, (await debtToken.balanceOf(alice)), {from: alice}); @@ -915,7 +915,7 @@ contract('CdpManager - Redistribution reward calculations', async accounts => { // Price drops to 100 $/E await priceFeed.setPrice(_newPrice) - let _aliceTotalDebt = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[0]; + let _aliceTotalDebt = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[0]; // Liquidate Alice await debtToken.transfer(owner, (await debtToken.balanceOf(alice)), {from: alice}); diff --git a/packages/contracts/test/CdpManager_RecoveryModeTest.js b/packages/contracts/test/CdpManager_RecoveryModeTest.js index 69102841c..1fe5c6f6a 100644 --- a/packages/contracts/test/CdpManager_RecoveryModeTest.js +++ b/packages/contracts/test/CdpManager_RecoveryModeTest.js @@ -558,7 +558,7 @@ contract('CdpManager - in Recovery Mode', async accounts => { assert.isTrue(toBN(alice_ICR).lt(mv._MCR)) assert.isTrue(toBN(dennis_ICR).lt(mv._MCR)) - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -1181,7 +1181,7 @@ contract('CdpManager - in Recovery Mode', async accounts => { const recoveryMode = await th.checkRecoveryMode(contracts) assert.isTrue(recoveryMode) - let _bobDebtAndColl = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); let _bobDebt = _bobDebtAndColl[0]; let _bobColl = _bobDebtAndColl[1]; @@ -1216,7 +1216,7 @@ contract('CdpManager - in Recovery Mode', async accounts => { await _signer.sendTransaction({ to: carol, value: ethers.utils.parseEther("10000")}); await openCdp({ ICR: toBN(dec(250, 16)), extraEBTCAmount: dec(240, 18), extraParams: { from: carol } }) let _carolCdpId = await sortedCdps.cdpOfOwnerByIndex(carol, 0); - let _carolDebtAndCollOriginal = await cdpManager.getDebtAndCollShares(_carolCdpId); + let _carolDebtAndCollOriginal = await cdpManager.getSyncedDebtAndCollShares(_carolCdpId); let _carolDebtOriginal = _carolDebtAndCollOriginal[0]; // --- TEST --- @@ -1268,7 +1268,7 @@ contract('CdpManager - in Recovery Mode', async accounts => { assert.isTrue((await cdpManager.getICR(_carolCdpId, price)).lt(mv._MCR)) // get total debt with redistributed - let _carolDebtAndColl = await cdpManager.getDebtAndCollShares(_carolCdpId); + let _carolDebtAndColl = await cdpManager.getSyncedDebtAndCollShares(_carolCdpId); let _carolDebt = _carolDebtAndColl[0]; let _carolColl = _carolDebtAndColl[1]; diff --git a/packages/contracts/test/CdpManager_RecoveryMode_Cooldown_Test.js b/packages/contracts/test/CdpManager_RecoveryMode_Cooldown_Test.js index 20ee4b88a..4a6eb15fd 100644 --- a/packages/contracts/test/CdpManager_RecoveryMode_Cooldown_Test.js +++ b/packages/contracts/test/CdpManager_RecoveryMode_Cooldown_Test.js @@ -45,7 +45,7 @@ contract('CdpManager - Cooldown switch with respect to Recovery Mode to ensure d defaultPool = contracts.defaultPool; feeSplit = await contracts.cdpManager.stakingRewardSplit(); liq_stipend = await contracts.cdpManager.LIQUIDATOR_REWARD(); - minDebt = await contracts.borrowerOperations.MIN_NET_COLL(); + minDebt = await contracts.borrowerOperations.MIN_NET_STETH_BALANCE(); _MCR = await cdpManager.MCR(); _CCR = await cdpManager.CCR(); LICR = await cdpManager.LICR(); diff --git a/packages/contracts/test/CdpManager_SimpleLiquidation_Test.js b/packages/contracts/test/CdpManager_SimpleLiquidation_Test.js index af6975a83..c87fbe33c 100644 --- a/packages/contracts/test/CdpManager_SimpleLiquidation_Test.js +++ b/packages/contracts/test/CdpManager_SimpleLiquidation_Test.js @@ -40,7 +40,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco debtToken = contracts.ebtcToken; activePool = contracts.activePool; defaultPool = contracts.defaultPool; - minDebt = await contracts.borrowerOperations.MIN_NET_COLL(); + minDebt = await contracts.borrowerOperations.MIN_NET_STETH_BALANCE(); liqReward = await contracts.cdpManager.LIQUIDATOR_REWARD(); _MCR = await cdpManager.MCR(); LICR = await cdpManager.LICR(); @@ -680,7 +680,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco const tx = await cdpManager.partiallyLiquidate(_aliceCdpId, _partialAmounts[i], _aliceCdpId, _aliceCdpId, {from: bob}) _partialLiquidationTxs.push(tx); }else{ - let _leftColl = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[1] + let _leftColl = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[1] const finalTx = await cdpManager.liquidate(_aliceCdpId, {from: bob}) _partialLiquidationTxs.push(finalTx); } @@ -750,7 +750,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await collToken.approve(borrowerOperations.address, mv._1Be18BN, {from: owner}); await borrowerOperations.openCdp(_ebtcAmt1, th.DUMMY_BYTES32, th.DUMMY_BYTES32, _collAmt1); let _cdpId1 = await sortedCdps.cdpOfOwnerByIndex(owner, 0); - let _cdpDebtColl1 = await cdpManager.getDebtAndCollShares(_cdpId1); + let _cdpDebtColl1 = await cdpManager.getSyncedDebtAndCollShares(_cdpId1); let _systemDebt = await cdpManager.getSystemDebt(); th.assertIsApproximatelyEqual(_systemDebt, _cdpDebtColl1[0], _errorTolerance.toNumber()); @@ -766,7 +766,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await collToken.deposit({from: owner, value: _collAmt2}); await borrowerOperations.openCdp(_ebtcAmt2, th.DUMMY_BYTES32, th.DUMMY_BYTES32, _collAmt2); let _cdpId2 = await sortedCdps.cdpOfOwnerByIndex(owner, 1); - let _cdpDebtColl2 = await cdpManager.getDebtAndCollShares(_cdpId2); + let _cdpDebtColl2 = await cdpManager.getSyncedDebtAndCollShares(_cdpId2); _systemDebt = await cdpManager.getSystemDebt(); th.assertIsApproximatelyEqual(_systemDebt, (_cdpDebtColl1[0].add(_cdpDebtColl2[0])), _errorTolerance.toNumber()); @@ -787,7 +787,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco // final check assert.isFalse(await sortedCdps.contains(_cdpId1)); - _cdpDebtColl2 = await cdpManager.getDebtAndCollShares(_cdpId2); + _cdpDebtColl2 = await cdpManager.getSyncedDebtAndCollShares(_cdpId2); _systemDebt = await cdpManager.getSystemDebt(); let _distributedError = (await cdpManager.lastEBTCDebtErrorRedistribution()).div(mv._1e18BN); th.assertIsApproximatelyEqual(_systemDebt, (_distributedError.add(_cdpDebtColl2[0])), _errorTolerance.toNumber()); @@ -813,7 +813,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await collToken.approve(borrowerOperations.address, mv._1Be18BN, {from: owner}); await borrowerOperations.openCdp(_ebtcAmt1, th.DUMMY_BYTES32, th.DUMMY_BYTES32, _collAmt1); let _cdpId1 = await sortedCdps.cdpOfOwnerByIndex(owner, 0); - let _cdpDebtColl1 = await cdpManager.getDebtAndCollShares(_cdpId1); + let _cdpDebtColl1 = await cdpManager.getSyncedDebtAndCollShares(_cdpId1); let _systemDebt = await cdpManager.getSystemDebt(); th.assertIsApproximatelyEqual(_systemDebt, (await debtToken.totalSupply()), _errorTolerance.toNumber()); @@ -835,7 +835,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco if (_totalSupplyDiff.lt(_partialAmount)) { await debtToken.unprotectedBurn(owner, _partialAmount.sub(_totalSupplyDiff)); } - let _cdpDebtColl1After = await cdpManager.getDebtAndCollShares(_cdpId1); + let _cdpDebtColl1After = await cdpManager.getSyncedDebtAndCollShares(_cdpId1); assert.isTrue(_cdpDebtColl1After[0].lt(_cdpDebtColl1[1])); // final check diff --git a/packages/contracts/test/CdpManager_StakingSplitFee_Test.js b/packages/contracts/test/CdpManager_StakingSplitFee_Test.js index cd13add9d..2f26b9cf1 100644 --- a/packages/contracts/test/CdpManager_StakingSplitFee_Test.js +++ b/packages/contracts/test/CdpManager_StakingSplitFee_Test.js @@ -45,7 +45,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco defaultPool = contracts.defaultPool; feeSplit = await contracts.cdpManager.stakingRewardSplit(); liq_stipend = await contracts.cdpManager.LIQUIDATOR_REWARD(); - minDebt = await contracts.borrowerOperations.MIN_NET_COLL(); + minDebt = await contracts.borrowerOperations.MIN_NET_STETH_BALANCE(); _MCR = await cdpManager.MCR(); _CCR = await cdpManager.CCR(); LICR = await cdpManager.LICR(); @@ -170,8 +170,8 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco let _totalStake = await cdpManager.totalStakes(); let _totalStakeAdded = toBN(_aliceStake.toString()).add(toBN(_bobStake.toString())); th.assertIsApproximatelyEqual(_totalStakeAdded, _totalStake, _errorTolerance); - let _aliceColl = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[1]; - let _bobColl = (await cdpManager.getDebtAndCollShares(_bobCdpId))[1]; + let _aliceColl = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[1]; + let _bobColl = (await cdpManager.getSyncedDebtAndCollShares(_bobCdpId))[1]; let _totalColl = await cdpManager.getSystemCollShares(); let _totalCollBeforeAdded = toBN(_aliceColl.toString()).add(toBN(_bobColl.toString())); th.assertIsApproximatelyEqual(_totalCollBeforeAdded, _totalColl, _errorTolerance); @@ -207,8 +207,8 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco th.assertIsApproximatelyEqual(_actualFee, _expectedFeeShare, _errorTolerance); // get collateral after applying accumulated split fee - let _aliceCollAfter = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[1]; - let _bobCollAfter = (await cdpManager.getDebtAndCollShares(_bobCdpId))[1]; + let _aliceCollAfter = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[1]; + let _bobCollAfter = (await cdpManager.getSyncedDebtAndCollShares(_bobCdpId))[1]; let _systemStEthFeePerUnitIndex = await cdpManager.systemStEthFeePerUnitIndex(); _systemStEthFeePerUnitIndexError = await cdpManager.systemStEthFeePerUnitIndexError(); @@ -345,9 +345,9 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco th.assertIsApproximatelyEqual(_feeBalAfter.sub(_feeBalBefore), _expectedFeeShare, _errorTolerance); // check after accumulated fee split applied to CDPs - let _aliceCollAfter = (await cdpManager.getDebtAndCollShares(_aliceCdpId))[1]; + let _aliceCollAfter = (await cdpManager.getSyncedDebtAndCollShares(_aliceCdpId))[1]; th.assertIsApproximatelyEqual(_aliceCollAfter, _aliceExpectedFeeApplied[1], _errorTolerance); - let _bobCollDebtAfter = await cdpManager.getDebtAndCollShares(_bobCdpId); + let _bobCollDebtAfter = await cdpManager.getSyncedDebtAndCollShares(_bobCdpId); th.assertIsApproximatelyEqual(_bobCollDebtAfter[1], _bobExpectedFeeApplied[1], _errorTolerance); // fully liquidate the riskiest CDP with fee split applied @@ -408,7 +408,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await collToken.approve(borrowerOperations.address, mv._1Be18BN, {from: owner}); await borrowerOperations.openCdp(_ebtcAmt, th.DUMMY_BYTES32, th.DUMMY_BYTES32, _collAmt); let _cdpId = await sortedCdps.cdpOfOwnerByIndex(owner, 0); - let _cdpDebtColl = await cdpManager.getDebtAndCollShares(_cdpId); + let _cdpDebtColl = await cdpManager.getSyncedDebtAndCollShares(_cdpId); let _activeColl = await activePool.getSystemCollShares(); let _systemDebt = await cdpManager.getSystemDebt(); th.assertIsApproximatelyEqual(_activeColl, _cdpDebtColl[1], _errorTolerance.toNumber()); @@ -424,7 +424,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await cdpManager.syncGlobalAccountingAndGracePeriod(); // final check - _cdpDebtColl = await cdpManager.getDebtAndCollShares(_cdpId); + _cdpDebtColl = await cdpManager.getSyncedDebtAndCollShares(_cdpId); _systemDebt = await cdpManager.getSystemDebt(); th.assertIsApproximatelyEqual(_systemDebt, _cdpDebtColl[0], _errorTolerance.toNumber()); @@ -717,7 +717,7 @@ contract('CdpManager - Simple Liquidation with external liquidators', async acco await collToken.approve(borrowerOperations.address, mv._1Be18BN, {from: owner}); await borrowerOperations.openCdp(_ebtcAmt, th.DUMMY_BYTES32, th.DUMMY_BYTES32, _collAmt); let _cdpId = await sortedCdps.cdpOfOwnerByIndex(owner, 0); - let _cdpDebtColl = await cdpManager.getDebtAndCollShares(_cdpId); + let _cdpDebtColl = await cdpManager.getSyncedDebtAndCollShares(_cdpId); let _nicrStart = await cdpManager.getNominalICR(_cdpId); let _cdpSplitIdxStart = await cdpManager.cdpStEthFeePerUnitIndex(_cdpId); console.log('startNICR:' + _nicrStart + ', _cdpSplitIdxStart=' + _cdpSplitIdxStart); diff --git a/packages/contracts/tests/simulation_helpers.py b/packages/contracts/tests/simulation_helpers.py index dd9a73d41..f6b527c24 100644 --- a/packages/contracts/tests/simulation_helpers.py +++ b/packages/contracts/tests/simulation_helpers.py @@ -377,7 +377,7 @@ def pending_liquidations(contracts, price_ether_current): stability_pool_balance = 0 ## Stability Pool is gone cdp = last_cdp for i in range(NUM_LIQUIDATIONS): - debt = contracts.cdpManager.getDebtAndCollShares(cdp)[0] + debt = contracts.cdpManager.getSyncedDebtAndCollShares(cdp)[0] if stability_pool_balance >= debt: return True cdp = contracts.sortedCdps.getPrev(cdp) @@ -457,7 +457,7 @@ def liquidate_cdps(accounts, contracts, active_accounts, inactive_accounts, pric cdp = contracts.sortedCdps.getLast() ## Note: Get last so we get at risk CDP for i in range(NUM_LIQUIDATIONS): print(f"i: {i}") - debt = contracts.cdpManager.getDebtAndCollShares(cdp)[0] + debt = contracts.cdpManager.getSyncedDebtAndCollShares(cdp)[0] print(f"debt: {debt / 1e18}") if stability_pool_balance >= debt: print("True!") @@ -538,7 +538,7 @@ def close_cdps(accounts, contracts, active_accounts, inactive_accounts, price_et account_index = active_accounts[drops[i]]['index'] account = accounts[account_index] cdp_id = active_accounts[drops[i]]['cdp_id'] - amounts = contracts.cdpManager.getDebtAndCollShares(cdp_id) + amounts = contracts.cdpManager.getSyncedDebtAndCollShares(cdp_id) coll = amounts['coll'] debt = amounts['debt'] pending = get_ebtc_to_repay(accounts, contracts, active_accounts, inactive_accounts, @@ -653,7 +653,7 @@ def adjust_cdps(accounts, contracts, active_accounts, inactive_accounts, price_e current_icr = contracts.cdpManager.getICR(cdp_id, floatToWei(price_ether_current)) / 1e18 - amounts = contracts.cdpManager.getDebtAndCollShares(cdp_id) + amounts = contracts.cdpManager.getSyncedDebtAndCollShares(cdp_id) coll = amounts['coll'] / 1e18 debt = amounts['debt'] / 1e18 diff --git a/packages/contracts/utils/hintExamples.js b/packages/contracts/utils/hintExamples.js index f4440d284..891b5f5bf 100644 --- a/packages/contracts/utils/hintExamples.js +++ b/packages/contracts/utils/hintExamples.js @@ -62,7 +62,7 @@ async function main() { const EBTCRepayment = toBN(toWei('230')) // borrower wants to repay 230 EBTC // Get cdp's current debt and coll - const {0: debt, 1: coll} = await cdpManager.getDebtAndCollShares(borrower) + const {0: debt, 1: coll} = await cdpManager.getSyncedDebtAndCollShares(borrower) const newDebt = debt.sub(EBTCRepayment) const newColl = coll.add(collIncrease) diff --git a/packages/contracts/utils/proxyHelpers.js b/packages/contracts/utils/proxyHelpers.js index 32c8b1c2d..a3497212a 100644 --- a/packages/contracts/utils/proxyHelpers.js +++ b/packages/contracts/utils/proxyHelpers.js @@ -139,8 +139,8 @@ class BorrowerOperationsProxy extends Proxy { return this.proxyFunction('LIQUIDATOR_REWARD', params) } - async MIN_NET_COLL(...params) { - return this.proxyFunction('MIN_NET_COLL', params) + async MIN_NET_STETH_BALANCE(...params) { + return this.proxyFunction('MIN_NET_STETH_BALANCE', params) } async BORROWING_FEE_FLOOR(...params) { @@ -255,8 +255,8 @@ class CdpManagerProxy extends Proxy { return this.proxyFunction('getRedemptionFeeWithDecay', params) } - async getDebtAndCollShares(...params) { - return this.proxyFunction('getDebtAndCollShares', params) + async getSyncedDebtAndCollShares(...params) { + return this.proxyFunction('getSyncedDebtAndCollShares', params) } } diff --git a/packages/contracts/utils/testHelpers.js b/packages/contracts/utils/testHelpers.js index 9285f1707..f1363ac3c 100644 --- a/packages/contracts/utils/testHelpers.js +++ b/packages/contracts/utils/testHelpers.js @@ -320,11 +320,11 @@ class TestHelper { } static async getCdpEntireColl(contracts, cdp) { - return this.toBN((await contracts.cdpManager.getDebtAndCollShares(cdp))[1]) + return this.toBN((await contracts.cdpManager.getSyncedDebtAndCollShares(cdp))[1]) } static async getCdpEntireDebt(contracts, cdp) { - return this.toBN((await contracts.cdpManager.getDebtAndCollShares(cdp))[0]) + return this.toBN((await contracts.cdpManager.getSyncedDebtAndCollShares(cdp))[0]) } static async getCdpStake(contracts, cdp) { @@ -757,7 +757,7 @@ class TestHelper { if (!upperHint) upperHint = this.DUMMY_BYTES32 //this.ZERO_ADDRESS if (!lowerHint) lowerHint = this.DUMMY_BYTES32 //this.ZERO_ADDRESS const price = await contracts.priceFeedTestnet.getPrice() - const minNetDebtEth = await contracts.borrowerOperations.MIN_NET_COLL() + const minNetDebtEth = await contracts.borrowerOperations.MIN_NET_STETH_BALANCE() const securityDeposit = await contracts.borrowerOperations.LIQUIDATOR_REWARD() const minNetDebt = minNetDebtEth.mul(price).div(MoneyValues._1e18BN) const MIN_DEBT = ( @@ -841,7 +841,7 @@ class TestHelper { let increasedTotalDebt if (ICR) { assert(extraParams.from, "A from account is needed") - const { debt, coll } = await contracts.cdpManager.getDebtAndCollShares(_cdpId) + const { debt, coll } = await contracts.cdpManager.getSyncedDebtAndCollShares(_cdpId) const price = await contracts.priceFeedTestnet.getPrice() const targetDebt = coll.mul(price).div(ICR) assert(targetDebt > debt, "ICR is already greater than or equal to target")