diff --git a/contracts/src/BorrowerOperations.sol b/contracts/src/BorrowerOperations.sol index e80164af..a98218f4 100644 --- a/contracts/src/BorrowerOperations.sol +++ b/contracts/src/BorrowerOperations.sol @@ -83,9 +83,9 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe event SortedTrovesAddressChanged(address _sortedTrovesAddress); event BoldTokenAddressChanged(address _boldTokenAddress); - event TroveCreated(address indexed _borrower, uint arrayIndex); - event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint stake, BorrowerOperation operation); - event BoldBorrowingFeePaid(address indexed _borrower, uint _boldFee); + event TroveCreated(address indexed _owner, uint256 _troveId, uint256 _arrayIndex); + event TroveUpdated(uint256 indexed _troveId, uint _debt, uint _coll, uint stake, BorrowerOperation operation); + event BoldBorrowingFeePaid(uint256 indexed _troveId, uint _boldFee); constructor(address _ETHAddress) { checkContract(_ETHAddress); @@ -150,7 +150,20 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe // --- Borrower Trove Operations --- - function openTrove(uint _maxFeePercentage, uint256 _ETHAmount, uint _boldAmount, address _upperHint, address _lowerHint, uint256 _annualInterestRate) external override { + function openTrove( + address _owner, + uint256 _ownerIndex, + uint _maxFeePercentage, + uint256 _ETHAmount, + uint _boldAmount, + uint256 _upperHint, + uint256 _lowerHint, + uint256 _annualInterestRate + ) + external + override + returns (uint256) + { ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, boldToken); LocalVariables_openTrove memory vars; @@ -159,7 +172,9 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe _requireValidAnnualInterestRate(_annualInterestRate); _requireValidMaxFeePercentage(_maxFeePercentage, isRecoveryMode); - _requireTroveisNotActive(contractsCache.troveManager, msg.sender); + + uint256 troveId = uint256(keccak256(abi.encode(_owner, _ownerIndex))); + _requireTroveisNotActive(contractsCache.troveManager, troveId); // TODO: apply aggregate pending interest, and take snapshot of current timestamp. @@ -185,17 +200,18 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe _requireNewTCRisAboveCCR(newTCR); } - // Set the stored Trove properties + // Set the stored Trove properties and mint the NFT vars.stake = contractsCache.troveManager.setTrovePropertiesOnOpen( - msg.sender, + _owner, + troveId, _ETHAmount, vars.compositeDebt, _annualInterestRate ); - sortedTroves.insert(msg.sender, _annualInterestRate, _upperHint, _lowerHint); - vars.arrayIndex = contractsCache.troveManager.addTroveOwnerToArray(msg.sender); - emit TroveCreated(msg.sender, vars.arrayIndex); + sortedTroves.insert(troveId, _annualInterestRate, _upperHint, _lowerHint); + vars.arrayIndex = contractsCache.troveManager.addTroveIdToArray(troveId); + emit TroveCreated(_owner, troveId, vars.arrayIndex); // Pull ETH tokens from sender and move them to the Active Pool _pullETHAndSendToActivePool(contractsCache.activePool, _ETHAmount); @@ -204,60 +220,84 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe // Move the Bold gas compensation to the Gas Pool _withdrawBold(contractsCache.activePool, contractsCache.boldToken, gasPoolAddress, BOLD_GAS_COMPENSATION, BOLD_GAS_COMPENSATION); - emit TroveUpdated(msg.sender, vars.compositeDebt, _ETHAmount, vars.stake, BorrowerOperation.openTrove); - emit BoldBorrowingFeePaid(msg.sender, vars.BoldFee); + emit TroveUpdated(troveId, vars.compositeDebt, _ETHAmount, vars.stake, BorrowerOperation.openTrove); + emit BoldBorrowingFeePaid(troveId, vars.BoldFee); + + return troveId; } // Send ETH as collateral to a trove - function addColl(uint256 _ETHAmount) external override { - _adjustTrove(msg.sender, _ETHAmount, true, 0, false, 0); + function addColl(uint256 _troveId, uint256 _ETHAmount) external override { + _adjustTrove(msg.sender, _troveId, _ETHAmount, true, 0, false, 0); } // Send ETH as collateral to a trove. Called by only the Stability Pool. - function moveETHGainToTrove(address _borrower, uint256 _ETHAmount) external override { + function moveETHGainToTrove(address _sender, uint256 _troveId, uint256 _ETHAmount) external override { _requireCallerIsStabilityPool(); - _adjustTrove(_borrower, _ETHAmount, true, 0, false, 0); + // TODO: check owner? + _adjustTrove(_sender, _troveId, _ETHAmount, true, 0, false, 0); } // Withdraw ETH collateral from a trove - function withdrawColl(uint _collWithdrawal) external override { - _adjustTrove(msg.sender, _collWithdrawal, false, 0, false, 0); + function withdrawColl(uint256 _troveId, uint _collWithdrawal) external override { + _adjustTrove(msg.sender, _troveId, _collWithdrawal, false, 0, false, 0); } // Withdraw Bold tokens from a trove: mint new Bold tokens to the owner, and increase the trove's debt accordingly - function withdrawBold(uint _maxFeePercentage, uint _boldAmount ) external override { - _adjustTrove(msg.sender, 0, false, _boldAmount, true, _maxFeePercentage); + function withdrawBold(uint256 _troveId, uint _maxFeePercentage, uint _boldAmount ) external override { + _adjustTrove(msg.sender, _troveId, 0, false, _boldAmount, true, _maxFeePercentage); } // Repay Bold tokens to a Trove: Burn the repaid Bold tokens, and reduce the trove's debt accordingly - function repayBold(uint _boldAmount) external override { - _adjustTrove(msg.sender, 0, false, _boldAmount, false, 0); + function repayBold(uint256 _troveId, uint _boldAmount) external override { + _adjustTrove(msg.sender, _troveId, 0, false, _boldAmount, false, 0); } - function adjustTrove(uint _maxFeePercentage, uint _collChange, bool _isCollIncrease, uint _boldChange, bool _isDebtIncrease) external override { - _adjustTrove(msg.sender, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease, _maxFeePercentage); + function adjustTrove( + uint256 _troveId, + uint _maxFeePercentage, + uint _collChange, + bool _isCollIncrease, + uint _boldChange, + bool _isDebtIncrease + ) + external + override + { + _adjustTrove(msg.sender, _troveId, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease, _maxFeePercentage); } - function adjustTroveInterestRate(uint _newAnnualInterestRate, address _upperHint, address _lowerHint) external { + function adjustTroveInterestRate(uint256 _troveId, uint _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint) external { // TODO: Delegation functionality _requireValidAnnualInterestRate(_newAnnualInterestRate); ITroveManager troveManagerCached = troveManager; - _requireTroveisActive(troveManagerCached, msg.sender); + _requireTroveisActive(troveManagerCached, _troveId); + _requireIsOwner(_troveId); // TODO: apply individual and aggregate pending interest, and take snapshots of current timestamp. // TODO: determine how applying pending interest should interact / be sequenced with applying pending rewards from redistributions. - troveManagerCached.applyPendingRewards(msg.sender); + troveManagerCached.applyPendingRewards(_troveId); - sortedTroves.reInsert(msg.sender, _newAnnualInterestRate, _upperHint, _lowerHint); + sortedTroves.reInsert(_troveId, _newAnnualInterestRate, _upperHint, _lowerHint); - troveManagerCached.changeAnnualInterestRate(msg.sender, _newAnnualInterestRate); + troveManagerCached.changeAnnualInterestRate(_troveId, _newAnnualInterestRate); } /* * _adjustTrove(): Alongside a debt change, this function can perform either a collateral top-up or a collateral withdrawal. */ - function _adjustTrove(address _borrower, uint _collChange, bool _isCollIncrease, uint _boldChange, bool _isDebtIncrease, uint _maxFeePercentage) internal { + function _adjustTrove( + address _sender, + uint256 _troveId, + uint _collChange, + bool _isCollIncrease, + uint _boldChange, + bool _isDebtIncrease, + uint _maxFeePercentage + ) + internal + { ContractsCache memory contractsCache = ContractsCache(troveManager, activePool, boldToken); LocalVariables_adjustTrove memory vars; @@ -272,14 +312,14 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe _requireNonZeroDebtChange(_boldChange); } _requireNonZeroAdjustment(_collChange, _boldChange); - _requireTroveisActive(contractsCache.troveManager, _borrower); + _requireTroveisActive(contractsCache.troveManager, _troveId); - // Confirm the operation is either a borrower adjusting their own trove, or a pure ETH transfer from the Stability Pool to a trove - assert(msg.sender == _borrower || (msg.sender == stabilityPoolAddress && _isCollIncrease && _boldChange == 0)); + // Confirm the operation is an ETH transfer if coming from the Stability Pool to a trove + assert((msg.sender != stabilityPoolAddress || (_isCollIncrease && _boldChange == 0))); // TODO: apply individual and aggregate pending interest, and take snapshots of current timestamp. - contractsCache.troveManager.applyPendingRewards(_borrower); + contractsCache.troveManager.applyPendingRewards(_troveId); vars.netDebtChange = _boldChange; @@ -288,8 +328,8 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe // TODO: implement interest rate charges } - vars.debt = contractsCache.troveManager.getTroveDebt(_borrower); - vars.coll = contractsCache.troveManager.getTroveColl(_borrower); + vars.debt = contractsCache.troveManager.getTroveDebt(_troveId); + vars.coll = contractsCache.troveManager.getTroveColl(_troveId); // Get the trove's old ICR before the adjustment, and what its new ICR will be after the adjustment vars.oldICR = LiquityMath._computeCR(vars.coll, vars.debt, vars.price); @@ -303,20 +343,31 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe if (!_isDebtIncrease && _boldChange > 0) { _requireAtLeastMinNetDebt(_getNetDebt(vars.debt) - vars.netDebtChange); _requireValidBoldRepayment(vars.debt, vars.netDebtChange); - _requireSufficientBoldBalance(contractsCache.boldToken, _borrower, vars.netDebtChange); + _requireSufficientBoldBalance(contractsCache.boldToken, msg.sender, vars.netDebtChange); } - (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment(contractsCache.troveManager, _borrower, _collChange, _isCollIncrease, vars.netDebtChange, _isDebtIncrease); - vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_borrower); + (vars.newColl, vars.newDebt) = _updateTroveFromAdjustment( + contractsCache.troveManager, + _sender, + _troveId, + vars.coll, + _collChange, + _isCollIncrease, + vars.debt, + vars.netDebtChange, + _isDebtIncrease + ); + vars.stake = contractsCache.troveManager.updateStakeAndTotalStakes(_troveId); - emit TroveUpdated(_borrower, vars.newDebt, vars.newColl, vars.stake, BorrowerOperation.adjustTrove); - emit BoldBorrowingFeePaid(msg.sender, vars.BoldFee); + emit TroveUpdated(_troveId, vars.newDebt, vars.newColl, vars.stake, BorrowerOperation.adjustTrove); + emit BoldBorrowingFeePaid(_troveId, vars.BoldFee); // Use the unmodified _boldChange here, as we don't send the fee to the user _moveTokensAndETHfromAdjustment( contractsCache.activePool, contractsCache.boldToken, - msg.sender, + contractsCache.troveManager, + _troveId, _collChange, _isCollIncrease, _boldChange, @@ -325,31 +376,32 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe ); } - function closeTrove() external override { + function closeTrove(uint256 _troveId) external override { ITroveManager troveManagerCached = troveManager; IActivePool activePoolCached = activePool; IBoldToken boldTokenCached = boldToken; - _requireTroveisActive(troveManagerCached, msg.sender); + _requireCallerIsBorrower(troveManagerCached, _troveId); + _requireTroveisActive(troveManagerCached, _troveId); uint price = priceFeed.fetchPrice(); _requireNotInRecoveryMode(price); // TODO: apply individual and aggregate pending interest, and take snapshots of current timestamp. - troveManagerCached.applyPendingRewards(msg.sender); + troveManagerCached.applyPendingRewards(_troveId); - uint coll = troveManagerCached.getTroveColl(msg.sender); - uint debt = troveManagerCached.getTroveDebt(msg.sender); + uint coll = troveManagerCached.getTroveColl(_troveId); + uint debt = troveManagerCached.getTroveDebt(_troveId); _requireSufficientBoldBalance(boldTokenCached, msg.sender, debt - BOLD_GAS_COMPENSATION); uint newTCR = _getNewTCRFromTroveChange(coll, false, debt, false, price); _requireNewTCRisAboveCCR(newTCR); - troveManagerCached.removeStake(msg.sender); - troveManagerCached.closeTrove(msg.sender); + troveManagerCached.removeStake(_troveId); + troveManagerCached.closeTrove(_troveId); - emit TroveUpdated(msg.sender, 0, 0, 0, BorrowerOperation.closeTrove); + emit TroveUpdated(_troveId, 0, 0, 0, BorrowerOperation.closeTrove); // Burn the repaid Bold from the user's balance and the gas compensation from the Gas Pool _repayBold(activePoolCached, boldTokenCached, msg.sender, debt - BOLD_GAS_COMPENSATION); @@ -359,12 +411,22 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe activePoolCached.sendETH(msg.sender, coll); } + function setAddManager(uint256 _troveId, address _manager) external { + troveManager.setAddManager(msg.sender, _troveId, _manager); + } + + function setRemoveManager(uint256 _troveId, address _manager) external { + troveManager.setRemoveManager(msg.sender, _troveId, _manager); + } + /** * Claim remaining collateral from a redemption or from a liquidation with ICR > MCR in Recovery Mode */ - function claimCollateral() external override { + function claimCollateral(uint256 _troveId) external override { + _requireIsOwner(_troveId); + // send ETH from CollSurplus Pool to owner - collSurplusPool.claimColl(msg.sender); + collSurplusPool.claimColl(msg.sender, _troveId); } // --- Helper functions --- @@ -379,19 +441,35 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe function _updateTroveFromAdjustment ( ITroveManager _troveManager, - address _borrower, + address _sender, + uint256 _troveId, + uint256 _coll, uint _collChange, bool _isCollIncrease, + uint256 _debt, uint _debtChange, bool _isDebtIncrease ) internal returns (uint, uint) { - uint newColl = (_isCollIncrease) ? _troveManager.increaseTroveColl(_borrower, _collChange) - : _troveManager.decreaseTroveColl(_borrower, _collChange); - uint newDebt = (_isDebtIncrease) ? _troveManager.increaseTroveDebt(_borrower, _debtChange) - : _troveManager.decreaseTroveDebt(_borrower, _debtChange); + uint256 newColl; + uint256 newDebt; + + if (_collChange > 0) { + newColl = (_isCollIncrease) ? + _troveManager.increaseTroveColl(_sender, _troveId, _collChange) : + _troveManager.decreaseTroveColl(_sender, _troveId, _collChange); + } else { + newColl = _coll; + } + if (_debtChange > 0) { + newDebt = (_isDebtIncrease) ? + _troveManager.increaseTroveDebt(_sender, _troveId, _debtChange) : + _troveManager.decreaseTroveDebt(_sender, _troveId, _debtChange); + } else { + newDebt = _debt; + } return (newColl, newDebt); } @@ -400,7 +478,8 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe ( IActivePool _activePool, IBoldToken _boldToken, - address _borrower, + ITroveManager _troveManager, + uint256 _troveId, uint _collChange, bool _isCollIncrease, uint _boldChange, @@ -410,17 +489,19 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe internal { if (_isDebtIncrease) { - _withdrawBold(_activePool, _boldToken, _borrower, _boldChange, _netDebtChange); + address borrower = _troveManager.ownerOf(_troveId); + _withdrawBold(_activePool, _boldToken, borrower, _boldChange, _netDebtChange); } else { - _repayBold(_activePool, _boldToken, _borrower, _boldChange); + _repayBold(_activePool, _boldToken, msg.sender, _boldChange); } if (_isCollIncrease) { // Pull ETH tokens from sender and move them to the Active Pool _pullETHAndSendToActivePool(_activePool, _collChange); } else { + address borrower = _troveManager.ownerOf(_troveId); // Pull ETH from Active Pool and decrease its recorded ETH balance - _activePool.sendETH(_borrower, _collChange); + _activePool.sendETH(borrower, _collChange); } } @@ -445,21 +526,25 @@ contract BorrowerOperations is LiquityBase, Ownable, CheckContract, IBorrowerOpe // --- 'Require' wrapper functions --- - function _requireCallerIsBorrower(address _borrower) internal view { - require(msg.sender == _borrower, "BorrowerOps: Caller must be the borrower for a withdrawal"); + function _requireCallerIsBorrower(ITroveManager _troveManager , uint256 _troveId) internal view { + require(msg.sender == _troveManager.ownerOf(_troveId), "BorrowerOps: Caller must be the borrower for a withdrawal"); } function _requireNonZeroAdjustment(uint _collChange, uint _boldChange) internal pure { require(_collChange != 0 || _boldChange != 0, "BorrowerOps: There must be either a collateral change or a debt change"); } - function _requireTroveisActive(ITroveManager _troveManager, address _borrower) internal view { - uint status = _troveManager.getTroveStatus(_borrower); + function _requireIsOwner(uint256 _troveId) internal view { + require(troveManager.ownerOf(_troveId) == msg.sender, "BO: Only owner"); + } + + function _requireTroveisActive(ITroveManager _troveManager, uint256 _troveId) internal view { + uint status = _troveManager.getTroveStatus(_troveId); require(status == 1, "BorrowerOps: Trove does not exist or is closed"); } - function _requireTroveisNotActive(ITroveManager _troveManager, address _borrower) internal view { - uint status = _troveManager.getTroveStatus(_borrower); + function _requireTroveisNotActive(ITroveManager _troveManager, uint256 _troveId) internal view { + uint status = _troveManager.getTroveStatus(_troveId); require(status != 1, "BorrowerOps: Trove is active"); } diff --git a/contracts/src/CollSurplusPool.sol b/contracts/src/CollSurplusPool.sol index edf64e93..c277e4d4 100644 --- a/contracts/src/CollSurplusPool.sol +++ b/contracts/src/CollSurplusPool.sol @@ -22,7 +22,7 @@ contract CollSurplusPool is Ownable, CheckContract, ICollSurplusPool { // deposited ether tracker uint256 internal ETHBalance; // Collateral surplus claimable by trove owners - mapping (address => uint) internal balances; + mapping (uint256 => uint) internal balances; // --- Events --- @@ -30,7 +30,7 @@ contract CollSurplusPool is Ownable, CheckContract, ICollSurplusPool { event TroveManagerAddressChanged(address _newTroveManagerAddress); event ActivePoolAddressChanged(address _newActivePoolAddress); - event CollBalanceUpdated(address indexed _account, uint _newBalance); + event CollBalanceUpdated(uint256 indexed _troveId, uint _newBalance); event EtherSent(address _to, uint _amount); constructor(address _ETHAddress) { @@ -70,29 +70,29 @@ contract CollSurplusPool is Ownable, CheckContract, ICollSurplusPool { return ETHBalance; } - function getCollateral(address _account) external view override returns (uint) { - return balances[_account]; + function getCollateral(uint256 _troveId) external view override returns (uint) { + return balances[_troveId]; } // --- Pool functionality --- - function accountSurplus(address _account, uint _amount) external override { + function accountSurplus(uint256 _troveId, uint _amount) external override { _requireCallerIsTroveManager(); - uint newAmount = balances[_account] + _amount; - balances[_account] = newAmount; + uint newAmount = balances[_troveId] + _amount; + balances[_troveId] = newAmount; ETHBalance = ETHBalance + _amount; - emit CollBalanceUpdated(_account, newAmount); + emit CollBalanceUpdated(_troveId, newAmount); } - function claimColl(address _account) external override { + function claimColl(address _account, uint256 _troveId) external override { _requireCallerIsBorrowerOperations(); - uint claimableColl = balances[_account]; + uint claimableColl = balances[_troveId]; require(claimableColl > 0, "CollSurplusPool: No collateral available to claim"); - balances[_account] = 0; - emit CollBalanceUpdated(_account, 0); + balances[_troveId] = 0; + emit CollBalanceUpdated(_troveId, 0); ETHBalance = ETHBalance - claimableColl; emit EtherSent(_account, claimableColl); diff --git a/contracts/src/Dependencies/LiquityMath.sol b/contracts/src/Dependencies/LiquityMath.sol index 69adf777..d53bc451 100644 --- a/contracts/src/Dependencies/LiquityMath.sol +++ b/contracts/src/Dependencies/LiquityMath.sol @@ -6,17 +6,6 @@ pragma solidity 0.8.18; library LiquityMath { uint internal constant DECIMAL_PRECISION = 1e18; - /* Precision for Nominal ICR (independent of price). Rationale for the value: - * - * - Making it “too high” could lead to overflows. - * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. - * - * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39 ETH, - * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator. - * - */ - uint internal constant NICR_PRECISION = 1e20; - function _min(uint _a, uint _b) internal pure returns (uint) { return (_a < _b) ? _a : _b; } @@ -85,16 +74,6 @@ library LiquityMath { return (_a >= _b) ? _a - _b : _b - _a; } - function _computeNominalCR(uint _coll, uint _debt) internal pure returns (uint) { - if (_debt > 0) { - return _coll * NICR_PRECISION / _debt; - } - // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. - else { // if (_debt == 0) - return 2**256 - 1; - } - } - function _computeCR(uint _coll, uint _debt, uint _price) internal pure returns (uint) { if (_debt > 0) { uint newCollRatio = _coll * _price / _debt; diff --git a/contracts/src/HintHelpers.sol b/contracts/src/HintHelpers.sol index 7549d55c..16bd80cb 100644 --- a/contracts/src/HintHelpers.sol +++ b/contracts/src/HintHelpers.sol @@ -8,6 +8,7 @@ import "./Dependencies/LiquityBase.sol"; import "./Dependencies/Ownable.sol"; import "./Dependencies/CheckContract.sol"; + contract HintHelpers is LiquityBase, Ownable, CheckContract { string constant public NAME = "HintHelpers"; @@ -42,103 +43,28 @@ contract HintHelpers is LiquityBase, Ownable, CheckContract { // --- Functions --- - /* getRedemptionHints() - Helper function for finding the right hints to pass to redeemCollateral(). - * - * It simulates a redemption of `_boldamount` to figure out where the redemption sequence will start and what state the final Trove - * of the sequence will end up in. - * - * Returns three hints: - * - `firstRedemptionHint` is the address of the first Trove with ICR >= MCR (i.e. the first Trove that will be redeemed). - * - `partialRedemptionHintNICR` is the final nominal ICR of the last Trove of the sequence after being hit by partial redemption, - * or zero in case of no partial redemption. - * - `truncatedBoldamount` is the maximum amount that can be redeemed out of the the provided `_boldamount`. This can be lower than - * `_boldamount` when redeeming the full amount would leave the last Trove of the redemption sequence with less net debt than the - * minimum allowed value (i.e. MIN_NET_DEBT). - * - * The number of Troves to consider for redemption can be capped by passing a non-zero value as `_maxIterations`, while passing zero - * will leave it uncapped. - */ - - function getRedemptionHints( - uint _boldamount, - uint _price, - uint _maxIterations - ) - external - view - returns ( - address firstRedemptionHint, - uint partialRedemptionHintNICR, - uint truncatedBoldamount - ) - { - ISortedTroves sortedTrovesCached = sortedTroves; - - uint remainingBold = _boldamount; - address currentTroveuser = sortedTrovesCached.getLast(); - - while (currentTroveuser != address(0) && troveManager.getCurrentICR(currentTroveuser, _price) < MCR) { - currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser); - } - - firstRedemptionHint = currentTroveuser; - - if (_maxIterations == 0) { - _maxIterations = type(uint256).max; - } - - while (currentTroveuser != address(0) && remainingBold > 0 && _maxIterations-- > 0) { - uint netBoldDebt = _getNetDebt(troveManager.getTroveDebt(currentTroveuser)) - + troveManager.getPendingBoldDebtReward(currentTroveuser); - - if (netBoldDebt > remainingBold) { - if (netBoldDebt > MIN_NET_DEBT) { - uint maxRedeemableBold = LiquityMath._min(remainingBold, netBoldDebt - MIN_NET_DEBT); - - uint ETH = troveManager.getTroveColl(currentTroveuser) - + troveManager.getPendingETHReward(currentTroveuser); - - uint newColl = ETH - maxRedeemableBold * DECIMAL_PRECISION / _price; - uint newDebt = netBoldDebt - maxRedeemableBold; - - uint compositeDebt = _getCompositeDebt(newDebt); - partialRedemptionHintNICR = LiquityMath._computeNominalCR(newColl, compositeDebt); - - remainingBold = remainingBold - maxRedeemableBold; - } - break; - } else { - remainingBold = remainingBold - netBoldDebt; - } - - currentTroveuser = sortedTrovesCached.getPrev(currentTroveuser); - } - - truncatedBoldamount = _boldamount - remainingBold; - } - - /* getApproxHint() - return address of a Trove that is, on average, (length / numTrials) positions away in the + /* getApproxHint() - return id of a Trove that is, on average, (length / numTrials) positions away in the sortedTroves list from the correct insert position of the Trove to be inserted. - Note: The output address is worst-case O(n) positions away from the correct insert position, however, the function + Note: The output id is worst-case O(n) positions away from the correct insert position, however, the function is probabilistic. Input can be tuned to guarantee results to a high degree of confidence, e.g: - Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput address will + Submitting numTrials = k * sqrt(length), with k = 15 makes it very, very likely that the ouput id will be <= sqrt(length) positions away from the correct insert position. */ - function getApproxHint(uint _CR, uint _numTrials, uint _inputRandomSeed) + function getApproxHint(uint _interestRate, uint _numTrials, uint _inputRandomSeed) external view - returns (address hintAddress, uint diff, uint latestRandomSeed) + returns (uint256 hintId, uint diff, uint latestRandomSeed) { - uint arrayLength = troveManager.getTroveOwnersCount(); + uint arrayLength = troveManager.getTroveIdsCount(); if (arrayLength == 0) { - return (address(0), 0, _inputRandomSeed); + return (0, 0, _inputRandomSeed); } - hintAddress = sortedTroves.getLast(); - diff = LiquityMath._getAbsoluteDifference(_CR, troveManager.getNominalICR(hintAddress)); + hintId = sortedTroves.getLast(); + diff = LiquityMath._getAbsoluteDifference(_interestRate, troveManager.getTroveAnnualInterestRate(hintId)); latestRandomSeed = _inputRandomSeed; uint i = 1; @@ -147,25 +73,17 @@ contract HintHelpers is LiquityBase, Ownable, CheckContract { latestRandomSeed = uint(keccak256(abi.encodePacked(latestRandomSeed))); uint arrayIndex = latestRandomSeed % arrayLength; - address currentAddress = troveManager.getTroveFromTroveOwnersArray(arrayIndex); - uint currentNICR = troveManager.getNominalICR(currentAddress); + uint256 currentId = troveManager.getTroveFromTroveIdsArray(arrayIndex); + uint currentInterestRate = troveManager.getTroveAnnualInterestRate(currentId); - // check if abs(current - CR) > abs(closest - CR), and update closest if current is closer - uint currentDiff = LiquityMath._getAbsoluteDifference(currentNICR, _CR); + // check if abs(current - IR) > abs(closest - IR), and update closest if current is closer + uint currentDiff = LiquityMath._getAbsoluteDifference(currentInterestRate, _interestRate); if (currentDiff < diff) { diff = currentDiff; - hintAddress = currentAddress; + hintId = currentId; } i++; } } - - function computeNominalCR(uint _coll, uint _debt) external pure returns (uint) { - return LiquityMath._computeNominalCR(_coll, _debt); - } - - function computeCR(uint _coll, uint _debt, uint _price) external pure returns (uint) { - return LiquityMath._computeCR(_coll, _debt, _price); - } } diff --git a/contracts/src/Interfaces/IBorrowerOperations.sol b/contracts/src/Interfaces/IBorrowerOperations.sol index 07cb35ed..08cd4448 100644 --- a/contracts/src/Interfaces/IBorrowerOperations.sol +++ b/contracts/src/Interfaces/IBorrowerOperations.sol @@ -24,25 +24,30 @@ interface IBorrowerOperations is ILiquityBase { address _boldTokenAddress ) external; - function openTrove(uint _maxFee, uint256 _ETHAmount, uint _boldAmount, address _upperHint, address _lowerHint, uint256 _annualInterestRate) external; + function openTrove(address _owner, uint256 _ownerIndex, uint _maxFee, uint256 _ETHAmount, uint _boldAmount, uint256 _upperHint, uint256 _lowerHint, uint256 _annualInterestRate) external returns (uint256); - function addColl(uint256 _ETHAmount) external; + function addColl(uint256 _troveId, uint256 _ETHAmount) external; - function moveETHGainToTrove(address _user, uint256 _ETHAmount) external; + function moveETHGainToTrove(address _sender, uint256 _troveId, uint256 _ETHAmount) external; - function withdrawColl(uint _amount) external; + function withdrawColl(uint256 _troveId, uint _amount) external; - function withdrawBold(uint _maxFee, uint _amount) external; + function withdrawBold(uint256 _troveId, uint _maxFee, uint _amount) external; - function repayBold(uint _amount) external; + function repayBold(uint256 _troveId, uint _amount) external; - function closeTrove() external; + function closeTrove(uint256 _troveId) external; - function adjustTrove(uint _maxFee, uint _collChange, bool _isCollIncrease, uint _debtChange, bool isDebtIncrease) external; + function adjustTrove(uint256 _troveId, uint _maxFee, uint _collChange, bool _isCollIncrease, uint _debtChange, bool isDebtIncrease) external; - function claimCollateral() external; + function claimCollateral(uint256 _troveId) external; + + function setAddManager(uint256 _troveId, address _manager) external; + function setRemoveManager(uint256 _troveId, address _manager) external; + + // TODO: addRepayWhitelistedAddress?(see github issue #64) function getCompositeDebt(uint _debt) external pure returns (uint); - function adjustTroveInterestRate(uint _newAnnualInterestRate, address _upperHint, address _lowerHint) external; + function adjustTroveInterestRate(uint256 _troveId, uint _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint) external; } diff --git a/contracts/src/Interfaces/ICollSurplusPool.sol b/contracts/src/Interfaces/ICollSurplusPool.sol index 2fb951c4..6e8dd02e 100644 --- a/contracts/src/Interfaces/ICollSurplusPool.sol +++ b/contracts/src/Interfaces/ICollSurplusPool.sol @@ -12,9 +12,9 @@ interface ICollSurplusPool { function getETHBalance() external view returns (uint); - function getCollateral(address _account) external view returns (uint); + function getCollateral(uint256 _troveId) external view returns (uint); - function accountSurplus(address _account, uint _amount) external; + function accountSurplus(uint256 _troveId, uint _amount) external; - function claimColl(address _account) external; + function claimColl(address _account, uint256 _troveId) external; } diff --git a/contracts/src/Interfaces/ISortedTroves.sol b/contracts/src/Interfaces/ISortedTroves.sol index 9cfaf1d3..f56f4be6 100644 --- a/contracts/src/Interfaces/ISortedTroves.sol +++ b/contracts/src/Interfaces/ISortedTroves.sol @@ -4,6 +4,11 @@ pragma solidity 0.8.18; import "./ITroveManager.sol"; +// TODO +//type Id is uint256; +//type Value is uint256; + + // Common interface for the SortedTroves Doubly Linked List. interface ISortedTroves { function borrowerOperationsAddress() external view returns (address); @@ -11,13 +16,13 @@ interface ISortedTroves { function setParams(uint256 _size, address _TroveManagerAddress, address _borrowerOperationsAddress) external; - function insert(address _id, uint256 _ICR, address _prevId, address _nextId) external; + function insert(uint256 _id, uint256 _value, uint256 _prevId, uint256 _nextId) external; - function remove(address _id) external; + function remove(uint256 _id) external; - function reInsert(address _id, uint256 _newICR, address _prevId, address _nextId) external; + function reInsert(uint256 _id, uint256 _newValue, uint256 _prevId, uint256 _nextId) external; - function contains(address _id) external view returns (bool); + function contains(uint256 _id) external view returns (bool); function isFull() external view returns (bool); @@ -27,15 +32,15 @@ interface ISortedTroves { function getMaxSize() external view returns (uint256); - function getFirst() external view returns (address); + function getFirst() external view returns (uint256); - function getLast() external view returns (address); + function getLast() external view returns (uint256); - function getNext(address _id) external view returns (address); + function getNext(uint256 _id) external view returns (uint256); - function getPrev(address _id) external view returns (address); + function getPrev(uint256 _id) external view returns (uint256); - function validInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (bool); + function validInsertPosition(uint256 _value, uint256 _prevId, uint256 _nextId) external view returns (bool); - function findInsertPosition(uint256 _ICR, address _prevId, address _nextId) external view returns (address, address); + function findInsertPosition(uint256 _value, uint256 _prevId, uint256 _nextId) external view returns (uint256, uint256); } diff --git a/contracts/src/Interfaces/IStabilityPool.sol b/contracts/src/Interfaces/IStabilityPool.sol index 2a2a2f10..532138bb 100644 --- a/contracts/src/Interfaces/IStabilityPool.sol +++ b/contracts/src/Interfaces/IStabilityPool.sol @@ -54,7 +54,7 @@ interface IStabilityPool is ILiquityBase { */ function provideToSP(uint _amount) external; - + /* withdrawFromSP(): * - Calculates depositor's ETH gain * - Calculates the compounded deposit @@ -69,7 +69,7 @@ interface IStabilityPool is ILiquityBase { * - Leaves their compounded deposit in the Stability Pool * - Takes new snapshots of accumulators P and S */ - function withdrawETHGainToTrove() external; + function withdrawETHGainToTrove(uint256 _troveId) external; /* * Initial checks: diff --git a/contracts/src/Interfaces/ITroveManager.sol b/contracts/src/Interfaces/ITroveManager.sol index 7469e5d9..871406e2 100644 --- a/contracts/src/Interfaces/ITroveManager.sol +++ b/contracts/src/Interfaces/ITroveManager.sol @@ -2,13 +2,15 @@ pragma solidity 0.8.18; +import "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol"; + import "./ILiquityBase.sol"; import "./IStabilityPool.sol"; import "./IBoldToken.sol"; import "./ISortedTroves.sol"; // Common interface for the Trove Manager. -interface ITroveManager is ILiquityBase { +interface ITroveManager is IERC721, ILiquityBase { function setAddresses( address _borrowerOperationsAddress, address _activePoolAddress, @@ -28,78 +30,81 @@ interface ITroveManager is ILiquityBase { function BOOTSTRAP_PERIOD() external view returns (uint256); - function getTroveOwnersCount() external view returns (uint); + function getTroveIdsCount() external view returns (uint); - function getTroveFromTroveOwnersArray(uint _index) external view returns (address); + function getTroveFromTroveIdsArray(uint _index) external view returns (uint256); - function getNominalICR(address _borrower) external view returns (uint); - function getCurrentICR(address _borrower, uint _price) external view returns (uint); + function getCurrentICR(uint256 _troveId, uint _price) external view returns (uint); - function liquidate(address _borrower) external; + function liquidate(uint256 _troveId) external; - function batchLiquidateTroves(address[] calldata _troveArray) external; + function batchLiquidateTroves(uint256[] calldata _troveArray) external; function redeemCollateral( uint _boldAmount, - address _firstRedemptionHint, - address _upperPartialRedemptionHint, - address _lowerPartialRedemptionHint, - uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFee - ) external; + ) external; - function updateStakeAndTotalStakes(address _borrower) external returns (uint); + function updateStakeAndTotalStakes(uint256 _troveId) external returns (uint); - function addTroveOwnerToArray(address _borrower) external returns (uint index); + function addTroveIdToArray(uint256 _troveId) external returns (uint index); - function applyPendingRewards(address _borrower) external; + function applyPendingRewards(uint256 _troveId) external; - function getPendingETHReward(address _borrower) external view returns (uint); + function getPendingETHReward(uint256 _troveId) external view returns (uint); - function getPendingBoldDebtReward(address _borrower) external view returns (uint); + function getPendingBoldDebtReward(uint256 _troveId) external view returns (uint); - function hasPendingRewards(address _borrower) external view returns (bool); + function hasPendingRewards(uint256 _troveId) external view returns (bool); - function getEntireDebtAndColl(address _borrower) external view returns ( + function getEntireDebtAndColl(uint256 _troveId) external view returns ( uint debt, uint coll, uint pendingBoldDebtReward, uint pendingETHReward ); - function closeTrove(address _borrower) external; + function closeTrove(uint256 _troveId) external; - function removeStake(address _borrower) external; + function removeStake(uint256 _troveId) external; function getRedemptionRate() external view returns (uint); function getRedemptionRateWithDecay() external view returns (uint); function getRedemptionFeeWithDecay(uint _ETHDrawn) external view returns (uint); - function getTroveStatus(address _borrower) external view returns (uint); + function getTroveStatus(uint256 _troveId) external view returns (uint); - function getTroveStake(address _borrower) external view returns (uint); + function getTroveStake(uint256 _troveId) external view returns (uint); + + function getTroveDebt(uint256 _troveId) external view returns (uint); - function getTroveDebt(address _borrower) external view returns (uint); + function getTroveColl(uint256 _troveId) external view returns (uint); - function getTroveColl(address _borrower) external view returns (uint); + function getTroveAnnualInterestRate(uint256 _troveId) external view returns (uint); - function getTroveAnnualInterestRate(address _borrower) external view returns (uint); + function TroveAddManagers(uint256 _troveId) external view returns (address); + function TroveRemoveManagers(uint256 _troveId) external view returns (address); - function setTrovePropertiesOnOpen(address _borrower, uint256 _coll, uint256 _debt, uint256 _annualInterestRate) external returns (uint256); + function setTrovePropertiesOnOpen(address _owner, uint256 _troveId, uint256 _coll, uint256 _debt, uint256 _annualInterestRate) external returns (uint256); - function increaseTroveColl(address _borrower, uint _collIncrease) external returns (uint); + function increaseTroveColl(address _sender, uint256 _troveId, uint _collIncrease) external returns (uint); - function decreaseTroveColl(address _borrower, uint _collDecrease) external returns (uint); + function decreaseTroveColl(address _sender, uint256 _troveId, uint _collDecrease) external returns (uint); - function increaseTroveDebt(address _borrower, uint _debtIncrease) external returns (uint); + function increaseTroveDebt(address _sender, uint256 _troveId, uint _debtIncrease) external returns (uint); - function decreaseTroveDebt(address _borrower, uint _collDecrease) external returns (uint); + function decreaseTroveDebt(address _sender, uint256 _troveId, uint _collDecrease) external returns (uint); - function changeAnnualInterestRate(address _borrower, uint256 _newAnnualInterestRate) external; + function changeAnnualInterestRate(uint256 _troveId, uint256 _newAnnualInterestRate) external; + + function setAddManager(address _sender, uint256 _troveId, address _manager) external; + function setRemoveManager(address _sender, uint256 _troveId, address _manager) external; function getTCR(uint _price) external view returns (uint); function checkRecoveryMode(uint _price) external view returns (bool); + + function checkTroveIsActive(uint256 _troveId) external view returns (bool); } diff --git a/contracts/src/MultiTroveGetter.sol b/contracts/src/MultiTroveGetter.sol index 61bd9b8e..efa88b0c 100644 --- a/contracts/src/MultiTroveGetter.sol +++ b/contracts/src/MultiTroveGetter.sol @@ -9,7 +9,7 @@ import "./SortedTroves.sol"; /* Helper contract for grabbing Trove data for the front end. Not part of the core Liquity system. */ contract MultiTroveGetter { struct CombinedTroveData { - address owner; + uint256 id; uint debt; uint coll; @@ -63,16 +63,16 @@ contract MultiTroveGetter { function _getMultipleSortedTrovesFromHead(uint _startIdx, uint _count) internal view returns (CombinedTroveData[] memory _troves) { - address currentTroveowner = sortedTroves.getFirst(); + uint256 currentTroveId = sortedTroves.getFirst(); for (uint idx = 0; idx < _startIdx; ++idx) { - currentTroveowner = sortedTroves.getNext(currentTroveowner); + currentTroveId = sortedTroves.getNext(currentTroveId); } _troves = new CombinedTroveData[](_count); for (uint idx = 0; idx < _count; ++idx) { - _troves[idx].owner = currentTroveowner; + _troves[idx].id = currentTroveId; ( _troves[idx].debt, _troves[idx].coll, @@ -80,29 +80,29 @@ contract MultiTroveGetter { /* status */, /* arrayIndex */, /* annualInterestRate */ - ) = troveManager.Troves(currentTroveowner); + ) = troveManager.Troves(currentTroveId); ( _troves[idx].snapshotETH, _troves[idx].snapshotBoldDebt - ) = troveManager.rewardSnapshots(currentTroveowner); + ) = troveManager.rewardSnapshots(currentTroveId); - currentTroveowner = sortedTroves.getNext(currentTroveowner); + currentTroveId = sortedTroves.getNext(currentTroveId); } } function _getMultipleSortedTrovesFromTail(uint _startIdx, uint _count) internal view returns (CombinedTroveData[] memory _troves) { - address currentTroveowner = sortedTroves.getLast(); + uint256 currentTroveId = sortedTroves.getLast(); for (uint idx = 0; idx < _startIdx; ++idx) { - currentTroveowner = sortedTroves.getPrev(currentTroveowner); + currentTroveId = sortedTroves.getPrev(currentTroveId); } _troves = new CombinedTroveData[](_count); for (uint idx = 0; idx < _count; ++idx) { - _troves[idx].owner = currentTroveowner; + _troves[idx].id = currentTroveId; ( _troves[idx].debt, _troves[idx].coll, @@ -110,13 +110,13 @@ contract MultiTroveGetter { /* status */, /* arrayIndex */, /* annualInterestRate */ - ) = troveManager.Troves(currentTroveowner); + ) = troveManager.Troves(currentTroveId); ( _troves[idx].snapshotETH, _troves[idx].snapshotBoldDebt - ) = troveManager.rewardSnapshots(currentTroveowner); + ) = troveManager.rewardSnapshots(currentTroveId); - currentTroveowner = sortedTroves.getPrev(currentTroveowner); + currentTroveId = sortedTroves.getPrev(currentTroveId); } } } diff --git a/contracts/src/SortedTroves.sol b/contracts/src/SortedTroves.sol index f87ada42..eb9a9901 100644 --- a/contracts/src/SortedTroves.sol +++ b/contracts/src/SortedTroves.sol @@ -37,8 +37,8 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { event TroveManagerAddressChanged(address _troveManagerAddress); event BorrowerOperationsAddressChanged(address _borrowerOperationsAddress); - event NodeAdded(address _id, uint _annualInterestRate); - event NodeRemoved(address _id); + event NodeAdded(uint256 _id, uint _annualInterestRate); + event NodeRemoved(uint256 _id); address public borrowerOperationsAddress; @@ -47,17 +47,17 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { // Information for a node in the list struct Node { bool exists; - address nextId; // Id of next node (smaller interest rate) in the list - address prevId; // Id of previous node (larger interest rate) in the list + uint256 nextId; // Id of next node (smaller interest rate) in the list + uint256 prevId; // Id of previous node (larger interest rate) in the list } // Information for the list struct Data { - address head; // Head of the list. Also the node in the list with the largest interest rate - address tail; // Tail of the list. Also the node in the list with the smallest interest rate + uint256 head; // Head of the list. Also the node in the list with the largest interest rate + uint256 tail; // Tail of the list. Also the node in the list with the smallest interest rate uint256 maxSize; // Maximum size of the list uint256 size; // Current size of the list - mapping (address => Node) nodes; // Track the corresponding ids for each node in the list + mapping (uint256 => Node) nodes; // Track the corresponding ids for each node in the list } Data public data; @@ -88,23 +88,23 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _nextId Id of next node for the insert position */ - function insert (address _id, uint256 _annualInterestRate, address _prevId, address _nextId) external override { + function insert (uint256 _id, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external override { ITroveManager troveManagerCached = troveManager; _requireCallerIsBOorTroveM(troveManagerCached); _insert(troveManagerCached, _id, _annualInterestRate, _prevId, _nextId); } - function _insert(ITroveManager _troveManager, address _id, uint256 _annualInterestRate, address _prevId, address _nextId) internal { + function _insert(ITroveManager _troveManager, uint256 _id, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) internal { // List must not be full require(!isFull(), "SortedTroves: List is full"); // List must not already contain node require(!contains(_id), "SortedTroves: List already contains the node"); // Node id must not be null - require(_id != address(0), "SortedTroves: Id cannot be zero"); + require(_id != 0, "SortedTroves: Id cannot be zero"); - address prevId = _prevId; - address nextId = _nextId; + uint256 prevId = _prevId; + uint256 nextId = _nextId; if (!_validInsertPosition(_troveManager, _annualInterestRate, prevId, nextId)) { // Sender's hint was not a valid insert position @@ -114,16 +114,16 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { data.nodes[_id].exists = true; - if (prevId == address(0) && nextId == address(0)) { + if (prevId == 0 && nextId == 0) { // Insert as head and tail data.head = _id; data.tail = _id; - } else if (prevId == address(0)) { + } else if (prevId == 0) { // Insert before `prevId` as the head data.nodes[_id].nextId = data.head; data.nodes[data.head].prevId = _id; data.head = _id; - } else if (nextId == address(0)) { + } else if (nextId == 0) { // Insert after `nextId` as the tail data.nodes[_id].prevId = data.tail; data.nodes[data.tail].nextId = _id; @@ -140,7 +140,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { emit NodeAdded(_id, _annualInterestRate); } - function remove(address _id) external override { + function remove(uint256 _id) external override { _requireCallerIsTroveManager(); _remove(_id); } @@ -149,7 +149,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @dev Remove a node from the list * @param _id Node's id */ - function _remove(address _id) internal { + function _remove(uint256 _id) internal { // List must contain the node require(contains(_id), "SortedTroves: List does not contain the id"); @@ -160,13 +160,13 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { // Set head to next node data.head = data.nodes[_id].nextId; // Set prev pointer of new head to null - data.nodes[data.head].prevId = address(0); + data.nodes[data.head].prevId = 0; } else if (_id == data.tail) { // The removed node is the tail // Set tail to previous node data.tail = data.nodes[_id].prevId; // Set next pointer of new tail to null - data.nodes[data.tail].nextId = address(0); + data.nodes[data.tail].nextId = 0; } else { // The removed node is neither the head nor the tail // Set next pointer of previous node to the next node @@ -177,8 +177,8 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { } else { // List contains a single node // Set the head and tail to null - data.head = address(0); - data.tail = address(0); + data.head = 0; + data.tail = 0; } delete data.nodes[_id]; @@ -193,7 +193,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _prevId Id of previous node for the new insert position * @param _nextId Id of next node for the new insert position */ - function reInsert(address _id, uint256 _newAnnualInterestRate, address _prevId, address _nextId) external override { + function reInsert(uint256 _id, uint256 _newAnnualInterestRate, uint256 _prevId, uint256 _nextId) external override { ITroveManager troveManagerCached = troveManager; _requireCallerIsBOorTroveM(troveManagerCached); @@ -209,7 +209,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { /* * @dev Checks if the list contains a node */ - function contains(address _id) public view override returns (bool) { + function contains(uint256 _id) public view override returns (bool) { return data.nodes[_id].exists; } @@ -244,14 +244,14 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { /* * @dev Returns the first node in the list (node with the largest annual interest rate) */ - function getFirst() external view override returns (address) { + function getFirst() external view override returns (uint256) { return data.head; } /* * @dev Returns the last node in the list (node with the smallest annual interest rate) */ - function getLast() external view override returns (address) { + function getLast() external view override returns (uint256) { return data.tail; } @@ -259,7 +259,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @dev Returns the next node (with a smaller interest rate) in the list for a given node * @param _id Node's id */ - function getNext(address _id) external view override returns (address) { + function getNext(uint256 _id) external view override returns (uint256) { return data.nodes[_id].nextId; } @@ -267,7 +267,7 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @dev Returns the previous node (with a larger interest rate) in the list for a given node * @param _id Node's id */ - function getPrev(address _id) external view override returns (address) { + function getPrev(uint256 _id) external view override returns (uint256) { return data.nodes[_id].prevId; } @@ -277,18 +277,18 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _prevId Id of previous node for the insert position * @param _nextId Id of next node for the insert position */ - function validInsertPosition(uint256 _annualInterestRate, address _prevId, address _nextId) external view override returns (bool) { + function validInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view override returns (bool) { return _validInsertPosition(troveManager, _annualInterestRate, _prevId, _nextId); } - function _validInsertPosition(ITroveManager _troveManager, uint256 _annualInterestRate, address _prevId, address _nextId) internal view returns (bool) { - if (_prevId == address(0) && _nextId == address(0)) { + function _validInsertPosition(ITroveManager _troveManager, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) internal view returns (bool) { + if (_prevId == 0 && _nextId == 0) { // `(null, null)` is a valid insert position if the list is empty return isEmpty(); - } else if (_prevId == address(0)) { + } else if (_prevId == 0) { // `(null, _nextId)` is a valid insert position if `_nextId` is the head of the list return data.head == _nextId && _annualInterestRate >= _troveManager.getTroveAnnualInterestRate(_nextId); - } else if (_nextId == address(0)) { + } else if (_nextId == 0) { // `(_prevId, null)` is a valid insert position if `_prevId` is the tail of the list return data.tail == _prevId && _annualInterestRate <= _troveManager.getTroveAnnualInterestRate(_prevId); } else { @@ -305,17 +305,17 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _annualInterestRate Node's annual interest rate * @param _startId Id of node to start descending the list from */ - function _descendList(ITroveManager _troveManager, uint256 _annualInterestRate, address _startId) internal view returns (address, address) { + function _descendList(ITroveManager _troveManager, uint256 _annualInterestRate, uint256 _startId) internal view returns (uint256, uint256) { // If `_startId` is the head, check if the insert position is before the head if (data.head == _startId && _annualInterestRate >= _troveManager.getTroveAnnualInterestRate(_startId)) { - return (address(0), _startId); + return (0, _startId); } - address prevId = _startId; - address nextId = data.nodes[prevId].nextId; + uint256 prevId = _startId; + uint256 nextId = data.nodes[prevId].nextId; // Descend the list until we reach the end or until we find a valid insert position - while (prevId != address(0) && !_validInsertPosition(_troveManager, _annualInterestRate, prevId, nextId)) { + while (prevId != 0 && !_validInsertPosition(_troveManager, _annualInterestRate, prevId, nextId)) { prevId = data.nodes[prevId].nextId; nextId = data.nodes[prevId].nextId; } @@ -329,17 +329,17 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _annualInterestRate Node's annual interest rate * @param _startId Id of node to start ascending the list from */ - function _ascendList(ITroveManager _troveManager, uint256 _annualInterestRate, address _startId) internal view returns (address, address) { + function _ascendList(ITroveManager _troveManager, uint256 _annualInterestRate, uint256 _startId) internal view returns (uint256, uint256) { // If `_startId` is the tail, check if the insert position is after the tail if (data.tail == _startId && _annualInterestRate <= _troveManager.getTroveAnnualInterestRate(_startId)) { - return (_startId, address(0)); + return (_startId, 0); } - address nextId = _startId; - address prevId = data.nodes[nextId].prevId; + uint256 nextId = _startId; + uint256 prevId = data.nodes[nextId].prevId; // Ascend the list until we reach the end or until we find a valid insertion point - while (nextId != address(0) && !_validInsertPosition(_troveManager, _annualInterestRate, prevId, nextId)) { + while (nextId != 0 && !_validInsertPosition(_troveManager, _annualInterestRate, prevId, nextId)) { nextId = data.nodes[nextId].prevId; prevId = data.nodes[nextId].prevId; } @@ -353,35 +353,35 @@ contract SortedTroves is Ownable, CheckContract, ISortedTroves { * @param _prevId Id of previous node for the insert position * @param _nextId Id of next node for the insert position */ - function findInsertPosition(uint256 _annualInterestRate, address _prevId, address _nextId) external view override returns (address, address) { + function findInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view override returns (uint256, uint256) { return _findInsertPosition(troveManager, _annualInterestRate, _prevId, _nextId); } - function _findInsertPosition(ITroveManager _troveManager, uint256 _annualInterestRate, address _prevId, address _nextId) internal view returns (address, address) { - address prevId = _prevId; - address nextId = _nextId; + function _findInsertPosition(ITroveManager _troveManager, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) internal view returns (uint256, uint256) { + uint256 prevId = _prevId; + uint256 nextId = _nextId; - if (prevId != address(0)) { + if (prevId != 0) { if (!contains(prevId) || _annualInterestRate > _troveManager.getTroveAnnualInterestRate(prevId)) { // `prevId` does not exist anymore or now has a smaller interest rate than the given interest rate - prevId = address(0); + prevId = 0; } } - if (nextId != address(0)) { + if (nextId != 0) { if (!contains(nextId) || _annualInterestRate < _troveManager.getTroveAnnualInterestRate(nextId)) { // `nextId` does not exist anymore or now has a larger interest rate than the given interest rate - nextId = address(0); + nextId = 0; } } - if (prevId == address(0) && nextId == address(0)) { + if (prevId == 0 && nextId == 0) { // No hint - descend list starting from head return _descendList(_troveManager, _annualInterestRate, data.head); - } else if (prevId == address(0)) { + } else if (prevId == 0) { // No `prevId` for hint - ascend list starting from `nextId` return _ascendList(_troveManager, _annualInterestRate, nextId); - } else if (nextId == address(0)) { + } else if (nextId == 0) { // No `nextId` for hint - descend list starting from `prevId` return _descendList(_troveManager, _annualInterestRate, prevId); } else { diff --git a/contracts/src/StabilityPool.sol b/contracts/src/StabilityPool.sol index 25eb50a7..f3f68b0e 100644 --- a/contracts/src/StabilityPool.sol +++ b/contracts/src/StabilityPool.sol @@ -310,7 +310,7 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { * - Decreases deposit by withdrawn amount and takes new snapshots of accumulators P and S */ function withdrawFromSP(uint _amount) external override { - if (_amount !=0) {_requireNoUnderCollateralizedTroves();} + // TODO: if (_amount !=0) {_requireNoUnderCollateralizedTroves();} uint initialDeposit = deposits[msg.sender].initialValue; _requireUserHasDeposit(initialDeposit); @@ -337,10 +337,10 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { * - Leaves their compounded deposit in the Stability Pool * - Takes new snapshots of accumulators P and S */ - function withdrawETHGainToTrove() external override { + function withdrawETHGainToTrove(uint256 _troveId) external override { uint initialDeposit = deposits[msg.sender].initialValue; _requireUserHasDeposit(initialDeposit); - _requireUserHasTrove(msg.sender); + _requireTroveIsActive(_troveId); _requireUserHasETHGain(msg.sender); uint depositorETHGain = getDepositorETHGain(msg.sender); @@ -361,7 +361,7 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { emit StabilityPoolETHBalanceUpdated(newETHBalance); emit EtherSent(msg.sender, depositorETHGain); - borrowerOperations.moveETHGainToTrove(msg.sender, depositorETHGain); + borrowerOperations.moveETHGainToTrove(msg.sender, _troveId, depositorETHGain); } // --- Liquidation functions --- @@ -674,12 +674,14 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { require(msg.sender == address(troveManager), "StabilityPool: Caller is not TroveManager"); } + /* TODO function _requireNoUnderCollateralizedTroves() internal { uint price = priceFeed.fetchPrice(); - address lowestTrove = sortedTroves.getLast(); + uint256 lowestTroveId = sortedTroves.getLast(); uint ICR = troveManager.getCurrentICR(lowestTrove, price); require(ICR >= MCR, "StabilityPool: Cannot withdraw while there are troves with ICR < MCR"); } + */ function _requireUserHasDeposit(uint _initialDeposit) internal pure { require(_initialDeposit > 0, 'StabilityPool: User must have a non-zero deposit'); @@ -694,8 +696,8 @@ contract StabilityPool is LiquityBase, Ownable, CheckContract, IStabilityPool { require(_amount > 0, 'StabilityPool: Amount must be non-zero'); } - function _requireUserHasTrove(address _depositor) internal view { - require(troveManager.getTroveStatus(_depositor) == 1, "StabilityPool: caller must have an active trove to withdraw ETHGain to"); + function _requireTroveIsActive(uint256 _troveId) internal view { + require(troveManager.checkTroveIsActive(_troveId), "StabilityPool: trove must be active to withdraw ETHGain to"); } function _requireUserHasETHGain(address _depositor) internal view { diff --git a/contracts/src/TroveManager.sol b/contracts/src/TroveManager.sol index ecf56887..b64d71ea 100644 --- a/contracts/src/TroveManager.sol +++ b/contracts/src/TroveManager.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.18; +import "openzeppelin-contracts/contracts/token/ERC721/ERC721.sol"; + import "./Interfaces/ITroveManager.sol"; import "./Interfaces/IStabilityPool.sol"; import "./Interfaces/ICollSurplusPool.sol"; @@ -13,8 +15,9 @@ import "./Dependencies/CheckContract.sol"; // import "forge-std/console2.sol"; -contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { - string constant public NAME = "TroveManager"; +contract TroveManager is ERC721, LiquityBase, Ownable, CheckContract, ITroveManager { + string constant public NAME = "TroveManager"; // TODO + string constant public SYMBOL = "Lv2T"; // TODO // --- Connected contract declarations --- @@ -75,7 +78,24 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // TODO: optimize this struct packing for gas reduction, which may break v1 tests that assume a certain order of properties } - mapping (address => Trove) public Troves; + mapping (uint256 => Trove) public Troves; + /* + * Mapping from TroveId to granted address for operations that “give” money to the trove (add collateral, pay debt). + * Useful for instance for cold/hot wallet setups. + * If its value is zero address, any address is allowed to do those operations on behalf of trove owner. + * Otherwise, only the address in this mapping (and the trove owner) will be allowed. + * To restrict this permission to no one, trove owner should be set in this mapping. + */ + mapping (uint256 => address) public TroveAddManagers; + /* + * Mapping from TroveId to granted address for operations that “withdraw” money from the trove (withdraw collateral, borrow). + * Useful for instance for cold/hot wallet setups. + * If its value is zero address, only owner is allowed to do those operations. + * Otherwise, only the address in this mapping (and the trove owner) will be allowed. + * Therefore, by default this permission is restricted to no one. + * Trove owner be set in this mapping is equivalent to zero address. + */ + mapping (uint256 => address) public TroveRemoveManagers; uint public totalStakes; @@ -97,13 +117,13 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { uint public L_boldDebt; // Map addresses with active troves to their RewardSnapshot - mapping (address => RewardSnapshot) public rewardSnapshots; + mapping (uint256 => RewardSnapshot) public rewardSnapshots; // Object containing the ETH and Bold snapshots for a given active trove struct RewardSnapshot { uint ETH; uint boldDebt;} // Array of all active trove addresses - used to to compute an approximate hint off-chain, for the sorted list insertion - address[] public TroveOwners; + uint256[] public TroveIds; // Error trackers for the trove redistribution calculation uint public lastETHError_Redistribution; @@ -134,7 +154,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { uint remainingBoldInStabPool; uint i; uint ICR; - address user; + uint256 troveId; bool backToNormalMode; uint entireSystemDebt; uint entireSystemColl; @@ -205,23 +225,24 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { event Liquidation(uint _liquidatedDebt, uint _liquidatedColl, uint _collGasCompensation, uint _boldGasCompensation); event Redemption(uint _attemptedBoldAmount, uint _actualBoldAmount, uint _ETHSent, uint _ETHFee); - event TroveUpdated(address indexed _borrower, uint _debt, uint _coll, uint _stake, TroveManagerOperation _operation); - event TroveLiquidated(address indexed _borrower, uint _debt, uint _coll, TroveManagerOperation _operation); + event TroveUpdated(uint256 indexed _troveId, uint _debt, uint _coll, uint _stake, TroveManagerOperation _operation); + event TroveLiquidated(uint256 indexed _troveId, uint _debt, uint _coll, TroveManagerOperation _operation); event BaseRateUpdated(uint _baseRate); event LastFeeOpTimeUpdated(uint _lastFeeOpTime); event TotalStakesUpdated(uint _newTotalStakes); event SystemSnapshotsUpdated(uint _totalStakesSnapshot, uint _totalCollateralSnapshot); event LTermsUpdated(uint _L_ETH, uint _L_boldDebt); event TroveSnapshotsUpdated(uint _L_ETH, uint _L_boldDebt); - event TroveIndexUpdated(address _borrower, uint _newIndex); + event TroveIndexUpdated(uint256 _troveId, uint _newIndex); - enum TroveManagerOperation { + enum TroveManagerOperation { applyPendingRewards, liquidateInNormalMode, liquidateInRecoveryMode, redeemCollateral } + constructor() ERC721(NAME, SYMBOL) {} // --- Dependency setter --- @@ -275,23 +296,23 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // --- Getters --- - function getTroveOwnersCount() external view override returns (uint) { - return TroveOwners.length; + function getTroveIdsCount() external view override returns (uint) { + return TroveIds.length; } - function getTroveFromTroveOwnersArray(uint _index) external view override returns (address) { - return TroveOwners[_index]; + function getTroveFromTroveIdsArray(uint _index) external view override returns (uint256) { + return TroveIds[_index]; } // --- Trove Liquidation functions --- // Single liquidation function. Closes the trove if its ICR is lower than the minimum collateral ratio. - function liquidate(address _borrower) external override { - _requireTroveIsActive(_borrower); + function liquidate(uint256 _troveId) external override { + _requireTroveIsActive(_troveId); - address[] memory borrowers = new address[](1); - borrowers[0] = _borrower; - batchLiquidateTroves(borrowers); + uint256[] memory troves = new uint256[](1); + troves[0] = _troveId; + batchLiquidateTroves(troves); } // --- Inner single liquidation functions --- @@ -300,7 +321,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { function _liquidateNormalMode( IActivePool _activePool, IDefaultPool _defaultPool, - address _borrower, + uint256 _troveId, uint _boldInStabPool ) internal @@ -311,10 +332,10 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { (singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, vars.pendingDebtReward, - vars.pendingCollReward) = getEntireDebtAndColl(_borrower); + vars.pendingCollReward) = getEntireDebtAndColl(_troveId); _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); - _removeStake(_borrower); + _removeStake(_troveId); singleLiquidation.collGasCompensation = _getCollGasCompensation(singleLiquidation.entireTroveColl); singleLiquidation.BoldGasCompensation = BOLD_GAS_COMPENSATION; @@ -325,9 +346,9 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { singleLiquidation.debtToRedistribute, singleLiquidation.collToRedistribute) = _getOffsetAndRedistributionVals(singleLiquidation.entireTroveDebt, collToLiquidate, _boldInStabPool); - _closeTrove(_borrower, Status.closedByLiquidation); - emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInNormalMode); - emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode); + _closeTrove(_troveId, Status.closedByLiquidation); + emit TroveLiquidated(_troveId, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInNormalMode); + emit TroveUpdated(_troveId, 0, 0, 0, TroveManagerOperation.liquidateInNormalMode); return singleLiquidation; } @@ -335,7 +356,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { function _liquidateRecoveryMode( IActivePool _activePool, IDefaultPool _defaultPool, - address _borrower, + uint256 _troveId, uint _ICR, uint _boldInStabPool, uint _TCR, @@ -345,11 +366,11 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { returns (LiquidationValues memory singleLiquidation) { LocalVariables_InnerSingleLiquidateFunction memory vars; - if (TroveOwners.length <= 1) {return singleLiquidation;} // don't liquidate if last trove + if (TroveIds.length <= 1) {return singleLiquidation;} // don't liquidate if last trove (singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, vars.pendingDebtReward, - vars.pendingCollReward) = getEntireDebtAndColl(_borrower); + vars.pendingCollReward) = getEntireDebtAndColl(_troveId); singleLiquidation.collGasCompensation = _getCollGasCompensation(singleLiquidation.entireTroveColl); singleLiquidation.BoldGasCompensation = BOLD_GAS_COMPENSATION; @@ -358,30 +379,30 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // If ICR <= 100%, purely redistribute the Trove across all active Troves if (_ICR <= _100pct) { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); - _removeStake(_borrower); + _removeStake(_troveId); singleLiquidation.debtToOffset = 0; singleLiquidation.collToSendToSP = 0; singleLiquidation.debtToRedistribute = singleLiquidation.entireTroveDebt; singleLiquidation.collToRedistribute = vars.collToLiquidate; - _closeTrove(_borrower, Status.closedByLiquidation); - emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); - emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); + _closeTrove(_troveId, Status.closedByLiquidation); + emit TroveLiquidated(_troveId, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); + emit TroveUpdated(_troveId, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); // If 100% < ICR < MCR, offset as much as possible, and redistribute the remainder } else if ((_ICR > _100pct) && (_ICR < MCR)) { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); - _removeStake(_borrower); + _removeStake(_troveId); (singleLiquidation.debtToOffset, singleLiquidation.collToSendToSP, singleLiquidation.debtToRedistribute, singleLiquidation.collToRedistribute) = _getOffsetAndRedistributionVals(singleLiquidation.entireTroveDebt, vars.collToLiquidate, _boldInStabPool); - _closeTrove(_borrower, Status.closedByLiquidation); - emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); - emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); + _closeTrove(_troveId, Status.closedByLiquidation); + emit TroveLiquidated(_troveId, singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, TroveManagerOperation.liquidateInRecoveryMode); + emit TroveUpdated(_troveId, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); /* * If 110% <= ICR < current TCR (accounting for the preceding liquidations in the current sequence) * and there is Bold in the Stability Pool, only offset, with no redistribution, @@ -392,16 +413,16 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, vars.pendingDebtReward, vars.pendingCollReward); assert(_boldInStabPool != 0); - _removeStake(_borrower); + _removeStake(_troveId); singleLiquidation = _getCappedOffsetVals(singleLiquidation.entireTroveDebt, singleLiquidation.entireTroveColl, _price); - _closeTrove(_borrower, Status.closedByLiquidation); + _closeTrove(_troveId, Status.closedByLiquidation); if (singleLiquidation.collSurplus > 0) { - collSurplusPool.accountSurplus(_borrower, singleLiquidation.collSurplus); + collSurplusPool.accountSurplus(_troveId, singleLiquidation.collSurplus); } - emit TroveLiquidated(_borrower, singleLiquidation.entireTroveDebt, singleLiquidation.collToSendToSP, TroveManagerOperation.liquidateInRecoveryMode); - emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); + emit TroveLiquidated(_troveId, singleLiquidation.entireTroveDebt, singleLiquidation.collToSendToSP, TroveManagerOperation.liquidateInRecoveryMode); + emit TroveUpdated(_troveId, 0, 0, 0, TroveManagerOperation.liquidateInRecoveryMode); } else { // if (_ICR >= MCR && ( _ICR >= _TCR || singleLiquidation.entireTroveDebt > _boldInStabPool)) LiquidationValues memory zeroVals; @@ -496,13 +517,13 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { vars.entireSystemDebt = getEntireSystemDebt(); vars.entireSystemColl = getEntireSystemColl(); - vars.user = _contractsCache.sortedTroves.getLast(); - address firstUser = _contractsCache.sortedTroves.getFirst(); - for (vars.i = 0; vars.i < _n && vars.user != firstUser; vars.i++) { - // we need to cache it, because current user is likely going to be deleted - address nextUser = _contractsCache.sortedTroves.getPrev(vars.user); + vars.troveId = _contractsCache.sortedTroves.getLast(); + uint256 firstUser = _contractsCache.sortedTroves.getFirst(); + for (vars.i = 0; vars.i < _n && vars.troveId != firstUser; vars.i++) { + // we need to cache it, because current trove is likely going to be deleted + uint256 nextUser = _contractsCache.sortedTroves.getPrev(vars.troveId); - vars.ICR = getCurrentICR(vars.user, _price); + vars.ICR = getCurrentICR(vars.troveId, _price); if (!vars.backToNormalMode) { // Break the loop if ICR is greater than MCR and Stability Pool is empty @@ -510,7 +531,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { uint TCR = LiquityMath._computeCR(vars.entireSystemColl, vars.entireSystemDebt, _price); - singleLiquidation = _liquidateRecoveryMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.user, vars.ICR, vars.remainingBoldInStabPool, TCR, _price); + singleLiquidation = _liquidateRecoveryMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.troveId, vars.ICR, vars.remainingBoldInStabPool, TCR, _price); // Update aggregate trackers vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; @@ -526,7 +547,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { vars.backToNormalMode = !_checkPotentialRecoveryMode(vars.entireSystemColl, vars.entireSystemDebt, _price); } else if (vars.backToNormalMode && vars.ICR < MCR) { - singleLiquidation = _liquidateNormalMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.user, vars.remainingBoldInStabPool); + singleLiquidation = _liquidateNormalMode(_contractsCache.activePool, _contractsCache.defaultPool, vars.troveId, vars.remainingBoldInStabPool); vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; @@ -535,7 +556,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { } else break; // break if the loop reaches a Trove with ICR >= MCR - vars.user = nextUser; + vars.troveId = nextUser; } } @@ -557,11 +578,11 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { vars.remainingBoldInStabPool = _boldInStabPool; for (vars.i = 0; vars.i < _n; vars.i++) { - vars.user = sortedTrovesCached.getLast(); - vars.ICR = getCurrentICR(vars.user, _price); + vars.troveId = sortedTrovesCached.getLast(); + vars.ICR = getCurrentICR(vars.troveId, _price); if (vars.ICR < MCR) { - singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingBoldInStabPool); + singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.troveId, vars.remainingBoldInStabPool); vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; @@ -575,7 +596,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { /* * Attempt to liquidate a custom list of troves provided by the caller. */ - function batchLiquidateTroves(address[] memory _troveArray) public override { + function batchLiquidateTroves(uint256[] memory _troveArray) public override { require(_troveArray.length != 0, "TroveManager: Calldata address array must not be empty"); IActivePool activePoolCached = activePool; @@ -626,7 +647,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { IDefaultPool _defaultPool, uint _price, uint _boldInStabPool, - address[] memory _troveArray + uint256[] memory _troveArray ) internal returns(LiquidationTotals memory totals) @@ -640,10 +661,10 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { vars.entireSystemColl = getEntireSystemColl(); for (vars.i = 0; vars.i < _troveArray.length; vars.i++) { - vars.user = _troveArray[vars.i]; + vars.troveId = _troveArray[vars.i]; // Skip non-active troves - if (Troves[vars.user].status != Status.active) { continue; } - vars.ICR = getCurrentICR(vars.user, _price); + if (Troves[vars.troveId].status != Status.active) { continue; } + vars.ICR = getCurrentICR(vars.troveId, _price); if (!vars.backToNormalMode) { @@ -652,7 +673,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { uint TCR = LiquityMath._computeCR(vars.entireSystemColl, vars.entireSystemDebt, _price); - singleLiquidation = _liquidateRecoveryMode(_activePool, _defaultPool, vars.user, vars.ICR, vars.remainingBoldInStabPool, TCR, _price); + singleLiquidation = _liquidateRecoveryMode(_activePool, _defaultPool, vars.troveId, vars.ICR, vars.remainingBoldInStabPool, TCR, _price); // Update aggregate trackers vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; @@ -669,7 +690,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { } else if (vars.backToNormalMode && vars.ICR < MCR) { - singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingBoldInStabPool); + singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.troveId, vars.remainingBoldInStabPool); vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; // Add liquidation values to their respective running totals @@ -685,7 +706,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { IDefaultPool _defaultPool, uint _price, uint _boldInStabPool, - address[] memory _troveArray + uint256[] memory _troveArray ) internal returns(LiquidationTotals memory totals) @@ -696,11 +717,11 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { vars.remainingBoldInStabPool = _boldInStabPool; for (vars.i = 0; vars.i < _troveArray.length; vars.i++) { - vars.user = _troveArray[vars.i]; - vars.ICR = getCurrentICR(vars.user, _price); + vars.troveId = _troveArray[vars.i]; + vars.ICR = getCurrentICR(vars.troveId, _price); if (vars.ICR < MCR) { - singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.user, vars.remainingBoldInStabPool); + singleLiquidation = _liquidateNormalMode(_activePool, _defaultPool, vars.troveId, vars.remainingBoldInStabPool); vars.remainingBoldInStabPool = vars.remainingBoldInStabPool - singleLiquidation.debtToOffset; // Add liquidation values to their respective running totals @@ -750,56 +771,39 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // Redeem as much collateral as possible from _borrower's Trove in exchange for Bold up to _maxBoldamount function _redeemCollateralFromTrove( ContractsCache memory _contractsCache, - address _borrower, + uint256 _troveId, uint _maxBoldamount, - uint _price, - address _upperPartialRedemptionHint, - address _lowerPartialRedemptionHint, - uint _partialRedemptionHintNICR + uint _price ) internal returns (SingleRedemptionValues memory singleRedemption) { // Determine the remaining amount (lot) to be redeemed, capped by the entire debt of the Trove minus the liquidation reserve - singleRedemption.BoldLot = LiquityMath._min(_maxBoldamount, Troves[_borrower].debt - BOLD_GAS_COMPENSATION); + singleRedemption.BoldLot = LiquityMath._min(_maxBoldamount, Troves[_troveId].debt - BOLD_GAS_COMPENSATION); // Get the ETHLot of equivalent value in USD singleRedemption.ETHLot = singleRedemption.BoldLot * DECIMAL_PRECISION / _price; // Decrease the debt and collateral of the current Trove according to the Bold lot and corresponding ETH to send - uint newDebt = Troves[_borrower].debt - singleRedemption.BoldLot; - uint newColl = Troves[_borrower].coll - singleRedemption.ETHLot; + uint newDebt = Troves[_troveId].debt - singleRedemption.BoldLot; + uint newColl = Troves[_troveId].coll - singleRedemption.ETHLot; + // TODO: zombi troves if (newDebt == BOLD_GAS_COMPENSATION) { // No debt left in the Trove (except for the liquidation reserve), therefore the trove gets closed - _removeStake(_borrower); - _closeTrove(_borrower, Status.closedByRedemption); - _redeemCloseTrove(_contractsCache, _borrower, BOLD_GAS_COMPENSATION, newColl); - emit TroveUpdated(_borrower, 0, 0, 0, TroveManagerOperation.redeemCollateral); + _removeStake(_troveId); + _closeTrove(_troveId, Status.closedByRedemption); + _redeemCloseTrove(_contractsCache, _troveId, BOLD_GAS_COMPENSATION, newColl); + emit TroveUpdated(_troveId, 0, 0, 0, TroveManagerOperation.redeemCollateral); } else { - uint newNICR = LiquityMath._computeNominalCR(newColl, newDebt); - - /* - * If the provided hint is out of date, we bail since trying to reinsert without a good hint will almost - * certainly result in running out of gas. - * - * If the resultant net debt of the partial is less than the minimum, net debt we bail. - */ - if (newNICR != _partialRedemptionHintNICR || _getNetDebt(newDebt) < MIN_NET_DEBT) { - singleRedemption.cancelledPartial = true; - return singleRedemption; - } - - _contractsCache.sortedTroves.reInsert(_borrower, newNICR, _upperPartialRedemptionHint, _lowerPartialRedemptionHint); - - Troves[_borrower].debt = newDebt; - Troves[_borrower].coll = newColl; - _updateStakeAndTotalStakes(_borrower); + Troves[_troveId].debt = newDebt; + Troves[_troveId].coll = newColl; + _updateStakeAndTotalStakes(_troveId); emit TroveUpdated( - _borrower, + _troveId, newDebt, newColl, - Troves[_borrower].stake, + Troves[_troveId].stake, TroveManagerOperation.redeemCollateral ); } @@ -814,28 +818,16 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { * The debt recorded on the trove's struct is zero'd elswhere, in _closeTrove. * Any surplus ETH left in the trove, is sent to the Coll surplus pool, and can be later claimed by the borrower. */ - function _redeemCloseTrove(ContractsCache memory _contractsCache, address _borrower, uint _bold, uint _ETH) internal { + function _redeemCloseTrove(ContractsCache memory _contractsCache, uint256 _troveId, uint _bold, uint _ETH) internal { _contractsCache.boldToken.burn(gasPoolAddress, _bold); // Update Active Pool Bold, and send ETH to account _contractsCache.activePool.decreaseBoldDebt(_bold); // send ETH from Active Pool to CollSurplus Pool - _contractsCache.collSurplusPool.accountSurplus(_borrower, _ETH); + _contractsCache.collSurplusPool.accountSurplus(_troveId, _ETH); _contractsCache.activePool.sendETH(address(_contractsCache.collSurplusPool), _ETH); } - function _isValidFirstRedemptionHint(ISortedTroves _sortedTroves, address _firstRedemptionHint, uint _price) internal view returns (bool) { - if (_firstRedemptionHint == address(0) || - !_sortedTroves.contains(_firstRedemptionHint) || - getCurrentICR(_firstRedemptionHint, _price) < MCR - ) { - return false; - } - - address nextTrove = _sortedTroves.getNext(_firstRedemptionHint); - return nextTrove == address(0) || getCurrentICR(nextTrove, _price) < MCR; - } - /* Send _boldamount Bold to the system and redeem the corresponding amount of collateral from as many Troves as are needed to fill the redemption * request. Applies pending rewards to a Trove before reducing its debt and coll. * @@ -859,10 +851,6 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { */ function redeemCollateral( uint _boldamount, - address _firstRedemptionHint, - address _upperPartialRedemptionHint, - address _lowerPartialRedemptionHint, - uint _partialRedemptionHintNICR, uint _maxIterations, uint _maxFeePercentage ) @@ -891,35 +879,29 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { assert(contractsCache.boldToken.balanceOf(msg.sender) <= totals.totalBoldSupplyAtStart); totals.remainingBold = _boldamount; - address currentBorrower; + uint256 currentTroveId; - if (_isValidFirstRedemptionHint(contractsCache.sortedTroves, _firstRedemptionHint, totals.price)) { - currentBorrower = _firstRedemptionHint; - } else { - currentBorrower = contractsCache.sortedTroves.getLast(); - // Find the first trove with ICR >= MCR - while (currentBorrower != address(0) && getCurrentICR(currentBorrower, totals.price) < MCR) { - currentBorrower = contractsCache.sortedTroves.getPrev(currentBorrower); - } - } + currentTroveId = contractsCache.sortedTroves.getLast(); // Loop through the Troves starting from the one with lowest collateral ratio until _amount of Bold is exchanged for collateral if (_maxIterations == 0) { _maxIterations = type(uint256).max; } - while (currentBorrower != address(0) && totals.remainingBold > 0 && _maxIterations > 0) { + while (currentTroveId != 0 && totals.remainingBold > 0 && _maxIterations > 0) { _maxIterations--; - // Save the address of the Trove preceding the current one, before potentially modifying the list - address nextUserToCheck = contractsCache.sortedTroves.getPrev(currentBorrower); + // Save the uint256 of the Trove preceding the current one, before potentially modifying the list + uint256 nextUserToCheck = contractsCache.sortedTroves.getPrev(currentTroveId); + // Skip if ICR < 100%, to make sure that redemptions always improve the CR of hit Troves + if (getCurrentICR(currentTroveId, totals.price) < _100pct) { + currentTroveId = nextUserToCheck; + continue; + } - _applyPendingRewards(contractsCache.activePool, contractsCache.defaultPool, currentBorrower); + _applyPendingRewards(contractsCache.activePool, contractsCache.defaultPool, currentTroveId); SingleRedemptionValues memory singleRedemption = _redeemCollateralFromTrove( contractsCache, - currentBorrower, + currentTroveId, totals.remainingBold, - totals.price, - _upperPartialRedemptionHint, - _lowerPartialRedemptionHint, - _partialRedemptionHintNICR + totals.price ); if (singleRedemption.cancelledPartial) break; // Partial redemption was cancelled (out-of-date hint, or new net debt < minimum), therefore we could not redeem from the last Trove @@ -928,7 +910,7 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { totals.totalETHDrawn = totals.totalETHDrawn + singleRedemption.ETHLot; totals.remainingBold = totals.remainingBold - singleRedemption.BoldLot; - currentBorrower = nextUserToCheck; + currentTroveId = nextUserToCheck; } require(totals.totalETHDrawn > 0, "TroveManager: Unable to redeem any amount"); @@ -955,79 +937,71 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // --- Helper functions --- - // Return the nominal collateral ratio (ICR) of a given Trove, without the price. Takes a trove's pending coll and debt rewards from redistributions into account. - function getNominalICR(address _borrower) public view override returns (uint) { - (uint currentETH, uint currentBoldDebt) = _getCurrentTroveAmounts(_borrower); - - uint NICR = LiquityMath._computeNominalCR(currentETH, currentBoldDebt); - return NICR; - } - // Return the current collateral ratio (ICR) of a given Trove. Takes a trove's pending coll and debt rewards from redistributions into account. - function getCurrentICR(address _borrower, uint _price) public view override returns (uint) { - (uint currentETH, uint currentBoldDebt) = _getCurrentTroveAmounts(_borrower); + function getCurrentICR(uint256 _troveId, uint _price) public view override returns (uint) { + (uint currentETH, uint currentBoldDebt) = _getCurrentTroveAmounts(_troveId); uint ICR = LiquityMath._computeCR(currentETH, currentBoldDebt, _price); return ICR; } - function _getCurrentTroveAmounts(address _borrower) internal view returns (uint, uint) { - uint pendingETHReward = getPendingETHReward(_borrower); - uint pendingBoldDebtReward = getPendingBoldDebtReward(_borrower); + function _getCurrentTroveAmounts(uint256 _troveId) internal view returns (uint, uint) { + uint pendingETHReward = getPendingETHReward(_troveId); + uint pendingBoldDebtReward = getPendingBoldDebtReward(_troveId); - uint currentETH = Troves[_borrower].coll + pendingETHReward; - uint currentBoldDebt = Troves[_borrower].debt + pendingBoldDebtReward; + uint currentETH = Troves[_troveId].coll + pendingETHReward; + uint currentBoldDebt = Troves[_troveId].debt + pendingBoldDebtReward; return (currentETH, currentBoldDebt); } - function applyPendingRewards(address _borrower) external override { + function applyPendingRewards(uint256 _troveId) external override { _requireCallerIsBorrowerOperations(); - return _applyPendingRewards(activePool, defaultPool, _borrower); + return _applyPendingRewards(activePool, defaultPool, _troveId); } // Add the borrowers's coll and debt rewards earned from redistributions, to their Trove - function _applyPendingRewards(IActivePool _activePool, IDefaultPool _defaultPool, address _borrower) internal { - if (hasPendingRewards(_borrower)) { - _requireTroveIsActive(_borrower); + function _applyPendingRewards(IActivePool _activePool, IDefaultPool _defaultPool, uint256 _troveId) internal { + if (hasPendingRewards(_troveId)) { + _requireTroveIsActive(_troveId); // Compute pending rewards - uint pendingETHReward = getPendingETHReward(_borrower); - uint pendingBoldDebtReward = getPendingBoldDebtReward(_borrower); + uint pendingETHReward = getPendingETHReward(_troveId); + uint pendingBoldDebtReward = getPendingBoldDebtReward(_troveId); // Apply pending rewards to trove's state - Troves[_borrower].coll = Troves[_borrower].coll + pendingETHReward; - Troves[_borrower].debt = Troves[_borrower].debt + pendingBoldDebtReward; + Troves[_troveId].coll = Troves[_troveId].coll + pendingETHReward; + Troves[_troveId].debt = Troves[_troveId].debt + pendingBoldDebtReward; - _updateTroveRewardSnapshots(_borrower); + _updateTroveRewardSnapshots(_troveId); // Transfer from DefaultPool to ActivePool _movePendingTroveRewardsToActivePool(_activePool, _defaultPool, pendingBoldDebtReward, pendingETHReward); emit TroveUpdated( - _borrower, - Troves[_borrower].debt, - Troves[_borrower].coll, - Troves[_borrower].stake, + _troveId, + Troves[_troveId].debt, + Troves[_troveId].coll, + Troves[_troveId].stake, TroveManagerOperation.applyPendingRewards ); } } - function _updateTroveRewardSnapshots(address _borrower) internal { - rewardSnapshots[_borrower].ETH = L_ETH; - rewardSnapshots[_borrower].boldDebt = L_boldDebt; + function _updateTroveRewardSnapshots(uint256 _troveId) internal { + rewardSnapshots[_troveId].ETH = L_ETH; + rewardSnapshots[_troveId].boldDebt = L_boldDebt; emit TroveSnapshotsUpdated(L_ETH, L_boldDebt); } // Get the borrower's pending accumulated ETH reward, earned by their stake - function getPendingETHReward(address _borrower) public view override returns (uint) { - uint snapshotETH = rewardSnapshots[_borrower].ETH; + function getPendingETHReward(uint256 _troveId) public view override returns (uint) { + uint snapshotETH = rewardSnapshots[_troveId].ETH; uint rewardPerUnitStaked = L_ETH - snapshotETH; - if ( rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) { return 0; } + if ( rewardPerUnitStaked == 0 || Troves[_troveId].status != Status.active) { return 0; } - uint stake = Troves[_borrower].stake; + uint stake = Troves[_troveId].stake; uint pendingETHReward = stake * rewardPerUnitStaked / DECIMAL_PRECISION; @@ -1035,71 +1009,71 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { } // Get the borrower's pending accumulated Bold reward, earned by their stake - function getPendingBoldDebtReward(address _borrower) public view override returns (uint) { - uint snapshotBoldDebt = rewardSnapshots[_borrower].boldDebt; + function getPendingBoldDebtReward(uint256 _troveId) public view override returns (uint) { + uint snapshotBoldDebt = rewardSnapshots[_troveId].boldDebt; uint rewardPerUnitStaked = L_boldDebt - snapshotBoldDebt; - if ( rewardPerUnitStaked == 0 || Troves[_borrower].status != Status.active) { return 0; } + if ( rewardPerUnitStaked == 0 || Troves[_troveId].status != Status.active) { return 0; } - uint stake = Troves[_borrower].stake; + uint stake = Troves[_troveId].stake; uint pendingBoldDebtReward = stake * rewardPerUnitStaked / DECIMAL_PRECISION; return pendingBoldDebtReward; } - function hasPendingRewards(address _borrower) public view override returns (bool) { + function hasPendingRewards(uint256 _troveId) public view override returns (bool) { /* * A Trove has pending rewards if its snapshot is less than the current rewards per-unit-staked sum: * this indicates that rewards have occured since the snapshot was made, and the user therefore has * pending rewards */ - if (Troves[_borrower].status != Status.active) {return false;} + if (Troves[_troveId].status != Status.active) {return false;} - return (rewardSnapshots[_borrower].ETH < L_ETH); + return (rewardSnapshots[_troveId].ETH < L_ETH); } // Return the Troves entire debt and coll, including pending rewards from redistributions. function getEntireDebtAndColl( - address _borrower + uint256 _troveId ) public view override returns (uint debt, uint coll, uint pendingBoldDebtReward, uint pendingETHReward) { - debt = Troves[_borrower].debt; - coll = Troves[_borrower].coll; + debt = Troves[_troveId].debt; + coll = Troves[_troveId].coll; - pendingBoldDebtReward = getPendingBoldDebtReward(_borrower); - pendingETHReward = getPendingETHReward(_borrower); + pendingBoldDebtReward = getPendingBoldDebtReward(_troveId); + pendingETHReward = getPendingETHReward(_troveId); debt = debt + pendingBoldDebtReward; coll = coll + pendingETHReward; } - function removeStake(address _borrower) external override { + function removeStake(uint256 _troveId) external override { _requireCallerIsBorrowerOperations(); - return _removeStake(_borrower); + return _removeStake(_troveId); } // Remove borrower's stake from the totalStakes sum, and set their stake to 0 - function _removeStake(address _borrower) internal { - uint stake = Troves[_borrower].stake; + function _removeStake(uint256 _troveId) internal { + uint stake = Troves[_troveId].stake; totalStakes = totalStakes - stake; - Troves[_borrower].stake = 0; + Troves[_troveId].stake = 0; } - function updateStakeAndTotalStakes(address _borrower) external override returns (uint) { + function updateStakeAndTotalStakes(uint256 _troveId) external override returns (uint) { _requireCallerIsBorrowerOperations(); - return _updateStakeAndTotalStakes(_borrower); + return _updateStakeAndTotalStakes(_troveId); } // Update borrower's stake based on their latest collateral value - function _updateStakeAndTotalStakes(address _borrower) internal returns (uint) { - uint newStake = _computeNewStake(Troves[_borrower].coll); - uint oldStake = Troves[_borrower].stake; - Troves[_borrower].stake = newStake; + function _updateStakeAndTotalStakes(uint256 _troveId) internal returns (uint) { + uint newStake = _computeNewStake(Troves[_troveId].coll); + uint oldStake = Troves[_troveId].stake; + Troves[_troveId].stake = newStake; totalStakes = totalStakes - oldStake + newStake; emit TotalStakesUpdated(totalStakes); @@ -1161,27 +1135,31 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { _activePool.sendETHToDefaultPool(_coll); } - function closeTrove(address _borrower) external override { + function closeTrove(uint256 _troveId) external override { _requireCallerIsBorrowerOperations(); - return _closeTrove(_borrower, Status.closedByOwner); + return _closeTrove(_troveId, Status.closedByOwner); } - function _closeTrove(address _borrower, Status closedStatus) internal { + function _closeTrove(uint256 _troveId, Status closedStatus) internal { assert(closedStatus != Status.nonExistent && closedStatus != Status.active); - uint TroveOwnersArrayLength = TroveOwners.length; - _requireMoreThanOneTroveInSystem(TroveOwnersArrayLength); + uint TroveIdsArrayLength = TroveIds.length; + _requireMoreThanOneTroveInSystem(TroveIdsArrayLength); + + Troves[_troveId].status = closedStatus; + Troves[_troveId].coll = 0; + Troves[_troveId].debt = 0; + Troves[_troveId].annualInterestRate = 0; - Troves[_borrower].status = closedStatus; - Troves[_borrower].coll = 0; - Troves[_borrower].debt = 0; - Troves[_borrower].annualInterestRate = 0; + rewardSnapshots[_troveId].ETH = 0; + rewardSnapshots[_troveId].boldDebt = 0; - rewardSnapshots[_borrower].ETH = 0; - rewardSnapshots[_borrower].boldDebt = 0; + _removeTroveId(_troveId, TroveIdsArrayLength); + sortedTroves.remove(_troveId); - _removeTroveOwner(_borrower, TroveOwnersArrayLength); - sortedTroves.remove(_borrower); + // burn ERC721 + // TODO: Should we do it? + _burn(_troveId); } /* @@ -1204,48 +1182,45 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { emit SystemSnapshotsUpdated(totalStakesSnapshot, totalCollateralSnapshot); } - // Push the owner's address to the Trove owners list, and record the corresponding array index on the Trove struct - function addTroveOwnerToArray(address _borrower) external override returns (uint index) { + // Push the trove's id to the Trove list, and record the corresponding array index on the Trove struct + function addTroveIdToArray(uint256 _troveId) external override returns (uint) { _requireCallerIsBorrowerOperations(); - return _addTroveOwnerToArray(_borrower); - } - function _addTroveOwnerToArray(address _borrower) internal returns (uint128 index) { /* Max array size is 2**128 - 1, i.e. ~3e30 troves. No risk of overflow, since troves have minimum Bold debt of liquidation reserve plus MIN_NET_DEBT. 3e30 Bold dwarfs the value of all wealth in the world ( which is < 1e15 USD). */ // Push the Troveowner to the array - TroveOwners.push(_borrower); + TroveIds.push(_troveId); // Record the index of the new Troveowner on their Trove struct - index = uint128(TroveOwners.length - 1); - Troves[_borrower].arrayIndex = index; + uint128 index = uint128(TroveIds.length - 1); + Troves[_troveId].arrayIndex = index; return index; } /* - * Remove a Trove owner from the TroveOwners array, not preserving array order. Removing owner 'B' does the following: + * Remove a Trove owner from the TroveIds array, not preserving array order. Removing owner 'B' does the following: * [A B C D E] => [A E C D], and updates E's Trove struct to point to its new array index. */ - function _removeTroveOwner(address _borrower, uint TroveOwnersArrayLength) internal { - Status troveStatus = Troves[_borrower].status; + function _removeTroveId(uint256 _troveId, uint TroveIdsArrayLength) internal { + Status troveStatus = Troves[_troveId].status; // It’s set in caller function `_closeTrove` assert(troveStatus != Status.nonExistent && troveStatus != Status.active); - uint128 index = Troves[_borrower].arrayIndex; - uint length = TroveOwnersArrayLength; + uint128 index = Troves[_troveId].arrayIndex; + uint length = TroveIdsArrayLength; uint idxLast = length - 1; assert(index <= idxLast); - address addressToMove = TroveOwners[idxLast]; + uint256 idToMove = TroveIds[idxLast]; - TroveOwners[index] = addressToMove; - Troves[addressToMove].arrayIndex = index; - emit TroveIndexUpdated(addressToMove, index); + TroveIds[index] = idToMove; + Troves[idToMove].arrayIndex = index; + emit TroveIndexUpdated(idToMove, index); - TroveOwners.pop(); + TroveIds.pop(); } // --- Recovery Mode and TCR functions --- @@ -1357,22 +1332,40 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { return (block.timestamp - lastFeeOperationTime) / SECONDS_IN_ONE_MINUTE; } + function checkTroveIsActive(uint256 _troveId) public view returns (bool) { + return Troves[_troveId].status == Status.active; + } + // --- 'require' wrapper functions --- function _requireCallerIsBorrowerOperations() internal view { require(msg.sender == borrowerOperationsAddress, "TroveManager: Caller is not the BorrowerOperations contract"); } - function _requireTroveIsActive(address _borrower) internal view { - require(Troves[_borrower].status == Status.active, "TroveManager: Trove does not exist or is closed"); + function _requireIsOwnerOrAddManager(uint256 _troveId, address _sender) internal view { + assert(_sender != address(0)); // TODO: remove + require( + _sender == ownerOf(_troveId) || _sender == TroveAddManagers[_troveId], + "TroveManager: sender is not trove owner nor manager"); + } + + function _requireIsOwnerOrRemoveManager(uint256 _troveId, address _sender) internal view { + assert(_sender != address(0)); // TODO: remove + require( + _sender == ownerOf(_troveId) || _sender == TroveRemoveManagers[_troveId], + "TroveManager: sender is not trove owner nor manager"); + } + + function _requireTroveIsActive(uint256 _troveId) internal view { + require(checkTroveIsActive(_troveId), "TroveManager: Trove does not exist or is closed"); } function _requireBoldBalanceCoversRedemption(IBoldToken _boldToken, address _redeemer, uint _amount) internal view { require(_boldToken.balanceOf(_redeemer) >= _amount, "TroveManager: Requested redemption amount must be <= user's Bold token balance"); } - function _requireMoreThanOneTroveInSystem(uint TroveOwnersArrayLength) internal view { - require (TroveOwnersArrayLength > 1 && sortedTroves.getSize() > 1, "TroveManager: Only one trove in the system"); + function _requireMoreThanOneTroveInSystem(uint TroveIdsArrayLength) internal view { + require (TroveIdsArrayLength > 1 && sortedTroves.getSize() > 1, "TroveManager: Only one trove in the system"); } function _requireAmountGreaterThanZero(uint _amount) internal pure { @@ -1395,70 +1388,105 @@ contract TroveManager is LiquityBase, Ownable, CheckContract, ITroveManager { // --- Trove property getters --- - function getTroveStatus(address _borrower) external view override returns (uint) { - return uint(Troves[_borrower].status); + function getTroveStatus(uint256 _troveId) external view override returns (uint) { + return uint(Troves[_troveId].status); } - function getTroveStake(address _borrower) external view override returns (uint) { - return Troves[_borrower].stake; + function getTroveStake(uint256 _troveId) external view override returns (uint) { + return Troves[_troveId].stake; } - function getTroveDebt(address _borrower) external view override returns (uint) { - return Troves[_borrower].debt; + function getTroveDebt(uint256 _troveId) external view override returns (uint) { + return Troves[_troveId].debt; } - function getTroveColl(address _borrower) external view override returns (uint) { - return Troves[_borrower].coll; + function getTroveColl(uint256 _troveId) external view override returns (uint) { + return Troves[_troveId].coll; } - function getTroveAnnualInterestRate(address _borrower) external view returns (uint) { - return Troves[_borrower].annualInterestRate; + function getTroveAnnualInterestRate(uint256 _troveId) external view returns (uint) { + return Troves[_troveId].annualInterestRate; } // --- Trove property setters, called by BorrowerOperations --- - function setTrovePropertiesOnOpen(address _borrower, uint256 _coll, uint256 _debt, uint256 _annualInterestRate) external returns (uint256) { + function setTrovePropertiesOnOpen( + address _owner, + uint256 _troveId, + uint256 _coll, + uint256 _debt, + uint256 _annualInterestRate + ) + external + returns (uint256) + { _requireCallerIsBorrowerOperations(); // TODO: optimize gas for writing to this struct - Troves[_borrower].status = Status.active; - Troves[_borrower].coll = _coll; - Troves[_borrower].debt = _debt; - Troves[_borrower].annualInterestRate = _annualInterestRate; + Troves[_troveId].status = Status.active; + Troves[_troveId].coll = _coll; + Troves[_troveId].debt = _debt; + Troves[_troveId].annualInterestRate = _annualInterestRate; + + _updateTroveRewardSnapshots(_troveId); + + // mint ERC721 + _mint(_owner, _troveId); - _updateTroveRewardSnapshots(_borrower); - return _updateStakeAndTotalStakes(_borrower); + return _updateStakeAndTotalStakes(_troveId); } - function increaseTroveColl(address _borrower, uint _collIncrease) external override returns (uint) { + function increaseTroveColl(address _sender, uint256 _troveId, uint _collIncrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); - uint newColl = Troves[_borrower].coll + _collIncrease; - Troves[_borrower].coll = newColl; + _requireIsOwnerOrAddManager(_troveId, _sender); + + uint newColl = Troves[_troveId].coll + _collIncrease; + Troves[_troveId].coll = newColl; return newColl; } - function decreaseTroveColl(address _borrower, uint _collDecrease) external override returns (uint) { + function decreaseTroveColl(address _sender, uint256 _troveId, uint _collDecrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); - uint newColl = Troves[_borrower].coll - _collDecrease; - Troves[_borrower].coll = newColl; + _requireIsOwnerOrRemoveManager(_troveId, _sender); + + uint newColl = Troves[_troveId].coll - _collDecrease; + Troves[_troveId].coll = newColl; return newColl; } - function increaseTroveDebt(address _borrower, uint _debtIncrease) external override returns (uint) { + function increaseTroveDebt(address _sender, uint256 _troveId, uint _debtIncrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); - uint newDebt = Troves[_borrower].debt + _debtIncrease; - Troves[_borrower].debt = newDebt; + _requireIsOwnerOrRemoveManager(_troveId, _sender); + + uint newDebt = Troves[_troveId].debt + _debtIncrease; + Troves[_troveId].debt = newDebt; return newDebt; } - function decreaseTroveDebt(address _borrower, uint _debtDecrease) external override returns (uint) { + function decreaseTroveDebt(address _sender, uint256 _troveId, uint _debtDecrease) external override returns (uint) { _requireCallerIsBorrowerOperations(); - uint newDebt = Troves[_borrower].debt - _debtDecrease; - Troves[_borrower].debt = newDebt; + _requireIsOwnerOrAddManager(_troveId, _sender); + + uint newDebt = Troves[_troveId].debt - _debtDecrease; + Troves[_troveId].debt = newDebt; return newDebt; } - function changeAnnualInterestRate(address _borrower, uint256 _newAnnualInterestRate) external { + function changeAnnualInterestRate(uint256 _troveId, uint256 _newAnnualInterestRate) external { + _requireCallerIsBorrowerOperations(); + Troves[_troveId].annualInterestRate = _newAnnualInterestRate; + } + + function setAddManager(address _sender, uint256 _troveId, address _manager) external { + _requireCallerIsBorrowerOperations(); + require(_sender == ownerOf(_troveId), "TroveManager: sender is not trove owner"); + + TroveAddManagers[_troveId] = _manager; + } + + function setRemoveManager(address _sender, uint256 _troveId, address _manager) external { _requireCallerIsBorrowerOperations(); - Troves[_borrower].annualInterestRate = _newAnnualInterestRate; + require(_sender == ownerOf(_troveId), "TroveManager: sender is not trove owner"); + + TroveRemoveManagers[_troveId] = _manager; } } diff --git a/contracts/src/test/TestContracts/BaseTest.sol b/contracts/src/test/TestContracts/BaseTest.sol index ee9f0bef..635581ea 100644 --- a/contracts/src/test/TestContracts/BaseTest.sol +++ b/contracts/src/test/TestContracts/BaseTest.sol @@ -32,6 +32,7 @@ contract BaseTest is Test { uint256 public constant MAX_UINT256 = type(uint256).max; uint256 public constant SECONDS_IN_1_YEAR = 31536000; // 60*60*24*365 + uint256 _100pct = 100e16; uint256 MCR = 110e16; uint256 CCR = 150e16; address public constant ZERO_ADDRESS = address(0); @@ -65,17 +66,33 @@ contract BaseTest is Test { uint256 _boldAmount, uint256 _annualInterestRate ) - public + public + returns (uint256) + { + return openTroveNoHints100pctMaxFeeWithIndex(_account, 0, _coll, _boldAmount, _annualInterestRate); + } + + function openTroveNoHints100pctMaxFeeWithIndex( + address _account, + uint256 _index, + uint256 _coll, + uint256 _boldAmount, + uint256 _annualInterestRate + ) + public + returns (uint256) { vm.startPrank(_account); - borrowerOperations.openTrove(1e18, _coll, _boldAmount, ZERO_ADDRESS, ZERO_ADDRESS, _annualInterestRate); + uint256 troveId = borrowerOperations.openTrove(_account, _index, 1e18, _coll, _boldAmount, 0, 0, _annualInterestRate); vm.stopPrank(); + return troveId; } // (uint _maxFeePercentage, uint _collWithdrawal, uint _boldChange, bool _isDebtIncrease) function adjustTrove100pctMaxFee( - address _account, + address _account, + uint256 _troveId, uint256 _collChange, uint256 _boldChange, bool _isCollIncrease, @@ -84,13 +101,13 @@ contract BaseTest is Test { public { vm.startPrank(_account); - borrowerOperations.adjustTrove(1e18, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease); + borrowerOperations.adjustTrove(_troveId, 1e18, _collChange, _isCollIncrease, _boldChange, _isDebtIncrease); vm.stopPrank(); } - function changeInterestRateNoHints(address _account, uint256 _newAnnualInterestRate) public { + function changeInterestRateNoHints(address _account, uint256 _troveId, uint256 _newAnnualInterestRate) public { vm.startPrank(_account); - borrowerOperations.adjustTroveInterestRate(_newAnnualInterestRate, ZERO_ADDRESS, ZERO_ADDRESS); + borrowerOperations.adjustTroveInterestRate(_troveId, _newAnnualInterestRate, 0, 0); vm.stopPrank(); } diff --git a/contracts/src/test/TestContracts/BorrowerOperationsTester.sol b/contracts/src/test/TestContracts/BorrowerOperationsTester.sol index 8214fe9a..39a5b164 100644 --- a/contracts/src/test/TestContracts/BorrowerOperationsTester.sol +++ b/contracts/src/test/TestContracts/BorrowerOperationsTester.sol @@ -48,7 +48,7 @@ contract BorrowerOperationsTester is BorrowerOperations { function callInternalAdjustLoan ( - address _borrower, + uint256 _troveId, uint _collWithdrawal, uint _debtChange, bool _isDebtIncrease @@ -56,6 +56,6 @@ contract BorrowerOperationsTester is BorrowerOperations { external { // TODO: Add coll increase - _adjustTrove(_borrower, _collWithdrawal, false, _debtChange, _isDebtIncrease, 0); + _adjustTrove(msg.sender, _troveId, _collWithdrawal, false, _debtChange, _isDebtIncrease, 0); } } diff --git a/contracts/src/test/TestContracts/LiquityMathTester.sol b/contracts/src/test/TestContracts/LiquityMathTester.sol index f609f1fb..7d914ebc 100644 --- a/contracts/src/test/TestContracts/LiquityMathTester.sol +++ b/contracts/src/test/TestContracts/LiquityMathTester.sol @@ -13,7 +13,7 @@ contract LiquityMathTester { } // Non-view wrapper for gas test - function callDecPowTx(uint _base, uint _n) external returns (uint) { + function callDecPowTx(uint _base, uint _n) external pure returns (uint) { return LiquityMath._decPow(_base, _n); } diff --git a/contracts/src/test/TestContracts/SortedTrovesTester.sol b/contracts/src/test/TestContracts/SortedTrovesTester.sol index 4cd41c6f..9075d419 100644 --- a/contracts/src/test/TestContracts/SortedTrovesTester.sol +++ b/contracts/src/test/TestContracts/SortedTrovesTester.sol @@ -14,24 +14,24 @@ contract SortedTrovesTester { sortedTroves = ISortedTroves(_sortedTrovesAddress); } - function insert(address _id, uint256 _annualInterestRate, address _prevId, address _nextId) external { + function insert(uint256 _id, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external { sortedTroves.insert(_id, _annualInterestRate, _prevId, _nextId); } - function remove(address _id) external { + function remove(uint256 _id) external { sortedTroves.remove(_id); } - function reInsert(address _id, uint256 _newAnnualInterestRate, address _prevId, address _nextId) external { + function reInsert(uint256 _id, uint256 _newAnnualInterestRate, uint256 _prevId, uint256 _nextId) external { sortedTroves.reInsert(_id, _newAnnualInterestRate, _prevId, _nextId); } // --- Mock TroveManager functions --- - function getTroveAnnualInterestRate(address) external pure returns (uint) { + function getTroveAnnualInterestRate(uint256) external pure returns (uint) { return 1; } - // function getCurrentICR(address, uint) external pure returns (uint) { + // function getCurrentICR(uint256, uint) external pure returns (uint) { // return 1; // } } diff --git a/contracts/src/test/TestContracts/TroveManagerTester.sol b/contracts/src/test/TestContracts/TroveManagerTester.sol index 0170badb..0a85729a 100644 --- a/contracts/src/test/TestContracts/TroveManagerTester.sol +++ b/contracts/src/test/TestContracts/TroveManagerTester.sol @@ -53,8 +53,8 @@ contract TroveManagerTester is TroveManager { return _getNetDebt(_debtVal); } - function callInternalRemoveTroveOwner(address _troveOwner) external { - uint troveOwnersArrayLength = TroveOwners.length; - _removeTroveOwner(_troveOwner, troveOwnersArrayLength); + function callInternalRemoveTroveId(uint256 _troveId) external { + uint troveOwnersArrayLength = TroveIds.length; + _removeTroveId(_troveId, troveOwnersArrayLength); } } diff --git a/contracts/src/test/basicOps.t.sol b/contracts/src/test/basicOps.t.sol index 79c25e9f..96e3261b 100644 --- a/contracts/src/test/basicOps.t.sol +++ b/contracts/src/test/basicOps.t.sol @@ -9,7 +9,7 @@ contract BasicOps is DevTestSetup { vm.startPrank(G); vm.expectRevert("ERC20: insufficient allowance"); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(G, 0, 1e18, 2e18, 2000e18, 0, 0, 0); vm.stopPrank(); } @@ -19,136 +19,127 @@ contract BasicOps is DevTestSetup { vm.startPrank(G); WETH.approve(address(borrowerOperations), 2e18); vm.expectRevert("ERC20: transfer amount exceeds balance"); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(G, 0, 1e18, 2e18, 2000e18, 0, 0, 0); vm.stopPrank(); } function testOpenTrove() public { priceFeed.setPrice(2000e18); - uint256 trovesCount = troveManager.getTroveOwnersCount(); + uint256 trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 0); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); - trovesCount = troveManager.getTroveOwnersCount(); + trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 1); } function testCloseTrove() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); vm.stopPrank(); vm.startPrank(B); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + uint256 B_Id = borrowerOperations.openTrove(B, 0, 1e18, 2e18, 2000e18, 0, 0, 0); - uint256 trovesCount = troveManager.getTroveOwnersCount(); + uint256 trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 2); vm.startPrank(B); - borrowerOperations.closeTrove(); + borrowerOperations.closeTrove(B_Id); vm.stopPrank(); // Check Troves count reduced by 1 - trovesCount = troveManager.getTroveOwnersCount(); + trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 1); } function testAdjustTrove() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + uint256 A_Id = borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); // Check Trove coll and debt - uint256 debt_1 = troveManager.getTroveDebt(A); + uint256 debt_1 = troveManager.getTroveDebt(A_Id); assertGt(debt_1, 0); - uint256 coll_1 = troveManager.getTroveColl(A); + uint256 coll_1 = troveManager.getTroveColl(A_Id); assertGt(coll_1, 0); // Adjust trove - borrowerOperations.adjustTrove(1e18, 1e18, true, 500e18, true); + borrowerOperations.adjustTrove(A_Id, 1e18, 1e18, true, 500e18, true); // Check coll and debt altered - uint256 debt_2 = troveManager.getTroveDebt(A); + uint256 debt_2 = troveManager.getTroveDebt(A_Id); assertGt(debt_2, debt_1); - uint256 coll_2 = troveManager.getTroveColl(A); + uint256 coll_2 = troveManager.getTroveColl(A_Id); assertGt(coll_2, coll_1); } function testRedeem() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 5e18, 5_000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + uint256 A_Id = borrowerOperations.openTrove(A, 0, 1e18, 5e18, 5_000e18, 0, 0, 0); vm.stopPrank(); - uint256 debt_1 = troveManager.getTroveDebt(A); + uint256 debt_1 = troveManager.getTroveDebt(A_Id); assertGt(debt_1, 0); - uint256 coll_1 = troveManager.getTroveColl(A); + uint256 coll_1 = troveManager.getTroveColl(A_Id); assertGt(coll_1, 0); vm.startPrank(B); - borrowerOperations.openTrove(1e18, 5e18, 4_000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(B, 0, 1e18, 5e18, 4_000e18, 0, 0, 0); vm.warp(block.timestamp + troveManager.BOOTSTRAP_PERIOD() + 1); uint256 redemptionAmount = 1000e18; // 1k BOLD - uint256 expectedCollReduction = redemptionAmount * 1e18 / priceFeed.fetchPrice(); - uint256 expectedColl_A = troveManager.getTroveColl(A) - expectedCollReduction; - uint256 expectedDebt_A = troveManager.getTroveDebt(A) - redemptionAmount; - uint256 expectedNICR = LiquityMath._computeNominalCR(expectedColl_A,expectedDebt_A); - // B redeems 1k BOLD troveManager.redeemCollateral( redemptionAmount, - ZERO_ADDRESS, - ZERO_ADDRESS, - ZERO_ADDRESS, - expectedNICR, 10, 1e18 ); // Check A's coll and debt reduced - uint256 debt_2 = troveManager.getTroveDebt(A); + uint256 debt_2 = troveManager.getTroveDebt(A_Id); assertLt(debt_2, debt_1); - uint256 coll_2 = troveManager.getTroveColl(A); + uint256 coll_2 = troveManager.getTroveColl(A_Id); assertLt(coll_2, coll_1); } function testLiquidation() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + uint256 A_Id = borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); vm.stopPrank(); vm.startPrank(B); - borrowerOperations.openTrove(1e18, 10e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(B, 0, 1e18, 10e18, 2000e18, 0, 0, 0); // Price drops priceFeed.setPrice(1200e18); uint256 price = priceFeed.fetchPrice(); // Check CR_A < MCR and TCR > CCR - assertLt(troveManager.getCurrentICR(A, price), MCR); + assertLt(troveManager.getCurrentICR(A_Id, price), MCR); assertGt(troveManager.getTCR(price), CCR); - uint256 trovesCount = troveManager.getTroveOwnersCount(); + uint256 trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 2); - troveManager.liquidate(A); + troveManager.liquidate(A_Id); // Check Troves count reduced by 1 - trovesCount = troveManager.getTroveOwnersCount(); + trovesCount = troveManager.getTroveIdsCount(); assertEq(trovesCount, 1); } function testSPDeposit() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); // A makes an SP deposit stabilityPool.provideToSP(100e18); @@ -167,7 +158,7 @@ contract BasicOps is DevTestSetup { function testSPWithdrawal() public { priceFeed.setPrice(2000e18); vm.startPrank(A); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 0); + borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 0); // A makes an SP deposit stabilityPool.provideToSP(100e18); diff --git a/contracts/src/test/borrowerOperations.t.sol b/contracts/src/test/borrowerOperations.t.sol index d86af057..c2a24ae3 100644 --- a/contracts/src/test/borrowerOperations.t.sol +++ b/contracts/src/test/borrowerOperations.t.sol @@ -7,14 +7,14 @@ contract BorrowerOperationsTest is DevTestSetup { // closeTrove(): reverts when trove is the only one in the system", async () => function testCloseLastTroveReverts() public { priceFeed.setPrice(2000e18); - openTroveNoHints100pctMaxFee(A, 100 ether, 100000e18, 1e17); + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 100000e18, 1e17); // Artificially mint to Alice so she has enough to close her trove deal(address(boldToken), A, 100200e18); // Check she has more Bold than her trove debt uint256 aliceBal = boldToken.balanceOf(A); - (uint256 aliceDebt,,,) = troveManager.getEntireDebtAndColl(A); + (uint256 aliceDebt,,,) = troveManager.getEntireDebtAndColl(ATroveId); assertGe(aliceBal, aliceDebt, "Not enough balance"); // check Recovery Mode @@ -23,7 +23,7 @@ contract BorrowerOperationsTest is DevTestSetup { // Alice attempts to close her trove vm.startPrank(A); vm.expectRevert("TroveManager: Only one trove in the system"); - borrowerOperations.closeTrove(); + borrowerOperations.closeTrove(ATroveId); vm.stopPrank(); } } diff --git a/contracts/src/test/borrowerOperationsOnBehalfTroveManagament.sol b/contracts/src/test/borrowerOperationsOnBehalfTroveManagament.sol new file mode 100644 index 00000000..4ed14e15 --- /dev/null +++ b/contracts/src/test/borrowerOperationsOnBehalfTroveManagament.sol @@ -0,0 +1,441 @@ +pragma solidity ^0.8.18; + +import "./TestContracts/DevTestSetup.sol"; + + +contract BorrowerOperationsOnBehalfTroveManagamentTest is DevTestSetup { + function testSetAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Check it’s initially empty + assertEq(troveManager.TroveAddManagers(ATroveId), ZERO_ADDRESS); + + // Set add manager + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s properly set + assertEq(troveManager.TroveAddManagers(ATroveId), B); + } + + function testSetAddManagerFailsFromNonOwner() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Try to set add manager + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner"); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s still unset + assertEq(troveManager.TroveAddManagers(ATroveId), ZERO_ADDRESS); + + vm.startPrank(C); + vm.expectRevert("TroveManager: sender is not trove owner"); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s still unset + assertEq(troveManager.TroveAddManagers(ATroveId), ZERO_ADDRESS); + } + + function testRemoveAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Check it’s initially empty + assertEq(troveManager.TroveRemoveManagers(ATroveId), ZERO_ADDRESS); + + // Set remove manager + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s properly set + assertEq(troveManager.TroveRemoveManagers(ATroveId), B); + } + + function testSetRemoveManagerFailsFromNonOwner() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Try to set add manager + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner"); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s still unset + assertEq(troveManager.TroveRemoveManagers(ATroveId), ZERO_ADDRESS); + + vm.startPrank(C); + vm.expectRevert("TroveManager: sender is not trove owner"); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + // Check it’s still unset + assertEq(troveManager.TroveRemoveManagers(ATroveId), ZERO_ADDRESS); + } + + function testAddCollWithAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Set add manager + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + // Owner can add coll + vm.startPrank(A); + uint256 AInitialCollBalance = WETH.balanceOf(A); + + borrowerOperations.addColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 101 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance - 1 ether, "Wrong owner balance"); + + // Manager can add coll + vm.startPrank(B); + uint256 BInitialCollBalance = WETH.balanceOf(B); + + borrowerOperations.addColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 102 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(B), BInitialCollBalance - 1 ether, "Wrong manager balance"); + } + + function testAddCollWithoutAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Owner can add coll + vm.startPrank(A); + uint256 AInitialCollBalance = WETH.balanceOf(A); + + borrowerOperations.addColl(ATroveId, 1 ether); + + assertEq(troveManager.getTroveColl(ATroveId), 101 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance - 1 ether, "Wrong owner balance"); + vm.stopPrank(); + + // Others can’t add coll + vm.startPrank(B); + uint256 BInitialCollBalance = WETH.balanceOf(B); + + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.addColl(ATroveId, 1 ether); + vm.stopPrank(); + + // Set remove manager - still won’t work + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.addColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 101 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(B), BInitialCollBalance, "Wrong manager balance"); + } + + function testWithdrawCollWithRemoveManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Set remove manager + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + // Owner can withdraw bold + vm.startPrank(A); + uint256 AInitialCollBalance = WETH.balanceOf(A); + uint256 initialColl = troveManager.getTroveColl(ATroveId); + + borrowerOperations.withdrawColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), initialColl - 1 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance + 1 ether, "Wrong owner balance"); + + // Manager can withdraw coll + vm.startPrank(B); + uint256 BInitialCollBalance = WETH.balanceOf(B); + + borrowerOperations.withdrawColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), initialColl - 2 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance + 2 ether, "Wrong owner balance"); + assertEq(WETH.balanceOf(B), BInitialCollBalance, "Wrong manager balance"); + } + + function testWithdrawCollWithoutRemoveManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Owner can withdraw bold + vm.startPrank(A); + uint256 AInitialCollBalance = WETH.balanceOf(A); + uint256 initialColl = troveManager.getTroveColl(ATroveId); + + borrowerOperations.withdrawColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), initialColl - 1 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance + 1 ether, "Wrong owner balance"); + + // Manager can’t withdraw coll + vm.startPrank(B); + uint256 BInitialCollBalance = WETH.balanceOf(B); + + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.withdrawColl(ATroveId, 1 ether); + vm.stopPrank(); + + // Set add manager - still won’t work + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.withdrawColl(ATroveId, 1 ether); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), initialColl - 1 ether, "Wrong trove coll"); + assertEq(WETH.balanceOf(A), AInitialCollBalance + 1 ether, "Wrong owner balance"); + assertEq(WETH.balanceOf(B), BInitialCollBalance, "Wrong manager balance"); + } + + function testRepayBoldWithAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Set add manager + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + // Owner can repay bold + vm.startPrank(A); + uint256 AInitialBoldBalance = boldToken.balanceOf(A); + uint256 initialDebt = troveManager.getTroveDebt(ATroveId); + + borrowerOperations.repayBold(ATroveId, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt - 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance - 10e18, "Wrong owner balance"); + + // Manager can repay bold + vm.startPrank(B); + deal(address(boldToken), B, 100e18); + uint256 BInitialBoldBalance = boldToken.balanceOf(B); + + borrowerOperations.repayBold(ATroveId, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt - 20e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(B), BInitialBoldBalance - 10e18, "Wrong manager balance"); + } + + function testRepayBoldWithoutAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Owner can repay bold + vm.startPrank(A); + uint256 AInitialBoldBalance = boldToken.balanceOf(A); + uint256 initialDebt = troveManager.getTroveDebt(ATroveId); + + borrowerOperations.repayBold(ATroveId, 10e18); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt - 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance - 10e18, "Wrong owner balance"); + vm.stopPrank(); + + // Manager can’t repay bold + vm.startPrank(B); + deal(address(boldToken), B, 100e18); + uint256 BInitialBoldBalance = boldToken.balanceOf(B); + + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.repayBold(ATroveId, 10e18); + vm.stopPrank(); + + // Set remove manager - still won’t work + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.repayBold(ATroveId, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt - 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(B), BInitialBoldBalance, "Wrong manager balance"); + } + + function testWithdrawBoldWithRemoveManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Set remove manager + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + // Owner can withdraw bold + vm.startPrank(A); + uint256 AInitialBoldBalance = boldToken.balanceOf(A); + uint256 initialDebt = troveManager.getTroveDebt(ATroveId); + + borrowerOperations.withdrawBold(ATroveId, 1e18, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt + 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance + 10e18, "Wrong owner balance"); + + // Manager can’t withdraw bold + vm.startPrank(B); + uint256 BInitialBoldBalance = boldToken.balanceOf(B); + + borrowerOperations.withdrawBold(ATroveId, 1e18, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt + 20e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance + 20e18, "Wrong owner balance"); + assertEq(boldToken.balanceOf(B), BInitialBoldBalance, "Wrong manager balance"); + } + + function testWithdrawBoldWithoutRemoveManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Owner can withdraw bold + vm.startPrank(A); + uint256 AInitialBoldBalance = boldToken.balanceOf(A); + uint256 initialDebt = troveManager.getTroveDebt(ATroveId); + + borrowerOperations.withdrawBold(ATroveId, 1e18, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt + 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance + 10e18, "Wrong owner balance"); + + // Manager can’t withdraw bold + vm.startPrank(B); + uint256 BInitialBoldBalance = boldToken.balanceOf(B); + + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.withdrawBold(ATroveId, 1e18, 10e18); + vm.stopPrank(); + + // Set add manager - still won’t work + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + vm.stopPrank(); + + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + borrowerOperations.withdrawBold(ATroveId, 1e18, 10e18); + vm.stopPrank(); + + assertEq(troveManager.getTroveDebt(ATroveId), initialDebt + 10e18, "Wrong trove debt"); + assertEq(boldToken.balanceOf(A), AInitialBoldBalance + 10e18, "Wrong owner balance"); + assertEq(boldToken.balanceOf(B), BInitialBoldBalance, "Wrong manager balance"); + } + + // TODO: withdrawETHGainToTrove + + function testWithdrawETHGainToTroveWithAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // Set add manager + vm.startPrank(A); + borrowerOperations.setAddManager(ATroveId, B); + // A provides to SP + stabilityPool.provideToSP(10000e18); + vm.stopPrank(); + + // B provides to SP + deal(address(boldToken), B, 10000e18); + vm.startPrank(B); + stabilityPool.provideToSP(10000e18); + vm.stopPrank(); + + // C opens trove, price drops and gets liquidated + uint256 CTroveId = openTroveNoHints100pctMaxFee(C, 100 ether, 14000e18, 1e17); + priceFeed.setPrice(priceFeed.getPrice() * 3 / 4); + troveManager.liquidate(CTroveId); + + // Owner can withdraw ETH gain to trove + vm.startPrank(A); + uint256 AInitialGain = stabilityPool.getDepositorETHGain(A); + + stabilityPool.withdrawETHGainToTrove(ATroveId); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 100 ether + AInitialGain, "Wrong trove coll"); + assertEq(stabilityPool.getDepositorETHGain(A), 0, "Wrong owner SP ETH balance"); + + // Manager can withdraw ETH gain to trove + vm.startPrank(B); + uint256 BInitialGain = stabilityPool.getDepositorETHGain(B); + + stabilityPool.withdrawETHGainToTrove(ATroveId); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 100 ether + AInitialGain + BInitialGain, "Wrong trove coll"); + assertEq(stabilityPool.getDepositorETHGain(B), 0, "Wrong manager balance"); + } + + function testWithdrawETHGainToTroveWithoutAddManager() public { + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 100 ether, 10000e18, 1e17); + + // A provides to SP + vm.startPrank(A); + stabilityPool.provideToSP(10000e18); + vm.stopPrank(); + + // B provides to SP + deal(address(boldToken), B, 10000e18); + vm.startPrank(B); + stabilityPool.provideToSP(10000e18); + vm.stopPrank(); + + // C opens trove, price drops and gets liquidated + uint256 CTroveId = openTroveNoHints100pctMaxFee(C, 100 ether, 14000e18, 1e17); + priceFeed.setPrice(priceFeed.getPrice() * 3 / 4); + troveManager.liquidate(CTroveId); + + // Owner can withdraw ETH gain to trove + vm.startPrank(A); + uint256 AInitialGain = stabilityPool.getDepositorETHGain(A); + + stabilityPool.withdrawETHGainToTrove(ATroveId); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 100 ether + AInitialGain, "Wrong trove coll"); + assertEq(stabilityPool.getDepositorETHGain(A), 0, "Wrong owner SP ETH balance"); + + // Others can’t withdraw ETH gain to trove + vm.startPrank(B); + uint256 BInitialGain = stabilityPool.getDepositorETHGain(B); + + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + stabilityPool.withdrawETHGainToTrove(ATroveId); + vm.stopPrank(); + + // Set remove manager - still won’t work + vm.startPrank(A); + borrowerOperations.setRemoveManager(ATroveId, B); + vm.stopPrank(); + + vm.startPrank(B); + vm.expectRevert("TroveManager: sender is not trove owner nor manager"); + stabilityPool.withdrawETHGainToTrove(ATroveId); + vm.stopPrank(); + + assertEq(troveManager.getTroveColl(ATroveId), 100 ether + AInitialGain, "Wrong trove coll"); + assertEq(stabilityPool.getDepositorETHGain(B), BInitialGain, "Wrong manager SP ETH balance"); + } +} diff --git a/contracts/src/test/interestRateBasic.t.sol b/contracts/src/test/interestRateBasic.t.sol index fb170450..3647170d 100644 --- a/contracts/src/test/interestRateBasic.t.sol +++ b/contracts/src/test/interestRateBasic.t.sol @@ -2,26 +2,23 @@ pragma solidity 0.8.18; import "./TestContracts/DevTestSetup.sol"; + contract InterestRateBasic is DevTestSetup { function testOpenTroveSetsInterestRate() public { priceFeed.setPrice(2000e18); - assertEq(troveManager.getTroveAnnualInterestRate(A), 0); - assertEq(troveManager.getTroveAnnualInterestRate(B), 0); - assertEq(troveManager.getTroveAnnualInterestRate(C), 0); - assertEq(troveManager.getTroveAnnualInterestRate(D), 0); - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 0); - assertEq(troveManager.getTroveAnnualInterestRate(A), 0); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 0); + assertEq(troveManager.getTroveAnnualInterestRate(A_Id), 0); - openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 1); - assertEq(troveManager.getTroveAnnualInterestRate(B), 1); + uint256 B_Id = openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 1); + assertEq(troveManager.getTroveAnnualInterestRate(B_Id), 1); - openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 37e16); - assertEq(troveManager.getTroveAnnualInterestRate(C), 37e16); + uint256 C_Id = openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 37e16); + assertEq(troveManager.getTroveAnnualInterestRate(C_Id), 37e16); - openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 1e18); - assertEq(troveManager.getTroveAnnualInterestRate(D), 1e18); + uint256 D_Id = openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 1e18); + assertEq(troveManager.getTroveAnnualInterestRate(D_Id), 1e18); } function testOpenTroveInsertsToCorrectPositionInSortedList() public { @@ -35,31 +32,31 @@ contract InterestRateBasic is DevTestSetup { uint256 interestRate_E = 4e17; // B and D open - openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, interestRate_B); - openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, interestRate_D); + uint256 B_Id = openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, interestRate_B); + uint256 D_Id = openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, interestRate_D); // Check initial list order - expect [B, D] // B - assertEq(sortedTroves.getNext(B), ZERO_ADDRESS); // tail - assertEq(sortedTroves.getPrev(B), D); + assertEq(sortedTroves.getNext(B_Id), 0); // tail + assertEq(sortedTroves.getPrev(B_Id), D_Id); // D - assertEq(sortedTroves.getNext(D), B); - assertEq(sortedTroves.getPrev(D), ZERO_ADDRESS); // head + assertEq(sortedTroves.getNext(D_Id), B_Id); + assertEq(sortedTroves.getPrev(D_Id), 0); // head // C opens. Expect to be inserted between B and D - openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, interestRate_C); - assertEq(sortedTroves.getNext(C), B); - assertEq(sortedTroves.getPrev(C), D); + uint256 C_Id = openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, interestRate_C); + assertEq(sortedTroves.getNext(C_Id), B_Id); + assertEq(sortedTroves.getPrev(C_Id), D_Id); // A opens. Expect to be inserted at the tail, below B - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, interestRate_A); - assertEq(sortedTroves.getNext(A), ZERO_ADDRESS); - assertEq(sortedTroves.getPrev(A), B); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, interestRate_A); + assertEq(sortedTroves.getNext(A_Id), 0); + assertEq(sortedTroves.getPrev(A_Id), B_Id); // E opens. Expect to be inserted at the head, above D - openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, interestRate_E); - assertEq(sortedTroves.getNext(E), D); - assertEq(sortedTroves.getPrev(E), ZERO_ADDRESS); + uint256 E_Id = openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, interestRate_E); + assertEq(sortedTroves.getNext(E_Id), D_Id); + assertEq(sortedTroves.getPrev(E_Id), 0); } @@ -68,131 +65,145 @@ contract InterestRateBasic is DevTestSetup { vm.startPrank(A); vm.expectRevert(); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 1e18 + 1); + borrowerOperations.openTrove(A, 0, 1e18, 2e18, 2000e18, 0, 0, 1e18 + 1); vm.expectRevert(); - borrowerOperations.openTrove(1e18, 2e18, 2000e18, ZERO_ADDRESS, ZERO_ADDRESS, 42e18); + borrowerOperations.openTrove(A, 1, 1e18, 2e18, 2000e18, 0, 0, 42e18); + } + + function testRevertWhenAdjustInterestRateFromNonOwner() public { + priceFeed.setPrice(2000e18); + + // A opens Trove + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 37e16); + assertEq(troveManager.getTroveAnnualInterestRate(A_Id), 37e16); + + // B (who is not delegate) tries to adjust it + vm.startPrank(B); + vm.expectRevert("BO: Only owner"); + borrowerOperations.adjustTroveInterestRate(A_Id, 40e16, 0, 0); + vm.stopPrank(); } function testRevertWhenAdjustInterestRateGreaterThanMax() public { priceFeed.setPrice(2000e18); // A opens Trove with valid annual interest rate ... - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 37e16); - assertEq(troveManager.getTroveAnnualInterestRate(A), 37e16); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 37e16); + assertEq(troveManager.getTroveAnnualInterestRate(A_Id), 37e16); // ... then tries to adjust it to an invalid value vm.startPrank(A); vm.expectRevert(); - borrowerOperations.adjustTroveInterestRate(1e18 + 1, ZERO_ADDRESS, ZERO_ADDRESS); + borrowerOperations.adjustTroveInterestRate(A_Id, 1e18 + 1, 0, 0); vm.expectRevert(); - borrowerOperations.adjustTroveInterestRate(42e18, ZERO_ADDRESS, ZERO_ADDRESS); + borrowerOperations.adjustTroveInterestRate(A_Id, 42e18, 0, 0); } function testAdjustTroveInterestRateSetsCorrectNewRate() public { priceFeed.setPrice(2000e18); // A, B, C opens Troves with valid annual interest rates - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 5e17); - openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 5e17); - openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 5e17); - assertEq(troveManager.getTroveAnnualInterestRate(A), 5e17); - assertEq(troveManager.getTroveAnnualInterestRate(B), 5e17); - assertEq(troveManager.getTroveAnnualInterestRate(C), 5e17); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 5e17); + uint256 B_Id = openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 5e17); + uint256 C_Id = openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 5e17); + assertEq(troveManager.getTroveAnnualInterestRate(A_Id), 5e17); + assertEq(troveManager.getTroveAnnualInterestRate(B_Id), 5e17); + assertEq(troveManager.getTroveAnnualInterestRate(C_Id), 5e17); - changeInterestRateNoHints(A, 0); - assertEq(troveManager.getTroveAnnualInterestRate(A), 0); + changeInterestRateNoHints(A, A_Id, 0); + assertEq(troveManager.getTroveAnnualInterestRate(A_Id), 0); - changeInterestRateNoHints(B, 6e17); - assertEq(troveManager.getTroveAnnualInterestRate(B), 6e17); + changeInterestRateNoHints(B, B_Id, 6e17); + assertEq(troveManager.getTroveAnnualInterestRate(B_Id), 6e17); - changeInterestRateNoHints(C, 1e18); - assertEq(troveManager.getTroveAnnualInterestRate(C), 1e18); + changeInterestRateNoHints(C, C_Id, 1e18); + assertEq(troveManager.getTroveAnnualInterestRate(C_Id), 1e18); } function testAdjustTroveInterestRateInsertsToCorrectPositionInSortedList() public { priceFeed.setPrice(2000e18); - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 1e17); - openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 2e17); - openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 3e17); - openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 4e17); - openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, 5e17); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 1e17); + uint256 B_Id = openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 2e17); + uint256 C_Id = openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 3e17); + uint256 D_Id = openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 4e17); + uint256 E_Id = openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, 5e17); // Check initial sorted list order - expect [A:10%, B:02%, C:30%, D:40%, E:50%] // A - assertEq(sortedTroves.getNext(A), ZERO_ADDRESS); // tail - assertEq(sortedTroves.getPrev(A), B); + assertEq(sortedTroves.getNext(A_Id), 0); // tail + assertEq(sortedTroves.getPrev(A_Id), B_Id); // B - assertEq(sortedTroves.getNext(B), A); - assertEq(sortedTroves.getPrev(B), C); + assertEq(sortedTroves.getNext(B_Id), A_Id); + assertEq(sortedTroves.getPrev(B_Id), C_Id); // C - assertEq(sortedTroves.getNext(C), B); - assertEq(sortedTroves.getPrev(C), D); + assertEq(sortedTroves.getNext(C_Id), B_Id); + assertEq(sortedTroves.getPrev(C_Id), D_Id); // D - assertEq(sortedTroves.getNext(D), C); - assertEq(sortedTroves.getPrev(D), E); + assertEq(sortedTroves.getNext(D_Id), C_Id); + assertEq(sortedTroves.getPrev(D_Id), E_Id); // E - assertEq(sortedTroves.getNext(E), D); - assertEq(sortedTroves.getPrev(E), ZERO_ADDRESS); // head + assertEq(sortedTroves.getNext(E_Id), D_Id); + assertEq(sortedTroves.getPrev(E_Id), 0); // head // C sets rate to 0%, moves to tail - expect [C:0%, A:10%, B:20%, D:40%, E:50%] - changeInterestRateNoHints(C, 0); - assertEq(sortedTroves.getNext(C), ZERO_ADDRESS); - assertEq(sortedTroves.getPrev(C), A); + changeInterestRateNoHints(C, C_Id, 0); + assertEq(sortedTroves.getNext(C_Id), 0); + assertEq(sortedTroves.getPrev(C_Id), A_Id); // D sets rate to 7%, moves to head - expect [C:0%, A:10%, B:20%, E:50%, D:70%] - changeInterestRateNoHints(D, 7e17); - assertEq(sortedTroves.getNext(D), E); - assertEq(sortedTroves.getPrev(D), ZERO_ADDRESS); + changeInterestRateNoHints(D, D_Id, 7e17); + assertEq(sortedTroves.getNext(D_Id), E_Id); + assertEq(sortedTroves.getPrev(D_Id), 0); // A sets rate to 6%, moves up 2 positions - expect [C:0%, B:20%, E:50%, A:60%, D:70%] - changeInterestRateNoHints(A, 6e17); - assertEq(sortedTroves.getNext(A), E); - assertEq(sortedTroves.getPrev(A), D); + changeInterestRateNoHints(A, A_Id, 6e17); + assertEq(sortedTroves.getNext(A_Id), E_Id); + assertEq(sortedTroves.getPrev(A_Id), D_Id); } function testAdjustTroveDoesNotChangeListPositions() public { priceFeed.setPrice(2000e18); // Troves opened in ascending order of interest rate - openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 1e17); - openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 2e17); - openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 3e17); - openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 4e17); - openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, 5e17); + uint256 A_Id = openTroveNoHints100pctMaxFee(A, 2 ether, 2000e18, 1e17); + uint256 B_Id = openTroveNoHints100pctMaxFee(B, 2 ether, 2000e18, 2e17); + uint256 C_Id = openTroveNoHints100pctMaxFee(C, 2 ether, 2000e18, 3e17); + uint256 D_Id = openTroveNoHints100pctMaxFee(D, 2 ether, 2000e18, 4e17); + uint256 E_Id = openTroveNoHints100pctMaxFee(E, 2 ether, 2000e18, 5e17); // Check A's neighbors - assertEq(sortedTroves.getNext(A), ZERO_ADDRESS); // tail - assertEq(sortedTroves.getPrev(A), B); + assertEq(sortedTroves.getNext(A_Id), 0); // tail + assertEq(sortedTroves.getPrev(A_Id), B_Id); // Adjust A's coll + debt - adjustTrove100pctMaxFee(A, 10 ether, 5000e18, true, true); + adjustTrove100pctMaxFee(A, A_Id, 10 ether, 5000e18, true, true); // Check A's neighbors unchanged - assertEq(sortedTroves.getNext(A), ZERO_ADDRESS); // tail - assertEq(sortedTroves.getPrev(A), B); + assertEq(sortedTroves.getNext(A_Id), 0); // tail + assertEq(sortedTroves.getPrev(A_Id), B_Id); // Check C's neighbors - assertEq(sortedTroves.getNext(C), B); - assertEq(sortedTroves.getPrev(C), D); + assertEq(sortedTroves.getNext(C_Id), B_Id); + assertEq(sortedTroves.getPrev(C_Id), D_Id); // Adjust C's coll + debt - adjustTrove100pctMaxFee(C, 10 ether, 5000e18, true, true); + adjustTrove100pctMaxFee(C, C_Id, 10 ether, 5000e18, true, true); // Check C's neighbors unchanged - assertEq(sortedTroves.getNext(C), B); - assertEq(sortedTroves.getPrev(C), D); + assertEq(sortedTroves.getNext(C_Id), B_Id); + assertEq(sortedTroves.getPrev(C_Id), D_Id); // Check E's neighbors - assertEq(sortedTroves.getNext(E), D); - assertEq(sortedTroves.getPrev(E), ZERO_ADDRESS); // head + assertEq(sortedTroves.getNext(E_Id), D_Id); + assertEq(sortedTroves.getPrev(E_Id), 0); // head // Adjust E's coll + debt - adjustTrove100pctMaxFee(E, 10 ether, 5000e18, true, true); + adjustTrove100pctMaxFee(E, E_Id, 10 ether, 5000e18, true, true); // Check E's neighbors unchanged - assertEq(sortedTroves.getNext(E), D); - assertEq(sortedTroves.getPrev(E), ZERO_ADDRESS); // head + assertEq(sortedTroves.getNext(E_Id), D_Id); + assertEq(sortedTroves.getPrev(E_Id), 0); // head } } diff --git a/contracts/src/test/troveManager.t.sol b/contracts/src/test/troveManager.t.sol new file mode 100644 index 00000000..035add25 --- /dev/null +++ b/contracts/src/test/troveManager.t.sol @@ -0,0 +1,54 @@ +pragma solidity 0.8.18; + +import "./TestContracts/DevTestSetup.sol"; + + +contract TroveManagerTest is DevTestSetup { + + function testRedeemSkipTrovesUnder100pct() public { + priceFeed.setPrice(2000e18); + uint256 ATroveId = openTroveNoHints100pctMaxFee(A, 2 ether, 2001e18, 1e17); + uint256 BTroveId = openTroveNoHints100pctMaxFee(B, 5 ether, 2000e18, 2e17); + uint256 CTroveId = openTroveNoHints100pctMaxFee(C, 5 ether, 2000e18, 3e17); + + uint256 debtA1 = troveManager.getTroveDebt(ATroveId); + assertGt(debtA1, 0); + uint256 collA1 = troveManager.getTroveColl(ATroveId); + assertGt(collA1, 0); + uint256 debtB1 = troveManager.getTroveDebt(BTroveId); + assertGt(debtB1, 0); + uint256 collB1 = troveManager.getTroveColl(BTroveId); + assertGt(collB1, 0); + + // fast-forward until redemptions are enabled + vm.warp(block.timestamp + troveManager.BOOTSTRAP_PERIOD() + 1); + // Reduce ETH price so A’s ICR goes below 100% + uint256 newPrice = 1000e18; + priceFeed.setPrice(newPrice); + assertLt(troveManager.getCurrentICR(ATroveId, newPrice), _100pct); + assertGt(troveManager.getCurrentICR(BTroveId, newPrice), _100pct); + + uint256 redemptionAmount = 1000e18; // 1k BOLD + + // C redeems 1k BOLD + vm.startPrank(C); + troveManager.redeemCollateral( + redemptionAmount, + 10, + 1e18 + ); + vm.stopPrank(); + + // Check A's coll and debt are the same + uint256 debtA2 = troveManager.getTroveDebt(ATroveId); + assertEq(debtA2, debtA1, "A debt mismatch"); + uint256 collA2 = troveManager.getTroveColl(ATroveId); + assertEq(collA2, collA1, "A coll mismatch"); + + // Check B's coll and debt reduced + uint256 debtB2 = troveManager.getTroveDebt(BTroveId); + assertLt(debtB2, debtB1, "B debt mismatch"); + uint256 collB2 = troveManager.getTroveColl(BTroveId); + assertLt(collB2, collB1, "B coll mismatch"); + } +} diff --git a/contracts/test/AccessControlTest.js b/contracts/test/AccessControlTest.js index 75080d32..d17fa409 100644 --- a/contracts/test/AccessControlTest.js +++ b/contracts/test/AccessControlTest.js @@ -72,6 +72,7 @@ contract( try { const tx1 = await borrowerOperations.moveETHGainToTrove( bob, + th.addressToTroveId(bob), 1, { from: bob } ); @@ -87,7 +88,7 @@ contract( it("applyPendingRewards(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.applyPendingRewards(bob, { + const txAlice = await troveManager.applyPendingRewards(th.addressToTroveId(bob), { from: alice, }); } catch (err) { @@ -111,7 +112,7 @@ contract( it("updateStakeAndTotalStakes(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.updateStakeAndTotalStakes(bob, { + const txAlice = await troveManager.updateStakeAndTotalStakes(th.addressToTroveId(bob), { from: alice, }); } catch (err) { @@ -124,18 +125,18 @@ contract( it("closeTrove(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.closeTrove(bob, { from: alice }); + const txAlice = await troveManager.closeTrove(th.addressToTroveId(bob), { from: alice }); } catch (err) { assert.include(err.message, "revert"); // assert.include(err.message, "Caller is not the BorrowerOperations contract") } }); - // addTroveOwnerToArray - it("addTroveOwnerToArray(): reverts when called by an account that is not BorrowerOperations", async () => { + // addTroveIdToArray + it("addTroveIdToArray(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.addTroveOwnerToArray(bob, { + const txAlice = await troveManager.addTroveIdToArray(th.addressToTroveId(bob), { from: alice, }); } catch (err) { @@ -148,7 +149,7 @@ contract( it("increaseTroveColl(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.increaseTroveColl(bob, 100, { + const txAlice = await troveManager.increaseTroveColl(bob, th.addressToTroveId(bob), 100, { from: alice, }); } catch (err) { @@ -161,7 +162,7 @@ contract( it("decreaseTroveColl(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.decreaseTroveColl(bob, 100, { + const txAlice = await troveManager.decreaseTroveColl(bob, th.addressToTroveId(bob), 100, { from: alice, }); } catch (err) { @@ -174,7 +175,7 @@ contract( it("increaseTroveDebt(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.increaseTroveDebt(bob, 100, { + const txAlice = await troveManager.increaseTroveDebt(bob, th.addressToTroveId(bob), 100, { from: alice, }); } catch (err) { @@ -187,7 +188,7 @@ contract( it("decreaseTroveDebt(): reverts when called by an account that is not BorrowerOperations", async () => { // Attempt call from alice try { - const txAlice = await troveManager.decreaseTroveDebt(bob, 100, { + const txAlice = await troveManager.decreaseTroveDebt(bob, th.addressToTroveId(bob), 100, { from: alice, }); } catch (err) { diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index 3b9853e4..274af94c 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -121,7 +121,7 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(): reverts when top-up would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); // Price drops @@ -130,7 +130,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); assert.isTrue( - (await troveManager.getCurrentICR(alice, price)).lt(toBN(dec(110, 16))) + (await troveManager.getCurrentICR(aliceTroveId, price)).lt(toBN(dec(110, 16))) ); const collTopUp = 1; // 1 wei top up @@ -177,9 +177,9 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(), active Trove: adds the correct collateral amount to the Trove", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const coll_before = alice_Trove_Before[1]; const status_Before = alice_Trove_Before[3]; @@ -192,7 +192,7 @@ contract("BorrowerOperations", async (accounts) => { value: dec(1, "ether"), }); - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const coll_After = alice_Trove_After[1]; const status_After = alice_Trove_After[3]; @@ -203,10 +203,10 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(), active Trove: Trove is in sortedList before and after", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // check Alice is in list before - const aliceTroveInList_Before = await sortedTroves.contains(alice); + const aliceTroveInList_Before = await sortedTroves.contains(aliceTroveId); const listIsEmpty_Before = await sortedTroves.isEmpty(); assert.equal(aliceTroveInList_Before, true); assert.equal(listIsEmpty_Before, false); @@ -217,7 +217,7 @@ contract("BorrowerOperations", async (accounts) => { }); // check Alice is still in list after - const aliceTroveInList_After = await sortedTroves.contains(alice); + const aliceTroveInList_After = await sortedTroves.contains(aliceTroveId); const listIsEmpty_After = await sortedTroves.isEmpty(); assert.equal(aliceTroveInList_After, true); assert.equal(listIsEmpty_After, false); @@ -225,9 +225,9 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(), active Trove: updates the stake and updates the total stakes", async () => { // Alice creates initial Trove with 1 ether - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const alice_Stake_Before = alice_Trove_Before[2]; const totalStakes_Before = await troveManager.totalStakes(); @@ -240,7 +240,7 @@ contract("BorrowerOperations", async (accounts) => { }); // Check stake and total stakes get updated - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const alice_Stake_After = alice_Trove_After[2]; const totalStakes_After = await troveManager.totalStakes(); @@ -255,19 +255,19 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(), active Trove: applies pending rewards and updates user's L_ETH, L_boldDebt snapshots", async () => { // --- SETUP --- - const { collateral: aliceCollBefore, totalDebt: aliceDebtBefore } = + const { troveId: aliceTroveId, collateral: aliceCollBefore, totalDebt: aliceDebtBefore } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const { collateral: bobCollBefore, totalDebt: bobDebtBefore } = + const { troveId: bobTroveId, collateral: bobCollBefore, totalDebt: bobDebtBefore } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -279,9 +279,9 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice("100000000000000000000"); // Liquidate Carol's Trove, - const tx = await troveManager.liquidate(carol, { from: owner }); + const tx = await troveManager.liquidate(carolTroveId, { from: owner }); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); const L_ETH = await troveManager.L_ETH(); const L_boldDebt = await troveManager.L_boldDebt(); @@ -294,7 +294,7 @@ contract("BorrowerOperations", async (accounts) => { const alice_BoldDebtRewardSnapshot_Before = alice_rewardSnapshot_Before[1]; - const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot_Before = bob_rewardSnapshot_Before[0]; const bob_BoldDebtRewardSnapshot_Before = bob_rewardSnapshot_Before[1]; @@ -303,15 +303,13 @@ contract("BorrowerOperations", async (accounts) => { assert.equal(bob_ETHrewardSnapshot_Before, 0); assert.equal(bob_BoldDebtRewardSnapshot_Before, 0); - const alicePendingETHReward = await troveManager.getPendingETHReward( - alice - ); - const bobPendingETHReward = await troveManager.getPendingETHReward(bob); + const alicePendingETHReward = await troveManager.getPendingETHReward(aliceTroveId); + const bobPendingETHReward = await troveManager.getPendingETHReward(bobTroveId); const alicePendingBoldDebtReward = - await troveManager.getPendingBoldDebtReward(alice); + await troveManager.getPendingBoldDebtReward(aliceTroveId); const bobPendingBoldDebtReward = - await troveManager.getPendingBoldDebtReward(bob); - for (reward of [ + await troveManager.getPendingBoldDebtReward(bobTroveId); + for (const reward of [ alicePendingETHReward, bobPendingETHReward, alicePendingBoldDebtReward, @@ -334,10 +332,10 @@ contract("BorrowerOperations", async (accounts) => { }); // Check that both alice and Bob have had pending rewards applied in addition to their top-ups. - const aliceNewColl = await getTroveEntireColl(alice); - const aliceNewDebt = await getTroveEntireDebt(alice); - const bobNewColl = await getTroveEntireColl(bob); - const bobNewDebt = await getTroveEntireDebt(bob); + const aliceNewColl = await getTroveEntireColl(aliceTroveId); + const aliceNewDebt = await getTroveEntireDebt(aliceTroveId); + const bobNewColl = await getTroveEntireColl(bobTroveId); + const bobNewDebt = await getTroveEntireDebt(bobTroveId); assert.isTrue( aliceNewColl.eq( @@ -354,13 +352,11 @@ contract("BorrowerOperations", async (accounts) => { /* Check that both Alice and Bob's snapshots of the rewards-per-unit-staked metrics should be updated to the latest values of L_ETH and L_boldDebt */ - const alice_rewardSnapshot_After = await troveManager.rewardSnapshots( - alice - ); + const alice_rewardSnapshot_After = await troveManager.rewardSnapshots(aliceTroveId); const alice_ETHrewardSnapshot_After = alice_rewardSnapshot_After[0]; const alice_BoldDebtRewardSnapshot_After = alice_rewardSnapshot_After[1]; - const bob_rewardSnapshot_After = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot_After = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot_After = bob_rewardSnapshot_After[0]; const bob_BoldDebtRewardSnapshot_After = bob_rewardSnapshot_After[1]; @@ -398,7 +394,7 @@ contract("BorrowerOperations", async (accounts) => { // await priceFeed.setPrice('100000000000000000000'); // // close Carol's Trove, liquidating her 5 ether and 900Bold. - // await troveManager.liquidate(carol, { from: owner }); + // await troveManager.liquidate(carolTroveId, { from: owner }); // // dennis tops up his trove by 1 ETH // await th.addCollWrapper(contracts,dennis, dennis, { from: dennis, value: dec(1, 'ether') }) @@ -415,7 +411,7 @@ contract("BorrowerOperations", async (accounts) => { // totalCollateral = (alice_Collateral + bob_Collateral + dennis_orig_coll + totalPendingETHReward) = (15 + 4 + 1 + 5) = 25 ETH. // Therefore, as Dennis adds 1 ether collateral, his corrected stake should be: s = 2 * (20 / 25 ) = 1.6 ETH */ - // const dennis_Trove = await troveManager.Troves(dennis) + // const dennis_Trove = await troveManager.Troves(dennisTroveId) // const dennis_Stake = dennis_Trove[2] // console.log(dennis_Stake.toString()) @@ -426,7 +422,7 @@ contract("BorrowerOperations", async (accounts) => { it("addColl(), reverts if trove is non-existent or closed", async () => { // A, B open troves await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); // Carol attempts to add collateral to her non-existent trove try { @@ -444,9 +440,9 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // Bob gets liquidated - await troveManager.liquidate(bob); + await troveManager.liquidate(bobTroveId); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Bob attempts to add collateral to his closed trove try { @@ -462,8 +458,8 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(): can add collateral in Recovery Mode", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const aliceCollBefore = await getTroveEntireColl(alice); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); assert.isFalse(await th.checkRecoveryMode(contracts)); await priceFeed.setPrice("105000000000000000000"); @@ -477,7 +473,7 @@ contract("BorrowerOperations", async (accounts) => { }); // Check Alice's collateral - const aliceCollAfter = (await troveManager.Troves(alice))[1]; + const aliceCollAfter = (await troveManager.Troves(aliceTroveId))[1]; assert.isTrue(aliceCollAfter.eq(aliceCollBefore.add(collTopUp))); }); @@ -485,7 +481,7 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawColl(): reverts when withdrawal would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); // Price drops @@ -494,13 +490,13 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); assert.isTrue( - (await troveManager.getCurrentICR(alice, price)).lt(toBN(dec(110, 16))) + (await troveManager.getCurrentICR(aliceTroveId, price)).lt(toBN(dec(110, 16))) ); const collWithdrawal = 1; // 1 wei withdrawal await assertRevert( - borrowerOperations.withdrawColl(1, { from: alice }), + borrowerOperations.withdrawColl(aliceTroveId, 1, { from: alice }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted" ); }); @@ -512,7 +508,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -520,8 +516,8 @@ contract("BorrowerOperations", async (accounts) => { // Bob successfully withdraws some coll const txBob = await borrowerOperations.withdrawColl( + bobTroveId, dec(100, "finney"), - { from: bob } ); assert.isTrue(txBob.receipt.status); @@ -529,8 +525,8 @@ contract("BorrowerOperations", async (accounts) => { // Carol with no active trove attempts to withdraw try { const txCarol = await borrowerOperations.withdrawColl( + th.addressToTroveId(carol), dec(1, "ether"), - { from: carol } ); assert.isFalse(txCarol.receipt.status); @@ -540,15 +536,15 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when system is in Recovery Mode", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); assert.isFalse(await th.checkRecoveryMode(contracts)); // Withdrawal possible when recoveryMode == false const txAlice = await borrowerOperations.withdrawColl( + aliceTroveId, 1000, - { from: alice } ); assert.isTrue(txAlice.receipt.status); @@ -559,7 +555,7 @@ contract("BorrowerOperations", async (accounts) => { //Check withdrawal impossible when recoveryMode == true try { - const txBob = await borrowerOperations.withdrawColl(1000, { + const txBob = await borrowerOperations.withdrawColl(bobTroveId, 1000, { from: bob, }); assert.isFalse(txBob.receipt.status); @@ -570,14 +566,14 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawColl(): reverts when requested ETH withdrawal is > the trove's collateral", async () => { await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: carol_Id } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); - const carolColl = await getTroveEntireColl(carol); - const bobColl = await getTroveEntireColl(bob); + const carolColl = await getTroveEntireColl(carol_Id); + const bobColl = await getTroveEntireColl(bobTroveId); // Carol withdraws exactly all her collateral await assertRevert( - borrowerOperations.withdrawColl(carolColl, { + borrowerOperations.withdrawColl(carol_Id, carolColl, { from: carol, }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted" @@ -586,8 +582,8 @@ contract("BorrowerOperations", async (accounts) => { // Bob attempts to withdraw 1 wei more than his collateral try { const txBob = await borrowerOperations.withdrawColl( + bobTroveId, bobColl.add(toBN(1)), - { from: bob } ); assert.isFalse(txBob.receipt.status); @@ -599,12 +595,12 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawColl(): reverts when withdrawal would bring the user's ICR < MCR", async () => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); // 110% ICR + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); // 110% ICR // Bob attempts to withdraws 1 wei, Which would leave him with < 110% ICR. try { - const txBob = await borrowerOperations.withdrawColl(1, { + const txBob = await borrowerOperations.withdrawColl(bobTroveId, 1, { from: bob, }); assert.isFalse(txBob.receipt.status); @@ -618,7 +614,7 @@ contract("BorrowerOperations", async (accounts) => { // A and B open troves at 150% ICR await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); const TCR = (await th.getTCR(contracts)).toString(); assert.equal(TCR, "1500000000000000000"); @@ -631,6 +627,7 @@ contract("BorrowerOperations", async (accounts) => { //Alice tries to withdraw collateral during Recovery Mode try { const txData = await borrowerOperations.withdrawColl( + aliceTroveId, "1", { from: alice } ); @@ -641,20 +638,20 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): doesn’t allow a user to completely withdraw all collateral from their Trove (due to gas compensation)", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const aliceColl = (await troveManager.getEntireDebtAndColl(alice))[1]; + const aliceColl = (await troveManager.getEntireDebtAndColl(aliceTroveId))[1]; // Check Trove is active - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const status_Before = alice_Trove_Before[3]; assert.equal(status_Before, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); // Alice attempts to withdraw all collateral await assertRevert( - borrowerOperations.withdrawColl(aliceColl, { + borrowerOperations.withdrawColl(aliceTroveId, aliceColl, { from: alice, }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted" @@ -663,38 +660,38 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawColl(): leaves the Trove active when the user withdraws less than all the collateral", async () => { // Open Trove - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // Check Trove is active - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const status_Before = alice_Trove_Before[3]; assert.equal(status_Before, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); // Withdraw some collateral - await borrowerOperations.withdrawColl(dec(100, "finney"), { + await borrowerOperations.withdrawColl(aliceTroveId, dec(100, "finney"), { from: alice, }); // Check Trove is still active - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const status_After = alice_Trove_After[3]; assert.equal(status_After, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); }); it("withdrawColl(): reduces the Trove's collateral by the correct amount", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const aliceCollBefore = await getTroveEntireColl(alice); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); // Alice withdraws 1 ether - await borrowerOperations.withdrawColl(dec(1, "ether"), { + await borrowerOperations.withdrawColl(aliceTroveId, dec(1, "ether"), { from: alice, }); // Check 1 ether remaining - const alice_Trove_After = await troveManager.Troves(alice); - const aliceCollAfter = await getTroveEntireColl(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); assert.isTrue( aliceCollAfter.eq(aliceCollBefore.sub(toBN(dec(1, "ether")))) @@ -702,8 +699,8 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reduces ActivePool ETH and raw ether by correct amount", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const aliceCollBefore = await getTroveEntireColl(alice); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); // check before const activePool_ETH_before = await activePool.getETHBalance(); @@ -711,7 +708,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.balanceOf(activePool.address) ); - await borrowerOperations.withdrawColl(dec(1, "ether"), { + await borrowerOperations.withdrawColl(aliceTroveId, dec(1, "ether"), { from: alice, }); @@ -734,14 +731,14 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawColl(): updates the stake and updates the total stakes", async () => { // Alice creates initial Trove with 2 ether - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice, value: toBN(dec(5, "ether")) }, }); - const aliceColl = await getTroveEntireColl(alice); + const aliceColl = await getTroveEntireColl(aliceTroveId); assert.isTrue(aliceColl.gt(toBN("0"))); - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const alice_Stake_Before = alice_Trove_Before[2]; const totalStakes_Before = await troveManager.totalStakes(); @@ -749,12 +746,12 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(totalStakes_Before.eq(aliceColl)); // Alice withdraws 1 ether - await borrowerOperations.withdrawColl(dec(1, "ether"), { + await borrowerOperations.withdrawColl(aliceTroveId, dec(1, "ether"), { from: alice, }); // Check stake and total stakes get updated - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const alice_Stake_After = alice_Trove_After[2]; const totalStakes_After = await troveManager.totalStakes(); @@ -767,7 +764,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): sends the correct amount of ETH to the user", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice, value: dec(2, "ether") }, }); @@ -775,7 +772,7 @@ contract("BorrowerOperations", async (accounts) => { const alice_ETHBalance_Before = toBN( web3.utils.toBN(await contracts.WETH.balanceOf(alice)) ); - await borrowerOperations.withdrawColl(dec(1, "ether"), { + await borrowerOperations.withdrawColl(aliceTroveId, dec(1, "ether"), { from: alice, gasPrice: 0, }); @@ -792,23 +789,23 @@ contract("BorrowerOperations", async (accounts) => { // --- SETUP --- // Alice adds 15 ether, Bob adds 5 ether, Carol adds 1 ether await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: alice, value: toBN(dec(100, "ether")) }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: bob, value: toBN(dec(100, "ether")) }, }); - await openTrove({ + const { troveId: carol_Id } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol, value: toBN(dec(10, "ether")) }, }); - const aliceCollBefore = await getTroveEntireColl(alice); - const aliceDebtBefore = await getTroveEntireDebt(alice); - const bobCollBefore = await getTroveEntireColl(bob); - const bobDebtBefore = await getTroveEntireDebt(bob); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); + const bobCollBefore = await getTroveEntireColl(bobTroveId); + const bobDebtBefore = await getTroveEntireDebt(bobTroveId); // --- TEST --- @@ -816,20 +813,20 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice("100000000000000000000"); // close Carol's Trove, liquidating her 1 ether and 180Bold. - await troveManager.liquidate(carol, { from: owner }); + await troveManager.liquidate(carol_Id, { from: owner }); const L_ETH = await troveManager.L_ETH(); const L_boldDebt = await troveManager.L_boldDebt(); // check Alice and Bob's reward snapshots are zero before they alter their Troves const alice_rewardSnapshot_Before = await troveManager.rewardSnapshots( - alice + aliceTroveId ); const alice_ETHrewardSnapshot_Before = alice_rewardSnapshot_Before[0]; const alice_BoldDebtRewardSnapshot_Before = alice_rewardSnapshot_Before[1]; - const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot_Before = bob_rewardSnapshot_Before[0]; const bob_BoldDebtRewardSnapshot_Before = bob_rewardSnapshot_Before[1]; @@ -839,15 +836,11 @@ contract("BorrowerOperations", async (accounts) => { assert.equal(bob_BoldDebtRewardSnapshot_Before, 0); // Check A and B have pending rewards - const pendingCollReward_A = await troveManager.getPendingETHReward(alice); - const pendingDebtReward_A = await troveManager.getPendingBoldDebtReward( - alice - ); - const pendingCollReward_B = await troveManager.getPendingETHReward(bob); - const pendingDebtReward_B = await troveManager.getPendingBoldDebtReward( - bob - ); - for (reward of [ + const pendingCollReward_A = await troveManager.getPendingETHReward(aliceTroveId); + const pendingDebtReward_A = await troveManager.getPendingBoldDebtReward(aliceTroveId); + const pendingCollReward_B = await troveManager.getPendingETHReward(bobTroveId); + const pendingDebtReward_B = await troveManager.getPendingBoldDebtReward(bobTroveId); + for (const reward of [ pendingCollReward_A, pendingDebtReward_A, pendingCollReward_B, @@ -860,18 +853,18 @@ contract("BorrowerOperations", async (accounts) => { const aliceCollWithdrawal = toBN(dec(5, "ether")); const bobCollWithdrawal = toBN(dec(1, "ether")); - await borrowerOperations.withdrawColl(aliceCollWithdrawal, { + await borrowerOperations.withdrawColl(aliceTroveId, aliceCollWithdrawal, { from: alice, }); - await borrowerOperations.withdrawColl(bobCollWithdrawal, { + await borrowerOperations.withdrawColl(bobTroveId, bobCollWithdrawal, { from: bob, }); // Check that both alice and Bob have had pending rewards applied in addition to their top-ups. - const aliceCollAfter = await getTroveEntireColl(alice); - const aliceDebtAfter = await getTroveEntireDebt(alice); - const bobCollAfter = await getTroveEntireColl(bob); - const bobDebtAfter = await getTroveEntireDebt(bob); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); + const aliceDebtAfter = await getTroveEntireDebt(aliceTroveId); + const bobCollAfter = await getTroveEntireColl(bobTroveId); + const bobDebtAfter = await getTroveEntireDebt(bobTroveId); // Check rewards have been applied to troves th.assertIsApproximatelyEqual( @@ -898,12 +891,12 @@ contract("BorrowerOperations", async (accounts) => { /* After top up, both Alice and Bob's snapshots of the rewards-per-unit-staked metrics should be updated to the latest values of L_ETH and L_boldDebt */ const alice_rewardSnapshot_After = await troveManager.rewardSnapshots( - alice + aliceTroveId ); const alice_ETHrewardSnapshot_After = alice_rewardSnapshot_After[0]; const alice_BoldDebtRewardSnapshot_After = alice_rewardSnapshot_After[1]; - const bob_rewardSnapshot_After = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot_After = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot_After = bob_rewardSnapshot_After[0]; const bob_BoldDebtRewardSnapshot_After = bob_rewardSnapshot_After[1]; @@ -929,7 +922,7 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawBold(): reverts when withdrawal would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); // Price drops @@ -938,13 +931,14 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); assert.isTrue( - (await troveManager.getCurrentICR(alice, price)).lt(toBN(dec(110, 16))) + (await troveManager.getCurrentICR(aliceTroveId, price)).lt(toBN(dec(110, 16))) ); const Boldwithdrawal = 1; // withdraw 1 wei Bold await assertRevert( borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, Boldwithdrawal, { from: alice } @@ -955,10 +949,11 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawBold(): reverts when calling address does not have active trove", async () => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); // Bob successfully withdraws Bold const txBob = await borrowerOperations.withdrawBold( + bobTroveId, th._100pct, dec(100, 18), { from: bob } @@ -968,9 +963,9 @@ contract("BorrowerOperations", async (accounts) => { // Carol with no active trove attempts to withdraw Bold try { const txCarol = await borrowerOperations.withdrawBold( + th.addressToTroveId(carol), th._100pct, dec(100, 18), - { from: carol } ); assert.isFalse(txCarol.receipt.status); @@ -980,11 +975,12 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when requested withdrawal amount is zero Bold", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); // Bob successfully withdraws 1e-18 Bold const txBob = await borrowerOperations.withdrawBold( + bobTroveId, th._100pct, 1, { from: bob } @@ -994,6 +990,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice attempts to withdraw 0 Bold try { const txAlice = await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, 0, { from: alice } @@ -1005,14 +1002,15 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when system is in Recovery Mode", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); assert.isFalse(await th.checkRecoveryMode(contracts)); // Withdrawal possible when recoveryMode == false const txAlice = await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, dec(100, 18), { from: alice } @@ -1026,6 +1024,7 @@ contract("BorrowerOperations", async (accounts) => { //Check Bold withdrawal impossible when recoveryMode == true try { const txBob = await borrowerOperations.withdrawBold( + bobTroveId, th._100pct, 1, { from: bob } @@ -1038,14 +1037,14 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawBold(): reverts when withdrawal would bring the trove's ICR < MCR", async () => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); // Bob tries to withdraw Bold that would bring his ICR < MCR try { const txBob = await borrowerOperations.withdrawBold( + bobTroveId, th._100pct, 1, - { from: bob } ); assert.isFalse(txBob.receipt.status); @@ -1060,7 +1059,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice and Bob creates troves with 150% ICR. System TCR = 150%. await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); var TCR = (await th.getTCR(contracts)).toString(); assert.equal(TCR, "1500000000000000000"); @@ -1069,9 +1068,9 @@ contract("BorrowerOperations", async (accounts) => { // System TCR would be: ((3+3) * 100 ) / (200+201) = 600/401 = 149.62%, i.e. below CCR of 150%. try { const txBob = await borrowerOperations.withdrawBold( + bobTroveId, th._100pct, dec(1, 18), - { from: bob } ); assert.isFalse(txBob.receipt.status); @@ -1082,7 +1081,7 @@ contract("BorrowerOperations", async (accounts) => { it("withdrawBold(): reverts if system is in Recovery Mode", async () => { // --- SETUP --- - await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); // --- TEST --- @@ -1093,9 +1092,9 @@ contract("BorrowerOperations", async (accounts) => { try { const txData = await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, "200", - { from: alice } ); assert.isFalse(txData.receipt.status); @@ -1105,21 +1104,21 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases the Trove's Bold debt by the correct amount", async () => { - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // check before - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN(0))); await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, await getNetBorrowingAmount(100), - { from: alice } ); // check after - const aliceDebtAfter = await getTroveEntireDebt(alice); + const aliceDebtAfter = await getTroveEntireDebt(aliceTroveId); th.assertIsApproximatelyEqual( aliceDebtAfter, aliceDebtBefore.add(toBN(100)) @@ -1127,12 +1126,12 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases Bold debt in ActivePool by correct amount", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice, value: toBN(dec(100, "ether")) }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN(0))); // check before @@ -1140,9 +1139,9 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(activePool_Bold_Before.eq(aliceDebtBefore)); await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, await getNetBorrowingAmount(dec(10000, 18)), - { from: alice } ); @@ -1155,7 +1154,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases user BoldToken balance by correct amount", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraParams: { value: toBN(dec(100, "ether")), from: alice }, }); @@ -1164,9 +1163,9 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(alice_BoldTokenBalance_Before.gt(toBN("0"))); await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, dec(10000, 18), - { from: alice } ); @@ -1182,7 +1181,7 @@ contract("BorrowerOperations", async (accounts) => { // --- repayBold() --- it("repayBold(): reverts when repayment would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); // Price drops @@ -1191,13 +1190,13 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); assert.isTrue( - (await troveManager.getCurrentICR(alice, price)).lt(toBN(dec(110, 16))) + (await troveManager.getCurrentICR(aliceTroveId, price)).lt(toBN(dec(110, 16))) ); const BoldRepayment = 1; // 1 wei repayment await assertRevert( - borrowerOperations.repayBold(BoldRepayment, { + borrowerOperations.repayBold(aliceTroveId, BoldRepayment, { from: alice, }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted" @@ -1206,7 +1205,7 @@ contract("BorrowerOperations", async (accounts) => { it("repayBold(): Succeeds when it would leave trove with net debt >= minimum net debt", async () => { // Make the Bold request 2 wei above min net debt to correct for floor division, and make net debt = min net debt + 1 wei - await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getNetBorrowingAmount(MIN_NET_DEBT.add(toBN("2"))), A, @@ -1215,15 +1214,15 @@ contract("BorrowerOperations", async (accounts) => { { from: A, value: dec(100, 30) } ); - const repayTxA = await borrowerOperations.repayBold(1, { from: A }); + const repayTxA = await borrowerOperations.repayBold(ATroveId, 1, { from: A }); assert.isTrue(repayTxA.receipt.status); - await th.openTroveWrapper(contracts,th._100pct, dec(20, 25), B, B, 0, { + const BTroveId = await th.openTroveWrapper(contracts,th._100pct, dec(20, 25), B, B, 0, { from: B, value: dec(100, 30) }); - const repayTxB = await borrowerOperations.repayBold(dec(19, 25),{ + const repayTxB = await borrowerOperations.repayBold(BTroveId, dec(19, 25),{ from: B, }); assert.isTrue(repayTxB.receipt.status); @@ -1231,7 +1230,7 @@ contract("BorrowerOperations", async (accounts) => { it("repayBold(): reverts when it would leave trove with net debt < minimum net debt", async () => { // Open the trove with min debt + 1 wei - await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getNetBorrowingAmount(MIN_NET_DEBT.add(toBN("1"))), A, @@ -1241,11 +1240,11 @@ contract("BorrowerOperations", async (accounts) => { ); // Check Trove debt is 1 wei above min - const debt = await troveManager.getTroveDebt(A); + const debt = await troveManager.getTroveDebt(ATroveId); assert.isTrue(debt.eq(th.toBN(dec(2000, 18)).add(th.toBN("1")))); // Try to repay 2 wei to bring Trove debt to 1 wei below minimum, and expect revert - const repayTxAPromise = borrowerOperations.repayBold(2, { + const repayTxAPromise = borrowerOperations.repayBold(ATroveId, 2, { from: A, }); await assertRevert( @@ -1255,7 +1254,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if repaid amount is greater than current debt", async () => { - const { totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -1272,6 +1271,7 @@ contract("BorrowerOperations", async (accounts) => { await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, 0, false, @@ -1289,13 +1289,13 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); // Bob successfully repays some Bold - const txBob = await borrowerOperations.repayBold(dec(10, 18), { + const txBob = await borrowerOperations.repayBold(bobTroveId, dec(10, 18), { from: bob, }); assert.isTrue(txBob.receipt.status); @@ -1303,8 +1303,8 @@ contract("BorrowerOperations", async (accounts) => { // Carol with no active trove attempts to repayBold try { const txCarol = await borrowerOperations.repayBold( + th.addressToTroveId(carol), dec(10, 18), - { from: carol } ); assert.isFalse(txCarol.receipt.status); @@ -1314,20 +1314,20 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when attempted repayment is > the debt of the trove", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - const aliceDebt = await getTroveEntireDebt(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); // Bob successfully repays some Bold - const txBob = await borrowerOperations.repayBold(dec(10, 18), { + const txBob = await borrowerOperations.repayBold(bobTroveId, dec(10, 18), { from: bob, }); assert.isTrue(txBob.receipt.status); @@ -1335,6 +1335,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice attempts to repay more than her debt try { const txAlice = await borrowerOperations.repayBold( + aliceTroveId, aliceDebt.add(toBN(dec(1, 18))), { from: alice } ); @@ -1346,7 +1347,7 @@ contract("BorrowerOperations", async (accounts) => { //repayBold: reduces Bold debt in Trove it("repayBold(): reduces the Trove's Bold debt by the correct amount", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1356,16 +1357,16 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); await borrowerOperations.repayBold( + aliceTroveId, aliceDebtBefore.div(toBN(10)), - { from: alice } ); // Repays 1/10 her debt - const aliceDebtAfter = await getTroveEntireDebt(alice); + const aliceDebtAfter = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtAfter.gt(toBN("0"))); th.assertIsApproximatelyEqual( @@ -1375,7 +1376,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases Bold debt in ActivePool by correct amount", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1385,7 +1386,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); // Check before @@ -1393,8 +1394,8 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(activePool_Bold_Before.gt(toBN("0"))); await borrowerOperations.repayBold( + aliceTroveId, aliceDebtBefore.div(toBN(10)), - { from: alice } ); // Repays 1/10 her debt @@ -1407,7 +1408,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases user BoldToken balance by correct amount", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1417,7 +1418,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); // check before @@ -1425,8 +1426,8 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(alice_BoldTokenBalance_Before.gt(toBN("0"))); await borrowerOperations.repayBold( + aliceTroveId, aliceDebtBefore.div(toBN(10)), - { from: alice } ); // Repays 1/10 her debt @@ -1439,7 +1440,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): can repay debt in Recovery Mode", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1449,7 +1450,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); assert.isFalse(await th.checkRecoveryMode(contracts)); @@ -1459,14 +1460,14 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); const tx = await borrowerOperations.repayBold( + aliceTroveId, aliceDebtBefore.div(toBN(10)), - { from: alice } ); assert.isTrue(tx.receipt.status); // Check Alice's debt: 110 (initial) - 50 (repaid) - const aliceDebtAfter = await getTroveEntireDebt(alice); + const aliceDebtAfter = await getTroveEntireDebt(aliceTroveId); th.assertIsApproximatelyEqual( aliceDebtAfter, aliceDebtBefore.mul(toBN(9)).div(toBN(10)) @@ -1479,7 +1480,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: BTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: B }, @@ -1498,7 +1499,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(bobBalAfter.eq(toBN(dec(5, 18)))); // Bob tries to repay 6 Bold - const repayBoldPromise_B = borrowerOperations.repayBold( + const repayBoldPromise_B = borrowerOperations.repayBold(BTroveId, toBN(dec(6, 18)), { from: B } ); @@ -1513,7 +1514,7 @@ contract("BorrowerOperations", async (accounts) => { it("adjustTrove(): reverts when adjustment would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); // Price drops @@ -1522,7 +1523,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); assert.isTrue( - (await troveManager.getCurrentICR(alice, price)).lt(toBN(dec(110, 16))) + (await troveManager.getCurrentICR(aliceTroveId, price)).lt(toBN(dec(110, 16))) ); const BoldRepayment = 1; // 1 wei repayment @@ -1532,6 +1533,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, collTopUp, { from: alice }); await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, collTopUp, true, @@ -1544,7 +1546,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when calling address has no active trove", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1559,6 +1561,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); // Alice coll and debt increase(+1 ETH, +50Bold) await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -1572,6 +1575,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: carol }); const txCarol = await borrowerOperations.adjustTrove( + th.addressToTroveId(carol), th._100pct, dec(1, "ether"), true, @@ -1587,12 +1591,12 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts in Recovery Mode when the adjustment would reduce the TCR", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(20000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -1603,6 +1607,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); const txAlice = await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -1619,6 +1624,7 @@ contract("BorrowerOperations", async (accounts) => { try { // collateral withdrawal should also fail const txAlice = await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), false, @@ -1634,6 +1640,7 @@ contract("BorrowerOperations", async (accounts) => { try { // debt increase should fail const txBob = await borrowerOperations.adjustTrove( + bobTroveId, th._100pct, 0, false, @@ -1651,6 +1658,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: bob }); const txBob = await borrowerOperations.adjustTrove( + bobTroveId, th._100pct, dec(1, "ether"), true, @@ -1665,7 +1673,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): collateral withdrawal reverts in Recovery Mode", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1685,6 +1693,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice attempts an adjustment that repays half her debt BUT withdraws 1 wei collateral, and fails await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, 1, false, @@ -1697,7 +1706,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would leave ICR < 150% reverts in Recovery Mode", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1716,10 +1725,10 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); - const ICR_A = await troveManager.getCurrentICR(alice, price); + const ICR_A = await troveManager.getCurrentICR(aliceTroveId, price); - const aliceDebt = await getTroveEntireDebt(alice); - const aliceColl = await getTroveEntireColl(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); + const aliceColl = await getTroveEntireColl(aliceTroveId); const debtIncrease = toBN(dec(50, 18)); const collIncrease = toBN(dec(1, "ether")); @@ -1736,6 +1745,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, collIncrease, true, @@ -1748,12 +1758,12 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would reduce the ICR reverts in Recovery Mode", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -1769,13 +1779,13 @@ contract("BorrowerOperations", async (accounts) => { //--- Alice with ICR > 150% tries to reduce her ICR --- - const ICR_A = await troveManager.getCurrentICR(alice, price); + const ICR_A = await troveManager.getCurrentICR(aliceTroveId, price); // Check Alice's initial ICR is above 150% assert.isTrue(ICR_A.gt(CCR)); - const aliceDebt = await getTroveEntireDebt(alice); - const aliceColl = await getTroveEntireColl(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); + const aliceColl = await getTroveEntireColl(aliceTroveId); const aliceDebtIncrease = toBN(dec(150, 18)); const aliceCollIncrease = toBN(dec(1, "ether")); @@ -1792,6 +1802,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, aliceCollIncrease, true, @@ -1804,13 +1815,13 @@ contract("BorrowerOperations", async (accounts) => { //--- Bob with ICR < 150% tries to reduce his ICR --- - const ICR_B = await troveManager.getCurrentICR(bob, price); + const ICR_B = await troveManager.getCurrentICR(bobTroveId, price); // Check Bob's initial ICR is below 150% assert.isTrue(ICR_B.lt(CCR)); - const bobDebt = await getTroveEntireDebt(bob); - const bobColl = await getTroveEntireColl(bob); + const bobDebt = await getTroveEntireDebt(bobTroveId); + const bobColl = await getTroveEntireColl(bobTroveId); const bobDebtIncrease = toBN(dec(450, 18)); const bobCollIncrease = toBN(dec(1, "ether")); @@ -1827,6 +1838,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: bob }); await assertRevert( borrowerOperations.adjustTrove( + bobTroveId, th._100pct, bobCollIncrease, true, @@ -1839,7 +1851,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): A trove with ICR < CCR in Recovery Mode can adjust their trove to ICR > CCR", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -1858,12 +1870,12 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); - const ICR_A = await troveManager.getCurrentICR(alice, price); + const ICR_A = await troveManager.getCurrentICR(aliceTroveId, price); // Check initial ICR is below 150% assert.isTrue(ICR_A.lt(CCR)); - const aliceDebt = await getTroveEntireDebt(alice); - const aliceColl = await getTroveEntireColl(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); + const aliceColl = await getTroveEntireColl(aliceTroveId); const debtIncrease = toBN(dec(5000, 18)); const collIncrease = toBN(dec(150, "ether")); @@ -1879,6 +1891,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); const tx = await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, collIncrease, true, @@ -1888,12 +1901,12 @@ contract("BorrowerOperations", async (accounts) => { ); assert.isTrue(tx.receipt.status); - const actualNewICR = await troveManager.getCurrentICR(alice, price); + const actualNewICR = await troveManager.getCurrentICR(aliceTroveId, price); assert.isTrue(actualNewICR.gt(CCR)); }); it("adjustTrove(): A trove with ICR > CCR in Recovery Mode can improve their ICR", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), extraParams: { from: alice }, @@ -1912,12 +1925,12 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); - const initialICR = await troveManager.getCurrentICR(alice, price); + const initialICR = await troveManager.getCurrentICR(aliceTroveId, price); // Check initial ICR is above 150% assert.isTrue(initialICR.gt(CCR)); - const aliceDebt = await getTroveEntireDebt(alice); - const aliceColl = await getTroveEntireColl(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); + const aliceColl = await getTroveEntireColl(aliceTroveId); const debtIncrease = toBN(dec(5000, 18)); const collIncrease = toBN(dec(150, "ether")); @@ -1933,6 +1946,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); const tx = await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, collIncrease, true, @@ -1942,7 +1956,7 @@ contract("BorrowerOperations", async (accounts) => { ); assert.isTrue(tx.receipt.status); - const actualNewICR = await troveManager.getCurrentICR(alice, price); + const actualNewICR = await troveManager.getCurrentICR(aliceTroveId, price); assert.isTrue(actualNewICR.gt(initialICR)); }); @@ -1950,7 +1964,7 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); // Check TCR and Recovery Mode const TCR = (await th.getTCR(contracts)).toString(); @@ -1960,6 +1974,7 @@ contract("BorrowerOperations", async (accounts) => { // Bob attempts an operation that would bring the TCR below the CCR try { const txBob = await borrowerOperations.adjustTrove( + bobTroveId, th._100pct, 0, false, @@ -1975,17 +1990,15 @@ contract("BorrowerOperations", async (accounts) => { it("adjustTrove(): reverts when Bold repaid is > debt of the trove", async () => { await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); - const bobOpenTx = ( - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }) - ).tx; + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); - const bobDebt = await getTroveEntireDebt(bob); + const bobDebt = await getTroveEntireDebt(bobTroveId); assert.isTrue(bobDebt.gt(toBN("0"))); // Alice transfers 1 Bold to bob await boldToken.transfer(bob, th.toBN(dec(1, 18)), { from: alice }); - const remainingDebt = (await troveManager.getTroveDebt(bob)).sub( + const remainingDebt = (await troveManager.getTroveDebt(bobTroveId)).sub( BOLD_GAS_COMPENSATION ); @@ -1994,6 +2007,7 @@ contract("BorrowerOperations", async (accounts) => { await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: bob }); await assertRevert( borrowerOperations.adjustTrove( + bobTroveId, th._100pct, dec(1, "ether"), true, @@ -2008,13 +2022,14 @@ contract("BorrowerOperations", async (accounts) => { it("adjustTrove(): reverts when attempted ETH withdrawal is >= the trove's collateral", async () => { await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); - const carolColl = await getTroveEntireColl(carol); + const carolColl = await getTroveEntireColl(carolTroveId); // Carol attempts an adjustment that would withdraw 1 wei more than her ETH try { const txCarol = await borrowerOperations.adjustTrove( + carolTroveId, th._100pct, carolColl.add(toBN(1)), false, @@ -2042,7 +2057,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(11, 17)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(11, 17)), extraParams: { from: bob }, @@ -2054,6 +2069,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: bob }); const txBob = await borrowerOperations.adjustTrove( + bobTroveId, th._100pct, dec(1, "ether"), true, @@ -2068,13 +2084,13 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 coll change, doesnt change borrower's coll or ActivePool coll", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceCollBefore = await getTroveEntireColl(alice); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); const activePoolCollBefore = await activePool.getETHBalance(); assert.isTrue(aliceCollBefore.gt(toBN("0"))); @@ -2082,6 +2098,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice adjusts trove. No coll change, and a debt increase (+50Bold) await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, 0, false, @@ -2090,7 +2107,7 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const aliceCollAfter = await getTroveEntireColl(alice); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); const activePoolCollAfter = await activePool.getETHBalance(); assert.isTrue(aliceCollAfter.eq(activePoolCollAfter)); @@ -2098,13 +2115,13 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 debt change, doesnt change borrower's debt or ActivePool debt", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceDebtBefore = await getTroveEntireDebt(alice); + const aliceDebtBefore = await getTroveEntireDebt(aliceTroveId); const activePoolDebtBefore = await activePool.getBoldDebt(); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); @@ -2114,6 +2131,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2122,7 +2140,7 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const aliceDebtAfter = await getTroveEntireDebt(alice); + const aliceDebtAfter = await getTroveEntireDebt(aliceTroveId); const activePoolDebtAfter = await activePool.getBoldDebt(); assert.isTrue(aliceDebtAfter.eq(aliceDebtBefore)); @@ -2136,14 +2154,14 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const debtBefore = await getTroveEntireDebt(alice); - const collBefore = await getTroveEntireColl(alice); + const debtBefore = await getTroveEntireDebt(aliceTroveId); + const collBefore = await getTroveEntireColl(aliceTroveId); assert.isTrue(debtBefore.gt(toBN("0"))); assert.isTrue(collBefore.gt(toBN("0"))); @@ -2151,6 +2169,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2159,8 +2178,8 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const debtAfter = await getTroveEntireDebt(alice); - const collAfter = await getTroveEntireColl(alice); + const debtAfter = await getTroveEntireDebt(aliceTroveId); + const collAfter = await getTroveEntireColl(aliceTroveId); th.assertIsApproximatelyEqual( debtAfter, @@ -2181,19 +2200,20 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const debtBefore = await getTroveEntireDebt(alice); - const collBefore = await getTroveEntireColl(alice); + const debtBefore = await getTroveEntireDebt(aliceTroveId); + const collBefore = await getTroveEntireColl(aliceTroveId); assert.isTrue(debtBefore.gt(toBN("0"))); assert.isTrue(collBefore.gt(toBN("0"))); // Alice adjusts trove coll and debt decrease (-0.5 ETH, -50Bold) await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(500, "finney"), false, @@ -2202,8 +2222,8 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const debtAfter = await getTroveEntireDebt(alice); - const collAfter = await getTroveEntireColl(alice); + const debtAfter = await getTroveEntireDebt(aliceTroveId); + const collAfter = await getTroveEntireColl(aliceTroveId); assert.isTrue(debtAfter.eq(debtBefore.sub(toBN(dec(50, 18))))); assert.isTrue(collAfter.eq(collBefore.sub(toBN(dec(5, 17))))); @@ -2216,14 +2236,14 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const debtBefore = await getTroveEntireDebt(alice); - const collBefore = await getTroveEntireColl(alice); + const debtBefore = await getTroveEntireDebt(aliceTroveId); + const collBefore = await getTroveEntireColl(aliceTroveId); assert.isTrue(debtBefore.gt(toBN("0"))); assert.isTrue(collBefore.gt(toBN("0"))); @@ -2231,6 +2251,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(500, "finney"), true, @@ -2239,8 +2260,8 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const debtAfter = await getTroveEntireDebt(alice); - const collAfter = await getTroveEntireColl(alice); + const debtAfter = await getTroveEntireDebt(aliceTroveId); + const collAfter = await getTroveEntireColl(aliceTroveId); th.assertIsApproximatelyEqual( debtAfter, @@ -2261,19 +2282,20 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const debtBefore = await getTroveEntireDebt(alice); - const collBefore = await getTroveEntireColl(alice); + const debtBefore = await getTroveEntireDebt(aliceTroveId); + const collBefore = await getTroveEntireColl(aliceTroveId); assert.isTrue(debtBefore.gt(toBN("0"))); assert.isTrue(collBefore.gt(toBN("0"))); // Alice adjusts trove - coll decrease and debt increase (0.1 ETH, 10Bold) await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, 17), false, @@ -2282,8 +2304,8 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const debtAfter = await getTroveEntireDebt(alice); - const collAfter = await getTroveEntireColl(alice); + const debtAfter = await getTroveEntireDebt(aliceTroveId); + const collAfter = await getTroveEntireColl(aliceTroveId); th.assertIsApproximatelyEqual( debtAfter, @@ -2304,13 +2326,13 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const stakeBefore = await troveManager.getTroveStake(alice); + const stakeBefore = await troveManager.getTroveStake(aliceTroveId); const totalStakesBefore = await troveManager.totalStakes(); assert.isTrue(stakeBefore.gt(toBN("0"))); assert.isTrue(totalStakesBefore.gt(toBN("0"))); @@ -2319,6 +2341,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2327,7 +2350,7 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const stakeAfter = await troveManager.getTroveStake(alice); + const stakeAfter = await troveManager.getTroveStake(aliceTroveId); const totalStakesAfter = await troveManager.totalStakes(); assert.isTrue(stakeAfter.eq(stakeBefore.add(toBN(dec(1, 18))))); @@ -2343,19 +2366,20 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const stakeBefore = await troveManager.getTroveStake(alice); + const stakeBefore = await troveManager.getTroveStake(aliceTroveId); const totalStakesBefore = await troveManager.totalStakes(); assert.isTrue(stakeBefore.gt(toBN("0"))); assert.isTrue(totalStakesBefore.gt(toBN("0"))); // Alice adjusts trove - coll decrease and debt decrease await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(500, "finney"), false, @@ -2364,7 +2388,7 @@ contract("BorrowerOperations", async (accounts) => { { from: alice } ); - const stakeAfter = await troveManager.getTroveStake(alice); + const stakeAfter = await troveManager.getTroveStake(aliceTroveId); const totalStakesAfter = await troveManager.totalStakes(); assert.isTrue(stakeAfter.eq(stakeBefore.sub(toBN(dec(5, 17))))); @@ -2380,7 +2404,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2391,6 +2415,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice adjusts trove - coll decrease and debt decrease await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(100, "finney"), false, @@ -2415,7 +2440,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2428,6 +2453,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2452,7 +2478,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2467,6 +2493,7 @@ contract("BorrowerOperations", async (accounts) => { // Alice adjusts trove - coll decrease and debt decrease await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(100, "finney"), false, @@ -2496,7 +2523,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2513,6 +2540,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2542,7 +2570,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2555,6 +2583,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2577,7 +2606,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -2590,6 +2619,7 @@ contract("BorrowerOperations", async (accounts) => { // approve ERC20 ETH await contracts.WETH.approve(borrowerOperations.address, dec(1, 24), { from: alice }); await borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, dec(1, "ether"), true, @@ -2613,21 +2643,22 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const aliceColl = await getTroveEntireColl(alice); - const aliceDebt = await getTroveEntireColl(alice); - const status_Before = await troveManager.getTroveStatus(alice); - const isInSortedList_Before = await sortedTroves.contains(alice); + const aliceColl = await getTroveEntireColl(aliceTroveId); + const aliceDebt = await getTroveEntireColl(aliceTroveId); + const status_Before = await troveManager.getTroveStatus(aliceTroveId); + const isInSortedList_Before = await sortedTroves.contains(aliceTroveId); assert.equal(status_Before, 1); // 1: Active assert.isTrue(isInSortedList_Before); await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, aliceColl, false, @@ -2645,14 +2676,14 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); await assertRevert( - borrowerOperations.adjustTrove(th._100pct, 0, false, 0, true, { + borrowerOperations.adjustTrove(aliceTroveId, th._100pct, 0, false, 0, true, { from: alice, }), "BorrowerOps: Debt increase requires non-zero debtChange" @@ -2660,14 +2691,14 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if it’s zero adjustment", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); await assertRevert( - borrowerOperations.adjustTrove(th._100pct, 0, false, 0, false, { + borrowerOperations.adjustTrove(aliceTroveId, th._100pct, 0, false, 0, false, { from: alice, }), "BorrowerOps: There must be either a collateral change or a debt change" @@ -2680,17 +2711,18 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - const aliceColl = await getTroveEntireColl(alice); + const aliceColl = await getTroveEntireColl(aliceTroveId); // Requested coll withdrawal > coll in the trove await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, aliceColl.add(toBN(1)), false, @@ -2701,12 +2733,13 @@ contract("BorrowerOperations", async (accounts) => { ); await assertRevert( borrowerOperations.adjustTrove( + aliceTroveId, th._100pct, aliceColl.add(toBN(dec(37, "ether"))), false, 0, false, - { from: bob } + { from: alice } ) ); }); @@ -2717,12 +2750,12 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); - await openTrove({ + const { troveId: BTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: B }, }); - const bobDebt = await getTroveEntireDebt(B); + const bobDebt = await getTroveEntireDebt(BTroveId); // Bob transfers some Bold to carol await boldToken.transfer(C, dec(10, 18), { from: B }); @@ -2732,6 +2765,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(B_BoldBal.lt(bobDebt)); const repayBoldPromise_B = borrowerOperations.adjustTrove( + BTroveId, th._100pct, 0, false, @@ -2800,7 +2834,7 @@ contract("BorrowerOperations", async (accounts) => { // --- closeTrove() --- it("closeTrove(): reverts when it would lower the TCR below CCR", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(300, 16)), extraParams: { from: alice }, }); @@ -2818,7 +2852,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await troveManager.checkRecoveryMode(price)); await assertRevert( - borrowerOperations.closeTrove({ from: alice }), + borrowerOperations.closeTrove(aliceTroveId, { from: alice }), "BorrowerOps: An operation that would result in TCR < CCR is not permitted" ); }); @@ -2837,7 +2871,7 @@ contract("BorrowerOperations", async (accounts) => { // Carol with no active trove attempts to close her trove try { - const txCarol = await borrowerOperations.closeTrove({ from: carol }); + const txCarol = await borrowerOperations.closeTrove(th.addressToTroveId(carol), { from: carol }); assert.isFalse(txCarol.receipt.status); } catch (err) { assert.include(err.message, "revert"); @@ -2850,12 +2884,12 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -2870,7 +2904,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Bob successfully closes his trove - const txBob = await borrowerOperations.closeTrove({ from: bob }); + const txBob = await borrowerOperations.closeTrove(bobTroveId, { from: bob }); assert.isTrue(txBob.receipt.status); await priceFeed.setPrice(dec(100, 18)); @@ -2879,7 +2913,7 @@ contract("BorrowerOperations", async (accounts) => { // Carol attempts to close her trove during Recovery Mode await assertRevert( - borrowerOperations.closeTrove({ from: carol }), + borrowerOperations.closeTrove(carolTroveId, { from: carol }), "BorrowerOps: Operation not permitted during Recovery Mode" ); }); @@ -2891,13 +2925,13 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceCollBefore = await getTroveEntireColl(alice); + const aliceCollBefore = await getTroveEntireColl(aliceTroveId); const dennisBold = await boldToken.balanceOf(dennis); assert.isTrue(aliceCollBefore.gt(toBN("0"))); assert.isTrue(dennisBold.gt(toBN("0"))); @@ -2908,9 +2942,9 @@ contract("BorrowerOperations", async (accounts) => { }); // Alice attempts to close trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); - const aliceCollAfter = await getTroveEntireColl(alice); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); assert.equal(aliceCollAfter, "0"); }); @@ -2921,13 +2955,13 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceDebtBefore = await getTroveEntireColl(alice); + const aliceDebtBefore = await getTroveEntireColl(aliceTroveId); const dennisBold = await boldToken.balanceOf(dennis); assert.isTrue(aliceDebtBefore.gt(toBN("0"))); assert.isTrue(dennisBold.gt(toBN("0"))); @@ -2938,9 +2972,9 @@ contract("BorrowerOperations", async (accounts) => { }); // Alice attempts to close trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); - const aliceCollAfter = await getTroveEntireColl(alice); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); assert.equal(aliceCollAfter, "0"); }); @@ -2951,13 +2985,13 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceStakeBefore = await getTroveStake(alice); + const aliceStakeBefore = await getTroveStake(aliceTroveId); assert.isTrue(aliceStakeBefore.gt(toBN("0"))); const dennisBold = await boldToken.balanceOf(dennis); @@ -2970,9 +3004,9 @@ contract("BorrowerOperations", async (accounts) => { }); // Alice attempts to close trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); - const stakeAfter = (await troveManager.Troves(alice))[2].toString(); + const stakeAfter = (await troveManager.Troves(aliceTroveId))[2].toString(); assert.equal(stakeAfter, "0"); // check withdrawal was successful }); @@ -2985,7 +3019,7 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -2995,19 +3029,19 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // Liquidate Bob - await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Price bounces back await priceFeed.setPrice(dec(200, 18)); // Alice and Carol open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: carol_Id } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -3017,23 +3051,23 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // Get Alice's pending reward snapshots - const L_ETH_A_Snapshot = (await troveManager.rewardSnapshots(alice))[0]; + const L_ETH_A_Snapshot = (await troveManager.rewardSnapshots(aliceTroveId))[0]; const L_boldDebt_A_Snapshot = ( - await troveManager.rewardSnapshots(alice) + await troveManager.rewardSnapshots(aliceTroveId) )[1]; assert.isTrue(L_ETH_A_Snapshot.gt(toBN("0"))); assert.isTrue(L_boldDebt_A_Snapshot.gt(toBN("0"))); // Liquidate Carol - await troveManager.liquidate(carol); - assert.isFalse(await sortedTroves.contains(carol)); + await troveManager.liquidate(carol_Id); + assert.isFalse(await sortedTroves.contains(carol_Id)); // Get Alice's pending reward snapshots after Carol's liquidation. Check above 0 const L_ETH_Snapshot_A_AfterLiquidation = ( - await troveManager.rewardSnapshots(alice) + await troveManager.rewardSnapshots(aliceTroveId) )[0]; const L_boldDebt_Snapshot_A_AfterLiquidation = ( - await troveManager.rewardSnapshots(alice) + await troveManager.rewardSnapshots(aliceTroveId) )[1]; assert.isTrue(L_ETH_Snapshot_A_AfterLiquidation.gt(toBN("0"))); @@ -3047,14 +3081,14 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(200, 18)); // Alice closes trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // Check Alice's pending reward snapshots are zero const L_ETH_Snapshot_A_afterAliceCloses = ( - await troveManager.rewardSnapshots(alice) + await troveManager.rewardSnapshots(aliceTroveId) )[0]; const L_boldDebt_Snapshot_A_afterAliceCloses = ( - await troveManager.rewardSnapshots(alice) + await troveManager.rewardSnapshots(aliceTroveId) )[1]; assert.equal(L_ETH_Snapshot_A_afterAliceCloses, "0"); @@ -3068,18 +3102,18 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); // Check Trove is active - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(aliceTroveId); const status_Before = alice_Trove_Before[3]; assert.equal(status_Before, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); // to compensate borrowing fees await boldToken.transfer(alice, await boldToken.balanceOf(dennis), { @@ -3087,29 +3121,29 @@ contract("BorrowerOperations", async (accounts) => { }); // Close the trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const status_After = alice_Trove_After[3]; assert.equal(status_After, 2); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); }); it("closeTrove(): reduces ActivePool ETH and raw ether by correct amount", async () => { - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const dennisColl = await getTroveEntireColl(dennis); - const aliceColl = await getTroveEntireColl(alice); + const dennisColl = await getTroveEntireColl(dennisTroveId); + const aliceColl = await getTroveEntireColl(aliceTroveId); assert.isTrue(dennisColl.gt("0")); assert.isTrue(aliceColl.gt("0")); @@ -3128,7 +3162,7 @@ contract("BorrowerOperations", async (accounts) => { }); // Close the trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // Check after const activePool_ETH_After = await activePool.getETHBalance(); @@ -3140,19 +3174,19 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces ActivePool debt by correct amount", async () => { - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const dennisDebt = await getTroveEntireDebt(dennis); - const aliceDebt = await getTroveEntireDebt(alice); + const dennisDebt = await getTroveEntireDebt(dennisTroveId); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); assert.isTrue(dennisDebt.gt("0")); assert.isTrue(aliceDebt.gt("0")); @@ -3167,7 +3201,7 @@ contract("BorrowerOperations", async (accounts) => { }); // Close the trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // Check after const activePool_Debt_After = (await activePool.getBoldDebt()).toString(); @@ -3175,26 +3209,26 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): updates the the total stakes", async () => { - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); // Get individual stakes - const aliceStakeBefore = await getTroveStake(alice); - const bobStakeBefore = await getTroveStake(bob); - const dennisStakeBefore = await getTroveStake(dennis); + const aliceStakeBefore = await getTroveStake(aliceTroveId); + const bobStakeBefore = await getTroveStake(bobTroveId); + const dennisStakeBefore = await getTroveStake(dennisTroveId); assert.isTrue(aliceStakeBefore.gt("0")); assert.isTrue(bobStakeBefore.gt("0")); assert.isTrue(dennisStakeBefore.gt("0")); @@ -3213,10 +3247,10 @@ contract("BorrowerOperations", async (accounts) => { }); // Alice closes trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // Check stake and total stakes get updated - const aliceStakeAfter = await getTroveStake(alice); + const aliceStakeAfter = await getTroveStake(aliceTroveId); const totalStakesAfter = await troveManager.totalStakes(); assert.equal(aliceStakeAfter, 0); @@ -3232,13 +3266,13 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceColl = await getTroveEntireColl(alice); + const aliceColl = await getTroveEntireColl(aliceTroveId); assert.isTrue(aliceColl.gt(toBN("0"))); const alice_ETHBalance_Before = web3.utils.toBN( @@ -3250,7 +3284,7 @@ contract("BorrowerOperations", async (accounts) => { from: dennis, }); - await borrowerOperations.closeTrove({ from: alice, gasPrice: 0 }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice, gasPrice: 0 }); const alice_ETHBalance_After = web3.utils.toBN( await contracts.WETH.balanceOf(alice) @@ -3266,13 +3300,13 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceDebt = await getTroveEntireDebt(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebt.gt(toBN("0"))); // to compensate borrowing fees @@ -3284,7 +3318,7 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(alice_BoldBalance_Before.gt(toBN("0"))); // close trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // check alice Bold balance after const alice_BoldBalance_After = await boldToken.balanceOf(alice); @@ -3296,32 +3330,32 @@ contract("BorrowerOperations", async (accounts) => { it("closeTrove(): applies pending rewards", async () => { // --- SETUP --- - await openTrove({ + const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(1000000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); - const whaleDebt = await getTroveEntireDebt(whale); - const whaleColl = await getTroveEntireColl(whale); + const whaleDebt = await getTroveEntireDebt(whaleTroveId); + const whaleColl = await getTroveEntireColl(whaleTroveId); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, }); - const carolDebt = await getTroveEntireDebt(carol); - const carolColl = await getTroveEntireColl(carol); + const carolDebt = await getTroveEntireDebt(carolTroveId); + const carolColl = await getTroveEntireColl(carolTroveId); // Whale transfers to A and B to cover their fees await boldToken.transfer(alice, dec(10000, 18), { from: whale }); @@ -3334,14 +3368,15 @@ contract("BorrowerOperations", async (accounts) => { const price = await priceFeed.getPrice(); // liquidate Carol's Trove, Alice and Bob earn rewards. - const liquidationTx = await troveManager.liquidate(carol, { + const liquidationTx = await troveManager.liquidate(carolTroveId, { from: owner, }); const [liquidatedDebt_C, liquidatedColl_C, gasComp_C] = th.getEmittedLiquidationValues(liquidationTx); - // Dennis opens a new Trove + // Carol opens a new Trove await openTrove({ + troveIndex: 1, extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -3355,7 +3390,7 @@ contract("BorrowerOperations", async (accounts) => { const alice_BoldDebtRewardSnapshot_Before = alice_rewardSnapshot_Before[1]; - const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot_Before = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot_Before = bob_rewardSnapshot_Before[0]; const bob_BoldDebtRewardSnapshot_Before = bob_rewardSnapshot_Before[1]; @@ -3374,15 +3409,13 @@ contract("BorrowerOperations", async (accounts) => { 100 ); - const pendingCollReward_A = await troveManager.getPendingETHReward(alice); - const pendingDebtReward_A = await troveManager.getPendingBoldDebtReward( - alice - ); + const pendingCollReward_A = await troveManager.getPendingETHReward(aliceTroveId); + const pendingDebtReward_A = await troveManager.getPendingBoldDebtReward(aliceTroveId); assert.isTrue(pendingCollReward_A.gt("0")); assert.isTrue(pendingDebtReward_A.gt("0")); // Close Alice's trove. Alice's pending rewards should be removed from the DefaultPool when she close. - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); const defaultPool_ETH_afterAliceCloses = await defaultPool.getETHBalance(); const defaultPool_BoldDebt_afterAliceCloses = @@ -3405,6 +3438,7 @@ contract("BorrowerOperations", async (accounts) => { // whale adjusts trove, pulling their rewards out of DefaultPool await borrowerOperations.adjustTrove( + whaleTroveId, th._100pct, 0, false, @@ -3414,7 +3448,7 @@ contract("BorrowerOperations", async (accounts) => { ); // Close Bob's trove. Expect DefaultPool coll and debt to drop to 0, since closing pulls his rewards out. - await borrowerOperations.closeTrove({ from: bob }); + await borrowerOperations.closeTrove(bobTroveId, { from: bob }); const defaultPool_ETH_afterBobCloses = await defaultPool.getETHBalance(); const defaultPool_BoldDebt_afterBobCloses = @@ -3436,7 +3470,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: A }, }); - await openTrove({ + const { troveId: BTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: B }, @@ -3447,11 +3481,11 @@ contract("BorrowerOperations", async (accounts) => { //Confirm B's Bold balance is less than his trove debt const B_BoldBal = await boldToken.balanceOf(B); - const B_troveDebt = await getTroveEntireDebt(B); + const B_troveDebt = await getTroveEntireDebt(BTroveId); assert.isTrue(B_BoldBal.lt(B_troveDebt)); - const closeTrovePromise_B = borrowerOperations.closeTrove({ from: B }); + const closeTrovePromise_B = borrowerOperations.closeTrove(BTroveId, { from: B }); // Check closing trove reverts await assertRevert( @@ -3464,34 +3498,28 @@ contract("BorrowerOperations", async (accounts) => { // TODO: use rawLogs instead of logs it("openTrove(): emits a TroveUpdated event with the correct collateral and debt", async () => { - const txA = ( - await openTrove({ - extraBoldAmount: toBN(dec(15000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: A }, - }) - ).tx; - const txB = ( - await openTrove({ - extraBoldAmount: toBN(dec(5000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: B }, - }) - ).tx; - const txC = ( - await openTrove({ - extraBoldAmount: toBN(dec(3000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: C }, - }) - ).tx; + const { troveId: ATroveId, tx: txA } = await openTrove({ + extraBoldAmount: toBN(dec(15000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: A }, + }); + const { troveId: BTroveId, tx: txB } = await openTrove({ + extraBoldAmount: toBN(dec(5000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: B }, + }); + const { troveId: CTroveId, tx: txC } = await openTrove({ + extraBoldAmount: toBN(dec(3000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: C }, + }); - const A_Coll = await getTroveEntireColl(A); - const B_Coll = await getTroveEntireColl(B); - const C_Coll = await getTroveEntireColl(C); - const A_Debt = await getTroveEntireDebt(A); - const B_Debt = await getTroveEntireDebt(B); - const C_Debt = await getTroveEntireDebt(C); + const A_Coll = await getTroveEntireColl(ATroveId); + const B_Coll = await getTroveEntireColl(BTroveId); + const C_Coll = await getTroveEntireColl(CTroveId); + const A_Debt = await getTroveEntireDebt(ATroveId); + const B_Debt = await getTroveEntireDebt(BTroveId); + const C_Debt = await getTroveEntireDebt(CTroveId); const A_emittedDebt = toBN( th.getEventArgByName(txA, "TroveUpdated", "_debt") @@ -3530,24 +3558,20 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue((await troveManager.baseRate()).gt(baseRateBefore)); - const txD = ( - await openTrove({ - extraBoldAmount: toBN(dec(5000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: D }, - }) - ).tx; - const txE = ( - await openTrove({ - extraBoldAmount: toBN(dec(3000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: E }, - }) - ).tx; - const D_Coll = await getTroveEntireColl(D); - const E_Coll = await getTroveEntireColl(E); - const D_Debt = await getTroveEntireDebt(D); - const E_Debt = await getTroveEntireDebt(E); + const { troveId: DTroveId, tx: txD } = await openTrove({ + extraBoldAmount: toBN(dec(5000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: D }, + }); + const { troveId: ETroveId, tx: txE } = await openTrove({ + extraBoldAmount: toBN(dec(3000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: E }, + }); + const D_Coll = await getTroveEntireColl(DTroveId); + const E_Coll = await getTroveEntireColl(ETroveId); + const D_Debt = await getTroveEntireDebt(DTroveId); + const E_Debt = await getTroveEntireDebt(ETroveId); const D_emittedDebt = toBN( th.getEventArgByName(txD, "TroveUpdated", "_debt") @@ -3573,7 +3597,7 @@ contract("BorrowerOperations", async (accounts) => { it("openTrove(): Opens a trove with net debt >= minimum net debt", async () => { // Add 1 wei to correct for rounding error in helper function - const txA = await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getNetBorrowingAmount(MIN_NET_DEBT.add(toBN(1))), A, @@ -3581,10 +3605,9 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: A, value: dec(100, 30) } ); - assert.isTrue(txA.receipt.status); - assert.isTrue(await sortedTroves.contains(A)); + assert.isTrue(await sortedTroves.contains(ATroveId)); - const txC = await th.openTroveWrapper(contracts, + const CTroveId = await th.openTroveWrapper(contracts, th._100pct, await getNetBorrowingAmount(MIN_NET_DEBT.add(toBN(dec(47789898, 22)))), A, @@ -3592,8 +3615,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: C, value: dec(100, 30) } ); - assert.isTrue(txC.receipt.status); - assert.isTrue(await sortedTroves.contains(C)); + assert.isTrue(await sortedTroves.contains(CTroveId)); }); it("openTrove(): reverts if net debt < minimum net debt", async () => { @@ -3794,20 +3816,20 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); // Carol opens at 150% ICR in Recovery Mode - const txCarol = ( + const { troveId: carolTroveId, tx: txCarol} = ( await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(15, 17)), extraParams: { from: carol }, }) - ).tx; + ); assert.isTrue(txCarol.receipt.status); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); - const carol_TroveStatus = await troveManager.getTroveStatus(carol); + const carol_TroveStatus = await troveManager.getTroveStatus(carolTroveId); assert.equal(carol_TroveStatus, 1); - const carolICR = await troveManager.getCurrentICR(carol, price); + const carolICR = await troveManager.getCurrentICR(carolTroveId, price); assert.isTrue(carolICR.eq(toBN(dec(150, 16)))); }); @@ -3846,9 +3868,10 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): creates a new Trove and assigns the correct collateral and debt amount", async () => { - const debt_Before = await getTroveEntireDebt(alice); - const coll_Before = await getTroveEntireColl(alice); - const status_Before = await troveManager.getTroveStatus(alice); + /* + const debt_Before = await getTroveEntireDebt(aliceTroveId); + const coll_Before = await getTroveEntireColl(aliceTroveId); + const status_Before = await troveManager.getTroveStatus(aliceTroveId); // check coll and debt before assert.equal(debt_Before, 0); @@ -3856,9 +3879,10 @@ contract("BorrowerOperations", async (accounts) => { // check non-existent status assert.equal(status_Before, 0); + */ const BoldRequest = MIN_NET_DEBT; - await th.openTroveWrapper(contracts,th._100pct, MIN_NET_DEBT, carol, carol, 0, { + const aliceTroveId = await th.openTroveWrapper(contracts,th._100pct, MIN_NET_DEBT, carol, carol, 0, { from: alice, value: dec(100, "ether"), }); @@ -3866,9 +3890,9 @@ contract("BorrowerOperations", async (accounts) => { // Get the expected debt based on the Bold request (adding fee and liq. reserve on top) const expectedDebt = BoldRequest.add(BOLD_GAS_COMPENSATION); - const debt_After = await getTroveEntireDebt(alice); - const coll_After = await getTroveEntireColl(alice); - const status_After = await troveManager.getTroveStatus(alice); + const debt_After = await getTroveEntireDebt(aliceTroveId); + const coll_After = await getTroveEntireColl(aliceTroveId); + const status_After = await troveManager.getTroveStatus(aliceTroveId); // check coll and debt after assert.isTrue(coll_After.gt("0")); @@ -3880,11 +3904,11 @@ contract("BorrowerOperations", async (accounts) => { assert.equal(status_After, 1); }); - it("openTrove(): adds Trove owner to TroveOwners array", async () => { - const TroveOwnersCount_Before = ( - await troveManager.getTroveOwnersCount() + it("openTrove(): adds Trove owner to TroveIds array", async () => { + const TroveIdsCount_Before = ( + await troveManager.getTroveIdsCount() ).toString(); - assert.equal(TroveOwnersCount_Before, "0"); + assert.equal(TroveIdsCount_Before, "0"); await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), @@ -3892,26 +3916,26 @@ contract("BorrowerOperations", async (accounts) => { extraParams: { from: alice }, }); - const TroveOwnersCount_After = ( - await troveManager.getTroveOwnersCount() + const TroveIdsCount_After = ( + await troveManager.getTroveIdsCount() ).toString(); - assert.equal(TroveOwnersCount_After, "1"); + assert.equal(TroveIdsCount_After, "1"); }); it("openTrove(): creates a stake and adds it to total stakes", async () => { - const aliceStakeBefore = await getTroveStake(alice); + //const aliceStakeBefore = await getTroveStake(aliceTroveId); const totalStakesBefore = await troveManager.totalStakes(); - assert.equal(aliceStakeBefore, "0"); + //assert.equal(aliceStakeBefore, "0"); assert.equal(totalStakesBefore, "0"); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceCollAfter = await getTroveEntireColl(alice); - const aliceStakeAfter = await getTroveStake(alice); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); + const aliceStakeAfter = await getTroveStake(aliceTroveId); assert.isTrue(aliceCollAfter.gt(toBN("0"))); assert.isTrue(aliceStakeAfter.eq(aliceCollAfter)); @@ -3922,19 +3946,19 @@ contract("BorrowerOperations", async (accounts) => { it("openTrove(): inserts Trove to Sorted Troves list", async () => { // Check before - const aliceTroveInList_Before = await sortedTroves.contains(alice); + //const aliceTroveInList_Before = await sortedTroves.contains(aliceTroveId); const listIsEmpty_Before = await sortedTroves.isEmpty(); - assert.equal(aliceTroveInList_Before, false); + //assert.equal(aliceTroveInList_Before, false); assert.equal(listIsEmpty_Before, true); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); // check after - const aliceTroveInList_After = await sortedTroves.contains(alice); + const aliceTroveInList_After = await sortedTroves.contains(aliceTroveId); const listIsEmpty_After = await sortedTroves.isEmpty(); assert.equal(aliceTroveInList_After, true); assert.equal(listIsEmpty_After, false); @@ -3948,12 +3972,12 @@ contract("BorrowerOperations", async (accounts) => { assert.equal(activePool_ETH_Before, 0); assert.equal(activePool_RawEther_Before, 0); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceCollAfter = await getTroveEntireColl(alice); + const aliceCollAfter = await getTroveEntireColl(aliceTroveId); const activePool_ETH_After = await activePool.getETHBalance(); const activePool_RawEther_After = toBN( @@ -3971,7 +3995,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -3983,7 +4007,7 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // close Carol's Trove, liquidating her 1 ether and 180Bold. - const liquidationTx = await troveManager.liquidate(carol, { + const liquidationTx = await troveManager.liquidate(carolTroveId, { from: owner, }); const [liquidatedDebt, liquidatedColl, gasComp] = @@ -3999,14 +4023,14 @@ contract("BorrowerOperations", async (accounts) => { assert.isTrue(L_Bold.gt(toBN("0"))); // Bob opens trove - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); // Check Bob's snapshots of L_ETH and L_Bold equal the respective current values - const bob_rewardSnapshot = await troveManager.rewardSnapshots(bob); + const bob_rewardSnapshot = await troveManager.rewardSnapshots(bobTroveId); const bob_ETHrewardSnapshot = bob_rewardSnapshot[0]; const bob_BoldDebtRewardSnapshot = bob_rewardSnapshot[1]; @@ -4024,7 +4048,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -4036,44 +4060,45 @@ contract("BorrowerOperations", async (accounts) => { }); // Check Trove is active - const alice_Trove_1 = await troveManager.Troves(alice); + const alice_Trove_1 = await troveManager.Troves(aliceTroveId); const status_1 = alice_Trove_1[3]; assert.equal(status_1, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); // to compensate borrowing fees await boldToken.transfer(alice, dec(10000, 18), { from: whale }); // Repay and close Trove - await borrowerOperations.closeTrove({ from: alice }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); // Check Trove is closed - const alice_Trove_2 = await troveManager.Troves(alice); + const alice_Trove_2 = await troveManager.Troves(aliceTroveId); const status_2 = alice_Trove_2[3]; assert.equal(status_2, 2); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Re-open Trove await openTrove({ + troveIndex: 0, extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); // Check Trove is re-opened - const alice_Trove_3 = await troveManager.Troves(alice); + const alice_Trove_3 = await troveManager.Troves(aliceTroveId); const status_3 = alice_Trove_3[3]; assert.equal(status_3, 1); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); }); it("openTrove(): increases the Trove's Bold debt by the correct amount", async () => { // check before - const alice_Trove_Before = await troveManager.Troves(alice); + const alice_Trove_Before = await troveManager.Troves(th.addressToTroveId(alice)); const debt_Before = alice_Trove_Before[0]; assert.equal(debt_Before, 0); - await th.openTroveWrapper(contracts, + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), alice, @@ -4083,7 +4108,7 @@ contract("BorrowerOperations", async (accounts) => { ); // check after - const alice_Trove_After = await troveManager.Troves(alice); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); const debt_After = alice_Trove_After[0]; th.assertIsApproximatelyEqual(debt_After, dec(10000, 18), 10000); }); @@ -4092,12 +4117,12 @@ contract("BorrowerOperations", async (accounts) => { const activePool_BoldDebt_Before = await activePool.getBoldDebt(); assert.equal(activePool_BoldDebt_Before, 0); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - const aliceDebt = await getTroveEntireDebt(alice); + const aliceDebt = await getTroveEntireDebt(aliceTroveId); assert.isTrue(aliceDebt.gt(toBN("0"))); const activePool_BoldDebt_After = await activePool.getBoldDebt(); @@ -4363,7 +4388,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4374,8 +4399,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4416,7 +4441,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4427,8 +4452,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4469,7 +4494,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4480,8 +4505,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4521,7 +4546,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4532,8 +4557,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4574,7 +4599,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4585,8 +4610,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4628,7 +4653,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4639,8 +4664,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4682,7 +4707,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4693,8 +4718,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4736,7 +4761,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4747,8 +4772,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -4790,7 +4815,7 @@ contract("BorrowerOperations", async (accounts) => { 0, { from: alice, value: troveColl } ); - await th.openTroveWrapper(contracts, + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, troveBoldAmount, bob, @@ -4801,8 +4826,8 @@ contract("BorrowerOperations", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); - const liquidationTx = await troveManager.liquidate(bob); - assert.isFalse(await sortedTroves.contains(bob)); + const liquidationTx = await troveManager.liquidate(bobTroveId); + assert.isFalse(await sortedTroves.contains(bobTroveId)); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); diff --git a/contracts/test/CollSurplusPool.js b/contracts/test/CollSurplusPool.js index d9bbbf92..afc77a86 100644 --- a/contracts/test/CollSurplusPool.js +++ b/contracts/test/CollSurplusPool.js @@ -82,14 +82,14 @@ contract("CollSurplusPool", async (accounts) => { it("CollSurplusPool: claimColl(): Reverts if caller is not Borrower Operations", async () => { await th.assertRevert( - collSurplusPool.claimColl(A, { from: A }), + collSurplusPool.claimColl(A, th.addressToTroveId(A), { from: A }), "CollSurplusPool: Caller is not Borrower Operations" ); }); it("CollSurplusPool: claimColl(): Reverts if nothing to claim", async () => { await th.assertRevert( - borrowerOperations.claimCollateral({ from: A }), + borrowerOperations.claimCollateral(th.addressToTroveId(A), { from: A }), "CollSurplusPool: No collateral available to claim" ); }); diff --git a/contracts/test/GasCompensationTest.js b/contracts/test/GasCompensationTest.js index 292663ff..0d4f0bc2 100644 --- a/contracts/test/GasCompensationTest.js +++ b/contracts/test/GasCompensationTest.js @@ -383,64 +383,64 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: whale } }); // A opens with 1 ETH, 110 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN("1818181818181818181"), extraParams: { from: alice }, }); const alice_ICR = ( - await troveManager.getCurrentICR(alice, price) + await troveManager.getCurrentICR(aliceTroveId, price) ).toString(); // Expect aliceICR = (1 * 200) / (110) = 181.81% assert.isAtMost(th.getDifference(alice_ICR, "1818181818181818181"), 1000); // B opens with 0.5 ETH, 50 Bold - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); - const bob_ICR = (await troveManager.getCurrentICR(bob, price)).toString(); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); + const bob_ICR = (await troveManager.getCurrentICR(bobTroveId, price)).toString(); // Expect Bob's ICR = (0.5 * 200) / 50 = 200% assert.isAtMost(th.getDifference(bob_ICR, dec(2, 18)), 1000); // F opens with 1 ETH, 100 Bold - await openTrove({ + const { troveId: flynTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(100, 18), extraParams: { from: flyn }, }); - const flyn_ICR = (await troveManager.getCurrentICR(flyn, price)).toString(); + const flyn_ICR = (await troveManager.getCurrentICR(flynTroveId, price)).toString(); // Expect Flyn's ICR = (1 * 200) / 100 = 200% assert.isAtMost(th.getDifference(flyn_ICR, dec(2, 18)), 1000); // C opens with 2.5 ETH, 160 Bold - await openTrove({ ICR: toBN(dec(3125, 15)), extraParams: { from: carol } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(3125, 15)), extraParams: { from: carol } }); const carol_ICR = ( - await troveManager.getCurrentICR(carol, price) + await troveManager.getCurrentICR(carolTroveId, price) ).toString(); // Expect Carol's ICR = (2.5 * 200) / (160) = 312.50% assert.isAtMost(th.getDifference(carol_ICR, "3125000000000000000"), 1000); // D opens with 1 ETH, 0 Bold - await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: dennis } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: dennis } }); const dennis_ICR = ( - await troveManager.getCurrentICR(dennis, price) + await troveManager.getCurrentICR(dennisTroveId, price) ).toString(); // Expect Dennis's ICR = (1 * 200) / (50) = 400.00% assert.isAtMost(th.getDifference(dennis_ICR, dec(4, 18)), 1000); // E opens with 4405.45 ETH, 32598.35 Bold - await openTrove({ + const { troveId: erinTroveId } = await openTrove({ ICR: toBN("27028668628933700000"), extraParams: { from: erin }, }); - const erin_ICR = (await troveManager.getCurrentICR(erin, price)).toString(); + const erin_ICR = (await troveManager.getCurrentICR(erinTroveId, price)).toString(); // Expect Erin's ICR = (4405.45 * 200) / (32598.35) = 2702.87% assert.isAtMost(th.getDifference(erin_ICR, "27028668628933700000"), 100000); // H opens with 1 ETH, 180 Bold - await openTrove({ + const { troveId: harrietTroveId } = await openTrove({ ICR: toBN("1111111111111111111"), extraParams: { from: harriet }, }); const harriet_ICR = ( - await troveManager.getCurrentICR(harriet, price) + await troveManager.getCurrentICR(harrietTroveId, price) ).toString(); // Expect Harriet's ICR = (1 * 200) / (180) = 111.11% assert.isAtMost(th.getDifference(harriet_ICR, "1111111111111111111"), 1000); @@ -452,17 +452,17 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: whale } }); // A-E open troves - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(100, 18), extraParams: { from: alice }, }); - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(200, 18), extraParams: { from: bob }, }); - const { totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(300, 18), extraParams: { from: carol }, @@ -499,7 +499,7 @@ contract("Gas compensation tests", async (accounts) => { -> Expect 0.5% of collaterall to be sent to liquidator, as gas compensation */ // Check collateral value in USD is < $10 - const aliceColl = (await troveManager.Troves(alice))[1]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; assert.isFalse(await th.checkRecoveryMode(contracts)); @@ -507,7 +507,7 @@ contract("Gas compensation tests", async (accounts) => { const liquidatorBalance_before_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(alice, { from: liquidator }); + await troveManager.liquidate(aliceTroveId, { from: liquidator }); const liquidatorBalance_after_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -536,14 +536,14 @@ contract("Gas compensation tests", async (accounts) => { -> Expect 0.5% of collaterall to be sent to liquidator, as gas compensation */ // Check collateral value in USD is < $10 - const bobColl = (await troveManager.Troves(bob))[1]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(bob, { from: liquidator }); + await troveManager.liquidate(bobTroveId, { from: liquidator }); const liquidatorBalance_after_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -579,14 +579,14 @@ contract("Gas compensation tests", async (accounts) => { -> Expect 0.5% of collaterall to be sent to liquidator, as gas compensation */ // Check collateral value in USD is < $10 - const carolColl = (await troveManager.Troves(carol))[1]; + const carolColl = (await troveManager.Troves(carolTroveId))[1]; assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_C = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(carol, { from: liquidator }) + await troveManager.liquidate(carolTroveId, { from: liquidator }); const liquidatorBalance_after_C = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -620,12 +620,12 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: whale } }); // A-E open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(200, 18), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(120, 16)), extraBoldAmount: dec(5000, 18), extraParams: { from: bob }, @@ -672,18 +672,18 @@ contract("Gas compensation tests", async (accounts) => { and (1 - 0.05000025000125001) = 0.94999974999875 ETH remainder liquidated */ // Check collateral value in USD is > $10 - const aliceColl = (await troveManager.Troves(alice))[1]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; assert.isFalse(await th.checkRecoveryMode(contracts)); - const aliceICR = await troveManager.getCurrentICR(alice, price_1); + const aliceICR = await troveManager.getCurrentICR(aliceTroveId, price_1); assert.isTrue(aliceICR.lt(mv._MCR)); // Liquidate A (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(alice, { from: liquidator }); + await troveManager.liquidate(aliceTroveId, { from: liquidator }); const liquidatorBalance_after_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -720,18 +720,18 @@ contract("Gas compensation tests", async (accounts) => { and (15 - 0.666666666666666666) ETH remainder liquidated */ // Check collateral value in USD is > $10 - const bobColl = (await troveManager.Troves(bob))[1]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; assert.isFalse(await th.checkRecoveryMode(contracts)); - const bobICR = await troveManager.getCurrentICR(bob, price_2); + const bobICR = await troveManager.getCurrentICR(bobTroveId, price_2); assert.isTrue(bobICR.lte(mv._MCR)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(bob, { from: liquidator }) + await troveManager.liquidate(bobTroveId, { from: liquidator }); const liquidatorBalance_after_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -762,12 +762,12 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: whale } }); // A-E open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(2000, 18), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(1875, 15)), extraBoldAmount: dec(8000, 18), extraParams: { from: bob }, @@ -813,19 +813,19 @@ contract("Gas compensation tests", async (accounts) => { and (10.001 - 0.050005) ETH remainder liquidated */ // Check value of 0.5% of collateral in USD is > $10 - const aliceColl = (await troveManager.Troves(alice))[1]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; const _0pt5percent_aliceColl = aliceColl.div(web3.utils.toBN("200")); assert.isFalse(await th.checkRecoveryMode(contracts)); - const aliceICR = await troveManager.getCurrentICR(alice, price_1); + const aliceICR = await troveManager.getCurrentICR(aliceTroveId, price_1); assert.isTrue(aliceICR.lt(mv._MCR)); // Liquidate A (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(alice, { from: liquidator }); + await troveManager.liquidate(aliceTroveId, { from: liquidator }); const liquidatorBalance_after_A = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -857,19 +857,19 @@ contract("Gas compensation tests", async (accounts) => { and (37.5 - 0.1875 ETH) ETH remainder liquidated */ // Check value of 0.5% of collateral in USD is > $10 - const bobColl = (await troveManager.Troves(bob))[1]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; const _0pt5percent_bobColl = bobColl.div(web3.utils.toBN("200")); assert.isFalse(await th.checkRecoveryMode(contracts)); - const bobICR = await troveManager.getCurrentICR(bob, price_1); + const bobICR = await troveManager.getCurrentICR(bobTroveId, price_1); assert.isTrue(bobICR.lt(mv._MCR)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) const liquidatorBalance_before_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); - await troveManager.liquidate(bob, { from: liquidator }); + await troveManager.liquidate(bobTroveId, { from: liquidator }); const liquidatorBalance_after_B = web3.utils.toBN( await contracts.WETH.balanceOf(liquidator) ); @@ -899,12 +899,12 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: whale } }); // A-E open troves - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(100, 18), extraParams: { from: alice }, }); - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(200, 18), extraParams: { from: bob }, @@ -943,14 +943,14 @@ contract("Gas compensation tests", async (accounts) => { -> Expect 0.5% of collaterall to be sent to liquidator, as gas compensation */ // Check collateral value in USD is < $10 - const aliceColl = (await troveManager.Troves(alice))[1]; - const aliceDebt = (await troveManager.Troves(alice))[0]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; + const aliceDebt = (await troveManager.Troves(aliceTroveId))[0]; // th.logBN('TCR', await troveManager.getTCR(await priceFeed.getPrice())) assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate A (use 0 gas price to easily check the amount the compensation amount the liquidator receives) - const liquidationTxA = await troveManager.liquidate(alice, { + const liquidationTxA = await troveManager.liquidate(aliceTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); @@ -981,12 +981,12 @@ contract("Gas compensation tests", async (accounts) => { -> Expect 0.5% of collaterall to be sent to liquidator, as gas compensation */ // Check collateral value in USD is < $10 - const bobColl = (await troveManager.Troves(bob))[1]; - const bobDebt = (await troveManager.Troves(bob))[0]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; + const bobDebt = (await troveManager.Troves(bobTroveId))[0]; assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) - const liquidationTxB = await troveManager.liquidate(bob, { + const liquidationTxB = await troveManager.liquidate(bobTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); @@ -1014,12 +1014,12 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: whale } }); // A-E open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(200, 18), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(120, 16)), extraBoldAmount: dec(5000, 18), extraParams: { from: bob }, @@ -1060,8 +1060,8 @@ contract("Gas compensation tests", async (accounts) => { and (1 - 0.05000025000125001) = 0.94999974999875 ETH remainder liquidated */ // Check collateral value in USD is > $10 - const aliceColl = (await troveManager.Troves(alice))[1]; - const aliceDebt = (await troveManager.Troves(alice))[0]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; + const aliceDebt = (await troveManager.Troves(aliceTroveId))[0]; const aliceCollValueInUSD = await borrowerOperationsTester.getUSDValue( aliceColl, price_1 @@ -1073,11 +1073,11 @@ contract("Gas compensation tests", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); - const aliceICR = await troveManager.getCurrentICR(alice, price_1); + const aliceICR = await troveManager.getCurrentICR(aliceTroveId, price_1); assert.isTrue(aliceICR.lt(mv._MCR)); // Liquidate A (use 0 gas price to easily check the amount the compensation amount the liquidator receives) - const liquidationTxA = await troveManager.liquidate(alice, { + const liquidationTxA = await troveManager.liquidate(aliceTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); @@ -1112,16 +1112,16 @@ contract("Gas compensation tests", async (accounts) => { and (15 - 0.666666666666666666) ETH remainder liquidated */ // Check collateral value in USD is > $10 - const bobColl = (await troveManager.Troves(bob))[1]; - const bobDebt = (await troveManager.Troves(bob))[0]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; + const bobDebt = (await troveManager.Troves(bobTroveId))[0]; assert.isFalse(await th.checkRecoveryMode(contracts)); - const bobICR = await troveManager.getCurrentICR(bob, price_2); + const bobICR = await troveManager.getCurrentICR(bobTroveId, price_2); assert.isTrue(bobICR.lte(mv._MCR)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives - const liquidationTxB = await troveManager.liquidate(bob, { + const liquidationTxB = await troveManager.liquidate(bobTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); @@ -1151,12 +1151,12 @@ contract("Gas compensation tests", async (accounts) => { await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: whale } }); // A-E open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(2000, 18), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(1875, 15)), extraBoldAmount: dec(8000, 18), extraParams: { from: bob }, @@ -1188,17 +1188,17 @@ contract("Gas compensation tests", async (accounts) => { const price_1 = await priceFeed.getPrice(); // Check value of 0.5% of collateral in USD is > $10 - const aliceColl = (await troveManager.Troves(alice))[1]; - const aliceDebt = (await troveManager.Troves(alice))[0]; + const aliceColl = (await troveManager.Troves(aliceTroveId))[1]; + const aliceDebt = (await troveManager.Troves(aliceTroveId))[0]; const _0pt5percent_aliceColl = aliceColl.div(web3.utils.toBN("200")); assert.isFalse(await th.checkRecoveryMode(contracts)); - const aliceICR = await troveManager.getCurrentICR(alice, price_1); + const aliceICR = await troveManager.getCurrentICR(aliceTroveId, price_1); assert.isTrue(aliceICR.lt(mv._MCR)); // Liquidate A (use 0 gas price to easily check the amount the compensation amount the liquidator receives) - const liquidationTxA = await troveManager.liquidate(alice, { + const liquidationTxA = await troveManager.liquidate(aliceTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); @@ -1229,17 +1229,17 @@ contract("Gas compensation tests", async (accounts) => { and (37.5 - 0.1875 ETH) ETH remainder liquidated */ // Check value of 0.5% of collateral in USD is > $10 - const bobColl = (await troveManager.Troves(bob))[1]; - const bobDebt = (await troveManager.Troves(bob))[0]; + const bobColl = (await troveManager.Troves(bobTroveId))[1]; + const bobDebt = (await troveManager.Troves(bobTroveId))[0]; const _0pt5percent_bobColl = bobColl.div(web3.utils.toBN("200")); assert.isFalse(await th.checkRecoveryMode(contracts)); - const bobICR = await troveManager.getCurrentICR(bob, price_1); + const bobICR = await troveManager.getCurrentICR(bobTroveId, price_1); assert.isTrue(bobICR.lt(mv._MCR)); // Liquidate B (use 0 gas price to easily check the amount the compensation amount the liquidator receives) - const liquidationTxB = await troveManager.liquidate(bob, { + const liquidationTxB = await troveManager.liquidate(bobTroveId, { from: liquidator, gasPrice: GAS_PRICE, }); diff --git a/contracts/test/HintHelpers_getApproxHintTest.js b/contracts/test/HintHelpers_getApproxHintTest.js index adec62d3..e9a7c6da 100644 --- a/contracts/test/HintHelpers_getApproxHintTest.js +++ b/contracts/test/HintHelpers_getApproxHintTest.js @@ -11,6 +11,8 @@ let latestRandomSeed = 31337; const TroveManagerTester = artifacts.require("TroveManagerTester"); const BoldToken = artifacts.require("BoldToken"); +const INITIAL_PRICE = dec(100, 18); + contract("HintHelpers", async (accounts) => { const [owner] = accounts; @@ -114,23 +116,23 @@ contract("HintHelpers", async (accounts) => { numAccounts = 10; - await priceFeed.setPrice(dec(100, 18)); + await priceFeed.setPrice(INITIAL_PRICE); await makeTrovesInSequence(accounts, numAccounts); // await makeTrovesInParallel(accounts, numAccounts) }); it("setup: makes accounts with nominal ICRs increasing by 1% consecutively", async () => { // check first 10 accounts - const ICR_0 = await troveManager.getNominalICR(accounts[0]); - const ICR_1 = await troveManager.getNominalICR(accounts[1]); - const ICR_2 = await troveManager.getNominalICR(accounts[2]); - const ICR_3 = await troveManager.getNominalICR(accounts[3]); - const ICR_4 = await troveManager.getNominalICR(accounts[4]); - const ICR_5 = await troveManager.getNominalICR(accounts[5]); - const ICR_6 = await troveManager.getNominalICR(accounts[6]); - const ICR_7 = await troveManager.getNominalICR(accounts[7]); - const ICR_8 = await troveManager.getNominalICR(accounts[8]); - const ICR_9 = await troveManager.getNominalICR(accounts[9]); + const ICR_0 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[0]), INITIAL_PRICE); + const ICR_1 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[1]), INITIAL_PRICE); + const ICR_2 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[2]), INITIAL_PRICE); + const ICR_3 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[3]), INITIAL_PRICE); + const ICR_4 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[4]), INITIAL_PRICE); + const ICR_5 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[5]), INITIAL_PRICE); + const ICR_6 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[6]), INITIAL_PRICE); + const ICR_7 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[7]), INITIAL_PRICE); + const ICR_8 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[8]), INITIAL_PRICE); + const ICR_9 = await troveManager.getCurrentICR(th.addressToTroveId(accounts[9]), INITIAL_PRICE); assert.isTrue(ICR_0.eq(toBN(dec(200, 16)))); assert.isTrue(ICR_1.eq(toBN(dec(201, 16)))); @@ -155,78 +157,78 @@ contract("HintHelpers", async (accounts) => { const CR_250 = "2500000000000000000"; const CRPercent_250 = Number(web3.utils.fromWei(CR_250, "ether")) * 100; - let hintAddress; + let hintId; - // const hintAddress_250 = await functionCaller.troveManager_getApproxHint(CR_250, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_250 = await functionCaller.troveManager_getApproxHint(CR_250, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_250, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_250 = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_250 = - Number(web3.utils.fromWei(ICR_hintAddress_250, "ether")) * 100; + const ICR_hintId_250 = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_250 = + Number(web3.utils.fromWei(ICR_hintId_250, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position - ICR_Difference_250 = ICRPercent_hintAddress_250 - CRPercent_250; + ICR_Difference_250 = ICRPercent_hintId_250 - CRPercent_250; assert.isBelow(ICR_Difference_250, sqrtLength); // CR = 287% const CR_287 = "2870000000000000000"; const CRPercent_287 = Number(web3.utils.fromWei(CR_287, "ether")) * 100; - // const hintAddress_287 = await functionCaller.troveManager_getApproxHint(CR_287, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_287 = await functionCaller.troveManager_getApproxHint(CR_287, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_287, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_287 = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_287 = - Number(web3.utils.fromWei(ICR_hintAddress_287, "ether")) * 100; + const ICR_hintId_287 = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_287 = + Number(web3.utils.fromWei(ICR_hintId_287, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position - ICR_Difference_287 = ICRPercent_hintAddress_287 - CRPercent_287; + ICR_Difference_287 = ICRPercent_hintId_287 - CRPercent_287; assert.isBelow(ICR_Difference_287, sqrtLength); // CR = 213% const CR_213 = "2130000000000000000"; const CRPercent_213 = Number(web3.utils.fromWei(CR_213, "ether")) * 100; - // const hintAddress_213 = await functionCaller.troveManager_getApproxHint(CR_213, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_213 = await functionCaller.troveManager_getApproxHint(CR_213, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_213, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_213 = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_213 = - Number(web3.utils.fromWei(ICR_hintAddress_213, "ether")) * 100; + const ICR_hintId_213 = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_213 = + Number(web3.utils.fromWei(ICR_hintId_213, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position - ICR_Difference_213 = ICRPercent_hintAddress_213 - CRPercent_213; + ICR_Difference_213 = ICRPercent_hintId_213 - CRPercent_213; assert.isBelow(ICR_Difference_213, sqrtLength); // CR = 201% const CR_201 = "2010000000000000000"; const CRPercent_201 = Number(web3.utils.fromWei(CR_201, "ether")) * 100; - // const hintAddress_201 = await functionCaller.troveManager_getApproxHint(CR_201, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_201 = await functionCaller.troveManager_getApproxHint(CR_201, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_201, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_201 = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_201 = - Number(web3.utils.fromWei(ICR_hintAddress_201, "ether")) * 100; + const ICR_hintId_201 = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_201 = + Number(web3.utils.fromWei(ICR_hintId_201, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position - ICR_Difference_201 = ICRPercent_hintAddress_201 - CRPercent_201; + ICR_Difference_201 = ICRPercent_hintId_201 - CRPercent_201; assert.isBelow(ICR_Difference_201, sqrtLength); }); - /* Pass 100 random collateral ratios to getApproxHint(). For each, check whether the returned hint address is within + /* Pass 100 random collateral ratios to getApproxHint(). For each, check whether the returned hint id is within sqrt(length) positions of where a Trove with that CR should be inserted. */ // it("getApproxHint(): for 100 random CRs, returns the address of a Trove within sqrt(length) positions of the correct insert position", async () => { // const sqrtLength = Math.ceil(Math.sqrt(numAccounts)) @@ -241,7 +243,7 @@ contract("HintHelpers", async (accounts) => { // const ICR = web3.utils.toWei((ICR_Percent * 10).toString(), 'finney') // const hintAddress = await hintHelpers.getApproxHint(ICR, sqrtLength * 10) - // const ICR_hintAddress = await troveManager.getNominalICR(hintAddress) + // const ICR_hintAddress = await troveManager.getCurrentICR(hintAddres, INITIAL_PRICES) // const ICRPercent_hintAddress = Number(web3.utils.fromWei(ICR_hintAddress, 'ether')) * 100 // // check the hint position is at most sqrtLength positions away from the correct position @@ -257,26 +259,26 @@ contract("HintHelpers", async (accounts) => { const CR_Max = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; - let hintAddress; + let hintId; - // const hintAddress_Max = await functionCaller.troveManager_getApproxHint(CR_Max, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_Max = await functionCaller.troveManager_getApproxHint(CR_Max, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_Max, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_Max = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_Max = - Number(web3.utils.fromWei(ICR_hintAddress_Max, "ether")) * 100; + const ICR_hintId_Max = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_Max = + Number(web3.utils.fromWei(ICR_hintId_Max, "ether")) * 100; const firstTrove = await sortedTroves.getFirst(); - const ICR_FirstTrove = await troveManager.getNominalICR(firstTrove); + const ICR_FirstTrove = await troveManager.getCurrentICR(firstTrove, INITIAL_PRICE); const ICRPercent_FirstTrove = Number(web3.utils.fromWei(ICR_FirstTrove, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position - ICR_Difference_Max = ICRPercent_hintAddress_Max - ICRPercent_FirstTrove; + ICR_Difference_Max = ICRPercent_hintId_Max - ICRPercent_FirstTrove; assert.isBelow(ICR_Difference_Max, sqrtLength); }); @@ -286,33 +288,28 @@ contract("HintHelpers", async (accounts) => { // CR = MCR const CR_Min = "1100000000000000000"; - let hintAddress; + let hintId; - // const hintAddress_Min = await functionCaller.troveManager_getApproxHint(CR_Min, sqrtLength * 10) - ({ hintAddress, latestRandomSeed } = await hintHelpers.getApproxHint( + // const hintId_Min = await functionCaller.troveManager_getApproxHint(CR_Min, sqrtLength * 10) + ({ hintId, latestRandomSeed } = await hintHelpers.getApproxHint( CR_Min, sqrtLength * 10, latestRandomSeed )); - const ICR_hintAddress_Min = await troveManager.getNominalICR(hintAddress); - const ICRPercent_hintAddress_Min = - Number(web3.utils.fromWei(ICR_hintAddress_Min, "ether")) * 100; + const ICR_hintId_Min = await troveManager.getCurrentICR(hintId, INITIAL_PRICE); + const ICRPercent_hintId_Min = + Number(web3.utils.fromWei(ICR_hintId_Min, "ether")) * 100; const lastTrove = await sortedTroves.getLast(); - const ICR_LastTrove = await troveManager.getNominalICR(lastTrove); + const ICR_LastTrove = await troveManager.getCurrentICR(lastTrove, INITIAL_PRICE); const ICRPercent_LastTrove = Number(web3.utils.fromWei(ICR_LastTrove, "ether")) * 100; // check the hint position is at most sqrtLength positions away from the correct position const ICR_Difference_Min = - ICRPercent_hintAddress_Min - ICRPercent_LastTrove; + ICRPercent_hintId_Min - ICRPercent_LastTrove; assert.isBelow(ICR_Difference_Min, sqrtLength); }); - - it("computeNominalCR()", async () => { - const NICR = await hintHelpers.computeNominalCR(dec(3, 18), dec(200, 18)); - assert.equal(NICR.toString(), dec(150, 16)); - }); }); // Gas usage: See gas costs spreadsheet. Cost per trial = 10k-ish. diff --git a/contracts/test/SP_P_TruncationTest.js b/contracts/test/SP_P_TruncationTest.js index 6d52dc2b..5c031c71 100644 --- a/contracts/test/SP_P_TruncationTest.js +++ b/contracts/test/SP_P_TruncationTest.js @@ -72,7 +72,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -81,10 +81,10 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); - th.logBN("Trove debt", await th.getTroveEntireDebt(contracts, account)) + //th.logBN("Trove debt", await th.getTroveEntireDebtByAddress(contracts, account)); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -94,22 +94,22 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -119,15 +119,15 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.isTrue(P_2.eq(th.toBN(1))); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); // A re-fills SP to same pre-liq level again const deposit_2 = deposit_0.sub( @@ -138,7 +138,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove C -> price rises await priceFeed.setPrice(dec(100, 18)); await troveManager.liquidate(C, { from: owner }); - assert.equal(await troveManager.getTroveStatus(C), 3); // status: closed by liq + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(C)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // This final liq fails. As expected, the 'assert' in SP line 618 reverts, since 'newP' equals 0 inside the final liq @@ -159,7 +159,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -169,7 +169,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -179,22 +179,22 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -204,15 +204,15 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.equal(P_2, dec(1, 0)); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); // A re-fills SP to same pre-liq level again const deposit_2 = deposit_0.sub( @@ -256,7 +256,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -266,7 +266,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -276,31 +276,31 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); let scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "0"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - console.log("LIQ 1"); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + //console.log("LIQ 1"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "1"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -310,20 +310,20 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - console.log("LIQ 2"); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + //console.log("LIQ 2"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.isTrue(P_2.eq(th.toBN(1))); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "2"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP to ~1.000000001x pre-liq level, i.e. to trigger a newProductFactor == 1e9, // (and trigger scale change) @@ -334,21 +334,21 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove C -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(C, { from: owner }); - console.log("LIQ 3"); - assert.equal(await troveManager.getTroveStatus(C), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(C), { from: owner }); + //console.log("LIQ 3"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(C)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P remains the same. Pool depletes to 1 billion'th of prior size, so newProductFactor is 1e9. // Due to scale change, raw value of P should equal (1 * 1e9 * 1e9 / 1e18) = 1, i.e. should not change. const P_3 = await stabilityPool.P(); assert.isTrue(P_3.eq(th.toBN(1))); - console.log("P_3:"); - console.log(P_3.toString()); + //console.log("P_3:"); + //console.log(P_3.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "3"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); }); it("4. Liquidation succeeds when P == 1 and liquidation has newProductFactor > 1e9", async () => { @@ -364,7 +364,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -374,7 +374,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -384,31 +384,31 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); let scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "0"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - console.log("LIQ 1"); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + //console.log("LIQ 1"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "1"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -418,20 +418,20 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - console.log("LIQ 2"); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + //console.log("LIQ 2"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.isTrue(P_2.eq(th.toBN(1))); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "2"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP to ~2x pre-liq level, i.e. to trigger a newProductFactor > 1e9, // and trigger scale change and *increase* raw value of P again. @@ -442,21 +442,21 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove C -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(C, { from: owner }); - console.log("LIQ 3"); - assert.equal(await troveManager.getTroveStatus(C), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(C), { from: owner }); + //console.log("LIQ 3"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(C)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P increases: 50% of the pool is liquidated, and there is a scale change. Pool depletion is 50%, so newProductFactor is 5e17. // Raw value of P should change from 1 to (1 * 5e17 * 1e9 / 1e18)= 5e8. const P_3 = await stabilityPool.P(); assert.isTrue(P_3.eq(th.toBN(dec(5, 8)))); - console.log("P_3:"); - console.log(P_3.toString()); + //console.log("P_3:"); + //console.log(P_3.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "3"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); }); // --- Check depositors have correct stakes after experiencing scale change from depositing when P is tiny --- @@ -474,7 +474,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -484,7 +484,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -494,31 +494,31 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); let scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "0"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - console.log("LIQ 1"); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + //console.log("LIQ 1"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "1"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -528,20 +528,20 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - console.log("LIQ 2"); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + //console.log("LIQ 2"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.isTrue(P_2.eq(th.toBN(1))); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "2"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // D makes deposit of 1000 Bold const D_deposit = dec(1, 21); @@ -557,27 +557,27 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove C -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(C, { from: owner }); - console.log("LIQ 3"); - assert.equal(await troveManager.getTroveStatus(C), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(C), { from: owner }); + //console.log("LIQ 3"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(C)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check liq succeeds and P remains the same. // Pool depletes to 1 billion'th of prior size, so newProductFactor is 1e9. // Due to scale change, raw value of P should equal (1 * 1e9 * 1e9 / 1e18) = 1, i.e. should not change. const P_3 = await stabilityPool.P(); assert.isTrue(P_3.eq(th.toBN(1))); - console.log("P_3:"); - console.log(P_3.toString()); + //console.log("P_3:"); + //console.log(P_3.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "3"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Check D's deposit has depleted to a billion'th of their initial deposit. That is, from 1e21 to 1e(21-9) = 1e12 const D_depletedDeposit = await stabilityPool.getCompoundedBoldDeposit(D); assert.isTrue(D_depletedDeposit.eq(th.toBN(dec(1, 12)))); - console.log("D_depletedDeposit:"); - console.log(D_depletedDeposit.toString()); + //console.log("D_depletedDeposit:"); + //console.log(D_depletedDeposit.toString()); }); it("6. Depositor have correct depleted stake after deposit at P == 1 and scale changing liq (with newProductFactor > 1e9)", async () => { @@ -593,7 +593,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { await boldToken.transfer(A, dec(50000, 18), { from: whale }); // Open 3 Troves with 2000 Bold debt - for (account of [A, B, C]) { + for (const account of [A, B, C]) { await th.openTroveWrapper(contracts, th._100pct, await getBoldAmountForDesiredDebt(2000), @@ -603,7 +603,7 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { { from: account, value: dec(15, "ether") } ); assert.isTrue( - (await th.getTroveEntireDebt(contracts, account)).eq( + (await th.getTroveEntireDebtByAddress(contracts, account)).eq( th.toBN(dec(2000, 18)) ) ); @@ -613,31 +613,31 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const deposit_0 = th.toBN("2000000000000000002001"); await stabilityPool.provideToSP(deposit_0, { from: A }); - console.log("P0:"); + //console.log("P0:"); const P_0 = await stabilityPool.P(); - console.log(P_0.toString()); + //console.log(P_0.toString()); assert.equal(P_0, dec(1, 18)); let scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "0"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Price drop -> liquidate Trove A -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(A, { from: owner }); - console.log("LIQ 1"); - assert.equal(await troveManager.getTroveStatus(A), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(A), { from: owner }); + //console.log("LIQ 1"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(A)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_1 = await stabilityPool.P(); assert.equal(P_1, dec(1, 9)); - console.log("P1:"); - console.log(P_1.toString()); + //console.log("P1:"); + //console.log(P_1.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "1"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // A re-fills SP back up to deposit 0 level, i.e. just enough to reduce P by 1e9 from a 2k debt liq. const deposit_1 = deposit_0.sub( @@ -647,20 +647,20 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove B -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(B, { from: owner }); - console.log("LIQ 2"); - assert.equal(await troveManager.getTroveStatus(B), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(B), { from: owner }); + //console.log("LIQ 2"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(B)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P reduced by factor of 1e9 const P_2 = await stabilityPool.P(); assert.isTrue(P_2.eq(th.toBN(1))); - console.log("P2:"); - console.log(P_2.toString()); + //console.log("P2:"); + //console.log(P_2.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "2"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // D makes deposit of 1000 Bold const D_deposit = dec(1, 21); @@ -676,27 +676,27 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { // Price drop -> liquidate Trove C -> price rises await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(C, { from: owner }); - console.log("LIQ 3"); - assert.equal(await troveManager.getTroveStatus(C), 3); // status: closed by liq + await troveManager.liquidate(th.addressToTroveId(C), { from: owner }); + //console.log("LIQ 3"); + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(C)), 3); // status: closed by liq await priceFeed.setPrice(dec(200, 18)); // Check P increases: 50% of the pool is liquidated, and there is a scale change. Pool depletion is 50%, so newProductFactor is 5e17. // Raw value of P should change from 1 to (1 * 5e17 * 1e9 / 1e18)= 5e8. const P_3 = await stabilityPool.P(); assert.isTrue(P_3.eq(th.toBN(dec(5, 8)))); - console.log("P_3:"); - console.log(P_3.toString()); + //console.log("P_3:"); + //console.log(P_3.toString()); scale = (await stabilityPool.currentScale()).toString(); assert.equal(scale, "3"); - console.log("scale:"); - console.log(scale); + //console.log("scale:"); + //console.log(scale); // Check D's deposit has depleted to 50% their initial deposit. That is, from 1e21 to 5e20. const D_depletedDeposit = await stabilityPool.getCompoundedBoldDeposit(D); assert.isTrue(D_depletedDeposit.eq(th.toBN(dec(5, 20)))); - console.log("D_depletedDeposit:"); - console.log(D_depletedDeposit.toString()); + //console.log("D_depletedDeposit:"); + //console.log(D_depletedDeposit.toString()); }); }); }); diff --git a/contracts/test/SortedTrovesTest.js b/contracts/test/SortedTrovesTest.js index f6b3f378..4fe8c0ad 100644 --- a/contracts/test/SortedTrovesTest.js +++ b/contracts/test/SortedTrovesTest.js @@ -134,25 +134,25 @@ contract("SortedTroves", async (accounts) => { }); it("contains(): returns true for addresses that have opened troves", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice }, }); - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: carol }, }); // Confirm trove statuses became active - assert.equal((await troveManager.Troves(alice))[3], "1"); - assert.equal((await troveManager.Troves(bob))[3], "1"); - assert.equal((await troveManager.Troves(carol))[3], "1"); + assert.equal((await troveManager.Troves(aliceTroveId))[3], "1"); + assert.equal((await troveManager.Troves(bobTroveId))[3], "1"); + assert.equal((await troveManager.Troves(carolTroveId))[3], "1"); // Check sorted list contains troves - assert.isTrue(await sortedTroves.contains(alice)); - assert.isTrue(await sortedTroves.contains(bob)); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); }); it("contains(): returns false for addresses that have not opened troves", async () => { @@ -182,12 +182,12 @@ contract("SortedTroves", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice }, }); - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: carol }, }); @@ -198,19 +198,19 @@ contract("SortedTroves", async (accounts) => { await boldToken.transfer(carol, dec(1000, 18), { from: whale }); // A, B, C close troves - await borrowerOperations.closeTrove({ from: alice }); - await borrowerOperations.closeTrove({ from: bob }); - await borrowerOperations.closeTrove({ from: carol }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); + await borrowerOperations.closeTrove(bobTroveId, { from: bob }); + await borrowerOperations.closeTrove(carolTroveId, { from: carol }); // Confirm trove statuses became closed - assert.equal((await troveManager.Troves(alice))[3], "2"); - assert.equal((await troveManager.Troves(bob))[3], "2"); - assert.equal((await troveManager.Troves(carol))[3], "2"); + assert.equal((await troveManager.Troves(aliceTroveId))[3], "2"); + assert.equal((await troveManager.Troves(bobTroveId))[3], "2"); + assert.equal((await troveManager.Troves(carolTroveId))[3], "2"); // Check sorted list does not contain troves - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); }); // true for addresses that opened -> closed -> opened a trove @@ -221,12 +221,12 @@ contract("SortedTroves", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice }, }); - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2000, 18)), extraParams: { from: carol }, }); @@ -237,14 +237,14 @@ contract("SortedTroves", async (accounts) => { await boldToken.transfer(carol, dec(1000, 18), { from: whale }); // A, B, C close troves - await borrowerOperations.closeTrove({ from: alice }); - await borrowerOperations.closeTrove({ from: bob }); - await borrowerOperations.closeTrove({ from: carol }); + await borrowerOperations.closeTrove(aliceTroveId, { from: alice }); + await borrowerOperations.closeTrove(bobTroveId, { from: bob }); + await borrowerOperations.closeTrove(carolTroveId, { from: carol }); // Confirm trove statuses became closed - assert.equal((await troveManager.Troves(alice))[3], "2"); - assert.equal((await troveManager.Troves(bob))[3], "2"); - assert.equal((await troveManager.Troves(carol))[3], "2"); + assert.equal((await troveManager.Troves(aliceTroveId))[3], "2"); + assert.equal((await troveManager.Troves(bobTroveId))[3], "2"); + assert.equal((await troveManager.Troves(carolTroveId))[3], "2"); await openTrove({ ICR: toBN(dec(1000, 16)), @@ -257,31 +257,31 @@ contract("SortedTroves", async (accounts) => { }); // Confirm trove statuses became open again - assert.equal((await troveManager.Troves(alice))[3], "1"); - assert.equal((await troveManager.Troves(bob))[3], "1"); - assert.equal((await troveManager.Troves(carol))[3], "1"); + assert.equal((await troveManager.Troves(aliceTroveId))[3], "1"); + assert.equal((await troveManager.Troves(bobTroveId))[3], "1"); + assert.equal((await troveManager.Troves(carolTroveId))[3], "1"); // Check sorted list does contain troves - assert.isTrue(await sortedTroves.contains(alice)); - assert.isTrue(await sortedTroves.contains(bob)); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); }); // false when list size is 0 it("contains(): returns false when there are no troves in the system", async () => { - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(alice))); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(bob))); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(carol))); }); // true when list size is 1 and the trove the only one in system it("contains(): true when list size is 1 and the trove the only one in system", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice }, }); - assert.isTrue(await sortedTroves.contains(alice)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); }); // false when list size is 1 and trove is not in the system @@ -291,7 +291,7 @@ contract("SortedTroves", async (accounts) => { extraParams: { from: alice }, }); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(bob))); }); // --- getMaxSize --- @@ -311,29 +311,29 @@ contract("SortedTroves", async (accounts) => { ICR: toBN(dec(500, 18)), extraParams: { from: whale }, }); - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: A, annualInterestRate: toBN(dec(1,18))}}); // 100% interest rate - await openTrove({ ICR: toBN(dec(5, 18)), extraParams: { from: B , annualInterestRate: toBN(dec(75, 16))}}); // 75% interest rate - await openTrove({ ICR: toBN(dec(250, 16)), extraParams: { from: C, annualInterestRate: toBN(dec(5, 17))}}); // 50% interest rate + const { troveId: ATroveId } = await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: A, annualInterestRate: toBN(dec(1,18))}}); // 100% interest rate + const { troveId: BTroveId } = await openTrove({ ICR: toBN(dec(5, 18)), extraParams: { from: B , annualInterestRate: toBN(dec(75, 16))}}); // 75% interest rate + const { troveId: CTroveId } = await openTrove({ ICR: toBN(dec(250, 16)), extraParams: { from: C, annualInterestRate: toBN(dec(5, 17))}}); // 50% interest rate await openTrove({ ICR: toBN(dec(166, 16)), extraParams: { from: D, annualInterestRate: toBN(dec(25,16))}}); // 25% interest rate - await openTrove({ ICR: toBN(dec(125, 16)), extraParams: { from: E, annualInterestRate: toBN(dec(1, 16))}}); // 1% interest rate + const { troveId: ETroveId } = await openTrove({ ICR: toBN(dec(125, 16)), extraParams: { from: E, annualInterestRate: toBN(dec(1, 16))}}); // 1% interest rate // Expect a trove with 60% interest rate to be inserted between B and C const targetAnnualIRate = toBN(dec(60, 16)); // Pass addresses that loosely bound the right postiion - const hints = await sortedTroves.findInsertPosition(targetAnnualIRate, A, E); + const hints = await sortedTroves.findInsertPosition(targetAnnualIRate, ATroveId, ETroveId); // Expect the exact correct insert hints have been returned - assert.equal(hints[0], B); - assert.equal(hints[1], C); + assert.isTrue(hints[0].eq(toBN(BTroveId))); + assert.isTrue(hints[1].eq(toBN(CTroveId))); // The price doesn’t affect the hints await priceFeed.setPrice(dec(500, 18)); - const hints2 = await sortedTroves.findInsertPosition(targetAnnualIRate, A, E); + const hints2 = await sortedTroves.findInsertPosition(targetAnnualIRate, ATroveId, ETroveId); // Expect the exact correct insert hints have been returned - assert.equal(hints2[0], B); - assert.equal(hints2[1], C); + assert.isTrue(hints2[0].eq(BTroveId)); + assert.isTrue(hints2[1].eq(CTroveId)); }); }); @@ -389,34 +389,34 @@ contract("SortedTroves", async (accounts) => { it("insert(): fails if id is zero", async () => { await th.assertRevert( - sortedTrovesTester.insert(th.ZERO_ADDRESS, 1, alice, alice), + sortedTrovesTester.insert(toBN(0), 1, alice, alice), "SortedTroves: Id cannot be zero" ); }); it("remove(): fails if id is not in the list", async () => { await th.assertRevert( - sortedTrovesTester.remove(alice), + sortedTrovesTester.remove(th.addressToTroveId(alice)), "SortedTroves: List does not contain the id" ); }); it("reInsert(): fails if list doesn’t contain the node", async () => { await th.assertRevert( - sortedTrovesTester.reInsert(alice, 1, alice, alice), + sortedTrovesTester.reInsert(th.addressToTroveId(alice), 1, th.addressToTroveId(alice), th.addressToTroveId(alice)), "SortedTroves: List does not contain the id" ); }); it("findInsertPosition(): No prevId for hint - ascend list starting from nextId, result is after the tail", async () => { - await sortedTrovesTester.insert(alice, 1, alice, alice); + await sortedTrovesTester.insert(th.addressToTroveId(alice), 1, th.addressToTroveId(alice), th.addressToTroveId(alice)); const pos = await sortedTroves.findInsertPosition( 1, - th.ZERO_ADDRESS, - alice + toBN(0), + th.addressToTroveId(alice) ); - assert.equal(pos[0], alice, "prevId result should be nextId param"); - assert.equal(pos[1], th.ZERO_ADDRESS, "nextId result should be zero"); + assert.isTrue(pos[0].eq(toBN(th.addressToTroveId(alice))), "prevId result should be nextId param"); + assert.isTrue(pos[1].eq(toBN(0)), "nextId result should be zero"); }); }); }); diff --git a/contracts/test/StabilityPoolTest.js b/contracts/test/StabilityPoolTest.js index b8c9af13..91b1b241 100644 --- a/contracts/test/StabilityPoolTest.js +++ b/contracts/test/StabilityPoolTest.js @@ -212,12 +212,12 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.provideToSP(whaleBold, { from: whale }); // 2 Troves opened, each withdraws minimum debt - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, @@ -236,10 +236,10 @@ contract("StabilityPool", async (accounts) => { const SPBold_Before = await stabilityPool.getTotalBoldDeposits(); // Troves are closed - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); // Confirm SP has decreased const SPBold_After = await stabilityPool.getTotalBoldDeposits(); @@ -284,17 +284,17 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.provideToSP(whaleBold, { from: whale }); // 3 Troves opened. Two users withdraw 160 Bold each - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1, value: dec(50, "ether") }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2, value: dec(50, "ether") }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_3, value: dec(50, "ether") }, @@ -322,8 +322,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 users with Trove with 180 Bold drawn are closed - await troveManager.liquidate(defaulter_1, { from: owner }); // 180 Bold closed - await troveManager.liquidate(defaulter_2, { from: owner }); // 180 Bold closed + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // 180 Bold closed + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // 180 Bold closed const alice_compoundedDeposit_1 = await stabilityPool.getCompoundedBoldDeposit(alice); @@ -366,7 +366,7 @@ contract("StabilityPool", async (accounts) => { }); // Defaulter 3 Trove is closed - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); const alice_compoundedDeposit_2 = await stabilityPool.getCompoundedBoldDeposit(alice); @@ -471,12 +471,12 @@ contract("StabilityPool", async (accounts) => { }); // Defaulter Troves opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, @@ -507,8 +507,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 defaulters are closed - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); const gain_1 = await stabilityPool.getDepositorETHGain( nonPayable.address @@ -569,12 +569,12 @@ contract("StabilityPool", async (accounts) => { }); // Would-be defaulters open troves - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, @@ -584,10 +584,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Defaulters are liquidated - await troveManager.liquidate(defaulter_1); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_1_TroveId); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); const alice_BoldDeposit_Before = ( await stabilityPool.getCompoundedBoldDeposit(alice) @@ -694,12 +694,12 @@ contract("StabilityPool", async (accounts) => { }); // Would-be defaulters open troves - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ extraBoldAmount: 0, ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, @@ -709,10 +709,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Defaulters are liquidated - await troveManager.liquidate(defaulter_1); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_1_TroveId); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); const activeDebt_Before = (await activePool.getBoldDebt()).toString(); const defaultedDebt_Before = (await defaultPool.getBoldDebt()).toString(); @@ -744,24 +744,24 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact any troves, including the caller's trove", async () => { - await openTrove({ + const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: whale, value: dec(50, "ether") }, }); // A, B, C open troves and make Stability Pool deposits - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(1000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(2000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(3000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -774,7 +774,7 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.provideToSP(dec(2000, 18), { from: bob }); // D opens a trove - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(1000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, @@ -786,31 +786,31 @@ contract("StabilityPool", async (accounts) => { // Get debt, collateral and ICR of all existing troves const whale_Debt_Before = ( - await troveManager.Troves(whale) + await troveManager.Troves(whaleTroveId) )[0].toString(); const alice_Debt_Before = ( - await troveManager.Troves(alice) + await troveManager.Troves(aliceTroveId) )[0].toString(); - const bob_Debt_Before = (await troveManager.Troves(bob))[0].toString(); + const bob_Debt_Before = (await troveManager.Troves(bobTroveId))[0].toString(); const carol_Debt_Before = ( - await troveManager.Troves(carol) + await troveManager.Troves(carolTroveId) )[0].toString(); const dennis_Debt_Before = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[0].toString(); const whale_Coll_Before = ( - await troveManager.Troves(whale) + await troveManager.Troves(whaleTroveId) )[1].toString(); const alice_Coll_Before = ( - await troveManager.Troves(alice) + await troveManager.Troves(aliceTroveId) )[1].toString(); - const bob_Coll_Before = (await troveManager.Troves(bob))[1].toString(); + const bob_Coll_Before = (await troveManager.Troves(bobTroveId))[1].toString(); const carol_Coll_Before = ( - await troveManager.Troves(carol) + await troveManager.Troves(carolTroveId) )[1].toString(); const dennis_Coll_Before = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[1].toString(); const whale_ICR_Before = ( @@ -838,20 +838,20 @@ contract("StabilityPool", async (accounts) => { dec(1000, 18) ); - const whale_Debt_After = (await troveManager.Troves(whale))[0].toString(); - const alice_Debt_After = (await troveManager.Troves(alice))[0].toString(); - const bob_Debt_After = (await troveManager.Troves(bob))[0].toString(); - const carol_Debt_After = (await troveManager.Troves(carol))[0].toString(); + const whale_Debt_After = (await troveManager.Troves(whaleTroveId))[0].toString(); + const alice_Debt_After = (await troveManager.Troves(aliceTroveId))[0].toString(); + const bob_Debt_After = (await troveManager.Troves(bobTroveId))[0].toString(); + const carol_Debt_After = (await troveManager.Troves(carolTroveId))[0].toString(); const dennis_Debt_After = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[0].toString(); - const whale_Coll_After = (await troveManager.Troves(whale))[1].toString(); - const alice_Coll_After = (await troveManager.Troves(alice))[1].toString(); - const bob_Coll_After = (await troveManager.Troves(bob))[1].toString(); - const carol_Coll_After = (await troveManager.Troves(carol))[1].toString(); + const whale_Coll_After = (await troveManager.Troves(whaleTroveId))[1].toString(); + const alice_Coll_After = (await troveManager.Troves(aliceTroveId))[1].toString(); + const bob_Coll_After = (await troveManager.Troves(bobTroveId))[1].toString(); + const carol_Coll_After = (await troveManager.Troves(carolTroveId))[1].toString(); const dennis_Coll_After = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[1].toString(); const whale_ICR_After = ( @@ -902,7 +902,7 @@ contract("StabilityPool", async (accounts) => { ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(2000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -920,8 +920,8 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.provideToSP(dec(1000, 18), { from: bob }); // Confirm Bob has an active trove in the system - assert.isTrue(await sortedTroves.contains(bob)); - assert.equal((await troveManager.getTroveStatus(bob)).toString(), "1"); // Confirm Bob's trove status is active + assert.isTrue(await sortedTroves.contains(bobTroveId)); + assert.equal((await troveManager.getTroveStatus(bobTroveId)).toString(), "1"); // Confirm Bob's trove status is active // Confirm Bob has a Stability deposit assert.equal( @@ -934,11 +934,11 @@ contract("StabilityPool", async (accounts) => { const price = await priceFeed.getPrice(); // Liquidate bob - await troveManager.liquidate(bob); + await troveManager.liquidate(bobTroveId); // Check Bob's trove has been removed from the system - assert.isFalse(await sortedTroves.contains(bob)); - assert.equal((await troveManager.getTroveStatus(bob)).toString(), "3"); // check Bob's trove status was closed by liquidation + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.equal((await troveManager.getTroveStatus(bobTroveId)).toString(), "3"); // check Bob's trove status was closed by liquidation }); it("provideToSP(): providing 0 Bold reverts", async () => { @@ -1088,7 +1088,7 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: D }, }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -1113,7 +1113,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); assert.isFalse(await th.checkRecoveryMode(contracts)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); // Price bounces back await priceFeed.setPrice(dec(200, 18)); @@ -1272,36 +1272,6 @@ contract("StabilityPool", async (accounts) => { } }); - it("withdrawFromSP(): reverts when amount > 0 and system has an undercollateralized trove", async () => { - await openTrove({ - extraBoldAmount: toBN(dec(100, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: alice }, - }); - - await stabilityPool.provideToSP(dec(100, 18), { - from: alice, - }); - - const alice_initialDeposit = ( - await stabilityPool.deposits(alice) - ).toString(); - assert.equal(alice_initialDeposit, dec(100, 18)); - - // defaulter opens trove - await openTrove({ - ICR: toBN(dec(2, 18)), - extraParams: { from: defaulter_1 }, - }); - - // ETH drops, defaulter is in liquidation range (but not liquidated yet) - await priceFeed.setPrice(dec(100, 18)); - - await th.assertRevert( - stabilityPool.withdrawFromSP(dec(100, 18), { from: alice }) - ); - }); - it("withdrawFromSP(): partial retrieval - retrieves correct Bold amount and the entire ETH Gain, and updates deposit", async () => { // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool @@ -1315,11 +1285,11 @@ contract("StabilityPool", async (accounts) => { }); // 2 Troves opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1340,10 +1310,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 users with Trove with 170 Bold drawn are closed - const liquidationTX_1 = await troveManager.liquidate(defaulter_1, { + const liquidationTX_1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner, }); // 170 Bold closed - const liquidationTX_2 = await troveManager.liquidate(defaulter_2, { + const liquidationTX_2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner, }); // 170 Bold closed @@ -1410,11 +1380,11 @@ contract("StabilityPool", async (accounts) => { }); // 2 Troves opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1437,10 +1407,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 users liquidated - const liquidationTX_1 = await troveManager.liquidate(defaulter_1, { + const liquidationTX_1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner, }); - const liquidationTX_2 = await troveManager.liquidate(defaulter_2, { + const liquidationTX_2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner, }); @@ -1481,11 +1451,11 @@ contract("StabilityPool", async (accounts) => { }); // 2 Troves opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1509,10 +1479,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 defaulters liquidated - const liquidationTX_1 = await troveManager.liquidate(defaulter_1, { + const liquidationTX_1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner, }); - const liquidationTX_2 = await troveManager.liquidate(defaulter_2, { + const liquidationTX_2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner, }); @@ -1572,11 +1542,11 @@ contract("StabilityPool", async (accounts) => { }); // 2 defaulters open - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1584,7 +1554,7 @@ contract("StabilityPool", async (accounts) => { // --- TEST --- // Alice makes deposit #1: 15000 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -1597,8 +1567,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Alice retrieves all of her entitled Bold: await stabilityPool.withdrawFromSP(dec(15000, 18), { from: alice }); @@ -1626,8 +1596,8 @@ contract("StabilityPool", async (accounts) => { }); assert.equal(await stabilityPool.getDepositorETHGain(alice), 0); - // Alice attempts third withdrawal (this time, frm SP to Trove) - const txPromise_A = stabilityPool.withdrawETHGainToTrove({ + // Alice attempts third withdrawal (this time, from SP to Trove) + const txPromise_A = stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice, }); await th.assertRevert(txPromise_A); @@ -1646,11 +1616,11 @@ contract("StabilityPool", async (accounts) => { }); // 2 defaulters open - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1678,8 +1648,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // 2 defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Alice retrieves part of her entitled Bold: 9000 Bold await stabilityPool.withdrawFromSP(dec(9000, 18), { from: alice }); @@ -1707,7 +1677,7 @@ contract("StabilityPool", async (accounts) => { }); // 1 defaulter opens - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -1728,7 +1698,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice("100000000000000000000"); // defaulter's Trove is closed. - const liquidationTx_1 = await troveManager.liquidate(defaulter_1, { + const liquidationTx_1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner, }); // 180 Bold closed const [, liquidatedColl] = @@ -1769,7 +1739,7 @@ contract("StabilityPool", async (accounts) => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); // 1 defaulter open - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -1788,7 +1758,7 @@ contract("StabilityPool", async (accounts) => { } await priceFeed.setPrice(dec(105, 18)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); await priceFeed.setPrice(dec(200, 18)); @@ -1822,7 +1792,7 @@ contract("StabilityPool", async (accounts) => { }); // 1 defaulter opens trove - await th.openTroveWrapper(contracts, + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, @@ -1832,7 +1802,7 @@ contract("StabilityPool", async (accounts) => { ); const defaulterDebt = ( - await troveManager.getEntireDebtAndColl(defaulter_1) + await troveManager.getEntireDebtAndColl(defaulter_1_TroveId) )[0]; // 6 Accounts open troves and provide to SP @@ -1849,7 +1819,7 @@ contract("StabilityPool", async (accounts) => { } await priceFeed.setPrice(dec(105, 18)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); const aliceBalBefore = await boldToken.balanceOf(alice); const bobBalBefore = await boldToken.balanceOf(bob); @@ -1864,7 +1834,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(200, 18)); // Bob issues a further 5000 Bold from his trove - await borrowerOperations.withdrawBold( + await borrowerOperations.withdrawBold(th.addressToTroveId(bob), th._100pct, dec(5000, 18), { from: bob } @@ -1929,11 +1899,11 @@ contract("StabilityPool", async (accounts) => { }); // Would-be defaulters open troves - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -1942,10 +1912,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Defaulters are liquidated - await troveManager.liquidate(defaulter_1); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_1_TroveId); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); const alice_BoldDeposit_Before = ( await stabilityPool.getCompoundedBoldDeposit(alice) @@ -2035,11 +2005,11 @@ contract("StabilityPool", async (accounts) => { }); // Would-be defaulters open troves - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -2048,10 +2018,10 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Defaulters are liquidated - await troveManager.liquidate(defaulter_1); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_1_TroveId); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); // Price rises await priceFeed.setPrice(dec(200, 18)); @@ -2085,24 +2055,24 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact any troves, including the caller's trove", async () => { - await openTrove({ + const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: whale }, }); // A, B, C open troves and make Stability Pool deposits - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(20000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(30000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -2125,25 +2095,25 @@ contract("StabilityPool", async (accounts) => { // Get debt, collateral and ICR of all existing troves const whale_Debt_Before = ( - await troveManager.Troves(whale) + await troveManager.Troves(whaleTroveId) )[0].toString(); const alice_Debt_Before = ( - await troveManager.Troves(alice) + await troveManager.Troves(aliceTroveId) )[0].toString(); - const bob_Debt_Before = (await troveManager.Troves(bob))[0].toString(); + const bob_Debt_Before = (await troveManager.Troves(bobTroveId))[0].toString(); const carol_Debt_Before = ( - await troveManager.Troves(carol) + await troveManager.Troves(carolTroveId) )[0].toString(); const whale_Coll_Before = ( - await troveManager.Troves(whale) + await troveManager.Troves(whaleTroveId) )[1].toString(); const alice_Coll_Before = ( - await troveManager.Troves(alice) + await troveManager.Troves(aliceTroveId) )[1].toString(); - const bob_Coll_Before = (await troveManager.Troves(bob))[1].toString(); + const bob_Coll_Before = (await troveManager.Troves(bobTroveId))[1].toString(); const carol_Coll_Before = ( - await troveManager.Troves(carol) + await troveManager.Troves(carolTroveId) )[1].toString(); const whale_ICR_Before = ( @@ -2170,15 +2140,15 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.withdrawFromSP(dec(30000, 18), { from: carol }); assert.equal((await stabilityPool.deposits(carol)).toString(), "0"); - const whale_Debt_After = (await troveManager.Troves(whale))[0].toString(); - const alice_Debt_After = (await troveManager.Troves(alice))[0].toString(); - const bob_Debt_After = (await troveManager.Troves(bob))[0].toString(); - const carol_Debt_After = (await troveManager.Troves(carol))[0].toString(); + const whale_Debt_After = (await troveManager.Troves(whaleTroveId))[0].toString(); + const alice_Debt_After = (await troveManager.Troves(aliceTroveId))[0].toString(); + const bob_Debt_After = (await troveManager.Troves(bobTroveId))[0].toString(); + const carol_Debt_After = (await troveManager.Troves(carolTroveId))[0].toString(); - const whale_Coll_After = (await troveManager.Troves(whale))[1].toString(); - const alice_Coll_After = (await troveManager.Troves(alice))[1].toString(); - const bob_Coll_After = (await troveManager.Troves(bob))[1].toString(); - const carol_Coll_After = (await troveManager.Troves(carol))[1].toString(); + const whale_Coll_After = (await troveManager.Troves(whaleTroveId))[1].toString(); + const alice_Coll_After = (await troveManager.Troves(aliceTroveId))[1].toString(); + const bob_Coll_After = (await troveManager.Troves(bobTroveId))[1].toString(); + const carol_Coll_After = (await troveManager.Troves(carolTroveId))[1].toString(); const whale_ICR_After = ( await troveManager.getCurrentICR(whale, price) @@ -2223,11 +2193,11 @@ contract("StabilityPool", async (accounts) => { assert.equal(A_initialDeposit, dec(100, 18)); // defaulters opens trove - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); @@ -2236,7 +2206,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); const price = await priceFeed.getPrice(); assert.isTrue( - await th.ICRbetween100and110(defaulter_1, troveManager, price) + await th.ICRbetween100and110(defaulter_1_TroveId, troveManager, price) ); await th.fastForwardTime( @@ -2245,14 +2215,14 @@ contract("StabilityPool", async (accounts) => { ); // Liquidate d1 - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); // Check d2 is undercollateralized assert.isTrue( - await th.ICRbetween100and110(defaulter_2, troveManager, price) + await th.ICRbetween100and110(defaulter_2_TroveId, troveManager, price) ); - assert.isTrue(await sortedTroves.contains(defaulter_2)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); const A_ETHBalBefore = toBN(await contracts.WETH.balanceOf(A)); @@ -2354,7 +2324,7 @@ contract("StabilityPool", async (accounts) => { }); // Would-be defaulter open trove - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, @@ -2366,10 +2336,10 @@ contract("StabilityPool", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Defaulter 1 liquidated, full offset - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); // Dennis opens trove and deposits to Stability Pool - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: dennis }, @@ -2386,7 +2356,7 @@ contract("StabilityPool", async (accounts) => { const dennis_ETHBalance_Before = contracts.WETH.balanceOf(dennis).toString(); const dennis_Collateral_Before = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[1].toString(); const ETHinSP_Before = (await stabilityPool.getETHBalance()).toString(); @@ -2401,7 +2371,7 @@ contract("StabilityPool", async (accounts) => { // Check withdrawal does not alter Dennis' ETH balance or his trove's collateral const dennis_ETHBalance_After = contracts.WETH.balanceOf(dennis).toString(); const dennis_Collateral_After = ( - await troveManager.Troves(dennis) + await troveManager.Troves(dennisTroveId) )[1].toString(); const ETHinSP_After = (await stabilityPool.getETHBalance()).toString(); @@ -2437,7 +2407,7 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: carol }, }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, @@ -2458,7 +2428,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Liquidate defaulter 1 - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); const alice_Bold_Balance_Before = await boldToken.balanceOf(alice); const bob_Bold_Balance_Before = await boldToken.balanceOf(bob); @@ -2543,7 +2513,7 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: carol }, }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -2559,7 +2529,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // Liquidate defaulter 1 - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); const bob_Bold_Balance_Before = await boldToken.balanceOf(bob); @@ -2627,7 +2597,7 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: carol }, }); - await th.openTroveWrapper(contracts, + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, @@ -2663,8 +2633,8 @@ contract("StabilityPool", async (accounts) => { assert.isTrue(await th.checkRecoveryMode(contracts)); // Liquidate defaulter 1 - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); const alice_Bold_Balance_Before = await boldToken.balanceOf(alice); const bob_Bold_Balance_Before = await boldToken.balanceOf(bob); @@ -2820,16 +2790,16 @@ contract("StabilityPool", async (accounts) => { }); // defaulters open troves - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_2 }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_3 }, }); @@ -2844,8 +2814,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Liquidate defaulter 1. Empties the Pool - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); const BoldinSP = (await stabilityPool.getTotalBoldDeposits()).toString(); assert.equal(BoldinSP, "0"); @@ -2873,8 +2843,8 @@ contract("StabilityPool", async (accounts) => { await stabilityPool.provideToSP(dec(1, 24), { from: whale }); // Liquidation 2 - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); // Check Alice and Bob have not received ETH gain from liquidation 2 while their deposit was 0 const alice_ETHGain_2 = ( @@ -2888,8 +2858,8 @@ contract("StabilityPool", async (accounts) => { assert.equal(bob_ETHGain_1, bob_ETHGain_2); // Liquidation 3 - await troveManager.liquidate(defaulter_3); - assert.isFalse(await sortedTroves.contains(defaulter_3)); + await troveManager.liquidate(defaulter_3_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); // Check Alice and Bob have not received ETH gain from liquidation 3 while their deposit was 0 const alice_ETHGain_3 = ( @@ -2910,7 +2880,7 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -2936,7 +2906,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); assert.isFalse(await th.checkRecoveryMode(contracts)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); const currentEpoch = await stabilityPool.currentEpoch(); const currentScale = await stabilityPool.currentScale(); @@ -3029,7 +2999,7 @@ contract("StabilityPool", async (accounts) => { }); await stabilityPool.provideToSP(dec(10000, 18), { from: A }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3047,8 +3017,8 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); assert.isFalse(await th.checkRecoveryMode(contracts)); - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); await priceFeed.setPrice(dec(200, 18)); @@ -3085,12 +3055,12 @@ contract("StabilityPool", async (accounts) => { extraParams: { from: whale }, }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, @@ -3111,21 +3081,21 @@ contract("StabilityPool", async (accounts) => { assert.equal(bob_initialDeposit, "0"); // Defaulter opens a trove, price drops, defaulter gets liquidated - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); await priceFeed.setPrice(dec(105, 18)); assert.isFalse(await th.checkRecoveryMode(contracts)); - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); - const txAlice = await stabilityPool.withdrawETHGainToTrove( { + const txAlice = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice, }); assert.isTrue(txAlice.receipt.status); - const txPromise_B = stabilityPool.withdrawETHGainToTrove( { + const txPromise_B = stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob, }); await th.assertRevert(txPromise_B); @@ -3144,7 +3114,7 @@ contract("StabilityPool", async (accounts) => { }); // Defaulter opens trove - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3152,7 +3122,7 @@ contract("StabilityPool", async (accounts) => { // --- TEST --- // Alice makes deposit #1: 15000 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, @@ -3162,7 +3132,7 @@ contract("StabilityPool", async (accounts) => { }); // check Alice's Trove recorded ETH Before: - const aliceTrove_Before = await troveManager.Troves(alice); + const aliceTrove_Before = await troveManager.Troves(aliceTroveId); const aliceTrove_ETH_Before = aliceTrove_Before[1]; assert.isTrue(aliceTrove_ETH_Before.gt(toBN("0"))); @@ -3170,7 +3140,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // Defaulter's Trove is closed - const liquidationTx_1 = await troveManager.liquidate(defaulter_1, { + const liquidationTx_1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner, }); const [liquidatedDebt, liquidatedColl, ,] = @@ -3198,10 +3168,10 @@ contract("StabilityPool", async (accounts) => { ); // Alice sends her ETH Gains to her Trove - await stabilityPool.withdrawETHGainToTrove( { from: alice }); + await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }); // check Alice's BoldLoss has been applied to her deposit expectedCompoundedDeposit_A - alice_deposit_afterDefault = (await stabilityPool.deposits(alice)); + const alice_deposit_afterDefault = (await stabilityPool.deposits(alice)); assert.isAtMost( th.getDifference( alice_deposit_afterDefault, @@ -3211,7 +3181,7 @@ contract("StabilityPool", async (accounts) => { ); // check alice's Trove recorded ETH has increased by the expected reward amount - const aliceTrove_After = await troveManager.Troves(alice); + const aliceTrove_After = await troveManager.Troves(aliceTroveId); const aliceTrove_ETH_After = aliceTrove_After[1]; const Trove_ETH_Increase = aliceTrove_ETH_After @@ -3234,7 +3204,7 @@ contract("StabilityPool", async (accounts) => { }); // defaulter opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3242,7 +3212,7 @@ contract("StabilityPool", async (accounts) => { // --- TEST --- // Alice makes deposit #1: 15000 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -3252,7 +3222,7 @@ contract("StabilityPool", async (accounts) => { }); // check alice's Trove recorded ETH Before: - const aliceTrove_Before = await troveManager.Troves(alice); + const aliceTrove_Before = await troveManager.Troves(aliceTroveId); const aliceTrove_ETH_Before = aliceTrove_Before[1]; assert.isTrue(aliceTrove_ETH_Before.gt(toBN("0"))); @@ -3260,11 +3230,11 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(10, 18)); // defaulter's Trove is closed. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Alice attempts to her ETH Gains to her Trove await assertRevert( - stabilityPool.withdrawETHGainToTrove( { from: alice }), + stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted" ); }); @@ -3282,7 +3252,7 @@ contract("StabilityPool", async (accounts) => { }); // defaulter opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3290,7 +3260,7 @@ contract("StabilityPool", async (accounts) => { // --- TEST --- // Alice makes deposit #1: 15000 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -3300,7 +3270,7 @@ contract("StabilityPool", async (accounts) => { }); // check alice's Trove recorded ETH Before: - const aliceTrove_Before = await troveManager.Troves(alice); + const aliceTrove_Before = await troveManager.Troves(aliceTroveId); const aliceTrove_ETH_Before = aliceTrove_Before[1]; assert.isTrue(aliceTrove_ETH_Before.gt(toBN("0"))); @@ -3308,20 +3278,20 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); // defaulter's Trove is closed. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // price bounces back await priceFeed.setPrice(dec(200, 18)); // Alice sends her ETH Gains to her Trove - await stabilityPool.withdrawETHGainToTrove( { from: alice }); + await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }); assert.equal(await stabilityPool.getDepositorETHGain(alice), 0); const ETHinSP_Before = (await stabilityPool.getETHBalance()).toString(); // Alice attempts second withdrawal from SP to Trove - reverts, due to 0 ETH Gain - const txPromise_A = stabilityPool.withdrawETHGainToTrove( { + const txPromise_A = stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice, }); await th.assertRevert(txPromise_A); @@ -3353,7 +3323,7 @@ contract("StabilityPool", async (accounts) => { }); // defaulter opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3361,7 +3331,7 @@ contract("StabilityPool", async (accounts) => { // --- TEST --- // Alice makes deposit #1: 15000 Bold - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -3374,7 +3344,7 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // defaulter's Trove is closed. - const liquidationTx = await troveManager.liquidate(defaulter_1); + const liquidationTx = await troveManager.liquidate(defaulter_1_TroveId); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTx); @@ -3393,7 +3363,7 @@ contract("StabilityPool", async (accounts) => { const stability_ETH_Before = await stabilityPool.getETHBalance(); // Alice retrieves redirects ETH gain to her Trove - await stabilityPool.withdrawETHGainToTrove({ from: alice }); + await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }); const active_ETH_After = await activePool.getETHBalance(); const stability_ETH_After = await stabilityPool.getETHBalance(); @@ -3422,7 +3392,7 @@ contract("StabilityPool", async (accounts) => { }); // Defaulter opens trove - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3441,33 +3411,33 @@ contract("StabilityPool", async (accounts) => { } await priceFeed.setPrice(dec(105, 18)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); // price bounces back await priceFeed.setPrice(dec(200, 18)); // All depositors attempt to withdraw - const tx1 = await stabilityPool.withdrawETHGainToTrove({ + const tx1 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(alice), { from: alice, }); assert.isTrue(tx1.receipt.status); - const tx2 = await stabilityPool.withdrawETHGainToTrove({ + const tx2 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(bob), { from: bob, }); assert.isTrue(tx1.receipt.status); - const tx3 = await stabilityPool.withdrawETHGainToTrove({ + const tx3 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(carol), { from: carol, }); assert.isTrue(tx1.receipt.status); - const tx4 = await stabilityPool.withdrawETHGainToTrove({ + const tx4 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(dennis), { from: dennis, }); assert.isTrue(tx1.receipt.status); - const tx5 = await stabilityPool.withdrawETHGainToTrove({ + const tx5 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(erin), { from: erin, }); assert.isTrue(tx1.receipt.status); - const tx6 = await stabilityPool.withdrawETHGainToTrove({ + const tx6 = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(flyn), { from: flyn, }); assert.isTrue(tx1.receipt.status); @@ -3482,7 +3452,7 @@ contract("StabilityPool", async (accounts) => { }); // defaulter opened - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3499,10 +3469,10 @@ contract("StabilityPool", async (accounts) => { from: account, }); } - const collBefore = (await troveManager.Troves(alice))[1]; // all troves have same coll before + const collBefore = (await troveManager.Troves(th.addressToTroveId(alice)))[1]; // all troves have same coll before await priceFeed.setPrice(dec(105, 18)); - const liquidationTx = await troveManager.liquidate(defaulter_1); + const liquidationTx = await troveManager.liquidate(defaulter_1_TroveId); const [, liquidatedColl, ,] = th.getEmittedLiquidationValues(liquidationTx); @@ -3517,45 +3487,45 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(200, 18)); - await stabilityPool.withdrawETHGainToTrove({ from: alice }); - const aliceCollAfter = (await troveManager.Troves(alice))[1]; + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(alice), { from: alice }); + const aliceCollAfter = (await troveManager.Troves(th.addressToTroveId(alice)))[1]; assert.isAtMost( th.getDifference(aliceCollAfter.sub(collBefore), expectedCollGain), 10000 ); - await stabilityPool.withdrawETHGainToTrove({ from: bob }); - const bobCollAfter = (await troveManager.Troves(bob))[1]; + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(bob), { from: bob }); + const bobCollAfter = (await troveManager.Troves(th.addressToTroveId(bob)))[1]; assert.isAtMost( th.getDifference(bobCollAfter.sub(collBefore), expectedCollGain), 10000 ); - await stabilityPool.withdrawETHGainToTrove({ from: carol }); - const carolCollAfter = (await troveManager.Troves(carol))[1]; + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(carol), { from: carol }); + const carolCollAfter = (await troveManager.Troves(th.addressToTroveId(carol)))[1]; assert.isAtMost( th.getDifference(carolCollAfter.sub(collBefore), expectedCollGain), 10000 ); - await stabilityPool.withdrawETHGainToTrove( { + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(dennis), { from: dennis, }); - const dennisCollAfter = (await troveManager.Troves(dennis))[1]; + const dennisCollAfter = (await troveManager.Troves(th.addressToTroveId(dennis)))[1]; assert.isAtMost( th.getDifference(dennisCollAfter.sub(collBefore), expectedCollGain), 10000 ); - await stabilityPool.withdrawETHGainToTrove({ from: erin }); - const erinCollAfter = (await troveManager.Troves(erin))[1]; + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(erin), { from: erin }); + const erinCollAfter = (await troveManager.Troves(th.addressToTroveId(erin)))[1]; assert.isAtMost( th.getDifference(erinCollAfter.sub(collBefore), expectedCollGain), 10000 ); - await stabilityPool.withdrawETHGainToTrove({ from: flyn }); - const flynCollAfter = (await troveManager.Troves(flyn))[1]; + await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(flyn), { from: flyn }); + const flynCollAfter = (await troveManager.Troves(th.addressToTroveId(flyn)))[1]; assert.isAtMost( th.getDifference(flynCollAfter.sub(collBefore), expectedCollGain), 10000 @@ -3566,23 +3536,23 @@ contract("StabilityPool", async (accounts) => { // --- SETUP --- // Defaulter opens - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); // A, B, C open troves - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ extraBoldAmount: toBN(dec(20000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ extraBoldAmount: toBN(dec(30000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: carol }, @@ -3607,17 +3577,17 @@ contract("StabilityPool", async (accounts) => { // Check defaulter 1 has ICR: 100% < ICR < 110%. assert.isTrue( - await th.ICRbetween100and110(defaulter_1, troveManager, price) + await th.ICRbetween100and110(defaulter_1_TroveId, troveManager, price) ); - const alice_Collateral_Before = (await troveManager.Troves(alice))[1]; - const bob_Collateral_Before = (await troveManager.Troves(bob))[1]; - const carol_Collateral_Before = (await troveManager.Troves(carol))[1]; + const alice_Collateral_Before = (await troveManager.Troves(aliceTroveId))[1]; + const bob_Collateral_Before = (await troveManager.Troves(bobTroveId))[1]; + const carol_Collateral_Before = (await troveManager.Troves(carolTroveId))[1]; // Liquidate defaulter 1 - assert.isTrue(await sortedTroves.contains(defaulter_1)); - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); const alice_ETHGain_Before = await stabilityPool.getDepositorETHGain( alice @@ -3628,9 +3598,9 @@ contract("StabilityPool", async (accounts) => { ); // A, B, C withdraw their full ETH gain from the Stability Pool to their trove - await stabilityPool.withdrawETHGainToTrove( { from: alice }); - await stabilityPool.withdrawETHGainToTrove({ from: bob }); - await stabilityPool.withdrawETHGainToTrove({ from: carol }); + await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }); + await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }); + await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }); // Check collateral of troves A, B, C has increased by the value of their ETH gain from liquidations, respectively const alice_expectedCollateral = alice_Collateral_Before @@ -3643,9 +3613,9 @@ contract("StabilityPool", async (accounts) => { .add(carol_ETHGain_Before) .toString(); - const alice_Collateral_After = (await troveManager.Troves(alice))[1]; - const bob_Collateral_After = (await troveManager.Troves(bob))[1]; - const carol_Collateral_After = (await troveManager.Troves(carol))[1]; + const alice_Collateral_After = (await troveManager.Troves(aliceTroveId))[1]; + const bob_Collateral_After = (await troveManager.Troves(bobTroveId))[1]; + const carol_Collateral_After = (await troveManager.Troves(carolTroveId))[1]; assert.equal(alice_expectedCollateral, alice_Collateral_After); assert.equal(bob_expectedColalteral, bob_Collateral_After); @@ -3681,7 +3651,7 @@ contract("StabilityPool", async (accounts) => { }); // Defaulter opens - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -3698,14 +3668,14 @@ contract("StabilityPool", async (accounts) => { await priceFeed.setPrice(dec(105, 18)); //Liquidate defaulter 1 - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); await priceFeed.setPrice(dec(200, 18)); // D attempts to withdraw his ETH gain to Trove await th.assertRevert( - stabilityPool.withdrawETHGainToTrove( { from: dennis }), + stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(dennis), { from: dennis }), "caller must have an active trove to withdraw ETHGain to" ); }); @@ -3722,12 +3692,12 @@ contract("StabilityPool", async (accounts) => { await boldToken.transfer(B, dec(20000, 18), { from: whale }); // C, D open troves - await openTrove({ + const { troveId: CTroveId } = await openTrove({ extraBoldAmount: toBN(dec(3000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: C }, }); - await openTrove({ + const { troveId: DTroveId } = await openTrove({ extraBoldAmount: toBN(dec(4000, 18)), ICR: toBN(dec(2, 18)), extraParams: { from: D }, @@ -3757,16 +3727,16 @@ contract("StabilityPool", async (accounts) => { assert.equal(await stabilityPool.getDepositorETHGain(C), "0"); // Check withdrawETHGainToTrove reverts for A, B, C - const txPromise_A = stabilityPool.withdrawETHGainToTrove({ + const txPromise_A = stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(A), { from: A, }); - const txPromise_B = stabilityPool.withdrawETHGainToTrove({ + const txPromise_B = stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(B), { from: B, }); - const txPromise_C = stabilityPool.withdrawETHGainToTrove({ + const txPromise_C = stabilityPool.withdrawETHGainToTrove(CTroveId, { from: C, }); - const txPromise_D = stabilityPool.withdrawETHGainToTrove({ + const txPromise_D = stabilityPool.withdrawETHGainToTrove(DTroveId, { from: D, }); diff --git a/contracts/test/StabilityPool_SPWithdrawalTest.js b/contracts/test/StabilityPool_SPWithdrawalTest.js index 24f37e10..8f98f8c8 100644 --- a/contracts/test/StabilityPool_SPWithdrawalTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalTest.js @@ -112,19 +112,19 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter opens trove with 200% ICR and 10k Bold net debt - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Check depositors' compounded deposit is 6666.66 Bold and ETH Gain is 33.16 ETH const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -151,21 +151,21 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Check depositors' compounded deposit is 3333.33 Bold and ETH Gain is 66.33 ETH const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -197,17 +197,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Check depositors' compounded deposit is 0 Bold and ETH Gain is 99.5 ETH const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -241,15 +241,15 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '70000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '50000000000000000000' }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '70000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Check depositors' compounded deposit const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -283,17 +283,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '60000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: '70000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '50000000000000000000' }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '60000000000000000000' }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: '70000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Check depositors' compounded deposit const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -329,15 +329,15 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: carol }) // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Depositors attempt to withdraw everything const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -371,17 +371,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: carol }) // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Depositors attempt to withdraw everything const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -425,17 +425,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 2: 5000 Bold & 50 ETH Defaulter 3: 46700 Bold & 500 ETH */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('207000000000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(2160, 18) }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5, 21)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(50, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('46700000000000000000000'), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(500, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('207000000000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(2160, 18) }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5, 21)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(50, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('46700000000000000000000'), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(500, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Depositors attempt to withdraw everything const txA = await stabilityPool.withdrawFromSP(dec(500000, 18), { from: alice }) @@ -472,23 +472,23 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Whale transfers 10k to Dennis who then provides to SP await boldToken.transfer(dennis, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: dennis }) // Third defaulter liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -527,25 +527,25 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis opens a trove and provides to SP await boldToken.transfer(dennis, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: dennis }) // Third and fourth defaulters liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -592,25 +592,25 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 3: 5000 Bold, 50 ETH Defaulter 4: 40000 Bold, 400 ETH */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(25000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '250000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(40000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(400, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(25000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: '250000000000000000000' }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: '50000000000000000000' }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(40000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(400, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis provides 25000 Bold await boldToken.transfer(dennis, dec(25000, 18), { from: whale }) await stabilityPool.provideToSP(dec(25000, 18), { from: dennis }) // Last two defaulters liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); // Each depositor withdraws as much as possible const txA = await stabilityPool.withdrawFromSP(dec(100000, 18), { from: alice }) @@ -650,17 +650,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -673,8 +673,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '49750000000000000000'), 100000) // Two more defaulters are liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -720,17 +720,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 3: 30000 Bold Defaulter 4: 5000 Bold */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(300, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(300, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -744,8 +744,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '122461538461538466100'), 100000000000) // Two more defaulters are liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(100000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(100000, 18), { from: bob }) @@ -779,23 +779,23 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulters open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Carol makes deposit await boldToken.transfer(carol, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: carol }) - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -807,7 +807,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference((await boldToken.balanceOf(dennis)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '82916666666666666667'), 100000) - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -842,30 +842,30 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale transfers 10k Bold to A, B who then deposit it to the SP const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. 20000 Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis each deposit 10000 Bold const depositors_2 = [carol, dennis] - for (account of depositors_2) { + for (const account of depositors_2) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // await th.openTroveWrapper(contracts, th._100pct, dec(1, 18), account, account, { from: erin, value: dec(2, 'ether') }) // await stabilityPool.provideToSP(dec(1, 18), { from: erin }) @@ -909,16 +909,16 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale transfers 10k Bold to A, B who then deposit it to the SP const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // 4 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); @@ -932,7 +932,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.equal(P_0, dec(1, 18)) // Defaulter 1 liquidated. 10--0 Bold fully offset, Pool remains non-zero - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_1 = (await stabilityPool.currentEpoch()).toString() @@ -944,7 +944,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(P_1, dec(5, 17)), 1000) // Defaulter 2 liquidated. 1--00 Bold, empties pool - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_2 = (await stabilityPool.currentEpoch()).toString() @@ -963,7 +963,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter 3 liquidated. 10000 Bold fully offset, Pool remains non-zero - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_3 = (await stabilityPool.currentEpoch()).toString() @@ -975,7 +975,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(P_3, dec(5, 17)), 1000) // Defaulter 4 liquidated. 10000 Bold, empties pool - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_4 = (await stabilityPool.currentEpoch()).toString() @@ -1007,14 +1007,14 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. 20000 Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis, Erin each deposit 10000, 20000, 30000 Bold respectively await boldToken.transfer(carol, dec(10000, 18), { from: whale }) @@ -1027,7 +1027,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: erin }) // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -1070,17 +1070,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1,2,3 withdraw 10000 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1, 2 and 3 liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) @@ -1109,10 +1109,10 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0,{ from: whale, value: dec(100000, 'ether') }) // 4 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(200, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(200, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); @@ -1125,7 +1125,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter 1 liquidated. 20k Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis each deposit 10000 Bold const depositors_2 = [carol, dennis] @@ -1135,7 +1135,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Erin, Flyn each deposit 10000 Bold const depositors_3 = [erin, flyn] @@ -1145,7 +1145,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter 3 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Graham, Harriet each deposit 10000 Bold const depositors_4 = [graham, harriet] @@ -1155,7 +1155,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter 4 liquidated. 10k Bold offset - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(10000, 18), { from: bob }) @@ -1221,18 +1221,18 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 withdraws 'almost' 10000 Bold: 9999.99991 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) assert.equal(await stabilityPool.currentScale(), '0') // Defaulter 2 withdraws 9900 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(9900, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(60, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(9900, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(60, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P reduced to 9e9. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.equal((await stabilityPool.P()).toString(), dec(9, 9)) // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -1247,7 +1247,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: bob }) // Defaulter 2 liquidated. 9900 Bold liquidated. P altered by a factor of 1-(9900/10000) = 0.01. Scale changed. - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.equal(await stabilityPool.currentScale(), '1') @@ -1278,16 +1278,16 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 withdraws 'almost' 10k Bold. - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) // Defaulter 2 withdraws 59400 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59400000000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(330, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59400000000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(330, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P reduced to 9e9 - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.equal((await stabilityPool.P()).toString(), dec(9, 9)) assert.equal(await stabilityPool.currentScale(), '0') @@ -1308,7 +1308,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: dennis }) // 54000 Bold liquidated. P altered by a factor of 1-(59400/60000) = 0.01. Scale changed. - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.currentScale(), '1') @@ -1360,14 +1360,14 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 and default 2 each withdraw 9999.999999999 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter 1 ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P updated to to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) th.logBN("P", await stabilityPool.P()) // 0.000009999999999999, so 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // P decreases. Expect P = 1e(18-5) = 1e13 @@ -1384,7 +1384,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: bob }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // Scale changes and P changes. P = 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') @@ -1416,14 +1416,14 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 and default 2 withdraw up to debt of 9999.9 Bold and 59999.4 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59999400000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(600, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59999400000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(600, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P updated to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); th.logBN("P", await stabilityPool.P()); // P = 0.000009999999999999, i.e. 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // P decreases. Expect P = 1e(18-5) = 1e13 assert.equal(await stabilityPool.currentScale(), '0') @@ -1445,7 +1445,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: dennis }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // P decreases. P = 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') @@ -1477,7 +1477,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0,{ from: whale, value: dec(100000, 'ether') }) // Defaulters 1 withdraws 9999.9999999 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999999900000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999999900000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) // Price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1486,7 +1486,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 liquidated. P -> (~1e-10)*P - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) const aliceDeposit = (await stabilityPool.getCompoundedBoldDeposit(alice)).toString() @@ -1513,10 +1513,10 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0,{ from: whale, value: dec(100000, 'ether') }) // Defaulters 1-4 each withdraw 9999.9 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1525,7 +1525,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 liquidated. P updated to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) th.logBN("P", await stabilityPool.P()) // P 0.000009999999999999, 1 wei less than expecteed assert.equal(await stabilityPool.P(), dec(1, 13)) // Expect P decreases to 1e(18-5) = 1e13 @@ -1536,7 +1536,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: bob }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // Scale changes and P changes to 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') @@ -1546,7 +1546,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: carol }) // Defaulter 3 liquidated - const txL3 = await troveManager.liquidate(defaulter_3, { from: owner }); + const txL3 = await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); assert.isTrue(txL3.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 12)) // P decreases to 1e(17-5) = 1e12 assert.equal(await stabilityPool.currentScale(), '1') @@ -1556,7 +1556,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: dennis }) // Defaulter 4 liquidated - const txL4 = await troveManager.liquidate(defaulter_4, { from: owner }); + const txL4 = await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); assert.isTrue(txL4.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 16)) // Scale changes and P changes to 1e(12-5+9) = 1e16 assert.equal(await stabilityPool.currentScale(), '2') @@ -1591,9 +1591,9 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0,{ from: whale, value: dec(100000, 'ether') }) // Defaulters 1-3 each withdraw 24100, 24300, 24500 Bold (inc gas comp) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24100, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24300, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24500, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24100, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24300, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24500, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1605,7 +1605,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: B }) // Defaulter 1 liquidated. SP emptied - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) // Check compounded deposits @@ -1645,7 +1645,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: D }) // Defaulter 2 liquidated. SP emptied - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) // Check compounded deposits @@ -1685,7 +1685,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: F }) // Defaulter 3 liquidated. SP emptied - const txL3 = await troveManager.liquidate(defaulter_3, { from: owner }); + const txL3 = await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); assert.isTrue(txL3.receipt.status) // Check compounded deposits @@ -1719,11 +1719,11 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0,{ from: whale, value: dec(100000, 'ether') }) // Defaulters 1-5 each withdraw up to debt of 9999.9999999 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_5, defaulter_5, 0, { from: defaulter_5, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_5_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_5, defaulter_5, 0, { from: defaulter_5, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1732,7 +1732,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 liquidated. P updated to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) th.logBN("P", await stabilityPool.P()); // P = 0.000009999999999999, 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // Expect P decreases to 1e(18-5) = 1e13 @@ -1743,7 +1743,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: bob }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // Scale changes and P changes to 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') @@ -1753,7 +1753,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: carol }) // Defaulter 3 liquidated - const txL3 = await troveManager.liquidate(defaulter_3, { from: owner }); + const txL3 = await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); assert.isTrue(txL3.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 12)) // P decreases to 1e(17-5) = 1e12 assert.equal(await stabilityPool.currentScale(), '1') @@ -1763,7 +1763,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: dennis }) // Defaulter 4 liquidated - const txL4 = await troveManager.liquidate(defaulter_4, { from: owner }); + const txL4 = await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); assert.isTrue(txL4.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 16)) // Scale changes and P changes to 1e(12-5+9) = 1e16 assert.equal(await stabilityPool.currentScale(), '2') @@ -1775,7 +1775,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: erin }) // Defaulter 5 liquidated - const txL5 = await troveManager.liquidate(defaulter_5, { from: owner }); + const txL5 = await troveManager.liquidate(defaulter_5_TroveId, { from: owner }); assert.isTrue(txL5.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 11)) // P decreases to 1e(16-5) = 1e11 assert.equal(await stabilityPool.currentScale(), '2') @@ -1798,19 +1798,19 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await priceFeed.setPrice(dec(2, 27)); const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await th.openTroveWrapper(contracts, th._100pct, dec(1, 36), account, account, 0, { from: account, value: dec(2, 27) }) await stabilityPool.provideToSP(dec(1, 36), { from: account }) } // Defaulter opens trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1, 36)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(1, 27) }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1, 36)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: dec(1, 27) }) // ETH:USD price drops to $1 billion per ETH await priceFeed.setPrice(dec(1, 27)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(1, 36), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(1, 36), { from: bob }) @@ -1856,19 +1856,19 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' const price = await priceFeed.getPrice() const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await th.openTroveWrapper(contracts, th._100pct, dec(1, 38), account, account, { from: account, value: dec(2, 29) }) await stabilityPool.provideToSP(dec(1, 38), { from: account }) } // Defaulter opens trove with 50e-7 ETH and 5000 Bold. 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '5000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0,{ from: defaulter_1, value: '5000000000000' }) // ETH:USD price drops to $1 billion per ETH await priceFeed.setPrice(dec(1, 27)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); const txA = await stabilityPool.withdrawFromSP(dec(1, 38), { from: alice }) const txB = await stabilityPool.withdrawFromSP(dec(1, 38), { from: bob }) diff --git a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js index 604c8ee4..e0f057e3 100644 --- a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js @@ -111,30 +111,30 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter opens trove with 200% ICR and 10k Bold net debt - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Check depositors' compounded deposit is 6666.66 Bold and ETH Gain is 33.16 ETH - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -155,32 +155,32 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Check depositors' compounded deposit is 3333.33 Bold and ETH Gain is 66.33 ETH - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() const bob_ETHWithdrawn = th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() @@ -200,34 +200,34 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Check depositors' compounded deposit is 0 Bold and ETH Gain is 99.5 ETH - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -249,32 +249,32 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '70000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '50000000000000000000' }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '70000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Check depositors' compounded deposit - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -296,34 +296,34 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '60000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: '70000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '50000000000000000000' }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '60000000000000000000' }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(7000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: '70000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Check depositors' compounded deposit - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -346,9 +346,9 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k, 20k, 30k Bold to A, B and C respectively who then deposit it to the SP await boldToken.transfer(alice, dec(10000, 18), { from: whale }) @@ -359,20 +359,20 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: carol }) // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Depositors attempt to withdraw everything - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -393,9 +393,9 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k, 20k, 30k Bold to A, B and C respectively who then deposit it to the SP await boldToken.transfer(alice, dec(10000, 18), { from: whale }) @@ -406,22 +406,22 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: carol }) // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Depositors attempt to withdraw everything - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -443,9 +443,9 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1000000, 18)), whale, whale, 0, { from: whale, value: dec(1000000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) /* Depositors provide:- Alice: 2000 Bold @@ -465,22 +465,22 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 2: 5000 Bold & 50 ETH Defaulter 3: 46700 Bold & 500 ETH */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('207000000000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(2160, 18) }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5, 21)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(50, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('46700000000000000000000'), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(500, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('207000000000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(2160, 18) }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5, 21)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(50, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('46700000000000000000000'), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(500, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Three defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Depositors attempt to withdraw everything - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -505,41 +505,41 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Whale transfers 10k to Dennis who then provides to SP await boldToken.transfer(dennis, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: dennis }) // Third defaulter liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -566,43 +566,43 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis opens a trove and provides to SP await boldToken.transfer(dennis, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: dennis }) // Third and fourth defaulters liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -626,10 +626,10 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1000000, 18)), whale, whale, 0, { from: whale, value: dec(1000000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) /* Depositors open troves and make SP deposit: Alice: 60000 Bold @@ -650,31 +650,31 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 3: 5000 Bold, 50 ETH Defaulter 4: 40000 Bold, 400 ETH */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(25000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '250000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: '50000000000000000000' }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(40000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(400, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(25000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: '250000000000000000000' }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: '50000000000000000000' }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(40000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(400, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis provides 25000 Bold await boldToken.transfer(dennis, dec(25000, 18), { from: whale }) await stabilityPool.provideToSP(dec(25000, 18), { from: dennis }) // Last two defaulters liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); // Each depositor withdraws as much as possible - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -701,35 +701,35 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and C who then deposit it to the SP const depositors = [alice, bob, carol, dennis] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal await priceFeed.setPrice(dec(200, 18)) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) await priceFeed.setPrice(dec(100, 18)) const dennis_ETHWithdrawn = th.getEventArgByName(txD, 'ETHGainWithdrawn', '_ETH').toString() @@ -737,12 +737,12 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '49750000000000000000'), 100000) // Two more defaulters are liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -763,9 +763,9 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) /* Initial deposits: Alice: 20000 Bold @@ -789,17 +789,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' Defaulter 3: 30000 Bold Defaulter 4: 5000 Bold */ - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(300, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: '50000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(300, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: '50000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -813,12 +813,12 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '122461538461538466100'), 100000000000) // Two more defaulters are liquidated - await troveManager.liquidate(defaulter_3, { from: owner }); - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -841,35 +841,35 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B and D who then deposit it to the SP const depositors = [alice, bob, dennis] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulters open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_4, defaulter_4, 0, { from: defaulter_4, value: '50000000000000000000' }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // First two defaulters liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Carol makes deposit await boldToken.transfer(carol, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: carol }) - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Dennis withdraws his deposit and ETH gain // Increasing the price for a moment to avoid pending liquidations to block withdrawal @@ -881,11 +881,11 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference((await boldToken.balanceOf(dennis)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference(dennis_ETHWithdrawn, '82916666666666666667'), 100000) - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -915,45 +915,45 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B who then deposit it to the SP const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. 20000 Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis each deposit 10000 Bold const depositors_2 = [carol, dennis] - for (account of depositors_2) { + for (const account of depositors_2) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // await th.openTroveWrapper(contracts, th._100pct, dec(1, 18), account, account, { from: erin, value: dec(2, 'ether') }) // await stabilityPool.provideToSP(dec(1, 18), { from: erin }) - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() const bob_ETHWithdrawn = th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() @@ -988,23 +988,23 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B who then deposit it to the SP const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // 4 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); @@ -1018,7 +1018,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.equal(P_0, dec(1, 18)) // Defaulter 1 liquidated. 10--0 Bold fully offset, Pool remains non-zero - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_1 = (await stabilityPool.currentEpoch()).toString() @@ -1030,7 +1030,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(P_1, dec(5, 17)), 1000) // Defaulter 2 liquidated. 1--00 Bold, empties pool - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_2 = (await stabilityPool.currentEpoch()).toString() @@ -1043,13 +1043,13 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Carol, Dennis each deposit 10000 Bold const depositors_2 = [carol, dennis] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 3 liquidated. 10000 Bold fully offset, Pool remains non-zero - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_3 = (await stabilityPool.currentEpoch()).toString() @@ -1061,7 +1061,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isAtMost(th.getDifference(P_3, dec(5, 17)), 1000) // Defaulter 4 liquidated. 10000 Bold, empties pool - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); //Check epoch, scale and sum const epoch_4 = (await stabilityPool.currentEpoch()).toString() @@ -1085,29 +1085,29 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: erin, value: dec(10000, 'ether') }) + // A, B, C, D, E open troves + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const erinTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: erin, value: dec(10000, 'ether') }) // Whale transfers 10k Bold to A, B who then deposit it to the SP const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // 2 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. 20000 Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis, Erin each deposit 10000, 20000, 30000 Bold respectively await boldToken.transfer(carol, dec(10000, 18), { from: whale }) @@ -1120,13 +1120,13 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: erin }) // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) - const txE = await stabilityPool.withdrawETHGainToTrove({ from: erin }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) + const txE = await stabilityPool.withdrawETHGainToTrove(erinTroveId, { from: erin }) const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() const bob_ETHWithdrawn = th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() @@ -1160,28 +1160,28 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) await boldToken.transfer(alice, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1,2,3 withdraw 10000 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1, 2 and 3 liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); - await troveManager.liquidate(defaulter_2, { from: owner }); - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() @@ -1208,72 +1208,72 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) // A, B, C, D, E, F, G, H open troves - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: erin, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: flyn, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: harriet, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: graham, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const erinTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: erin, value: dec(10000, 'ether') }) + const flynTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: flyn, value: dec(10000, 'ether') }) + const harrietTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: harriet, value: dec(10000, 'ether') }) + const grahamTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: graham, value: dec(10000, 'ether') }) // 4 Defaulters open trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(200, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_3, defaulter_3, 0,{ from: defaulter_3, value: dec(200, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(200, 'ether') }) // price drops by 50%: defaulter ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Alice, Bob each deposit 10k Bold const depositors_1 = [alice, bob] - for (account of depositors_1) { + for (const account of depositors_1) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 1 liquidated. 20k Bold fully offset with pool. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); // Carol, Dennis each deposit 10000 Bold const depositors_2 = [carol, dennis] - for (account of depositors_2) { + for (const account of depositors_2) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 2 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); // Erin, Flyn each deposit 10000 Bold const depositors_3 = [erin, flyn] - for (account of depositors_3) { + for (const account of depositors_3) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 3 liquidated. 10000 Bold offset - await troveManager.liquidate(defaulter_3, { from: owner }); + await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); // Graham, Harriet each deposit 10000 Bold const depositors_4 = [graham, harriet] - for (account of depositors_4) { + for (const account of depositors_4) { await boldToken.transfer(account, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: account }) } // Defaulter 4 liquidated. 10k Bold offset - await troveManager.liquidate(defaulter_4, { from: owner }); + await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) - const txE = await stabilityPool.withdrawETHGainToTrove({ from: erin }) - const txF = await stabilityPool.withdrawETHGainToTrove({ from: flyn }) - const txG = await stabilityPool.withdrawETHGainToTrove({ from: graham }) - const txH = await stabilityPool.withdrawETHGainToTrove({ from: harriet }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) + const txE = await stabilityPool.withdrawETHGainToTrove(erinTroveId, { from: erin }) + const txF = await stabilityPool.withdrawETHGainToTrove(flynTroveId, { from: flyn }) + const txG = await stabilityPool.withdrawETHGainToTrove(grahamTroveId, { from: graham }) + const txH = await stabilityPool.withdrawETHGainToTrove(harrietTroveId, { from: harriet }) const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() const bob_ETHWithdrawn = th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() @@ -1326,25 +1326,25 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) await boldToken.transfer(alice, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 withdraws 'almost' 10000 Bold: 9999.99991 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) assert.equal(await stabilityPool.currentScale(), '0') // Defaulter 2 withdraws 9900 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(9900, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(60, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(9900, 18)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(60, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P reduced to 9e9. - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); th.logBN("P", await stabilityPool.P()); // 8999999999, i.e. 1 wei less than expected assert.equal((await stabilityPool.P()).toString(), dec(9, 9)) @@ -1360,11 +1360,11 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: bob }) // Defaulter 2 liquidated. 9900 Bold liquidated. P altered by a factor of 1-(9900/10000) = 0.01. Scale changed. - await troveManager.liquidate(defaulter_2, { from: owner }); + await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.equal(await stabilityPool.currentScale(), '1') - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) const bob_ETHWithdrawn = await th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() // Expect Bob to retain 1% of initial deposit (100 Bold) and all the liquidated ETH (60 ether) @@ -1388,25 +1388,25 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) await boldToken.transfer(alice, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 withdraws 'almost' 10k Bold. - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999910000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) // Defaulter 2 withdraws 59400 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59400000000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(330, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59400000000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(330, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P reduced to 9e9 - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); th.logBN("P", await stabilityPool.P()) // P = 8999999999, i.e. 1 wei less than expected assert.equal((await stabilityPool.P()).toString(), dec(9, 9)) @@ -1428,14 +1428,14 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: dennis }) // 54000 Bold liquidated. P altered by a factor of 1-(59400/60000) = 0.01. Scale changed. - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.currentScale(), '1') - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) /* Expect depositors to retain 1% of their initial deposit, and an ETH gain in proportion to their initial deposit: @@ -1476,22 +1476,22 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) await boldToken.transfer(alice, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 and default 2 each withdraw 9999.999999999 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(99999, 17)), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) // price drops by 50%: defaulter 1 ICR falls to 100% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. Value of P updated to to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) th.logBN("P", await stabilityPool.P()) // P = 0.000009999999999999 i.e. 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // P decreases. P = 1e(18-5) = 1e13 @@ -1508,12 +1508,12 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: bob }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // Scale changes and P changes. P = 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) const bob_ETHWithdrawn = await th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() // Bob should withdraw 1e-5 of initial deposit: 0.1 Bold and the full ETH gain of 100 ether @@ -1536,23 +1536,23 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) await boldToken.transfer(alice, dec(10000, 18), { from: whale }) await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 and default 2 withdraw up to debt of 9999.9 Bold and 59999.4 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59999400000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(600, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('59999400000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(600, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); // Defaulter 1 liquidated. P updated to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); th.logBN("P",await stabilityPool.P()) // P: 0.000009999999999999, 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // P decreases. P = 1e(18-5) = 1e13 assert.equal(await stabilityPool.currentScale(), '0') @@ -1574,18 +1574,18 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(30000, 18), { from: dennis }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // P decreases. P = 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) const bob_ETHWithdrawn = await th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) const carol_ETHWithdrawn = await th.getEventArgByName(txC, 'ETHGainWithdrawn', '_ETH').toString() - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) const dennis_ETHWithdrawn = await th.getEventArgByName(txD, 'ETHGainWithdrawn', '_ETH').toString() // {B, C, D} should have a compounded deposit of {0.1, 0.2, 0.3} Bold @@ -1605,13 +1605,13 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Defaulters 1 withdraws 9999.9999999 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999999900000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999999999900000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) // Price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1620,7 +1620,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 liquidated. P -> (~1e-10)*P - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) const aliceDeposit = (await stabilityPool.getCompoundedBoldDeposit(alice)).toString() @@ -1647,16 +1647,16 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) + const aliceTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: alice, value: dec(10000, 'ether') }) + const bobTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: bob, value: dec(10000, 'ether') }) + const carolTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: carol, value: dec(10000, 'ether') }) + const dennisTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: dennis, value: dec(10000, 'ether') }) // Defaulters 1-4 each withdraw 9999.9 Bold - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_3, defaulter_3, 0,0,{ from: defaulter_3, value: dec(100, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(100, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_2, defaulter_2, 0,{ from: defaulter_2, value: dec(100, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_3, defaulter_3, 0,0,{ from: defaulter_3, value: dec(100, 'ether') }) + const defaulter_4_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount('9999900000000000000000'), defaulter_4, defaulter_4, 0,{ from: defaulter_4, value: dec(100, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1665,7 +1665,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: alice }) // Defaulter 1 liquidated. P decreases to 1e13 - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) th.logBN("P", await stabilityPool.P()) // P = 0.000009999999999999, 1 wei less than expected assert.equal(await stabilityPool.P(), dec(1, 13)) // P decreases to 1e(18-5) = 1e13 @@ -1676,7 +1676,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: bob }) // Defaulter 2 liquidated - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 17)) // Scale changes and P changes to 1e(13-5+9) = 1e17 assert.equal(await stabilityPool.currentScale(), '1') @@ -1686,7 +1686,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: carol }) // Defaulter 3 liquidated - const txL3 = await troveManager.liquidate(defaulter_3, { from: owner }); + const txL3 = await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); assert.isTrue(txL3.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 12)) // P decreases to 1e(17-5) = 1e12 assert.equal(await stabilityPool.currentScale(), '1') @@ -1696,15 +1696,15 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(99999, 17), { from: dennis }) // Defaulter 4 liquidated - const txL4 = await troveManager.liquidate(defaulter_4, { from: owner }); + const txL4 = await troveManager.liquidate(defaulter_4_TroveId, { from: owner }); assert.isTrue(txL4.receipt.status) assert.equal(await stabilityPool.P(), dec(1, 16)) // Scale changes and P changes to 1e(12-5+9) = 1e16 assert.equal(await stabilityPool.currentScale(), '2') - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: carol }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: dennis }) + const txA = await stabilityPool.withdrawETHGainToTrove(aliceTroveId, { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(bobTroveId, { from: bob }) + const txC = await stabilityPool.withdrawETHGainToTrove(carolTroveId, { from: carol }) + const txD = await stabilityPool.withdrawETHGainToTrove(dennisTroveId, { from: dennis }) const alice_ETHWithdrawn = await th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH').toString() const bob_ETHWithdrawn = await th.getEventArgByName(txB, 'ETHGainWithdrawn', '_ETH').toString() @@ -1730,17 +1730,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Whale opens Trove with 100k ETH await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(100000, 18)), whale, whale, 0, { from: whale, value: dec(100000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: A, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: B, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: C, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: D, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: E, value: dec(10000, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: F, value: dec(10000, 'ether') }) + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: A, value: dec(10000, 'ether') }) + const BTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: B, value: dec(10000, 'ether') }) + const CTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: C, value: dec(10000, 'ether') }) + const DTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: D, value: dec(10000, 'ether') }) + const ETroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: E, value: dec(10000, 'ether') }) + const FTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), ZERO_ADDRESS, ZERO_ADDRESS, 0, { from: F, value: dec(10000, 'ether') }) // Defaulters 1-3 each withdraw 24100, 24300, 24500 Bold (inc gas comp) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24100, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24300, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24500, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24100, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(200, 'ether') }) + const defaulter_2_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24300, 18)), defaulter_2, defaulter_2, 0, { from: defaulter_2, value: dec(200, 'ether') }) + const defaulter_3_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(24500, 18)), defaulter_3, defaulter_3, 0, { from: defaulter_3, value: dec(200, 'ether') }) // price drops by 50% await priceFeed.setPrice(dec(100, 18)); @@ -1752,7 +1752,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: B }) // Defaulter 1 liquidated. SP emptied - const txL1 = await troveManager.liquidate(defaulter_1, { from: owner }); + const txL1 = await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); assert.isTrue(txL1.receipt.status) // Check compounded deposits @@ -1776,8 +1776,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Attempt withdrawals // Increasing the price for a moment to avoid pending liquidations to block withdrawal await priceFeed.setPrice(dec(200, 18)) - const txA = await stabilityPool.withdrawETHGainToTrove({ from: A }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: B }) + const txA = await stabilityPool.withdrawETHGainToTrove(ATroveId, { from: A }) + const txB = await stabilityPool.withdrawETHGainToTrove(BTroveId, { from: B }) await priceFeed.setPrice(dec(100, 18)) assert.isTrue(txA.receipt.status) @@ -1792,7 +1792,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: D }) // Defaulter 2 liquidated. SP emptied - const txL2 = await troveManager.liquidate(defaulter_2, { from: owner }); + const txL2 = await troveManager.liquidate(defaulter_2_TroveId, { from: owner }); assert.isTrue(txL2.receipt.status) // Check compounded deposits @@ -1816,8 +1816,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' // Attempt withdrawals // Increasing the price for a moment to avoid pending liquidations to block withdrawal await priceFeed.setPrice(dec(200, 18)) - const txC = await stabilityPool.withdrawETHGainToTrove({ from: C }) - const txD = await stabilityPool.withdrawETHGainToTrove({ from: D }) + const txC = await stabilityPool.withdrawETHGainToTrove(CTroveId, { from: C }) + const txD = await stabilityPool.withdrawETHGainToTrove(DTroveId, { from: D }) await priceFeed.setPrice(dec(100, 18)) assert.isTrue(txC.receipt.status) @@ -1832,7 +1832,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await stabilityPool.provideToSP(dec(10000, 18), { from: F }) // Defaulter 3 liquidated. SP emptied - const txL3 = await troveManager.liquidate(defaulter_3, { from: owner }); + const txL3 = await troveManager.liquidate(defaulter_3_TroveId, { from: owner }); assert.isTrue(txL3.receipt.status) // Check compounded deposits @@ -1853,8 +1853,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.equal(SPBoldBalance_3, '0') // Attempt withdrawals - const txE = await stabilityPool.withdrawETHGainToTrove({ from: E }) - const txF = await stabilityPool.withdrawETHGainToTrove({ from: F }) + const txE = await stabilityPool.withdrawETHGainToTrove(ETroveId, { from: E }) + const txF = await stabilityPool.withdrawETHGainToTrove(FTroveId, { from: F }) assert.isTrue(txE.receipt.status) assert.isTrue(txF.receipt.status) }) @@ -1869,22 +1869,22 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await priceFeed.setPrice(dec(2, 27)); const depositors = [alice, bob] - for (account of depositors) { + for (const account of depositors) { await th.openTroveWrapper(contracts, th._100pct, dec(1, 36), account, account, 0, { from: account, value: dec(2, 27) }) await stabilityPool.provideToSP(dec(1, 36), { from: account }) } // Defaulter opens trove with 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1, 36)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(1, 27) }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1, 36)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: dec(1, 27) }) // ETH:USD price drops to $1 billion per ETH await priceFeed.setPrice(dec(1, 27)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); - const txA = await stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txB = await stabilityPool.withdrawETHGainToTrove({ from: bob }) + const txA = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(alice), { from: alice }) + const txB = await stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(bob), { from: bob }) // Grab the ETH gain from the emitted event in the tx log const alice_ETHWithdrawn = th.getEventArgByName(txA, 'ETHGainWithdrawn', '_ETH') @@ -1933,16 +1933,16 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' } // Defaulter opens trove with 50e-7 ETH and 5000 Bold. 200% ICR - await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '5000000000000' }) + const defaulter_1_TroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(5000, 18)), defaulter_1, defaulter_1, 0, { from: defaulter_1, value: '5000000000000' }) // ETH:USD price drops to $1 billion per ETH await priceFeed.setPrice(dec(1, 27)); // Defaulter liquidated - await troveManager.liquidate(defaulter_1, { from: owner }); + await troveManager.liquidate(defaulter_1_TroveId, { from: owner }); - const txAPromise = stabilityPool.withdrawETHGainToTrove({ from: alice }) - const txBPromise = stabilityPool.withdrawETHGainToTrove({ from: bob }) + const txAPromise = stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(alice), { from: alice }) + const txBPromise = stabilityPool.withdrawETHGainToTrove(th.addressToTroveId(bob), { from: bob }) // Expect ETH gain per depositor of ~1e11 wei to be rounded to 0 by the ETHGainedPerUnitStaked calculation (e / D), where D is ~1e36. await th.assertRevert(txAPromise, 'StabilityPool: caller must have non-zero ETH Gain') diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index 2a6ab2e3..4777cda1 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -120,10 +120,10 @@ contract("TroveManager", async (accounts) => { it("liquidate(): closes a Trove that has ICR < MCR", async () => { await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); const price = await priceFeed.getPrice(); - const ICR_Before = await troveManager.getCurrentICR(alice, price); + const ICR_Before = await troveManager.getCurrentICR(aliceTroveId, price); assert.equal(ICR_Before, dec(4, 18)); const MCR = (await troveManager.MCR()).toString(); @@ -135,7 +135,7 @@ contract("TroveManager", async (accounts) => { const targetICR = toBN("1111111111111111111"); await withdrawBold({ ICR: targetICR, extraParams: { from: alice } }); - const ICR_AfterWithdrawal = await troveManager.getCurrentICR(alice, price); + const ICR_AfterWithdrawal = await troveManager.getCurrentICR(aliceTroveId, price); assert.isAtMost(th.getDifference(ICR_AfterWithdrawal, targetICR), 100); // price drops to 1ETH:100Bold, reducing Alice's ICR below MCR @@ -145,20 +145,20 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // close Trove - await troveManager.liquidate(alice, { from: owner }); + await troveManager.liquidate(aliceTroveId, { from: owner }); // check the Trove is successfully closed, and removed from sortedList - const status = (await troveManager.Troves(alice))[3]; + const status = (await troveManager.Troves(aliceTroveId))[3]; assert.equal(status, 3); // status enum 3 corresponds to "Closed by liquidation" - const alice_Trove_isInSortedList = await sortedTroves.contains(alice); + const alice_Trove_isInSortedList = await sortedTroves.contains(aliceTroveId); assert.isFalse(alice_Trove_isInSortedList); }); it("liquidate(): decreases ActivePool ETH and BoldDebt by correct amounts", async () => { // --- SETUP --- - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - const { collateral: B_collateral, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); // --- TEST --- @@ -187,7 +187,7 @@ contract("TroveManager", async (accounts) => { /* close Bob's Trove. Should liquidate his ether and Bold, leaving Alice’s ether and Bold debt in the ActivePool. */ - await troveManager.liquidate(bob, { from: owner }); + await troveManager.liquidate(bobTroveId, { from: owner }); // check ActivePool ETH and Bold debt const activePool_ETH_After = (await activePool.getETHBalance()).toString(); @@ -205,9 +205,9 @@ contract("TroveManager", async (accounts) => { it("liquidate(): increases DefaultPool ETH and Bold debt by correct amounts", async () => { // --- SETUP --- - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - const { collateral: B_collateral, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); // --- TEST --- @@ -232,7 +232,7 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // close Bob's Trove - await troveManager.liquidate(bob, { from: owner }); + await troveManager.liquidate(bobTroveId, { from: owner }); // check after const defaultPool_ETH_After = (await defaultPool.getETHBalance()).toString(); @@ -251,9 +251,9 @@ contract("TroveManager", async (accounts) => { it("liquidate(): removes the Trove's stake from the total stakes", async () => { // --- SETUP --- - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - const { collateral: B_collateral, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); // --- TEST --- @@ -269,69 +269,69 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Close Bob's Trove - await troveManager.liquidate(bob, { from: owner }); + await troveManager.liquidate(bobTroveId, { from: owner }); // check totalStakes after const totalStakes_After = (await troveManager.totalStakes()).toString(); assert.equal(totalStakes_After, A_collateral); }); - it("liquidate(): Removes the correct trove from the TroveOwners array, and moves the last array element to the new empty slot", async () => { + it("liquidate(): Removes the correct trove from the TroveIds array, and moves the last array element to the new empty slot", async () => { // --- SETUP --- - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); // Alice, Bob, Carol, Dennis, Erin open troves with consecutively decreasing collateral ratio - await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(214, 16)), extraParams: { from: carol } }); - await openTrove({ ICR: toBN(dec(212, 16)), extraParams: { from: dennis } }); - await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: erin } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(214, 16)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(212, 16)), extraParams: { from: dennis } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: erin } }); - // At this stage, TroveOwners array should be: [W, A, B, C, D, E] + // At this stage, TroveIds array should be: [W, A, B, C, D, E] // Drop price await priceFeed.setPrice(dec(100, 18)); - const arrayLength_Before = await troveManager.getTroveOwnersCount(); + const arrayLength_Before = await troveManager.getTroveIdsCount(); assert.equal(arrayLength_Before, 6); // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate carol - await troveManager.liquidate(carol); + await troveManager.liquidate(carolTroveId); // Check Carol no longer has an active trove - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Check length of array has decreased by 1 - const arrayLength_After = await troveManager.getTroveOwnersCount(); + const arrayLength_After = await troveManager.getTroveIdsCount(); assert.equal(arrayLength_After, 5); /* After Carol is removed from array, the last element (Erin's address) should have been moved to fill - the empty slot left by Carol, and the array length decreased by one. The final TroveOwners array should be: + the empty slot left by Carol, and the array length decreased by one. The final TroveIds array should be: [W, A, B, E, D] Check all remaining troves in the array are in the correct order */ - const trove_0 = await troveManager.TroveOwners(0); - const trove_1 = await troveManager.TroveOwners(1); - const trove_2 = await troveManager.TroveOwners(2); - const trove_3 = await troveManager.TroveOwners(3); - const trove_4 = await troveManager.TroveOwners(4); - - assert.equal(trove_0, whale); - assert.equal(trove_1, alice); - assert.equal(trove_2, bob); - assert.equal(trove_3, erin); - assert.equal(trove_4, dennis); + const trove_0 = await troveManager.TroveIds(0); + const trove_1 = await troveManager.TroveIds(1); + const trove_2 = await troveManager.TroveIds(2); + const trove_3 = await troveManager.TroveIds(3); + const trove_4 = await troveManager.TroveIds(4); + + assert.isTrue(trove_0.eq(whaleTroveId)); + assert.isTrue(trove_1.eq(aliceTroveId)); + assert.isTrue(trove_2.eq(bobTroveId)); + assert.isTrue(trove_3.eq(erinTroveId)); + assert.isTrue(trove_4.eq(dennisTroveId)); // Check correct indices recorded on the active trove structs - const whale_arrayIndex = (await troveManager.Troves(whale))[4]; - const alice_arrayIndex = (await troveManager.Troves(alice))[4]; - const bob_arrayIndex = (await troveManager.Troves(bob))[4]; - const dennis_arrayIndex = (await troveManager.Troves(dennis))[4]; - const erin_arrayIndex = (await troveManager.Troves(erin))[4]; + const whale_arrayIndex = (await troveManager.Troves(whaleTroveId))[4]; + const alice_arrayIndex = (await troveManager.Troves(aliceTroveId))[4]; + const bob_arrayIndex = (await troveManager.Troves(bobTroveId))[4]; + const dennis_arrayIndex = (await troveManager.Troves(dennisTroveId))[4]; + const erin_arrayIndex = (await troveManager.Troves(erinTroveId))[4]; // [W, A, B, E, D] assert.equal(whale_arrayIndex, 0); @@ -343,9 +343,9 @@ contract("TroveManager", async (accounts) => { it("liquidate(): updates the snapshots of total stakes and total collateral", async () => { // --- SETUP --- - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - const { collateral: B_collateral, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); // --- TEST --- @@ -367,7 +367,7 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // close Bob's Trove. His ether*0.995 and Bold should be added to the DefaultPool. - await troveManager.liquidate(bob, { from: owner }); + await troveManager.liquidate(bobTroveId, { from: owner }); /* check snapshots after. Total stakes should be equal to the remaining stake then the system: 10 ether, Alice's stake. @@ -390,11 +390,11 @@ contract("TroveManager", async (accounts) => { it("liquidate(): updates the L_ETH and L_boldDebt reward-per-unit-staked totals", async () => { // --- SETUP --- - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); - const { collateral: B_collateral, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: bob } }); - const { collateral: C_collateral, totalDebt: C_totalDebt } = + const { troveId: carolTroveId, collateral: C_collateral, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(111, 16)), extraParams: { from: carol }, @@ -409,9 +409,9 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // close Carol's Trove. - assert.isTrue(await sortedTroves.contains(carol)); - await troveManager.liquidate(carol, { from: owner }); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); + await troveManager.liquidate(carolTroveId, { from: owner }); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Carol's ether*0.995 and Bold should be added to the DefaultPool. const L_ETH_AfterCarolLiquidated = await troveManager.L_ETH(); @@ -447,9 +447,9 @@ contract("TroveManager", async (accounts) => { const price = await priceFeed.getPrice(); // close Bob's Trove - assert.isTrue(await sortedTroves.contains(bob)); - await troveManager.liquidate(bob, { from: owner }); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); + await troveManager.liquidate(bobTroveId, { from: owner }); + assert.isFalse(await sortedTroves.contains(bobTroveId)); /* Alice now has all the active stake. totalStakes in the system is now 10 ether. @@ -489,13 +489,13 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Liquidates undercollateralized trove if there are two troves in the system", async () => { - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: bob, value: dec(100, "ether") }, }); // Alice creates a single trove with 0.7 ETH and a debt of 70 Bold, and provides 10 Bold to SP - const { collateral: A_collateral, totalDebt: A_totalDebt } = + const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // Alice proves 10 Bold to SP @@ -508,11 +508,11 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); const alice_ICR = ( - await troveManager.getCurrentICR(alice, price) + await troveManager.getCurrentICR(aliceTroveId, price) ).toString(); assert.equal(alice_ICR, "1050000000000000000"); - const activeTrovesCount_Before = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_Before = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_Before, 2); @@ -520,32 +520,32 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate the trove - await troveManager.liquidate(alice, { from: owner }); + await troveManager.liquidate(aliceTroveId, { from: owner }); // Check Alice's trove is removed, and bob remains - const activeTrovesCount_After = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_After = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_After, 1); - const alice_isInSortedList = await sortedTroves.contains(alice); + const alice_isInSortedList = await sortedTroves.contains(aliceTroveId); assert.isFalse(alice_isInSortedList); - const bob_isInSortedList = await sortedTroves.contains(bob); + const bob_isInSortedList = await sortedTroves.contains(bobTroveId); assert.isTrue(bob_isInSortedList); }); it("liquidate(): reverts if trove is non-existent", async () => { - await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); - assert.equal(await troveManager.getTroveStatus(carol), 0); // check trove non-existent + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(carol)), 0); // check trove non-existent - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(carol))); // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); try { - const txCarol = await troveManager.liquidate(carol); + const txCarol = await troveManager.liquidate(th.addressToTroveId(carol)); assert.isFalse(txCarol.receipt.status); } catch (err) { @@ -557,26 +557,26 @@ contract("TroveManager", async (accounts) => { it("liquidate(): reverts if trove has been closed", async () => { await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); // price drops, Carol ICR falls below MCR await priceFeed.setPrice(dec(100, 18)); // Carol liquidated, and her trove is closed - const txCarol_L1 = await troveManager.liquidate(carol); + const txCarol_L1 = await troveManager.liquidate(carolTroveId); assert.isTrue(txCarol_L1.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); - assert.equal(await troveManager.getTroveStatus(carol), 3); // check trove closed by liquidation + assert.equal(await troveManager.getTroveStatus(carolTroveId), 3); // check trove closed by liquidation // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); try { - const txCarol_L2 = await troveManager.liquidate(carol); + const txCarol_L2 = await troveManager.liquidate(carolTroveId); assert.isFalse(txCarol_L2.receipt.status); } catch (err) { @@ -586,8 +586,8 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does nothing if trove has >= 110% ICR", async () => { - await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: bob } }); + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: whale } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: bob } }); const TCR_Before = (await th.getTCR(contracts)).toString(); const listSize_Before = (await sortedTroves.getSize()).toString(); @@ -595,7 +595,7 @@ contract("TroveManager", async (accounts) => { const price = await priceFeed.getPrice(); // Check Bob's ICR > 110% - const bob_ICR = await troveManager.getCurrentICR(bob, price); + const bob_ICR = await troveManager.getCurrentICR(bobTroveId, price); assert.isTrue(bob_ICR.gte(mv._MCR)); // Confirm system is not in Recovery Mode @@ -603,13 +603,13 @@ contract("TroveManager", async (accounts) => { // Attempt to liquidate bob await assertRevert( - troveManager.liquidate(bob), + troveManager.liquidate(bobTroveId), "TroveManager: nothing to liquidate" ); // Check bob active, check whale active - assert.isTrue(await sortedTroves.contains(bob)); - assert.isTrue(await sortedTroves.contains(whale)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); + assert.isTrue(await sortedTroves.contains(whaleTroveId)); const TCR_After = (await th.getTCR(contracts)).toString(); const listSize_After = (await sortedTroves.getSize()).toString(); @@ -635,27 +635,27 @@ contract("TroveManager", async (accounts) => { const TCR_Before = (await th.getTCR(contracts)).toString(); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(202, 16)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: defaulter_2 }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ ICR: toBN(dec(196, 16)), extraParams: { from: defaulter_3 }, }); - await openTrove({ + const { troveId: defaulter_4_TroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: defaulter_4 }, }); - assert.isTrue(await sortedTroves.contains(defaulter_1)); - assert.isTrue(await sortedTroves.contains(defaulter_2)); - assert.isTrue(await sortedTroves.contains(defaulter_3)); - assert.isTrue(await sortedTroves.contains(defaulter_4)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_4_TroveId)); // Price drop await priceFeed.setPrice(dec(100, 18)); @@ -664,17 +664,17 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // All defaulters liquidated - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); - await troveManager.liquidate(defaulter_3); - assert.isFalse(await sortedTroves.contains(defaulter_3)); + await troveManager.liquidate(defaulter_3_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); - await troveManager.liquidate(defaulter_4); - assert.isFalse(await sortedTroves.contains(defaulter_4)); + await troveManager.liquidate(defaulter_4_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_4_TroveId)); // Price bounces back await priceFeed.setPrice(dec(200, 18)); @@ -698,27 +698,27 @@ contract("TroveManager", async (accounts) => { await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: dennis } }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(202, 16)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: defaulter_2 }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ ICR: toBN(dec(196, 16)), extraParams: { from: defaulter_3 }, }); - await openTrove({ + const { troveId: defaulter_4_TroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: defaulter_4 }, }); - assert.isTrue(await sortedTroves.contains(defaulter_1)); - assert.isTrue(await sortedTroves.contains(defaulter_2)); - assert.isTrue(await sortedTroves.contains(defaulter_3)); - assert.isTrue(await sortedTroves.contains(defaulter_4)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_4_TroveId)); await priceFeed.setPrice(dec(100, 18)); @@ -728,23 +728,23 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Check TCR improves with each liquidation that is offset with Pool - await troveManager.liquidate(defaulter_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + await troveManager.liquidate(defaulter_1_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); const TCR_2 = await th.getTCR(contracts); assert.isTrue(TCR_2.gte(TCR_1)); - await troveManager.liquidate(defaulter_2); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + await troveManager.liquidate(defaulter_2_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); const TCR_3 = await th.getTCR(contracts); assert.isTrue(TCR_3.gte(TCR_2)); - await troveManager.liquidate(defaulter_3); - assert.isFalse(await sortedTroves.contains(defaulter_3)); + await troveManager.liquidate(defaulter_3_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); const TCR_4 = await th.getTCR(contracts); assert.isTrue(TCR_4.gte(TCR_3)); - await troveManager.liquidate(defaulter_4); - assert.isFalse(await sortedTroves.contains(defaulter_4)); + await troveManager.liquidate(defaulter_4_TroveId); + assert.isFalse(await sortedTroves.contains(defaulter_4_TroveId)); const TCR_5 = await th.getTCR(contracts); assert.isTrue(TCR_5.gte(TCR_4)); }); @@ -757,27 +757,27 @@ contract("TroveManager", async (accounts) => { await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: dennis } }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(202, 16)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: defaulter_2 }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ ICR: toBN(dec(196, 16)), extraParams: { from: defaulter_3 }, }); - await openTrove({ + const { troveId: defaulter_4_TroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: defaulter_4 }, }); - assert.isTrue(await sortedTroves.contains(defaulter_1)); - assert.isTrue(await sortedTroves.contains(defaulter_2)); - assert.isTrue(await sortedTroves.contains(defaulter_3)); - assert.isTrue(await sortedTroves.contains(defaulter_4)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_4_TroveId)); await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); @@ -797,10 +797,10 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Check TCR does not decrease with each liquidation - const liquidationTx_1 = await troveManager.liquidate(defaulter_1); + const liquidationTx_1 = await troveManager.liquidate(defaulter_1_TroveId); const [liquidatedDebt_1, liquidatedColl_1, gasComp_1] = th.getEmittedLiquidationValues(liquidationTx_1); - assert.isFalse(await sortedTroves.contains(defaulter_1)); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); const TCR_1 = await th.getTCR(contracts); // Expect only change to TCR to be due to the issued gas compensation @@ -811,10 +811,10 @@ contract("TroveManager", async (accounts) => { assert.isTrue(expectedTCR_1.eq(TCR_1)); - const liquidationTx_2 = await troveManager.liquidate(defaulter_2); + const liquidationTx_2 = await troveManager.liquidate(defaulter_2_TroveId); const [liquidatedDebt_2, liquidatedColl_2, gasComp_2] = th.getEmittedLiquidationValues(liquidationTx_2); - assert.isFalse(await sortedTroves.contains(defaulter_2)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); const TCR_2 = await th.getTCR(contracts); @@ -826,10 +826,11 @@ contract("TroveManager", async (accounts) => { assert.isTrue(expectedTCR_2.eq(TCR_2)); - const liquidationTx_3 = await troveManager.liquidate(defaulter_3); + const liquidationTx_3 = await troveManager.liquidate(defaulter_3_TroveId); const [liquidatedDebt_3, liquidatedColl_3, gasComp_3] = th.getEmittedLiquidationValues(liquidationTx_3); - assert.isFalse(await sortedTroves.contains(defaulter_3)); + + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); const TCR_3 = await th.getTCR(contracts); @@ -842,10 +843,10 @@ contract("TroveManager", async (accounts) => { assert.isTrue(expectedTCR_3.eq(TCR_3)); - const liquidationTx_4 = await troveManager.liquidate(defaulter_4); + const liquidationTx_4 = await troveManager.liquidate(defaulter_4_TroveId); const [liquidatedDebt_4, liquidatedColl_4, gasComp_4] = th.getEmittedLiquidationValues(liquidationTx_4); - assert.isFalse(await sortedTroves.contains(defaulter_4)); + assert.isFalse(await sortedTroves.contains(defaulter_4_TroveId)); const TCR_4 = await th.getTCR(contracts); @@ -868,7 +869,7 @@ contract("TroveManager", async (accounts) => { extraBoldAmount: spDeposit, extraParams: { from: bob }, }); - const { C_totalDebt, C_collateral } = await openTrove({ + const { troveId: carolTroveId, C_totalDebt, C_collateral } = await openTrove({ ICR: toBN(dec(218, 16)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: carol }, @@ -882,11 +883,11 @@ contract("TroveManager", async (accounts) => { // Carol gets liquidated await priceFeed.setPrice(dec(100, 18)); - const liquidationTX_C = await troveManager.liquidate(carol); + const liquidationTX_C = await troveManager.liquidate(carolTroveId); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTX_C); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Check Dennis' SP deposit has absorbed Carol's debt, and he has received her liquidated ETH const dennis_Deposit_Before = ( await stabilityPool.getCompoundedBoldDeposit(dennis) @@ -908,7 +909,7 @@ contract("TroveManager", async (accounts) => { // Attempt to liquidate Dennis try { - const txDennis = await troveManager.liquidate(dennis); + const txDennis = await troveManager.liquidate(th.addressToTroveId(dennis)); assert.isFalse(txDennis.receipt.status); } catch (err) { assert.include(err.message, "revert"); @@ -929,12 +930,12 @@ contract("TroveManager", async (accounts) => { it("liquidate(): does not liquidate a SP depositor's trove with ICR > 110%, and does not affect their SP deposit or ETH gain", async () => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const spDeposit = toBN(dec(1, 24)); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraBoldAmount: spDeposit, extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(218, 16)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: carol }, @@ -945,15 +946,15 @@ contract("TroveManager", async (accounts) => { // Carol gets liquidated await priceFeed.setPrice(dec(100, 18)); - const liquidationTX_C = await troveManager.liquidate(carol); + const liquidationTX_C = await troveManager.liquidate(carolTroveId); const [liquidatedDebt, liquidatedColl, gasComp] = th.getEmittedLiquidationValues(liquidationTX_C); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // price bounces back - Bob's trove is >110% ICR again await priceFeed.setPrice(dec(200, 18)); const price = await priceFeed.getPrice(); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).gt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).gt(mv._MCR)); // Check Bob' SP deposit has absorbed Carol's debt, and he has received her liquidated ETH const bob_Deposit_Before = ( @@ -973,12 +974,12 @@ contract("TroveManager", async (accounts) => { // Attempt to liquidate Bob await assertRevert( - troveManager.liquidate(bob), + troveManager.liquidate(bobTroveId), "TroveManager: nothing to liquidate" ); // Confirm Bob's trove is still active - assert.isTrue(await sortedTroves.contains(bob)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); // Check Bob' SP deposit does not change after liquidation attempt const bob_Deposit_After = ( @@ -1000,12 +1001,12 @@ contract("TroveManager", async (accounts) => { extraBoldAmount: A_spDeposit, extraParams: { from: alice }, }); - const { collateral: B_collateral, totalDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_collateral, totalDebt: B_debt } = await openTrove({ ICR: toBN(dec(218, 16)), extraBoldAmount: B_spDeposit, extraParams: { from: bob }, }); - const { collateral: C_collateral, totalDebt: C_debt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_collateral, totalDebt: C_debt } = await openTrove({ ICR: toBN(dec(210, 16)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: carol }, @@ -1016,7 +1017,7 @@ contract("TroveManager", async (accounts) => { // Carol gets liquidated await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(carol); + await troveManager.liquidate(carolTroveId); // Check Bob' SP deposit has absorbed Carol's debt, and he has received her liquidated ETH const bob_Deposit_Before = await stabilityPool.getCompoundedBoldDeposit( @@ -1042,11 +1043,11 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate Bob - await troveManager.liquidate(bob); + await troveManager.liquidate(bobTroveId); // Confirm Bob's trove has been closed - assert.isFalse(await sortedTroves.contains(bob)); - const bob_Trove_Status = (await troveManager.Troves(bob))[3].toString(); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + const bob_Trove_Status = (await troveManager.Troves(bobTroveId))[3].toString(); assert.equal(bob_Trove_Status, 3); // check closed by liquidation /* Alice's Bold Loss = (300 / 400) * 200 = 150 Bold @@ -1108,17 +1109,17 @@ contract("TroveManager", async (accounts) => { it("liquidate(): does not alter the liquidated user's token balance", async () => { await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); - const { boldAmount: A_boldAmount } = await openTrove({ + const { troveId: aliceTroveId, boldAmount: A_boldAmount } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: toBN(dec(300, 18)), extraParams: { from: alice }, }); - const { boldAmount: B_boldAmount } = await openTrove({ + const { troveId: bobTroveId, boldAmount: B_boldAmount } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: toBN(dec(200, 18)), extraParams: { from: bob }, }); - const { boldAmount: C_boldAmount } = await openTrove({ + const { troveId: carolTroveId, boldAmount: C_boldAmount } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: carol }, @@ -1136,20 +1137,20 @@ contract("TroveManager", async (accounts) => { const activeBoldDebt_0 = await activePool.getBoldDebt(); const defaultBoldDebt_0 = await defaultPool.getBoldDebt(); - await troveManager.liquidate(alice); + await troveManager.liquidate(aliceTroveId); const activeBoldDebt_A = await activePool.getBoldDebt(); const defaultBoldDebt_A = await defaultPool.getBoldDebt(); - await troveManager.liquidate(bob); + await troveManager.liquidate(bobTroveId); const activeBoldDebt_B = await activePool.getBoldDebt(); const defaultBoldDebt_B = await defaultPool.getBoldDebt(); - await troveManager.liquidate(carol); + await troveManager.liquidate(carolTroveId); // Confirm A, B, C closed - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Check sortedList size reduced to 1 assert.equal((await sortedTroves.getSize()).toString(), "1"); @@ -1161,24 +1162,24 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(8, 18)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: alice }, }); - await openTrove({ + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(221, 16)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: toBN(dec(100, 18)), extraParams: { from: carol }, }); // Defaulter opens with 60 Bold, 0.6 ETH - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: defaulter_1 }, }); @@ -1187,9 +1188,9 @@ contract("TroveManager", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); - const alice_ICR_Before = await troveManager.getCurrentICR(alice, price); - const bob_ICR_Before = await troveManager.getCurrentICR(bob, price); - const carol_ICR_Before = await troveManager.getCurrentICR(carol, price); + const alice_ICR_Before = await troveManager.getCurrentICR(aliceTroveId, price); + const bob_ICR_Before = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_Before = await troveManager.getCurrentICR(carolTroveId, price); /* Before liquidation: Alice ICR: = (2 * 100 / 50) = 400% @@ -1210,11 +1211,11 @@ contract("TroveManager", async (accounts) => { B receives (30 * 1/4) = 7.5 Bold, and (0.3*1/4) = 0.075 ETH C receives (30 * 1/4) = 7.5 Bold, and (0.3*1/4) = 0.075 ETH */ - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); - const alice_ICR_After = await troveManager.getCurrentICR(alice, price); - const bob_ICR_After = await troveManager.getCurrentICR(bob, price); - const carol_ICR_After = await troveManager.getCurrentICR(carol, price); + const alice_ICR_After = await troveManager.getCurrentICR(aliceTroveId, price); + const bob_ICR_After = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_After = await troveManager.getCurrentICR(carolTroveId, price); /* After liquidation: @@ -1230,8 +1231,8 @@ contract("TroveManager", async (accounts) => { /* Though Bob's true ICR (including pending rewards) is below the MCR, check that Bob's raw coll and debt has not changed, and that his "raw" ICR is above the MCR */ - const bob_Coll = (await troveManager.Troves(bob))[1]; - const bob_Debt = (await troveManager.Troves(bob))[0]; + const bob_Coll = (await troveManager.Troves(bobTroveId))[1]; + const bob_Debt = (await troveManager.Troves(bobTroveId))[0]; const bob_rawICR = bob_Coll.mul(toBN(dec(100, 18))).div(bob_Debt); assert.isTrue(bob_rawICR.gte(mv._MCR)); @@ -1242,31 +1243,31 @@ contract("TroveManager", async (accounts) => { // Liquidate Alice, Bob, Carol await assertRevert( - troveManager.liquidate(alice), + troveManager.liquidate(aliceTroveId), "TroveManager: nothing to liquidate" ); - await troveManager.liquidate(bob); - await troveManager.liquidate(carol); + await troveManager.liquidate(bobTroveId); + await troveManager.liquidate(carolTroveId); /* Check Alice stays active, Carol gets liquidated, and Bob gets liquidated (because his pending rewards bring his ICR < MCR) */ - assert.isTrue(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Check trove statuses - A active (1), B and C liquidated (3) - assert.equal((await troveManager.Troves(alice))[3].toString(), "1"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); - assert.equal((await troveManager.Troves(carol))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "1"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(carolTroveId))[3].toString(), "3"); }); // --- batchLiquidateTroves() --- it("batchLiquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(221, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(221, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: defaulter_1 }, }); @@ -1275,9 +1276,9 @@ contract("TroveManager", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); - const alice_ICR_Before = await troveManager.getCurrentICR(alice, price); - const bob_ICR_Before = await troveManager.getCurrentICR(bob, price); - const carol_ICR_Before = await troveManager.getCurrentICR(carol, price); + const alice_ICR_Before = await troveManager.getCurrentICR(aliceTroveId, price); + const bob_ICR_Before = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_Before = await troveManager.getCurrentICR(carolTroveId, price); /* Before liquidation: Alice ICR: = (2 * 100 / 100) = 200% @@ -1290,11 +1291,11 @@ contract("TroveManager", async (accounts) => { assert.isTrue(carol_ICR_Before.lte(mv._MCR)); // Liquidate defaulter. 30 Bold and 0.3 ETH is distributed uniformly between A, B and C. Each receive 10 Bold, 0.1 ETH - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); - const alice_ICR_After = await troveManager.getCurrentICR(alice, price); - const bob_ICR_After = await troveManager.getCurrentICR(bob, price); - const carol_ICR_After = await troveManager.getCurrentICR(carol, price); + const alice_ICR_After = await troveManager.getCurrentICR(aliceTroveId, price); + const bob_ICR_After = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_After = await troveManager.getCurrentICR(carolTroveId, price); /* After liquidation: @@ -1308,8 +1309,8 @@ contract("TroveManager", async (accounts) => { assert.isTrue(carol_ICR_After.lte(mv._MCR)); /* Though Bob's true ICR (including pending rewards) is below the MCR, check that Bob's raw coll and debt has not changed */ - const bob_Coll = (await troveManager.Troves(bob))[1]; - const bob_Debt = (await troveManager.Troves(bob))[0]; + const bob_Coll = (await troveManager.Troves(bobTroveId))[1]; + const bob_Debt = (await troveManager.Troves(bobTroveId))[0]; const bob_rawICR = bob_Coll.mul(toBN(dec(100, 18))).div(bob_Debt); assert.isTrue(bob_rawICR.gte(mv._MCR)); @@ -1325,31 +1326,31 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); //liquidate A, B, C - await troveManager.batchLiquidateTroves([alice, bob, carol]); + await troveManager.batchLiquidateTroves([aliceTroveId, bobTroveId, carolTroveId]); // Check A stays active, B and C get liquidated - assert.isTrue(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // check trove statuses - A active (1), B and C closed by liquidation (3) - assert.equal((await troveManager.Troves(alice))[3].toString(), "1"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); - assert.equal((await troveManager.Troves(carol))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "1"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(carolTroveId))[3].toString(), "3"); }); it("batchLiquidateTroves(): liquidates troves with ICR < MCR", async () => { - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // A, B, C open troves that will remain active when price drops to 100 - await openTrove({ ICR: toBN(dec(220, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(230, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(240, 16)), extraParams: { from: carol } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(220, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(230, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(240, 16)), extraParams: { from: carol } }); // D, E, F open troves that will fall below MCR when price drops to 100 - await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: dennis } }); - await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: erin } }); - await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: flyn } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: dennis } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: erin } }); + const { troveId: flynTroveId } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: flyn } }); // Check list size is 7 assert.equal((await sortedTroves.getSize()).toString(), "7"); @@ -1358,12 +1359,12 @@ contract("TroveManager", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); - const alice_ICR = await troveManager.getCurrentICR(alice, price); - const bob_ICR = await troveManager.getCurrentICR(bob, price); - const carol_ICR = await troveManager.getCurrentICR(carol, price); - const dennis_ICR = await troveManager.getCurrentICR(dennis, price); - const erin_ICR = await troveManager.getCurrentICR(erin, price); - const flyn_ICR = await troveManager.getCurrentICR(flyn, price); + const alice_ICR = await troveManager.getCurrentICR(aliceTroveId, price); + const bob_ICR = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR = await troveManager.getCurrentICR(carolTroveId, price); + const dennis_ICR = await troveManager.getCurrentICR(dennisTroveId, price); + const erin_ICR = await troveManager.getCurrentICR(erinTroveId, price); + const flyn_ICR = await troveManager.getCurrentICR(flynTroveId, price); // Check A, B, C have ICR above MCR assert.isTrue(alice_ICR.gte(mv._MCR)); @@ -1379,30 +1380,30 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); //Liquidate sequence - await troveManager.batchLiquidateTroves([alice, bob, carol, dennis, erin, flyn, whale]); + await troveManager.batchLiquidateTroves([aliceTroveId, bobTroveId, carolTroveId, dennisTroveId, erinTroveId, flynTroveId, whaleTroveId]); // check list size reduced to 4 assert.equal((await sortedTroves.getSize()).toString(), "4"); // Check Whale and A, B, C remain in the system - assert.isTrue(await sortedTroves.contains(whale)); - assert.isTrue(await sortedTroves.contains(alice)); - assert.isTrue(await sortedTroves.contains(bob)); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(whaleTroveId)); + assert.isTrue(await sortedTroves.contains(aliceTroveId)); + assert.isTrue(await sortedTroves.contains(bobTroveId)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); // Check D, E, F have been removed - assert.isFalse(await sortedTroves.contains(dennis)); - assert.isFalse(await sortedTroves.contains(erin)); - assert.isFalse(await sortedTroves.contains(flyn)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); + assert.isFalse(await sortedTroves.contains(flynTroveId)); }); it("batchLiquidateTroves(): does not affect the liquidated user's token balances", async () => { - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // D, E, F open troves that will fall below MCR when price drops to 100 - await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: dennis } }); - await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: erin } }); - await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: flyn } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(218, 16)), extraParams: { from: dennis } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(216, 16)), extraParams: { from: erin } }); + const { troveId: flynTroveId } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: flyn } }); const D_balanceBefore = await boldToken.balanceOf(dennis); const E_balanceBefore = await boldToken.balanceOf(erin); @@ -1419,18 +1420,18 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); //Liquidate sequence - await troveManager.batchLiquidateTroves([dennis, erin, flyn, whale]); + await troveManager.batchLiquidateTroves([dennisTroveId, erinTroveId, flynTroveId, whaleTroveId]); // check list size reduced to 1 assert.equal((await sortedTroves.getSize()).toString(), "1"); // Check Whale remains in the system - assert.isTrue(await sortedTroves.contains(whale)); + assert.isTrue(await sortedTroves.contains(whaleTroveId)); // Check D, E, F have been removed - assert.isFalse(await sortedTroves.contains(dennis)); - assert.isFalse(await sortedTroves.contains(erin)); - assert.isFalse(await sortedTroves.contains(flyn)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); + assert.isFalse(await sortedTroves.contains(flynTroveId)); // Check token balances of users whose troves were liquidated, have not changed assert.equal( @@ -1443,7 +1444,7 @@ contract("TroveManager", async (accounts) => { it("batchLiquidateTroves(): A liquidation sequence containing Pool offsets increases the TCR", async () => { // Whale provides 500 Bold to SP - await openTrove({ + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(100, 18)), extraBoldAmount: toBN(dec(500, 18)), extraParams: { from: whale }, @@ -1452,32 +1453,32 @@ contract("TroveManager", async (accounts) => { from: whale, }); - await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(28, 18)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: carol } }); - await openTrove({ ICR: toBN(dec(80, 18)), extraParams: { from: dennis } }); + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(28, 18)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(80, 18)), extraParams: { from: dennis } }); - await openTrove({ + const { troveId: defaulter_1_TroveId } = await openTrove({ ICR: toBN(dec(199, 16)), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: defaulter_2_TroveId } = await openTrove({ ICR: toBN(dec(156, 16)), extraParams: { from: defaulter_2 }, }); - await openTrove({ + const { troveId: defaulter_3_TroveId } = await openTrove({ ICR: toBN(dec(183, 16)), extraParams: { from: defaulter_3 }, }); - await openTrove({ + const { troveId: defaulter_4_TroveId } = await openTrove({ ICR: toBN(dec(166, 16)), extraParams: { from: defaulter_4 }, }); - assert.isTrue(await sortedTroves.contains(defaulter_1)); - assert.isTrue(await sortedTroves.contains(defaulter_2)); - assert.isTrue(await sortedTroves.contains(defaulter_3)); - assert.isTrue(await sortedTroves.contains(defaulter_4)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_4_TroveId)); assert.equal((await sortedTroves.getSize()).toString(), "9"); @@ -1496,16 +1497,16 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate troves - await troveManager.batchLiquidateTroves([alice, bob, carol, dennis, defaulter_1, defaulter_2, defaulter_3, defaulter_4, whale]); + await troveManager.batchLiquidateTroves([aliceTroveId, bobTroveId, carolTroveId, dennisTroveId, defaulter_1_TroveId, defaulter_2_TroveId, defaulter_3_TroveId, defaulter_4_TroveId, whaleTroveId]); // Check pool has been emptied by the liquidations assert.equal((await stabilityPool.getTotalBoldDeposits()).toString(), "0"); // Check all defaulters have been liquidated - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); - assert.isFalse(await sortedTroves.contains(defaulter_3)); - assert.isFalse(await sortedTroves.contains(defaulter_4)); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_4_TroveId)); // check system sized reduced to 5 troves assert.equal((await sortedTroves.getSize()).toString(), "5"); @@ -1516,40 +1517,40 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): A liquidation sequence of pure redistributions decreases the TCR, due to gas compensation, but up to 0.5%", async () => { - const { collateral: W_coll, totalDebt: W_debt } = await openTrove({ + const { troveId: whaleTroveId, collateral: W_coll, totalDebt: W_debt } = await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale }, }); - const { collateral: A_coll, totalDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_debt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_debt } = await openTrove({ ICR: toBN(dec(28, 18)), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_debt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_debt } = await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: carol }, }); - const { collateral: D_coll, totalDebt: D_debt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_debt } = await openTrove({ ICR: toBN(dec(80, 18)), extraParams: { from: dennis }, }); - const { collateral: d1_coll, totalDebt: d1_debt } = await openTrove({ + const { troveId: defaulter_1_TroveId, collateral: d1_coll, totalDebt: d1_debt } = await openTrove({ ICR: toBN(dec(199, 16)), extraParams: { from: defaulter_1 }, }); - const { collateral: d2_coll, totalDebt: d2_debt } = await openTrove({ + const { troveId: defaulter_2_TroveId, collateral: d2_coll, totalDebt: d2_debt } = await openTrove({ ICR: toBN(dec(156, 16)), extraParams: { from: defaulter_2 }, }); - const { collateral: d3_coll, totalDebt: d3_debt } = await openTrove({ + const { troveId: defaulter_3_TroveId, collateral: d3_coll, totalDebt: d3_debt } = await openTrove({ ICR: toBN(dec(183, 16)), extraParams: { from: defaulter_3 }, }); - const { collateral: d4_coll, totalDebt: d4_debt } = await openTrove({ + const { troveId: defaulter_4_TroveId, collateral: d4_coll, totalDebt: d4_debt } = await openTrove({ ICR: toBN(dec(166, 16)), extraParams: { from: defaulter_4 }, }); @@ -1569,10 +1570,10 @@ contract("TroveManager", async (accounts) => { .add(d3_debt) .add(d4_debt); - assert.isTrue(await sortedTroves.contains(defaulter_1)); - assert.isTrue(await sortedTroves.contains(defaulter_2)); - assert.isTrue(await sortedTroves.contains(defaulter_3)); - assert.isTrue(await sortedTroves.contains(defaulter_4)); + assert.isTrue(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isTrue(await sortedTroves.contains(defaulter_4_TroveId)); assert.equal((await sortedTroves.getSize()).toString(), "9"); @@ -1593,13 +1594,13 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate - await troveManager.batchLiquidateTroves([alice, bob, carol, dennis, defaulter_1, defaulter_2, defaulter_3, defaulter_4, whale]); + await troveManager.batchLiquidateTroves([aliceTroveId, bobTroveId, carolTroveId, dennisTroveId, defaulter_1_TroveId, defaulter_2_TroveId, defaulter_3_TroveId, defaulter_4_TroveId, whaleTroveId]); // Check all defaulters have been liquidated - assert.isFalse(await sortedTroves.contains(defaulter_1)); - assert.isFalse(await sortedTroves.contains(defaulter_2)); - assert.isFalse(await sortedTroves.contains(defaulter_3)); - assert.isFalse(await sortedTroves.contains(defaulter_4)); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_2_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_3_TroveId)); + assert.isFalse(await sortedTroves.contains(defaulter_4_TroveId)); // check system sized reduced to 5 troves assert.equal((await sortedTroves.getSize()).toString(), "5"); @@ -1624,7 +1625,7 @@ contract("TroveManager", async (accounts) => { it("batchLiquidateTroves(): Liquidating troves with SP deposits correctly impacts their SP deposit and ETH gain", async () => { // Whale provides 400 Bold to the SP const whaleDeposit = toBN(dec(40000, 18)); - await openTrove({ + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(100, 18)), extraBoldAmount: whaleDeposit, extraParams: { from: whale }, @@ -1635,17 +1636,17 @@ contract("TroveManager", async (accounts) => { const A_deposit = toBN(dec(10000, 18)); const B_deposit = toBN(dec(30000, 18)); - const { collateral: A_coll, totalDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_debt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: A_deposit, extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_debt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: B_deposit, extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_debt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_debt } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol }, }); @@ -1673,12 +1674,12 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Liquidate - await troveManager.batchLiquidateTroves([alice, bob, carol, whale]); + await troveManager.batchLiquidateTroves([aliceTroveId, bobTroveId, carolTroveId, whaleTroveId]); // Check all defaulters have been liquidated - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // check system sized reduced to 1 troves assert.equal((await sortedTroves.getSize()).toString(), "1"); @@ -1792,11 +1793,11 @@ contract("TroveManager", async (accounts) => { it("batchLiquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards", async () => { // A, B, C, D, E open troves - await openTrove({ ICR: toBN(dec(300, 16)), extraParams: { from: C } }); - await openTrove({ ICR: toBN(dec(364, 16)), extraParams: { from: D } }); - await openTrove({ ICR: toBN(dec(364, 16)), extraParams: { from: E } }); - await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: A } }); - await openTrove({ ICR: toBN(dec(133, 16)), extraParams: { from: B } }); + const { troveId: CTroveId } = await openTrove({ ICR: toBN(dec(300, 16)), extraParams: { from: C } }); + const { troveId: DTroveId } = await openTrove({ ICR: toBN(dec(364, 16)), extraParams: { from: D } }); + const { troveId: ETroveId } = await openTrove({ ICR: toBN(dec(364, 16)), extraParams: { from: E } }); + const { troveId: ATroveId } = await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: A } }); + const { troveId: BTroveId } = await openTrove({ ICR: toBN(dec(133, 16)), extraParams: { from: B } }); // Price drops await priceFeed.setPrice(dec(175, 18)); @@ -1806,9 +1807,9 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // A gets liquidated, creates pending rewards for all - const liqTxA = await troveManager.liquidate(A); + const liqTxA = await troveManager.liquidate(ATroveId); assert.isTrue(liqTxA.receipt.status); - assert.isFalse(await sortedTroves.contains(A)); + assert.isFalse(await sortedTroves.contains(ATroveId)); // A adds 10 Bold to the SP, but less than C's debt await stabilityPool.provideToSP(dec(10, 18), { from: A }); @@ -1826,26 +1827,26 @@ contract("TroveManager", async (accounts) => { assert.isTrue(ICR_C.gt(TCR)); // Attempt to liquidate B and C, which skips C in the liquidation since it is immune - const liqTxBC = await troveManager.batchLiquidateTroves([B,C]); + const liqTxBC = await troveManager.batchLiquidateTroves([BTroveId, CTroveId]); assert.isTrue(liqTxBC.receipt.status); - assert.isFalse(await sortedTroves.contains(B)); - assert.isTrue(await sortedTroves.contains(C)); - assert.isTrue(await sortedTroves.contains(D)); - assert.isTrue(await sortedTroves.contains(E)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isTrue(await sortedTroves.contains(CTroveId)); + assert.isTrue(await sortedTroves.contains(DTroveId)); + assert.isTrue(await sortedTroves.contains(ETroveId)); // // All remaining troves D and E repay a little debt, applying their pending rewards assert.isTrue((await sortedTroves.getSize()).eq(toBN("3"))); - await borrowerOperations.repayBold(dec(1, 18), { from: D }); - await borrowerOperations.repayBold(dec(1, 18), { from: E }); + await borrowerOperations.repayBold(DTroveId, dec(1, 18), { from: D }); + await borrowerOperations.repayBold(ETroveId, dec(1, 18), { from: E }); // Check C is the only trove that has pending rewards - assert.isTrue(await troveManager.hasPendingRewards(C)); - assert.isFalse(await troveManager.hasPendingRewards(D)); - assert.isFalse(await troveManager.hasPendingRewards(E)); + assert.isTrue(await troveManager.hasPendingRewards(CTroveId)); + assert.isFalse(await troveManager.hasPendingRewards(DTroveId)); + assert.isFalse(await troveManager.hasPendingRewards(ETroveId)); // Check C's pending coll and debt rewards are <= the coll and debt in the DefaultPool - const pendingETH_C = await troveManager.getPendingETHReward(C); - const pendingBoldDebt_C = await troveManager.getPendingBoldDebtReward(C); + const pendingETH_C = await troveManager.getPendingETHReward(CTroveId); + const pendingBoldDebt_C = await troveManager.getPendingBoldDebtReward(CTroveId); const defaultPoolETH = await defaultPool.getETHBalance(); const defaultPoolBoldDebt = await defaultPool.getBoldDebt(); assert.isTrue(pendingETH_C.lte(defaultPoolETH)); @@ -1867,11 +1868,11 @@ contract("TroveManager", async (accounts) => { await priceFeed.setPrice(dec(50, 18)); // Try to liquidate C again. Check it succeeds and closes C's trove - const liqTx2 = await troveManager.batchLiquidateTroves([C, D]); + const liqTx2 = await troveManager.batchLiquidateTroves([CTroveId, DTroveId]); assert.isTrue(liqTx2.receipt.status); - assert.isFalse(await sortedTroves.contains(C)); - assert.isFalse(await sortedTroves.contains(D)); - assert.isTrue(await sortedTroves.contains(E)); + assert.isFalse(await sortedTroves.contains(CTroveId)); + assert.isFalse(await sortedTroves.contains(DTroveId)); + assert.isTrue(await sortedTroves.contains(ETroveId)); assert.isTrue((await sortedTroves.getSize()).eq(toBN("1"))); }); @@ -1879,14 +1880,14 @@ contract("TroveManager", async (accounts) => { // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(133, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(133, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(2000, 16)), extraParams: { from: dennis }, }); - await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); // Check full sorted list size is 6 assert.equal((await sortedTroves.getSize()).toString(), "6"); @@ -1906,33 +1907,33 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Confirm troves A-C are ICR < 110% - assert.isTrue((await troveManager.getCurrentICR(alice, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(carol, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(aliceTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(carolTroveId, price)).lt(mv._MCR)); // Confirm D-E are ICR > 110% assert.isTrue( - (await troveManager.getCurrentICR(dennis, price)).gte(mv._MCR) + (await troveManager.getCurrentICR(dennisTroveId, price)).gte(mv._MCR) ); - assert.isTrue((await troveManager.getCurrentICR(erin, price)).gte(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(erinTroveId, price)).gte(mv._MCR)); // Confirm Whale is ICR >= 110% assert.isTrue( (await troveManager.getCurrentICR(whale, price)).gte(mv._MCR) ); - liquidationArray = [alice, bob, carol, dennis, erin]; + const liquidationArray = [aliceTroveId, bobTroveId, carolTroveId, dennisTroveId, erinTroveId]; await troveManager.batchLiquidateTroves(liquidationArray); // Confirm troves A-C have been removed from the system - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Check all troves A-C are now closed by liquidation - assert.equal((await troveManager.Troves(alice))[3].toString(), "3"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); - assert.equal((await troveManager.Troves(carol))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(carolTroveId))[3].toString(), "3"); // Check sorted list has been reduced to length 3 assert.equal((await sortedTroves.getSize()).toString(), "3"); @@ -1942,15 +1943,15 @@ contract("TroveManager", async (accounts) => { // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(180, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(180, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: toBN(dec(500, 18)), extraParams: { from: dennis }, }); - await openTrove({ + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: toBN(dec(500, 18)), extraParams: { from: erin }, @@ -1974,34 +1975,34 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Confirm troves A-E are ICR < 110% - assert.isTrue((await troveManager.getCurrentICR(alice, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(carol, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(aliceTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(carolTroveId, price)).lt(mv._MCR)); assert.isTrue( - (await troveManager.getCurrentICR(dennis, price)).lt(mv._MCR) + (await troveManager.getCurrentICR(dennisTroveId, price)).lt(mv._MCR) ); - assert.isTrue((await troveManager.getCurrentICR(erin, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(erinTroveId, price)).lt(mv._MCR)); - liquidationArray = [alice, bob]; // C-E not included + const liquidationArray = [aliceTroveId, bobTroveId]; // C-E not included await troveManager.batchLiquidateTroves(liquidationArray); // Confirm troves A-B have been removed from the system - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Check all troves A-B are now closed by liquidation - assert.equal((await troveManager.Troves(alice))[3].toString(), "3"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); // Confirm troves C-E remain in the system - assert.isTrue(await sortedTroves.contains(carol)); - assert.isTrue(await sortedTroves.contains(dennis)); - assert.isTrue(await sortedTroves.contains(erin)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); + assert.isTrue(await sortedTroves.contains(dennisTroveId)); + assert.isTrue(await sortedTroves.contains(erinTroveId)); // Check all troves C-E are still active - assert.equal((await troveManager.Troves(carol))[3].toString(), "1"); - assert.equal((await troveManager.Troves(dennis))[3].toString(), "1"); - assert.equal((await troveManager.Troves(erin))[3].toString(), "1"); + assert.equal((await troveManager.Troves(carolTroveId))[3].toString(), "1"); + assert.equal((await troveManager.Troves(dennisTroveId))[3].toString(), "1"); + assert.equal((await troveManager.Troves(erinTroveId))[3].toString(), "1"); // Check sorted list has been reduced to length 4 assert.equal((await sortedTroves.getSize()).toString(), "4"); @@ -2009,16 +2010,16 @@ contract("TroveManager", async (accounts) => { it("batchLiquidateTroves(): does not close troves with ICR >= MCR in the given array", async () => { // --- SETUP --- - await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); + const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); - await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: alice } }); - await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(195, 16)), extraParams: { from: carol } }); - await openTrove({ + const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: alice } }); + const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: bob } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(195, 16)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(2000, 16)), extraParams: { from: dennis }, }); - await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); // Check full sorted list size is 6 assert.equal((await sortedTroves.getSize()).toString(), "6"); @@ -2038,33 +2039,33 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Confirm troves A-C are ICR < 110% - assert.isTrue((await troveManager.getCurrentICR(alice, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(carol, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(aliceTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(carolTroveId, price)).lt(mv._MCR)); // Confirm D-E are ICR >= 110% assert.isTrue( - (await troveManager.getCurrentICR(dennis, price)).gte(mv._MCR) + (await troveManager.getCurrentICR(dennisTroveId, price)).gte(mv._MCR) ); - assert.isTrue((await troveManager.getCurrentICR(erin, price)).gte(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(erinTroveId, price)).gte(mv._MCR)); // Confirm Whale is ICR > 110% assert.isTrue( (await troveManager.getCurrentICR(whale, price)).gte(mv._MCR) ); - liquidationArray = [alice, bob, carol, dennis, erin]; + const liquidationArray = [aliceTroveId, bobTroveId, carolTroveId, dennisTroveId, erinTroveId]; await troveManager.batchLiquidateTroves(liquidationArray); // Confirm troves D-E and whale remain in the system - assert.isTrue(await sortedTroves.contains(dennis)); - assert.isTrue(await sortedTroves.contains(erin)); - assert.isTrue(await sortedTroves.contains(whale)); + assert.isTrue(await sortedTroves.contains(dennisTroveId)); + assert.isTrue(await sortedTroves.contains(erinTroveId)); + assert.isTrue(await sortedTroves.contains(whaleTroveId)); // Check all troves D-E and whale remain active - assert.equal((await troveManager.Troves(dennis))[3].toString(), "1"); - assert.equal((await troveManager.Troves(erin))[3].toString(), "1"); - assert.isTrue(await sortedTroves.contains(whale)); + assert.equal((await troveManager.Troves(dennisTroveId))[3].toString(), "1"); + assert.equal((await troveManager.Troves(erinTroveId))[3].toString(), "1"); + assert.isTrue(await sortedTroves.contains(whaleTroveId)); // Check sorted list has been reduced to length 3 assert.equal((await sortedTroves.getSize()).toString(), "3"); @@ -2100,7 +2101,7 @@ contract("TroveManager", async (accounts) => { // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); - liquidationArray = []; + const liquidationArray = []; try { const tx = await troveManager.batchLiquidateTroves(liquidationArray); assert.isFalse(tx.receipt.status); @@ -2121,21 +2122,21 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { totalDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_debt } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: alice }, }); - const { totalDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_debt } = await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: bob }, }); - await openTrove({ + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(2000, 16)), extraParams: { from: dennis }, }); - await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); - assert.equal(await troveManager.getTroveStatus(carol), 0); // check trove non-existent + assert.equal(await troveManager.getTroveStatus(th.addressToTroveId(carol)), 0); // check trove non-existent // Check full sorted list size is 6 assert.equal((await sortedTroves.getSize()).toString(), "5"); @@ -2153,14 +2154,14 @@ contract("TroveManager", async (accounts) => { assert.isFalse(await th.checkRecoveryMode(contracts)); // Confirm troves A-B are ICR < 110% - assert.isTrue((await troveManager.getCurrentICR(alice, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(aliceTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).lt(mv._MCR)); // Confirm D-E are ICR > 110% assert.isTrue( - (await troveManager.getCurrentICR(dennis, price)).gte(mv._MCR) + (await troveManager.getCurrentICR(dennisTroveId, price)).gte(mv._MCR) ); - assert.isTrue((await troveManager.getCurrentICR(erin, price)).gte(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(erinTroveId, price)).gte(mv._MCR)); // Confirm Whale is ICR >= 110% assert.isTrue( @@ -2168,23 +2169,23 @@ contract("TroveManager", async (accounts) => { ); // Liquidate - trove C in between the ones to be liquidated! - const liquidationArray = [alice, carol, bob, dennis, erin]; + const liquidationArray = [aliceTroveId, th.addressToTroveId(carol), bobTroveId, dennisTroveId, erinTroveId]; await troveManager.batchLiquidateTroves(liquidationArray); // Confirm troves A-B have been removed from the system - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Check all troves A-B are now closed by liquidation - assert.equal((await troveManager.Troves(alice))[3].toString(), "3"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); // Check sorted list has been reduced to length 3 assert.equal((await sortedTroves.getSize()).toString(), "3"); // Confirm trove C non-existent - assert.isFalse(await sortedTroves.contains(carol)); - assert.equal((await troveManager.Troves(carol))[3].toString(), "0"); + assert.isFalse(await sortedTroves.contains(th.addressToTroveId(carol))); + assert.equal((await troveManager.Troves(th.addressToTroveId(carol)))[3].toString(), "0"); // Check Stability pool has only been reduced by A-B th.assertIsApproximatelyEqual( @@ -2205,22 +2206,22 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { totalDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_debt } = await openTrove({ ICR: toBN(dec(190, 16)), extraParams: { from: alice }, }); - const { totalDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_debt } = await openTrove({ ICR: toBN(dec(120, 16)), extraParams: { from: bob }, }); - await openTrove({ ICR: toBN(dec(195, 16)), extraParams: { from: carol } }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(195, 16)), extraParams: { from: carol } }); + const { troveId: dennisTroveId } = await openTrove({ ICR: toBN(dec(2000, 16)), extraParams: { from: dennis }, }); - await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); + const { troveId: erinTroveId } = await openTrove({ ICR: toBN(dec(1800, 16)), extraParams: { from: erin } }); - assert.isTrue(await sortedTroves.contains(carol)); + assert.isTrue(await sortedTroves.contains(carolTroveId)); // Check full sorted list size is 6 assert.equal((await sortedTroves.getSize()).toString(), "6"); @@ -2238,25 +2239,25 @@ contract("TroveManager", async (accounts) => { const price = await priceFeed.getPrice(); // Carol liquidated, and her trove is closed - const txCarolClose = await borrowerOperations.closeTrove({ from: carol }); + const txCarolClose = await borrowerOperations.closeTrove(carolTroveId, { from: carol }); assert.isTrue(txCarolClose.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); - assert.equal(await troveManager.getTroveStatus(carol), 2); // check trove closed + assert.equal(await troveManager.getTroveStatus(carolTroveId), 2); // check trove closed // Confirm system is not in Recovery Mode assert.isFalse(await th.checkRecoveryMode(contracts)); // Confirm troves A-B are ICR < 110% - assert.isTrue((await troveManager.getCurrentICR(alice, price)).lt(mv._MCR)); - assert.isTrue((await troveManager.getCurrentICR(bob, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(aliceTroveId, price)).lt(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(bobTroveId, price)).lt(mv._MCR)); // Confirm D-E are ICR > 110% assert.isTrue( - (await troveManager.getCurrentICR(dennis, price)).gte(mv._MCR) + (await troveManager.getCurrentICR(dennisTroveId, price)).gte(mv._MCR) ); - assert.isTrue((await troveManager.getCurrentICR(erin, price)).gte(mv._MCR)); + assert.isTrue((await troveManager.getCurrentICR(erinTroveId, price)).gte(mv._MCR)); // Confirm Whale is ICR >= 110% assert.isTrue( @@ -2264,18 +2265,18 @@ contract("TroveManager", async (accounts) => { ); // Liquidate - trove C in between the ones to be liquidated! - const liquidationArray = [alice, carol, bob, dennis, erin]; + const liquidationArray = [aliceTroveId, carolTroveId, bobTroveId, dennisTroveId, erinTroveId]; await troveManager.batchLiquidateTroves(liquidationArray); // Confirm troves A-B have been removed from the system - assert.isFalse(await sortedTroves.contains(alice)); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Check all troves A-B are now closed by liquidation - assert.equal((await troveManager.Troves(alice))[3].toString(), "3"); - assert.equal((await troveManager.Troves(bob))[3].toString(), "3"); + assert.equal((await troveManager.Troves(aliceTroveId))[3].toString(), "3"); + assert.equal((await troveManager.Troves(bobTroveId))[3].toString(), "3"); // Trove C still closed by user - assert.equal((await troveManager.Troves(carol))[3].toString(), "2"); + assert.equal((await troveManager.Troves(carolTroveId))[3].toString(), "2"); // Check sorted list has been reduced to length 3 assert.equal((await sortedTroves.getSize()).toString(), "3"); @@ -2354,17 +2355,17 @@ contract("TroveManager", async (accounts) => { it.skip("redeemCollateral(): cancels the provided Bold with debt from Troves with the lowest ICRs and sends an equivalent amount of Ether", async () => { // --- SETUP --- - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: alice }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(8, 18), extraParams: { from: bob }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(250, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: carol }, @@ -2426,9 +2427,9 @@ contract("TroveManager", async (accounts) => { const ETHFee = th.getEmittedRedemptionValues(redemptionTx)[3]; - const alice_Trove_After = await troveManager.Troves(alice); - const bob_Trove_After = await troveManager.Troves(bob); - const carol_Trove_After = await troveManager.Troves(carol); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); + const bob_Trove_After = await troveManager.Troves(bobTroveId); + const carol_Trove_After = await troveManager.Troves(carolTroveId); const alice_debt_After = alice_Trove_After[0].toString(); const bob_debt_After = bob_Trove_After[0].toString(); @@ -2472,17 +2473,17 @@ contract("TroveManager", async (accounts) => { it.skip("redeemCollateral(): with invalid first hint, zero address", async () => { // --- SETUP --- - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: alice }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(8, 18), extraParams: { from: bob }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(250, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: carol }, @@ -2544,9 +2545,9 @@ contract("TroveManager", async (accounts) => { const ETHFee = th.getEmittedRedemptionValues(redemptionTx)[3]; - const alice_Trove_After = await troveManager.Troves(alice); - const bob_Trove_After = await troveManager.Troves(bob); - const carol_Trove_After = await troveManager.Troves(carol); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); + const bob_Trove_After = await troveManager.Troves(bobTroveId); + const carol_Trove_After = await troveManager.Troves(carolTroveId); const alice_debt_After = alice_Trove_After[0].toString(); const bob_debt_After = bob_Trove_After[0].toString(); @@ -2581,17 +2582,17 @@ contract("TroveManager", async (accounts) => { it.skip("redeemCollateral(): with invalid first hint, non-existent trove", async () => { // --- SETUP --- - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: alice }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(8, 18), extraParams: { from: bob }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(250, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: carol }, @@ -2653,9 +2654,9 @@ contract("TroveManager", async (accounts) => { const ETHFee = th.getEmittedRedemptionValues(redemptionTx)[3]; - const alice_Trove_After = await troveManager.Troves(alice); - const bob_Trove_After = await troveManager.Troves(bob); - const carol_Trove_After = await troveManager.Troves(carol); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); + const bob_Trove_After = await troveManager.Troves(bobTroveId); + const carol_Trove_After = await troveManager.Troves(carolTroveId); const alice_debt_After = alice_Trove_After[0].toString(); const bob_debt_After = bob_Trove_After[0].toString(); @@ -2690,17 +2691,17 @@ contract("TroveManager", async (accounts) => { it.skip("redeemCollateral(): with invalid first hint, trove below MCR", async () => { // --- SETUP --- - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: alice }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(8, 18), extraParams: { from: bob }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(250, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: carol }, @@ -2767,9 +2768,9 @@ contract("TroveManager", async (accounts) => { const ETHFee = th.getEmittedRedemptionValues(redemptionTx)[3]; - const alice_Trove_After = await troveManager.Troves(alice); - const bob_Trove_After = await troveManager.Troves(bob); - const carol_Trove_After = await troveManager.Troves(carol); + const alice_Trove_After = await troveManager.Troves(aliceTroveId); + const bob_Trove_After = await troveManager.Troves(bobTroveId); + const carol_Trove_After = await troveManager.Troves(carolTroveId); const alice_debt_After = alice_Trove_After[0].toString(); const bob_debt_After = bob_Trove_After[0].toString(); @@ -2807,28 +2808,28 @@ contract("TroveManager", async (accounts) => { await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); // Alice, Bob, Carol, Dennis, Erin open troves - const { netDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, netDebt: A_debt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: alice }, }); - const { netDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_debt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: bob }, }); - const { netDebt: C_debt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_debt } = await openTrove({ ICR: toBN(dec(290, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: carol }, }); const redemptionAmount = A_debt.add(B_debt).add(C_debt); - const { totalDebt: D_totalDebt, collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, totalDebt: D_totalDebt, collateral: D_coll } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: dennis }, }); - const { totalDebt: E_totalDebt, collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, totalDebt: E_totalDebt, collateral: E_coll } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: erin }, @@ -2869,31 +2870,31 @@ contract("TroveManager", async (accounts) => { ); // Check debt of Alice, Bob, Carol - const alice_Debt = await troveManager.getTroveDebt(alice); - const bob_Debt = await troveManager.getTroveDebt(bob); - const carol_Debt = await troveManager.getTroveDebt(carol); + const alice_Debt = await troveManager.getTroveDebt(aliceTroveId); + const bob_Debt = await troveManager.getTroveDebt(bobTroveId); + const carol_Debt = await troveManager.getTroveDebt(carolTroveId); assert.equal(alice_Debt, 0); assert.equal(bob_Debt, 0); assert.equal(carol_Debt, 0); // check Alice, Bob and Carol troves are closed by redemption - const alice_Status = await troveManager.getTroveStatus(alice); - const bob_Status = await troveManager.getTroveStatus(bob); - const carol_Status = await troveManager.getTroveStatus(carol); + const alice_Status = await troveManager.getTroveStatus(aliceTroveId); + const bob_Status = await troveManager.getTroveStatus(bobTroveId); + const carol_Status = await troveManager.getTroveStatus(carolTroveId); assert.equal(alice_Status, 4); assert.equal(bob_Status, 4); assert.equal(carol_Status, 4); // check debt and coll of Dennis, Erin has not been impacted by redemption - const dennis_Debt = await troveManager.getTroveDebt(dennis); - const erin_Debt = await troveManager.getTroveDebt(erin); + const dennis_Debt = await troveManager.getTroveDebt(dennisTroveId); + const erin_Debt = await troveManager.getTroveDebt(erinTroveId); th.assertIsApproximatelyEqual(dennis_Debt, D_totalDebt); th.assertIsApproximatelyEqual(erin_Debt, E_totalDebt); - const dennis_Coll = await troveManager.getTroveColl(dennis); - const erin_Coll = await troveManager.getTroveColl(erin); + const dennis_Coll = await troveManager.getTroveColl(dennisTroveId); + const erin_Coll = await troveManager.getTroveColl(erinTroveId); assert.equal(dennis_Coll.toString(), D_coll.toString()); assert.equal(erin_Coll.toString(), E_coll.toString()); @@ -2904,17 +2905,17 @@ contract("TroveManager", async (accounts) => { await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); // Alice, Bob, Carol open troves with equal collateral ratio - const { netDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, netDebt: A_debt } = await openTrove({ ICR: toBN(dec(286, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: alice }, }); - const { netDebt: B_debt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_debt } = await openTrove({ ICR: toBN(dec(286, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: bob }, }); - const { netDebt: C_debt, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_debt, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(286, 16)), extraBoldAmount: dec(20, 18), extraParams: { from: carol }, @@ -2925,7 +2926,7 @@ contract("TroveManager", async (accounts) => { // --- TEST --- // open trove from redeemer. Redeemer has highest ICR (100ETH, 100 Bold), 20000% - const { boldAmount: F_boldAmount } = await openTrove({ + const { troveId: flynTroveId, boldAmount: F_boldAmount } = await openTrove({ ICR: toBN(dec(200, 18)), extraBoldAmount: redemptionAmount.mul(toBN(2)), extraParams: { from: flyn }, @@ -2957,39 +2958,39 @@ contract("TroveManager", async (accounts) => { ); // Check debt of Alice, Bob, Carol - const alice_Debt = await troveManager.getTroveDebt(alice); - const bob_Debt = await troveManager.getTroveDebt(bob); - const carol_Debt = await troveManager.getTroveDebt(carol); + const alice_Debt = await troveManager.getTroveDebt(aliceTroveId); + const bob_Debt = await troveManager.getTroveDebt(bobTroveId); + const carol_Debt = await troveManager.getTroveDebt(carolTroveId); assert.equal(alice_Debt, 0); assert.equal(bob_Debt, 0); th.assertIsApproximatelyEqual(carol_Debt, C_totalDebt); // check Alice and Bob troves are closed, but Carol is not - const alice_Status = await troveManager.getTroveStatus(alice); - const bob_Status = await troveManager.getTroveStatus(bob); - const carol_Status = await troveManager.getTroveStatus(carol); + const alice_Status = await troveManager.getTroveStatus(aliceTroveId); + const bob_Status = await troveManager.getTroveStatus(bobTroveId); + const carol_Status = await troveManager.getTroveStatus(carolTroveId); assert.equal(alice_Status, 4); assert.equal(bob_Status, 4); assert.equal(carol_Status, 1); }); it.skip("redeemCollateral(): performs partial redemption if resultant debt is > minimum net debt", async () => { - await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), A, A, { from: A, value: dec(1000, "ether") } ); - await th.openTroveWrapper(contracts, + const BTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), B, B, { from: B, value: dec(1000, "ether") } ); - await th.openTroveWrapper(contracts, + const CTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), C, @@ -3019,31 +3020,31 @@ contract("TroveManager", async (accounts) => { ); // Check B, C closed and A remains active - assert.isTrue(await sortedTroves.contains(A)); - assert.isFalse(await sortedTroves.contains(B)); - assert.isFalse(await sortedTroves.contains(C)); + assert.isTrue(await sortedTroves.contains(ATroveId)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isFalse(await sortedTroves.contains(CTroveId)); // A's remaining debt = 29800 + 19800 + 9800 + 200 - 55000 = 4600 - const A_debt = await troveManager.getTroveDebt(A); + const A_debt = await troveManager.getTroveDebt(ATroveId); await th.assertIsApproximatelyEqual(A_debt, dec(4600, 18), 1000); }); it.skip("redeemCollateral(): doesn't perform partial redemption if resultant debt would be < minimum net debt", async () => { - await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), A, A, { from: A, value: dec(1000, "ether") } ); - await th.openTroveWrapper(contracts, + const BTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(20000, 18)), B, B, { from: B, value: dec(1000, "ether") } ); - await th.openTroveWrapper(contracts, + const CTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(30000, 18)), C, @@ -3073,29 +3074,29 @@ contract("TroveManager", async (accounts) => { ); // Check B, C closed and A remains active - assert.isTrue(await sortedTroves.contains(A)); - assert.isFalse(await sortedTroves.contains(B)); - assert.isFalse(await sortedTroves.contains(C)); + assert.isTrue(await sortedTroves.contains(ATroveId)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isFalse(await sortedTroves.contains(CTroveId)); // A's remaining debt would be 29950 + 19950 + 5950 + 50 - 55000 = 900. // Since this is below the min net debt of 100, A should be skipped and untouched by the redemption - const A_debt = await troveManager.getTroveDebt(A); + const A_debt = await troveManager.getTroveDebt(ATroveId); await th.assertIsApproximatelyEqual(A_debt, dec(6000, 18)); }); it.skip("redeemCollateral(): doesnt perform the final partial redemption in the sequence if the hint is out-of-date", async () => { // --- SETUP --- - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(363, 16)), extraBoldAmount: dec(5, 18), extraParams: { from: alice }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: bobTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(344, 16)), extraBoldAmount: dec(8, 18), extraParams: { from: bob }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: carolTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(333, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: carol }, @@ -3275,11 +3276,11 @@ contract("TroveManager", async (accounts) => { it.skip("redeemCollateral(): doesn't touch Troves with ICR < 110%", async () => { // --- SETUP --- - const { netDebt: A_debt } = await openTrove({ + const { troveId: aliceTroveId, netDebt: A_debt } = await openTrove({ ICR: toBN(dec(13, 18)), extraParams: { from: alice }, }); - const { boldAmount: B_boldAmount, totalDebt: B_totalDebt } = + const { troveId: bobTroveId, boldAmount: B_boldAmount, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(133, 16)), extraBoldAmount: A_debt, @@ -3312,34 +3313,34 @@ contract("TroveManager", async (accounts) => { ); // Alice's Trove was cleared of debt - const { debt: alice_Debt_After } = await troveManager.Troves(alice); + const { debt: alice_Debt_After } = await troveManager.Troves(aliceTroveId); assert.equal(alice_Debt_After, "0"); // Bob's Trove was left untouched - const { debt: bob_Debt_After } = await troveManager.Troves(bob); + const { debt: bob_Debt_After } = await troveManager.Troves(bobTroveId); th.assertIsApproximatelyEqual(bob_Debt_After, B_totalDebt); }); it.skip("redeemCollateral(): finds the last Trove with ICR == 110% even if there is more than one", async () => { // --- SETUP --- const amount1 = toBN(dec(100, 18)); - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: amount1, extraParams: { from: alice }, }); - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: amount1, extraParams: { from: bob }, }); - const { totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: amount1, extraParams: { from: carol }, }); const redemptionAmount = C_totalDebt.add(B_totalDebt).add(A_totalDebt); - const { totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(195, 16)), extraBoldAmount: redemptionAmount, extraParams: { from: dennis }, @@ -3383,23 +3384,23 @@ contract("TroveManager", async (accounts) => { { from: dennis } ); - const { debt: alice_Debt_After } = await troveManager.Troves(alice); + const { debt: alice_Debt_After } = await troveManager.Troves(aliceTroveId); assert.equal(alice_Debt_After, "0"); - const { debt: bob_Debt_After } = await troveManager.Troves(bob); + const { debt: bob_Debt_After } = await troveManager.Troves(bobTroveId); assert.equal(bob_Debt_After, "0"); - const { debt: carol_Debt_After } = await troveManager.Troves(carol); + const { debt: carol_Debt_After } = await troveManager.Troves(carolTroveId); assert.equal(carol_Debt_After, "0"); - const { debt: dennis_Debt_After } = await troveManager.Troves(dennis); + const { debt: dennis_Debt_After } = await troveManager.Troves(dennisTroveId); th.assertIsApproximatelyEqual(dennis_Debt_After, D_totalDebt); }); it.skip("redeemCollateral(): reverts when TCR < MCR", async () => { await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: bob } }); - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); await openTrove({ ICR: toBN(dec(196, 16)), extraParams: { from: dennis } }); // This will put Dennis slightly below 110%, and everyone else exactly at 110% @@ -3417,7 +3418,7 @@ contract("TroveManager", async (accounts) => { ); await assertRevert( - th.redeemCollateral(carol, contracts, GAS_PRICE, dec(270, 18)), + th.redeemCollateral(carolTroveId, contracts, GAS_PRICE, dec(270, 18)), "TroveManager: Cannot redeem when TCR < MCR" ); }); @@ -3660,22 +3661,22 @@ contract("TroveManager", async (accounts) => { await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // B, C, D, F open trove - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: bob }, }); - const { totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(195, 16)), extraBoldAmount: dec(200, 18), extraParams: { from: carol }, }); - const { totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(400, 18), extraParams: { from: dennis }, }); - const { totalDebt: F_totalDebt } = await openTrove({ + const { troveId: flynTroveId, totalDebt: F_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: flyn }, @@ -3702,18 +3703,18 @@ contract("TroveManager", async (accounts) => { }); let price = await priceFeed.getPrice(); - const bob_ICR_before = await troveManager.getCurrentICR(bob, price); - const carol_ICR_before = await troveManager.getCurrentICR(carol, price); - const dennis_ICR_before = await troveManager.getCurrentICR(dennis, price); + const bob_ICR_before = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_before = await troveManager.getCurrentICR(carolTroveId, price); + const dennis_ICR_before = await troveManager.getCurrentICR(dennisTroveId, price); // Price drops await priceFeed.setPrice(dec(100, 18)); - assert.isTrue(await sortedTroves.contains(flyn)); + assert.isTrue(await sortedTroves.contains(flynTroveId)); // Liquidate Flyn - await troveManager.liquidate(flyn); - assert.isFalse(await sortedTroves.contains(flyn)); + await troveManager.liquidate(flynTroveId); + assert.isFalse(await sortedTroves.contains(flynTroveId)); // Price bounces back, bringing B, C, D back above MCR await priceFeed.setPrice(dec(200, 18)); @@ -3754,9 +3755,9 @@ contract("TroveManager", async (accounts) => { await th.redeemCollateral(erin, contracts, redemptionAmount, th._100pct); price = await priceFeed.getPrice(); - const bob_ICR_after = await troveManager.getCurrentICR(bob, price); - const carol_ICR_after = await troveManager.getCurrentICR(carol, price); - const dennis_ICR_after = await troveManager.getCurrentICR(dennis, price); + const bob_ICR_after = await troveManager.getCurrentICR(bobTroveId, price); + const carol_ICR_after = await troveManager.getCurrentICR(carolTroveId, price); + const dennis_ICR_after = await troveManager.getCurrentICR(dennisTroveId, price); // Check ICR of B, C and D troves has increased,i.e. they have been hit by redemptions assert.isTrue(bob_ICR_after.gte(bob_ICR_before)); @@ -3900,7 +3901,7 @@ contract("TroveManager", async (accounts) => { }); // Alice opens trove and transfers 400 Bold to Erin, the would-be redeemer - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(400, 18), extraParams: { from: alice }, @@ -3912,17 +3913,17 @@ contract("TroveManager", async (accounts) => { assert.equal(erin_balance_before, dec(400, 18)); // B, C, D open trove - const { collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(590, 18), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(1990, 18), extraParams: { from: carol }, }); - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(500, 16)), extraBoldAmount: dec(1990, 18), extraParams: { from: dennis }, @@ -4109,7 +4110,7 @@ contract("TroveManager", async (accounts) => { }); // Alice opens trove and transfers 1000 Bold each to Erin, Flyn, Graham - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(4990, 18), extraParams: { from: alice }, @@ -4119,17 +4120,17 @@ contract("TroveManager", async (accounts) => { await boldToken.transfer(graham, dec(1000, 18), { from: alice }); // B, C, D open trove - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(300, 16)), extraBoldAmount: dec(1590, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(600, 16)), extraBoldAmount: dec(1090, 18), extraParams: { from: carol }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(800, 16)), extraBoldAmount: dec(1090, 18), extraParams: { from: dennis }, @@ -4305,12 +4306,12 @@ contract("TroveManager", async (accounts) => { assert.equal(await boldToken.balanceOf(bob), "101000000000000000000"); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(1000, 16)), extraBoldAmount: dec(40, 18), extraParams: { from: carol }, }); - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(1000, 16)), extraBoldAmount: dec(40, 18), extraParams: { from: dennis }, @@ -4371,17 +4372,17 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { totalDebt: A_totalDebt } = await openTrove({ + const { troveId: ATroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: A }, }); - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: BTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: B }, }); - const { totalDebt: C_totalDebt } = await openTrove({ + const { troveId: CTroveId, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(180, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: C }, @@ -4438,22 +4439,22 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { netDebt: A_netDebt } = await openTrove({ + const { troveId: ATroveId, netDebt: A_netDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: A }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: BTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: B }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: CTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(180, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: C }, }); - const { netDebt: D_netDebt } = await openTrove({ + const { troveId: DTroveId, netDebt: D_netDebt } = await openTrove({ ICR: toBN(dec(280, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: D }, @@ -4470,12 +4471,12 @@ contract("TroveManager", async (accounts) => { await th.redeemCollateral(whale, contracts, redemptionAmount, GAS_PRICE); // Check A, B, C have been closed - assert.isFalse(await sortedTroves.contains(A)); - assert.isFalse(await sortedTroves.contains(B)); - assert.isFalse(await sortedTroves.contains(C)); + assert.isFalse(await sortedTroves.contains(ATroveId)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isFalse(await sortedTroves.contains(CTroveId)); // Check D remains active - assert.isTrue(await sortedTroves.contains(D)); + assert.isTrue(await sortedTroves.contains(DTroveId)); }); const redeemCollateral3Full1Partial = async () => { @@ -4491,22 +4492,22 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { netDebt: A_netDebt, collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, netDebt: A_netDebt, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: A }, }); - const { netDebt: B_netDebt, collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, netDebt: B_netDebt, collateral: B_coll } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: B }, }); - const { netDebt: C_netDebt, collateral: C_coll } = await openTrove({ + const { troveId: CTroveId, netDebt: C_netDebt, collateral: C_coll } = await openTrove({ ICR: toBN(dec(180, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: C }, }); - const { netDebt: D_netDebt } = await openTrove({ + const { troveId: DTroveId, netDebt: D_netDebt } = await openTrove({ ICR: toBN(dec(280, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: D }, @@ -4520,10 +4521,10 @@ contract("TroveManager", async (accounts) => { const C_balanceBefore = toBN(await contracts.WETH.balanceOf(C)); const D_balanceBefore = toBN(await contracts.WETH.balanceOf(D)); - const A_collBefore = await troveManager.getTroveColl(A); - const B_collBefore = await troveManager.getTroveColl(B); - const C_collBefore = await troveManager.getTroveColl(C); - const D_collBefore = await troveManager.getTroveColl(D); + const A_collBefore = await troveManager.getTroveColl(ATroveId); + const B_collBefore = await troveManager.getTroveColl(BTroveId); + const C_collBefore = await troveManager.getTroveColl(CTroveId); + const D_collBefore = await troveManager.getTroveColl(DTroveId); // Confirm baseRate before redemption is 0 const baseRate = await troveManager.baseRate(); @@ -4533,12 +4534,12 @@ contract("TroveManager", async (accounts) => { await th.redeemCollateral(whale, contracts, redemptionAmount, GAS_PRICE); // Check A, B, C have been closed - assert.isFalse(await sortedTroves.contains(A)); - assert.isFalse(await sortedTroves.contains(B)); - assert.isFalse(await sortedTroves.contains(C)); + assert.isFalse(await sortedTroves.contains(ATroveId)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isFalse(await sortedTroves.contains(CTroveId)); // Check D stays active - assert.isTrue(await sortedTroves.contains(D)); + assert.isTrue(await sortedTroves.contains(DTroveId)); /* At ETH:USD price of 200, with full redemptions from A, B, C: @@ -4554,15 +4555,15 @@ contract("TroveManager", async (accounts) => { const D_balanceAfter = toBN(await contracts.WETH.balanceOf(D)); // Check A, B, C’s trove collateral balance is zero (fully redeemed-from troves) - const A_collAfter = await troveManager.getTroveColl(A); - const B_collAfter = await troveManager.getTroveColl(B); - const C_collAfter = await troveManager.getTroveColl(C); + const A_collAfter = await troveManager.getTroveColl(ATroveId); + const B_collAfter = await troveManager.getTroveColl(BTroveId); + const C_collAfter = await troveManager.getTroveColl(CTroveId); assert.isTrue(A_collAfter.eq(toBN(0))); assert.isTrue(B_collAfter.eq(toBN(0))); assert.isTrue(C_collAfter.eq(toBN(0))); // check D's trove collateral balances have decreased (the partially redeemed-from trove) - const D_collAfter = await troveManager.getTroveColl(D); + const D_collAfter = await troveManager.getTroveColl(DTroveId); assert.isTrue(D_collAfter.lt(D_collBefore)); // Check A, B, C (fully redeemed-from troves), and D's (the partially redeemed-from trove) balance has not changed @@ -4597,22 +4598,22 @@ contract("TroveManager", async (accounts) => { extraParams: { from: whale }, }); - const { netDebt: A_netDebt } = await openTrove({ + const { troveId: ATroveId, netDebt: A_netDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: A }, }); - const { netDebt: B_netDebt } = await openTrove({ + const { troveId: BTroveId, netDebt: B_netDebt } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: B }, }); - const { netDebt: C_netDebt } = await openTrove({ + const { troveId: CTroveId, netDebt: C_netDebt } = await openTrove({ ICR: toBN(dec(180, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: C }, }); - const { totalDebt: D_totalDebt, collateral: D_coll } = await openTrove({ + const { troveId: DTroveId, totalDebt: D_totalDebt, collateral: D_coll } = await openTrove({ ICR: toBN(dec(280, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: D }, @@ -4638,12 +4639,12 @@ contract("TroveManager", async (accounts) => { ); // Check A, B, C have been closed - assert.isFalse(await sortedTroves.contains(A)); - assert.isFalse(await sortedTroves.contains(B)); - assert.isFalse(await sortedTroves.contains(C)); + assert.isFalse(await sortedTroves.contains(ATroveId)); + assert.isFalse(await sortedTroves.contains(BTroveId)); + assert.isFalse(await sortedTroves.contains(CTroveId)); // Check D stays active - assert.isTrue(await sortedTroves.contains(D)); + assert.isTrue(await sortedTroves.contains(DTroveId)); const troveUpdatedEvents = th.getAllEventsByName( redemptionTx, @@ -4691,7 +4692,7 @@ contract("TroveManager", async (accounts) => { // CollSurplusPool endpoint cannot be called directly await assertRevert( - collSurplusPool.claimColl(A), + collSurplusPool.claimColl(ATroveId), "CollSurplusPool: Caller is not Borrower Operations" ); @@ -4730,25 +4731,25 @@ contract("TroveManager", async (accounts) => { const B_surplus = B_collBefore.sub(B_netDebt.mul(mv._1e18BN).div(price)); const C_surplus = C_collBefore.sub(C_netDebt.mul(mv._1e18BN).div(price)); - const { collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: A }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(190, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: B }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: CTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(180, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: C }, }); - const A_collAfter = await troveManager.getTroveColl(A); - const B_collAfter = await troveManager.getTroveColl(B); - const C_collAfter = await troveManager.getTroveColl(C); + const A_collAfter = await troveManager.getTroveColl(ATroveId); + const B_collAfter = await troveManager.getTroveColl(BTroveId); + const C_collAfter = await troveManager.getTroveColl(CTroveId); assert.isTrue(A_collAfter.eq(A_coll)); assert.isTrue(B_collAfter.eq(B_coll)); @@ -4778,13 +4779,13 @@ contract("TroveManager", async (accounts) => { it("getPendingBoldDebtReward(): Returns 0 if there is no pending BoldDebt reward", async () => { // Make some troves - const { totalDebt } = await openTrove({ + const { troveId: defaulter_1_TroveId, totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(100, 18), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraBoldAmount: dec(20, 18), extraParams: { from: carol }, @@ -4800,34 +4801,34 @@ contract("TroveManager", async (accounts) => { // Price drops await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); // Confirm defaulter_1 liquidated - assert.isFalse(await sortedTroves.contains(defaulter_1)); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); // Confirm there are no pending rewards from liquidation const current_L_boldDebt = await troveManager.L_boldDebt(); assert.equal(current_L_boldDebt, 0); const carolSnapshot_L_boldDebt = ( - await troveManager.rewardSnapshots(carol) + await troveManager.rewardSnapshots(carolTroveId) )[1]; assert.equal(carolSnapshot_L_boldDebt, 0); const carol_PendingBoldDebtReward = - await troveManager.getPendingBoldDebtReward(carol); + await troveManager.getPendingBoldDebtReward(carolTroveId); assert.equal(carol_PendingBoldDebtReward, 0); }); it("getPendingETHReward(): Returns 0 if there is no pending ETH reward", async () => { // make some troves - const { totalDebt } = await openTrove({ + const { troveId: defaulter_1_TroveId, totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), extraBoldAmount: dec(100, 18), extraParams: { from: defaulter_1 }, }); - await openTrove({ + const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(3, 18)), extraBoldAmount: dec(20, 18), extraParams: { from: carol }, @@ -4843,16 +4844,16 @@ contract("TroveManager", async (accounts) => { // Price drops await priceFeed.setPrice(dec(100, 18)); - await troveManager.liquidate(defaulter_1); + await troveManager.liquidate(defaulter_1_TroveId); // Confirm defaulter_1 liquidated - assert.isFalse(await sortedTroves.contains(defaulter_1)); + assert.isFalse(await sortedTroves.contains(defaulter_1_TroveId)); // Confirm there are no pending rewards from liquidation const current_L_ETH = await troveManager.L_ETH(); assert.equal(current_L_ETH, 0); - const carolSnapshot_L_ETH = (await troveManager.rewardSnapshots(carol))[0]; + const carolSnapshot_L_ETH = (await troveManager.rewardSnapshots(carolTroveId))[0]; assert.equal(carolSnapshot_L_ETH, 0); const carol_PendingETHReward = await troveManager.getPendingETHReward( @@ -4994,48 +4995,48 @@ contract("TroveManager", async (accounts) => { // --- Getters --- it("getTroveStake(): Returns stake", async () => { - const { collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, }); - const A_Stake = await troveManager.getTroveStake(A); - const B_Stake = await troveManager.getTroveStake(B); + const A_Stake = await troveManager.getTroveStake(ATroveId); + const B_Stake = await troveManager.getTroveStake(BTroveId); assert.equal(A_Stake, A_coll.toString()); assert.equal(B_Stake, B_coll.toString()); }); it("getTroveColl(): Returns coll", async () => { - const { collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, }); - assert.equal(await troveManager.getTroveColl(A), A_coll.toString()); - assert.equal(await troveManager.getTroveColl(B), B_coll.toString()); + assert.equal(await troveManager.getTroveColl(ATroveId), A_coll.toString()); + assert.equal(await troveManager.getTroveColl(BTroveId), B_coll.toString()); }); it("getTroveDebt(): Returns debt", async () => { - const { totalDebt: totalDebtA } = await openTrove({ + const { troveId: ATroveId, totalDebt: totalDebtA } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, }); - const { totalDebt: totalDebtB } = await openTrove({ + const { troveId: BTroveId, totalDebt: totalDebtB } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, }); - const A_Debt = await troveManager.getTroveDebt(A); - const B_Debt = await troveManager.getTroveDebt(B); + const A_Debt = await troveManager.getTroveDebt(ATroveId); + const B_Debt = await troveManager.getTroveDebt(BTroveId); // Expect debt = requested + 0.5% fee + 50 (due to gas comp) @@ -5044,11 +5045,11 @@ contract("TroveManager", async (accounts) => { }); it("getTroveStatus(): Returns status", async () => { - const { totalDebt: B_totalDebt } = await openTrove({ + const { troveId: BTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, }); - await openTrove({ + const { troveId: ATroveId } = await openTrove({ ICR: toBN(dec(150, 16)), extraBoldAmount: B_totalDebt, extraParams: { from: A }, @@ -5056,11 +5057,11 @@ contract("TroveManager", async (accounts) => { // to be able to repay: await boldToken.transfer(B, B_totalDebt, { from: A }); - await borrowerOperations.closeTrove({ from: B }); + await borrowerOperations.closeTrove(BTroveId, { from: B }); - const A_Status = await troveManager.getTroveStatus(A); - const B_Status = await troveManager.getTroveStatus(B); - const C_Status = await troveManager.getTroveStatus(C); + const A_Status = await troveManager.getTroveStatus(ATroveId); + const B_Status = await troveManager.getTroveStatus(BTroveId); + const C_Status = await troveManager.getTroveStatus(th.addressToTroveId(C)); assert.equal(A_Status, "1"); // active assert.equal(B_Status, "2"); // closed by user @@ -5068,7 +5069,7 @@ contract("TroveManager", async (accounts) => { }); it("hasPendingRewards(): Returns false it trove is not active", async () => { - assert.isFalse(await troveManager.hasPendingRewards(alice)); + assert.isFalse(await troveManager.hasPendingRewards(th.addressToTroveId(alice))); }); }); diff --git a/contracts/test/TroveManager_LiquidationRewardsTest.js b/contracts/test/TroveManager_LiquidationRewardsTest.js index a6589fce..5c5c620f 100644 --- a/contracts/test/TroveManager_LiquidationRewardsTest.js +++ b/contracts/test/TroveManager_LiquidationRewardsTest.js @@ -109,11 +109,11 @@ contract( it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { // A, B open trove - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: bob }, }); @@ -125,19 +125,19 @@ contract( assert.isFalse(await th.checkRecoveryMode(contracts)); // L1: B liquidated - const txB = await troveManager.liquidate(bob); + const txB = await troveManager.liquidate(bobTroveId); assert.isTrue(txB.receipt.status); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // C, D open troves - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: carol }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: dennis }, }); @@ -149,16 +149,16 @@ contract( assert.isFalse(await th.checkRecoveryMode(contracts)); // L2: D Liquidated - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txB.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Get entire coll of A and C - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const carol_Coll = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); /* Expected collateral: @@ -208,15 +208,15 @@ contract( it("redistribution: A, B, C Open. C Liquidated. D, E, F Open. F Liquidated. Distributes correct rewards", async () => { // A, B C open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: carol }, }); @@ -228,23 +228,23 @@ contract( assert.isFalse(await th.checkRecoveryMode(contracts)); // L1: C liquidated - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // D, E, F open troves - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: dennis }, }); - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: erin }, }); - const { collateral: F_coll } = await openTrove({ + const { troveId: freddyTroveId, collateral: F_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: freddy }, }); @@ -256,22 +256,22 @@ contract( assert.isFalse(await th.checkRecoveryMode(contracts)); // L2: F Liquidated - const txF = await troveManager.liquidate(freddy); + const txF = await troveManager.liquidate(freddyTroveId); assert.isTrue(txF.receipt.status); - assert.isFalse(await sortedTroves.contains(freddy)); + assert.isFalse(await sortedTroves.contains(freddyTroveId)); // Get entire coll of A, B, D and E - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const dennis_Coll = (await troveManager.Troves(dennis))[1] - .add(await troveManager.getPendingETHReward(dennis)) + const dennis_Coll = (await troveManager.Troves(dennisTroveId))[1] + .add(await troveManager.getPendingETHReward(dennisTroveId)) .toString(); - const erin_Coll = (await troveManager.Troves(erin))[1] - .add(await troveManager.getPendingETHReward(erin)) + const erin_Coll = (await troveManager.Troves(erinTroveId))[1] + .add(await troveManager.getPendingETHReward(erinTroveId)) .toString(); /* Expected collateral: @@ -331,11 +331,11 @@ contract( it("redistribution: Sequence of alternate opening/liquidation: final surviving trove has ETH from all previously liquidated troves", async () => { // A, B open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: bob }, }); @@ -344,14 +344,14 @@ contract( await priceFeed.setPrice(dec(1, 18)); // L1: A liquidated - const txA = await troveManager.liquidate(alice); + const txA = await troveManager.liquidate(aliceTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // C, opens trove - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: carol }, }); @@ -360,14 +360,14 @@ contract( await priceFeed.setPrice(dec(1, 18)); // L2: B Liquidated - const txB = await troveManager.liquidate(bob); + const txB = await troveManager.liquidate(bobTroveId); assert.isTrue(txB.receipt.status); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // D opens trove - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: dennis }, }); @@ -376,14 +376,14 @@ contract( await priceFeed.setPrice(dec(1, 18)); // L3: C Liquidated - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // E opens trove - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: erin }, }); @@ -392,14 +392,14 @@ contract( await priceFeed.setPrice(dec(1, 18)); // L4: D Liquidated - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txD.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // F opens trove - const { collateral: F_coll } = await openTrove({ + const { troveId: freddyTroveId, collateral: F_coll } = await openTrove({ ICR: toBN(dec(210, 16)), extraParams: { from: freddy }, }); @@ -408,30 +408,30 @@ contract( await priceFeed.setPrice(dec(1, 18)); // L5: E Liquidated - const txE = await troveManager.liquidate(erin); + const txE = await troveManager.liquidate(erinTroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(erin)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); // Get entire coll of A, B, D, E and F - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); - const dennis_Coll = (await troveManager.Troves(dennis))[1] - .add(await troveManager.getPendingETHReward(dennis)) + const dennis_Coll = (await troveManager.Troves(dennisTroveId))[1] + .add(await troveManager.getPendingETHReward(dennisTroveId)) .toString(); - const erin_Coll = (await troveManager.Troves(erin))[1] - .add(await troveManager.getPendingETHReward(erin)) + const erin_Coll = (await troveManager.Troves(erinTroveId))[1] + .add(await troveManager.getPendingETHReward(erinTroveId)) .toString(); - const freddy_rawColl = (await troveManager.Troves(freddy))[1].toString(); + const freddy_rawColl = (await troveManager.Troves(freddyTroveId))[1].toString(); const freddy_ETHReward = ( - await troveManager.getPendingETHReward(freddy) + await troveManager.getPendingETHReward(freddyTroveId) ).toString(); /* Expected collateral: @@ -482,27 +482,27 @@ contract( // Test based on scenario in: https://docs.google.com/spreadsheets/d/1F5p3nZy749K5jwO-bwJeTsRoY7ewMfWIQ3QHtokxqzo/edit?usp=sharing it("redistribution: A,B,C,D,E open. Liq(A). B adds coll. Liq(C). B and D have correct coll and debt", async () => { // A, B, C, D, E open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: A }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: B }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: CTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: C }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: DTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(20000, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: D }, }); - const { collateral: E_coll } = await openTrove({ + const { troveId: ETroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: E }, @@ -513,18 +513,18 @@ contract( // Liquidate A // console.log(`ICR A: ${await troveManager.getCurrentICR(A, price)}`) - const txA = await troveManager.liquidate(A); + const txA = await troveManager.liquidate(ATroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(A)); + assert.isFalse(await sortedTroves.contains(ATroveId)); // Check entireColl for each trove: - const B_entireColl_1 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const C_entireColl_1 = (await th.getEntireCollAndDebt(contracts, C)) + const C_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, C)) .entireColl; - const D_entireColl_1 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; - const E_entireColl_1 = (await th.getEntireCollAndDebt(contracts, E)) + const E_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, E)) .entireColl; const totalCollAfterL1 = B_coll.add(C_coll).add(D_coll).add(E_coll); @@ -550,15 +550,15 @@ contract( await th.addCollWrapper(contracts, { from: B, value: addedColl1 }); // Liquidate C - const txC = await troveManager.liquidate(C); + const txC = await troveManager.liquidate(CTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(C)); + assert.isFalse(await sortedTroves.contains(CTroveId)); - const B_entireColl_2 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const D_entireColl_2 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; - const E_entireColl_2 = (await th.getEntireCollAndDebt(contracts, E)) + const E_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, E)) .entireColl; const totalCollAfterL2 = B_collAfterL1.add(addedColl1) @@ -593,9 +593,9 @@ contract( await th.addCollWrapper(contracts, { from: B, value: addedColl2 }); // Liquidate E - const txE = await troveManager.liquidate(E); + const txE = await troveManager.liquidate(ETroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(E)); + assert.isFalse(await sortedTroves.contains(ETroveId)); const totalCollAfterL3 = B_collAfterL2.add(addedColl2).add(D_collAfterL2); const B_collAfterL3 = B_collAfterL2.add(addedColl2).add( @@ -611,9 +611,9 @@ contract( .div(totalCollAfterL3) ); - const B_entireColl_3 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_3 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const D_entireColl_3 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_3 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; const diff_entireColl_B = getDifference(B_entireColl_3, B_collAfterL3); @@ -626,27 +626,27 @@ contract( // Test based on scenario in: https://docs.google.com/spreadsheets/d/1F5p3nZy749K5jwO-bwJeTsRoY7ewMfWIQ3QHtokxqzo/edit?usp=sharing it("redistribution: A,B,C,D open. Liq(A). B adds coll. Liq(C). B and D have correct coll and debt", async () => { // A, B, C, D, E open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: A }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: BTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: B }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: CTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: C }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: DTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(20000, 16)), extraBoldAmount: dec(10, 18), extraParams: { from: D }, }); - const { collateral: E_coll } = await openTrove({ + const { troveId: ETroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100000, 18), extraParams: { from: E }, @@ -656,15 +656,15 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Check entireColl for each trove: - const A_entireColl_0 = (await th.getEntireCollAndDebt(contracts, A)) + const A_entireColl_0 = (await th.getEntireCollAndDebtByAddress(contracts, A)) .entireColl; - const B_entireColl_0 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_0 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const C_entireColl_0 = (await th.getEntireCollAndDebt(contracts, C)) + const C_entireColl_0 = (await th.getEntireCollAndDebtByAddress(contracts, C)) .entireColl; - const D_entireColl_0 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_0 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; - const E_entireColl_0 = (await th.getEntireCollAndDebt(contracts, E)) + const E_entireColl_0 = (await th.getEntireCollAndDebtByAddress(contracts, E)) .entireColl; // entireSystemColl, excluding A @@ -674,9 +674,9 @@ contract( // Liquidate A // console.log(`ICR A: ${await troveManager.getCurrentICR(A, price)}`) - const txA = await troveManager.liquidate(A); + const txA = await troveManager.liquidate(ATroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(A)); + assert.isFalse(await sortedTroves.contains(ATroveId)); const A_collRedistribution = A_entireColl_0.mul(toBN(995)).div( toBN(1000) @@ -684,10 +684,10 @@ contract( // console.log(`A_collRedistribution: ${A_collRedistribution}`) // Check accumulated ETH gain for each trove - const B_ETHGain_1 = await troveManager.getPendingETHReward(B); - const C_ETHGain_1 = await troveManager.getPendingETHReward(C); - const D_ETHGain_1 = await troveManager.getPendingETHReward(D); - const E_ETHGain_1 = await troveManager.getPendingETHReward(E); + const B_ETHGain_1 = await troveManager.getPendingETHReward(BTroveId); + const C_ETHGain_1 = await troveManager.getPendingETHReward(CTroveId); + const D_ETHGain_1 = await troveManager.getPendingETHReward(DTroveId); + const E_ETHGain_1 = await troveManager.getPendingETHReward(ETroveId); // Check gains are what we'd expect from a distribution proportional to each trove's entire coll const B_expectedPendingETH_1 = @@ -711,13 +711,13 @@ contract( }); // Check entireColl for each trove - const B_entireColl_1 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const C_entireColl_1 = (await th.getEntireCollAndDebt(contracts, C)) + const C_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, C)) .entireColl; - const D_entireColl_1 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; - const E_entireColl_1 = (await th.getEntireCollAndDebt(contracts, E)) + const E_entireColl_1 = (await th.getEntireCollAndDebtByAddress(contracts, E)) .entireColl; // entireSystemColl, excluding C @@ -726,18 +726,18 @@ contract( ); // Liquidate C - const txC = await troveManager.liquidate(C); + const txC = await troveManager.liquidate(CTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(C)); + assert.isFalse(await sortedTroves.contains(CTroveId)); const C_collRedistribution = C_entireColl_1.mul(toBN(995)).div( toBN(1000) ); // remove the gas comp // console.log(`C_collRedistribution: ${C_collRedistribution}`) - const B_ETHGain_2 = await troveManager.getPendingETHReward(B); - const D_ETHGain_2 = await troveManager.getPendingETHReward(D); - const E_ETHGain_2 = await troveManager.getPendingETHReward(E); + const B_ETHGain_2 = await troveManager.getPendingETHReward(BTroveId); + const D_ETHGain_2 = await troveManager.getPendingETHReward(DTroveId); + const E_ETHGain_2 = await troveManager.getPendingETHReward(ETroveId); // Since B topped up, he has no previous pending ETH gain const B_expectedPendingETH_2 = @@ -763,11 +763,11 @@ contract( }); // Check entireColl for each trove - const B_entireColl_2 = (await th.getEntireCollAndDebt(contracts, B)) + const B_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, B)) .entireColl; - const D_entireColl_2 = (await th.getEntireCollAndDebt(contracts, D)) + const D_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, D)) .entireColl; - const E_entireColl_2 = (await th.getEntireCollAndDebt(contracts, E)) + const E_entireColl_2 = (await th.getEntireCollAndDebtByAddress(contracts, E)) .entireColl; // entireSystemColl, excluding E @@ -776,17 +776,17 @@ contract( ); // Liquidate E - const txE = await troveManager.liquidate(E); + const txE = await troveManager.liquidate(ETroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(E)); + assert.isFalse(await sortedTroves.contains(ETroveId)); const E_collRedistribution = E_entireColl_2.mul(toBN(995)).div( toBN(1000) ); // remove the gas comp // console.log(`E_collRedistribution: ${E_collRedistribution}`) - const B_ETHGain_3 = await troveManager.getPendingETHReward(B); - const D_ETHGain_3 = await troveManager.getPendingETHReward(D); + const B_ETHGain_3 = await troveManager.getPendingETHReward(BTroveId); + const D_ETHGain_3 = await troveManager.getPendingETHReward(DTroveId); // Since B topped up, he has no previous pending ETH gain const B_expectedPendingETH_3 = @@ -803,16 +803,16 @@ contract( it("redistribution: A,B,C Open. Liq(C). B adds coll. Liq(A). B acquires all coll and debt", async () => { // A, B, C open troves - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: carol }, @@ -822,9 +822,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Carol - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); @@ -838,6 +838,7 @@ contract( // Alice withdraws Bold await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, await getNetBorrowingAmount(A_totalDebt), { from: alice } @@ -847,17 +848,17 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Alice - const txA = await troveManager.liquidate(alice); + const txA = await troveManager.liquidate(aliceTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Expect Bob now holds all Ether and BoldDebt in the system: 2 + 0.4975+0.4975*0.995+0.995 Ether and 110*3 Bold (10 each for gas compensation) - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const bob_BoldDebt = (await troveManager.Troves(bob))[0] - .add(await troveManager.getPendingBoldDebtReward(bob)) + const bob_BoldDebt = (await troveManager.Troves(bobTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(bobTroveId)) .toString(); const expected_B_coll = B_coll.add(addedColl) @@ -880,16 +881,16 @@ contract( it("redistribution: A,B,C Open. Liq(C). B tops up coll. D Opens. Liq(D). Distributes correct rewards.", async () => { // A, B, C open troves - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: carol }, @@ -899,9 +900,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Carol - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); @@ -914,7 +915,7 @@ contract( }); // D opens trove - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis }, @@ -924,9 +925,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate D - const txA = await troveManager.liquidate(dennis); + const txA = await troveManager.liquidate(dennisTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); /* Bob rewards: L1: 1/2*0.995 ETH, 55 Bold @@ -945,20 +946,20 @@ contract( totalColl: 4.99 ETH totalDebt 380 Bold (includes 50 each for gas compensation) */ - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const bob_BoldDebt = (await troveManager.Troves(bob))[0] - .add(await troveManager.getPendingBoldDebtReward(bob)) + const bob_BoldDebt = (await troveManager.Troves(bobTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(bobTroveId)) .toString(); - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const alice_BoldDebt = (await troveManager.Troves(alice))[0] - .add(await troveManager.getPendingBoldDebtReward(alice)) + const alice_BoldDebt = (await troveManager.Troves(aliceTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(aliceTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -995,20 +996,20 @@ contract( it("redistribution: Trove with the majority stake tops up. A,B,C, D open. Liq(D). C tops up. E Enters, Liq(E). Distributes correct rewards", async () => { const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ extraBoldAmount: dec(110, 18), extraParams: { from: carol, value: _998_Ether }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis, value: dec(1000, "ether") }, @@ -1018,17 +1019,17 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Dennis - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txD.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // Expected rewards: alice: 1 ETH, bob: 1 ETH, carol: 998 ETH - const alice_ETHReward_1 = await troveManager.getPendingETHReward(alice); - const bob_ETHReward_1 = await troveManager.getPendingETHReward(bob); - const carol_ETHReward_1 = await troveManager.getPendingETHReward(carol); + const alice_ETHReward_1 = await troveManager.getPendingETHReward(aliceTroveId); + const bob_ETHReward_1 = await troveManager.getPendingETHReward(bobTroveId); + const carol_ETHReward_1 = await troveManager.getPendingETHReward(carolTroveId); //Expect 1000 + 1000*0.995 ETH in system now const entireSystemColl_1 = (await activePool.getETHBalance()) @@ -1070,7 +1071,7 @@ contract( ); // E opens with another 1996 ETH - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: erin, value: entireSystemColl_2 }, }); @@ -1079,9 +1080,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Erin - const txE = await troveManager.liquidate(erin); + const txE = await troveManager.liquidate(erinTroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(erin)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); /* Expected ETH rewards: Carol = 1992.01/1996 * 1996*0.995 = 1982.05 ETH @@ -1097,16 +1098,16 @@ contract( total = 3982.02 ETH */ - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -1161,20 +1162,20 @@ contract( it("redistribution: Trove with the majority stake tops up. A,B,C, D open. Liq(D). A, B, C top up. E Enters, Liq(E). Distributes correct rewards", async () => { const _998_Ether = toBN("998000000000000000000"); // A, B, C open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ extraBoldAmount: dec(110, 18), extraParams: { from: carol, value: _998_Ether }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis, value: dec(1000, "ether") }, @@ -1184,17 +1185,17 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Dennis - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txD.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // Expected rewards: alice: 1 ETH, bob: 1 ETH, carol: 998 ETH (*0.995) - const alice_ETHReward_1 = await troveManager.getPendingETHReward(alice); - const bob_ETHReward_1 = await troveManager.getPendingETHReward(bob); - const carol_ETHReward_1 = await troveManager.getPendingETHReward(carol); + const alice_ETHReward_1 = await troveManager.getPendingETHReward(aliceTroveId); + const bob_ETHReward_1 = await troveManager.getPendingETHReward(bobTroveId); + const carol_ETHReward_1 = await troveManager.getPendingETHReward(carolTroveId); //Expect 1995 ETH in system now const entireSystemColl_1 = (await activePool.getETHBalance()) @@ -1248,7 +1249,7 @@ contract( ); // E opens with another 1998 ETH - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: erin, value: entireSystemColl_2 }, }); @@ -1257,9 +1258,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Erin - const txE = await troveManager.liquidate(erin); + const txE = await troveManager.liquidate(erinTroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(erin)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); /* Expected ETH rewards: Carol = 1992.01/1998 * 1998*0.995 = 1982.04995 ETH @@ -1275,16 +1276,16 @@ contract( total = 3986.01 ETH */ - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -1340,16 +1341,16 @@ contract( it("redistribution: A,B,C Open. Liq(C). B withdraws coll. Liq(A). B acquires all coll and debt", async () => { // A, B, C open troves - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: carol }, @@ -1359,21 +1360,22 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Carol - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); //Bob withdraws 0.5 ETH from his trove const withdrawnColl = toBN(dec(500, "finney")); - await borrowerOperations.withdrawColl(withdrawnColl, { + await borrowerOperations.withdrawColl(bobTroveId, withdrawnColl, { from: bob, }); // Alice withdraws Bold await borrowerOperations.withdrawBold( + aliceTroveId, th._100pct, await getNetBorrowingAmount(A_totalDebt), { from: alice } @@ -1383,18 +1385,18 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Alice - const txA = await troveManager.liquidate(alice); + const txA = await troveManager.liquidate(aliceTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Expect Bob now holds all Ether and BoldDebt in the system: 2.5 Ether and 300 Bold // 1 + 0.995/2 - 0.5 + 1.4975*0.995 - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const bob_BoldDebt = (await troveManager.Troves(bob))[0] - .add(await troveManager.getPendingBoldDebtReward(bob)) + const bob_BoldDebt = (await troveManager.Troves(bobTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(bobTroveId)) .toString(); const expected_B_coll = B_coll.sub(withdrawnColl) @@ -1420,16 +1422,16 @@ contract( it("redistribution: A,B,C Open. Liq(C). B withdraws coll. D Opens. Liq(D). Distributes correct rewards.", async () => { // A, B, C open troves - const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll, totalDebt: C_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: carol }, @@ -1439,21 +1441,21 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Carol - const txC = await troveManager.liquidate(carol); + const txC = await troveManager.liquidate(carolTroveId); assert.isTrue(txC.receipt.status); - assert.isFalse(await sortedTroves.contains(carol)); + assert.isFalse(await sortedTroves.contains(carolTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); //Bob withdraws 0.5 ETH from his trove const withdrawnColl = toBN(dec(500, "finney")); - await borrowerOperations.withdrawColl(withdrawnColl, { + await borrowerOperations.withdrawColl(bobTroveId, withdrawnColl, { from: bob, }); // D opens trove - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis }, @@ -1463,9 +1465,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate D - const txA = await troveManager.liquidate(dennis); + const txA = await troveManager.liquidate(dennisTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); /* Bob rewards: L1: 0.4975 ETH, 55 Bold @@ -1484,20 +1486,20 @@ contract( totalColl: 3.49 ETH totalDebt 380 Bold (Includes 50 in each trove for gas compensation) */ - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const bob_BoldDebt = (await troveManager.Troves(bob))[0] - .add(await troveManager.getPendingBoldDebtReward(bob)) + const bob_BoldDebt = (await troveManager.Troves(bobTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(bobTroveId)) .toString(); - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const alice_BoldDebt = (await troveManager.Troves(alice))[0] - .add(await troveManager.getPendingBoldDebtReward(alice)) + const alice_BoldDebt = (await troveManager.Troves(aliceTroveId))[0] + .add(await troveManager.getPendingBoldDebtReward(aliceTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -1555,20 +1557,20 @@ contract( it("redistribution: Trove with the majority stake withdraws. A,B,C,D open. Liq(D). C withdraws some coll. E Enters, Liq(E). Distributes correct rewards", async () => { const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ extraBoldAmount: dec(110, 18), extraParams: { from: carol, value: _998_Ether }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis, value: dec(1000, "ether") }, @@ -1578,17 +1580,17 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Dennis - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txD.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // Expected rewards: alice: 1 ETH, bob: 1 ETH, carol: 998 ETH (*0.995) - const alice_ETHReward_1 = await troveManager.getPendingETHReward(alice); - const bob_ETHReward_1 = await troveManager.getPendingETHReward(bob); - const carol_ETHReward_1 = await troveManager.getPendingETHReward(carol); + const alice_ETHReward_1 = await troveManager.getPendingETHReward(aliceTroveId); + const bob_ETHReward_1 = await troveManager.getPendingETHReward(bobTroveId); + const carol_ETHReward_1 = await troveManager.getPendingETHReward(carolTroveId); //Expect 1995 ETH in system now const entireSystemColl_1 = (await activePool.getETHBalance()).add( @@ -1615,7 +1617,7 @@ contract( //Carol wthdraws 1 ETH from her trove, brings it to 1990.01 total coll const C_withdrawnColl = toBN(dec(1, "ether")); - await borrowerOperations.withdrawColl(C_withdrawnColl, { + await borrowerOperations.withdrawColl(carolTroveId, C_withdrawnColl, { from: carol, }); @@ -1629,7 +1631,7 @@ contract( ); // E opens with another 1994 ETH - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: erin, value: entireSystemColl_2 }, }); @@ -1638,9 +1640,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Erin - const txE = await troveManager.liquidate(erin); + const txE = await troveManager.liquidate(erinTroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(erin)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); /* Expected ETH rewards: Carol = 1990.01/1994 * 1994*0.995 = 1980.05995 ETH @@ -1656,16 +1658,16 @@ contract( total = 3978.03 ETH */ - const alice_Coll = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -1717,20 +1719,20 @@ contract( it("redistribution: Trove with the majority stake withdraws. A,B,C,D open. Liq(D). A, B, C withdraw. E Enters, Liq(E). Distributes correct rewards", async () => { const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ extraBoldAmount: dec(110, 18), extraParams: { from: carol, value: _998_Ether }, }); - const { collateral: D_coll } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis, value: dec(1000, "ether") }, @@ -1740,17 +1742,17 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Dennis - const txD = await troveManager.liquidate(dennis); + const txD = await troveManager.liquidate(dennisTroveId); assert.isTrue(txD.receipt.status); - assert.isFalse(await sortedTroves.contains(dennis)); + assert.isFalse(await sortedTroves.contains(dennisTroveId)); // Price bounces back to 200 $/E await priceFeed.setPrice(dec(200, 18)); // Expected rewards: alice: 1 ETH, bob: 1 ETH, carol: 998 ETH (*0.995) - const alice_ETHReward_1 = await troveManager.getPendingETHReward(alice); - const bob_ETHReward_1 = await troveManager.getPendingETHReward(bob); - const carol_ETHReward_1 = await troveManager.getPendingETHReward(carol); + const alice_ETHReward_1 = await troveManager.getPendingETHReward(aliceTroveId); + const bob_ETHReward_1 = await troveManager.getPendingETHReward(bobTroveId); + const carol_ETHReward_1 = await troveManager.getPendingETHReward(carolTroveId); //Expect 1995 ETH in system now const entireSystemColl_1 = (await activePool.getETHBalance()).add( @@ -1778,26 +1780,26 @@ contract( /* Alice, Bob, Carol each withdraw 0.5 ETH to their troves, bringing them to 1.495, 1.495, 1990.51 total coll each. */ const withdrawnColl = toBN(dec(500, "finney")); - await borrowerOperations.withdrawColl(withdrawnColl, { + await borrowerOperations.withdrawColl(aliceTroveId,withdrawnColl, { from: alice, }); - await borrowerOperations.withdrawColl(withdrawnColl, { + await borrowerOperations.withdrawColl(bobTroveId, withdrawnColl, { from: bob, }); - await borrowerOperations.withdrawColl(withdrawnColl, { + await borrowerOperations.withdrawColl(carolTroveId, withdrawnColl, { from: carol, }); - const alice_Coll_1 = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll_1 = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll_1 = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll_1 = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll_1 = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll_1 = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); const totalColl_1 = A_coll.add(B_coll).add(C_coll); @@ -1841,7 +1843,7 @@ contract( ); // E opens with another 1993.5 ETH - const { collateral: E_coll } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: erin, value: entireSystemColl_2 }, }); @@ -1850,9 +1852,9 @@ contract( await priceFeed.setPrice(dec(100, 18)); // Liquidate Erin - const txE = await troveManager.liquidate(erin); + const txE = await troveManager.liquidate(erinTroveId); assert.isTrue(txE.receipt.status); - assert.isFalse(await sortedTroves.contains(erin)); + assert.isFalse(await sortedTroves.contains(erinTroveId)); /* Expected ETH rewards: Carol = 1990.51/1993.5 * 1993.5*0.995 = 1980.55745 ETH @@ -1868,16 +1870,16 @@ contract( total = 3977.0325 ETH */ - const alice_Coll_2 = (await troveManager.Troves(alice))[1] - .add(await troveManager.getPendingETHReward(alice)) + const alice_Coll_2 = (await troveManager.Troves(aliceTroveId))[1] + .add(await troveManager.getPendingETHReward(aliceTroveId)) .toString(); - const bob_Coll_2 = (await troveManager.Troves(bob))[1] - .add(await troveManager.getPendingETHReward(bob)) + const bob_Coll_2 = (await troveManager.Troves(bobTroveId))[1] + .add(await troveManager.getPendingETHReward(bobTroveId)) .toString(); - const carol_Coll_2 = (await troveManager.Troves(carol))[1] - .add(await troveManager.getPendingETHReward(carol)) + const carol_Coll_2 = (await troveManager.Troves(carolTroveId))[1] + .add(await troveManager.getPendingETHReward(carolTroveId)) .toString(); const totalCollAfterL1 = A_coll.add(B_coll) @@ -1930,17 +1932,17 @@ contract( // https://docs.google.com/spreadsheets/d/1F5p3nZy749K5jwO-bwJeTsRoY7ewMfWIQ3QHtokxqzo/edit?usp=sharing it("redistribution, all operations: A,B,C open. Liq(A). D opens. B adds, C withdraws. Liq(B). E & F open. D adds. Liq(F). Distributes correct rewards", async () => { // A, B, C open troves - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: alice }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: bob }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(100, 18), extraParams: { from: carol }, @@ -1950,9 +1952,9 @@ contract( await priceFeed.setPrice(dec(1, 18)); // Liquidate A - const txA = await troveManager.liquidate(alice); + const txA = await troveManager.liquidate(aliceTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Check rewards for B and C const B_pendingRewardsAfterL1 = th @@ -1965,14 +1967,14 @@ contract( .div(B_coll.add(C_coll)); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(bob), + await troveManager.getPendingETHReward(bobTroveId), B_pendingRewardsAfterL1 ), 1000000 ); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(carol), + await troveManager.getPendingETHReward(carolTroveId), C_pendingRewardsAfterL1 ), 1000000 @@ -1995,7 +1997,7 @@ contract( await priceFeed.setPrice(dec(1000, 18)); // D opens trove - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: dennis }, @@ -2010,7 +2012,7 @@ contract( //Carol withdraws 1 ETH from her trove const C_withdrawnColl = toBN(dec(1, "ether")); - await borrowerOperations.withdrawColl(C_withdrawnColl, { + await borrowerOperations.withdrawColl(carolTroveId, C_withdrawnColl, { from: carol, }); @@ -2025,9 +2027,9 @@ contract( await priceFeed.setPrice(dec(1, 18)); // Liquidate B - const txB = await troveManager.liquidate(bob); + const txB = await troveManager.liquidate(bobTroveId); assert.isTrue(txB.receipt.status); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Check rewards for C and D const C_pendingRewardsAfterL2 = C_collAfterL1.mul( @@ -2038,14 +2040,14 @@ contract( ).div(C_collAfterL1.add(D_coll)); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(carol), + await troveManager.getPendingETHReward(carolTroveId), C_pendingRewardsAfterL2 ), 1000000 ); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(dennis), + await troveManager.getPendingETHReward(dennisTroveId), D_pendingRewardsAfterL2 ), 1000000 @@ -2084,12 +2086,12 @@ contract( await priceFeed.setPrice(dec(1000, 18)); // E and F open troves - const { collateral: E_coll, totalDebt: E_totalDebt } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll, totalDebt: E_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: erin }, }); - const { collateral: F_coll, totalDebt: F_totalDebt } = await openTrove({ + const { troveId: freddyTroveId, collateral: F_coll, totalDebt: F_totalDebt } = await openTrove({ ICR: toBN(dec(200, 16)), extraBoldAmount: dec(110, 18), extraParams: { from: freddy }, @@ -2106,24 +2108,24 @@ contract( await priceFeed.setPrice(dec(1, 18)); // Liquidate F - const txF = await troveManager.liquidate(freddy); + const txF = await troveManager.liquidate(freddyTroveId); assert.isTrue(txF.receipt.status); - assert.isFalse(await sortedTroves.contains(freddy)); + assert.isFalse(await sortedTroves.contains(freddyTroveId)); // Grab remaining troves' collateral - const carol_rawColl = (await troveManager.Troves(carol))[1].toString(); + const carol_rawColl = (await troveManager.Troves(carolTroveId))[1].toString(); const carol_pendingETHReward = ( - await troveManager.getPendingETHReward(carol) + await troveManager.getPendingETHReward(carolTroveId) ).toString(); - const dennis_rawColl = (await troveManager.Troves(dennis))[1].toString(); + const dennis_rawColl = (await troveManager.Troves(dennisTroveId))[1].toString(); const dennis_pendingETHReward = ( - await troveManager.getPendingETHReward(dennis) + await troveManager.getPendingETHReward(dennisTroveId) ).toString(); - const erin_rawColl = (await troveManager.Troves(erin))[1].toString(); + const erin_rawColl = (await troveManager.Troves(erinTroveId))[1].toString(); const erin_pendingETHReward = ( - await troveManager.getPendingETHReward(erin) + await troveManager.getPendingETHReward(erinTroveId) ).toString(); // Check raw collateral of C, D, E @@ -2225,15 +2227,15 @@ contract( B: 8901 ETH C: 23.902 ETH */ - const { collateral: A_coll } = await openTrove({ + const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(90000, 16)), extraParams: { from: alice, value: toBN("450000000000000000000") }, }); - const { collateral: B_coll } = await openTrove({ + const { troveId: bobTroveId, collateral: B_coll } = await openTrove({ ICR: toBN(dec(1800000, 16)), extraParams: { from: bob, value: toBN("8901000000000000000000") }, }); - const { collateral: C_coll } = await openTrove({ + const { troveId: carolTroveId, collateral: C_coll } = await openTrove({ ICR: toBN(dec(4600, 16)), extraParams: { from: carol, value: toBN("23902000000000000000") }, }); @@ -2242,9 +2244,9 @@ contract( await priceFeed.setPrice("1"); // Liquidate A - const txA = await troveManager.liquidate(alice); + const txA = await troveManager.liquidate(aliceTroveId); assert.isTrue(txA.receipt.status); - assert.isFalse(await sortedTroves.contains(alice)); + assert.isFalse(await sortedTroves.contains(aliceTroveId)); // Check rewards for B and C const B_pendingRewardsAfterL1 = th @@ -2257,14 +2259,14 @@ contract( .div(B_coll.add(C_coll)); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(bob), + await troveManager.getPendingETHReward(bobTroveId), B_pendingRewardsAfterL1 ), 1000000 ); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(carol), + await troveManager.getPendingETHReward(carolTroveId), C_pendingRewardsAfterL1 ), 1000000 @@ -2287,7 +2289,7 @@ contract( await priceFeed.setPrice(dec(1, 27)); // D opens trove: 0.035 ETH - const { collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ + const { troveId: dennisTroveId, collateral: D_coll, totalDebt: D_totalDebt } = await openTrove({ extraBoldAmount: dec(100, 18), extraParams: { from: dennis, value: toBN(dec(35, 15)) }, }); @@ -2301,7 +2303,7 @@ contract( // Carol withdraws 15 ETH from her trove const C_withdrawnColl = toBN(dec(15, "ether")); - await borrowerOperations.withdrawColl(C_withdrawnColl, { + await borrowerOperations.withdrawColl(carolTroveId, C_withdrawnColl, { from: carol, }); @@ -2316,9 +2318,9 @@ contract( await priceFeed.setPrice("1"); // Liquidate B - const txB = await troveManager.liquidate(bob); + const txB = await troveManager.liquidate(bobTroveId); assert.isTrue(txB.receipt.status); - assert.isFalse(await sortedTroves.contains(bob)); + assert.isFalse(await sortedTroves.contains(bobTroveId)); // Check rewards for C and D const C_pendingRewardsAfterL2 = C_collAfterL1.mul( @@ -2330,14 +2332,14 @@ contract( const C_collAfterL2 = C_collAfterL1.add(C_pendingRewardsAfterL2); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(carol), + await troveManager.getPendingETHReward(carolTroveId), C_pendingRewardsAfterL2 ), 10000000 ); assert.isAtMost( th.getDifference( - await troveManager.getPendingETHReward(dennis), + await troveManager.getPendingETHReward(dennisTroveId), D_pendingRewardsAfterL2 ), 10000000 @@ -2379,11 +2381,11 @@ contract( E: 10000 ETH F: 0.0007 ETH */ - const { collateral: E_coll, totalDebt: E_totalDebt } = await openTrove({ + const { troveId: erinTroveId, collateral: E_coll, totalDebt: E_totalDebt } = await openTrove({ extraBoldAmount: dec(100, 18), extraParams: { from: erin, value: toBN(dec(1, 22)) }, }); - const { collateral: F_coll, totalDebt: F_totalDebt } = await openTrove({ + const { troveId: freddyTroveId, collateral: F_coll, totalDebt: F_totalDebt } = await openTrove({ extraBoldAmount: dec(100, 18), extraParams: { from: freddy, value: toBN("700000000000000") }, }); @@ -2403,28 +2405,28 @@ contract( await priceFeed.setPrice("1"); // Liquidate F - const txF = await troveManager.liquidate(freddy); + const txF = await troveManager.liquidate(freddyTroveId); assert.isTrue(txF.receipt.status); - assert.isFalse(await sortedTroves.contains(freddy)); + assert.isFalse(await sortedTroves.contains(freddyTroveId)); // Grab remaining troves' collateral - const carol_rawColl = (await troveManager.Troves(carol))[1].toString(); + const carol_rawColl = (await troveManager.Troves(carolTroveId))[1].toString(); const carol_pendingETHReward = ( - await troveManager.getPendingETHReward(carol) + await troveManager.getPendingETHReward(carolTroveId) ).toString(); - const carol_Stake = (await troveManager.Troves(carol))[2].toString(); + const carol_Stake = (await troveManager.Troves(carolTroveId))[2].toString(); - const dennis_rawColl = (await troveManager.Troves(dennis))[1].toString(); + const dennis_rawColl = (await troveManager.Troves(dennisTroveId))[1].toString(); const dennis_pendingETHReward = ( - await troveManager.getPendingETHReward(dennis) + await troveManager.getPendingETHReward(dennisTroveId) ).toString(); - const dennis_Stake = (await troveManager.Troves(dennis))[2].toString(); + const dennis_Stake = (await troveManager.Troves(dennisTroveId))[2].toString(); - const erin_rawColl = (await troveManager.Troves(erin))[1].toString(); + const erin_rawColl = (await troveManager.Troves(erinTroveId))[1].toString(); const erin_pendingETHReward = ( - await troveManager.getPendingETHReward(erin) + await troveManager.getPendingETHReward(erinTroveId) ).toString(); - const erin_Stake = (await troveManager.Troves(erin))[2].toString(); + const erin_Stake = (await troveManager.Troves(erinTroveId))[2].toString(); // Check raw collateral of C, D, E const totalCollForL3 = C_collAfterL2.add(D_collAfterL2).add(E_coll); diff --git a/contracts/test/TroveManager_RecoveryModeTest.js b/contracts/test/TroveManager_RecoveryModeTest.js index 61b7470f..47cec8f6 100644 --- a/contracts/test/TroveManager_RecoveryModeTest.js +++ b/contracts/test/TroveManager_RecoveryModeTest.js @@ -12,7 +12,7 @@ const timeValues = testHelpers.TimeValues; const TroveManagerTester = artifacts.require("./TroveManagerTester"); const BoldToken = artifacts.require("./BoldToken.sol"); -contract("TroveManager - in Recovery Mode", async (accounts) => { +contract.skip("TroveManager - in Recovery Mode", async (accounts) => { const _1_Ether = web3.utils.toWei("1", "ether"); const _2_Ether = web3.utils.toWei("2", "ether"); const _3_Ether = web3.utils.toWei("3", "ether"); @@ -1344,7 +1344,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { assert.isTrue(bob_Trove_isInSortedList_After); }); - it("liquidate(), with ICR > 110%, and StabilityPool Bold < liquidated debt: Trove remains in TroveOwners array", async () => { + it("liquidate(), with ICR > 110%, and StabilityPool Bold < liquidated debt: Trove remains in TroveIds array", async () => { // --- SETUP --- // Alice withdraws up to 1500 Bold of debt, and Dennis up to 150, resulting in ICRs of 266%. // Bob withdraws up to 250 Bold of debt, resulting in ICR of 240%. Bob has lowest ICR. @@ -1393,12 +1393,12 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { expect Bob's trove to only be partially offset, and remain active after liquidation */ // Check Bob is in Trove owners array - const arrayLength = (await troveManager.getTroveOwnersCount()).toNumber(); + const arrayLength = (await troveManager.getTroveIdsCount()).toNumber(); let addressFound = false; let addressIdx = 0; for (let i = 0; i < arrayLength; i++) { - const address = (await troveManager.TroveOwners(i)).toString(); + const address = (await troveManager.TroveIds(i)).toString(); if (address == bob) { addressFound = true; addressIdx = i; @@ -1407,7 +1407,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { assert.isTrue(addressFound); - // Check TroveOwners idx on trove struct == idx of address found in TroveOwners array + // Check TroveIds idx on trove struct == idx of address found in TroveIds array const idxOnStruct = (await troveManager.Troves(bob))[4].toString(); assert.equal(addressIdx.toString(), idxOnStruct); }); @@ -1810,7 +1810,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { ).toString(); assert.equal(alice_ICR, "1050000000000000000"); - const activeTrovesCount_Before = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_Before = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_Before, 1); @@ -1821,7 +1821,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { ); // Check Alice's trove has not been removed - const activeTrovesCount_After = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_After = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_After, 1); const alice_isInSortedList = await sortedTroves.contains(alice); @@ -1850,7 +1850,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { ).toString(); assert.equal(alice_ICR, "1050000000000000000"); - const activeTrovesCount_Before = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_Before = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_Before, 2); @@ -1858,7 +1858,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { await troveManager.liquidate(alice, { from: owner }); // Check Alice's trove is removed, and bob remains - const activeTrovesCount_After = await troveManager.getTroveOwnersCount(); + const activeTrovesCount_After = await troveManager.getTroveIdsCount(); assert.equal(activeTrovesCount_After, 1); const alice_isInSortedList = await sortedTroves.contains(alice); @@ -2878,12 +2878,12 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { await troveManager.batchLiquidateTroves(trovesToLiquidate); // Check C is in Trove owners array - const arrayLength = (await troveManager.getTroveOwnersCount()).toNumber(); + const arrayLength = (await troveManager.getTroveIdsCount()).toNumber(); let addressFound = false; let addressIdx = 0; for (let i = 0; i < arrayLength; i++) { - const address = (await troveManager.TroveOwners(i)).toString(); + const address = (await troveManager.TroveIds(i)).toString(); if (address == carol) { addressFound = true; addressIdx = i; @@ -2892,7 +2892,7 @@ contract("TroveManager - in Recovery Mode", async (accounts) => { assert.isTrue(addressFound); - // Check TroveOwners idx on trove struct == idx of address found in TroveOwners array + // Check TroveIds idx on trove struct == idx of address found in TroveIds array const idxOnStruct = (await troveManager.Troves(carol))[4].toString(); assert.equal(addressIdx.toString(), idxOnStruct); }); diff --git a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js index 1952e0e6..cb6a6ee8 100644 --- a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js +++ b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js @@ -6,7 +6,7 @@ const { toBN, dec, ZERO_ADDRESS } = th; const TroveManagerTester = artifacts.require("./TroveManagerTester"); const BoldToken = artifacts.require("./BoldToken.sol"); -contract( +contract.skip( "TroveManager - in Recovery Mode - back to normal mode in 1 tx", async (accounts) => { const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice( diff --git a/contracts/test/stakeDeclineTest.js b/contracts/test/stakeDeclineTest.js index 5c8eea9b..16d05c78 100644 --- a/contracts/test/stakeDeclineTest.js +++ b/contracts/test/stakeDeclineTest.js @@ -77,7 +77,7 @@ contract("TroveManager", async (accounts) => { await priceFeed.setPrice(dec(100, 18)); // Make 1 mega troves A at ~50% total collateral - await th.openTroveWrapper(contracts, + const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(1, 31)), ZERO_ADDRESS, @@ -87,7 +87,7 @@ contract("TroveManager", async (accounts) => { ); // Make 5 large troves B, C, D, E, F at ~10% total collateral - await th.openTroveWrapper(contracts, + const BTroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(2, 30)), ZERO_ADDRESS, @@ -148,7 +148,7 @@ contract("TroveManager", async (accounts) => { assert.isTrue( await troveManager.checkRecoveryMode(await priceFeed.getPrice()) ); - await troveManager.liquidate(A); + await troveManager.liquidate(ATroveId); console.log( `totalStakesSnapshot after L1: ${await troveManager.totalStakesSnapshot()}` @@ -162,10 +162,11 @@ contract("TroveManager", async (accounts) => { B )}` ); - console.log(`B stake after L1: ${(await troveManager.Troves(B))[2]}`); + console.log(`B stake after L1: ${(await troveManager.Troves(BTroveId))[2]}`); // adjust trove B 1 wei: apply rewards await borrowerOperations.adjustTrove( + BTroveId, th._100pct, 0, false, @@ -173,21 +174,22 @@ contract("TroveManager", async (accounts) => { false, { from: B } ); // B repays 1 wei - console.log(`B stake after A1: ${(await troveManager.Troves(B))[2]}`); + console.log(`B stake after A1: ${(await troveManager.Troves(BTroveId))[2]}`); console.log(`Snapshots ratio after A1: ${await getSnapshotsRatio()}`); // Loop over tiny troves, and alternately: // - Liquidate a tiny trove // - Adjust B's collateral by 1 wei for (let [idx, trove] of tinyTroves.entries()) { - await troveManager.liquidate(trove); + await troveManager.liquidate(th.addressToTroveId(trove)); console.log( - `B stake after L${idx + 2}: ${(await troveManager.Troves(B))[2]}` + `B stake after L${idx + 2}: ${(await troveManager.Troves(BTroveId))[2]}` ); console.log( `Snapshots ratio after L${idx + 2}: ${await getSnapshotsRatio()}` ); await borrowerOperations.adjustTrove( + BTroveId, th._100pct, 0, false, diff --git a/contracts/utils/testHelpers.js b/contracts/utils/testHelpers.js index 38217ac4..d0360ea5 100644 --- a/contracts/utils/testHelpers.js +++ b/contracts/utils/testHelpers.js @@ -169,6 +169,10 @@ class TestHelper { return ICR; } + static addressToTroveId(address, index=0) { + return web3.utils.soliditySha3(web3.eth.abi.encodeParameters(['address', 'uint256'], [address, index])); + } + static async ICRbetween100and110(account, troveManager, price) { const ICR = await troveManager.getCurrentICR(account, price); return ICR.gt(MoneyValues._ICR100) && ICR.lt(MoneyValues._MCR); @@ -313,12 +317,20 @@ class TestHelper { return compositeDebt; } + static async getTroveEntireCollByAddress(contracts, account) { + return await this.getTroveEntireColl(contracts, this.addressToTroveId(account)); + } + static async getTroveEntireColl(contracts, trove) { return this.toBN( (await contracts.troveManager.getEntireDebtAndColl(trove))[1] ); } + static async getTroveEntireDebtByAddress(contracts, account) { + return await this.getTroveEntireDebt(contracts, this.addressToTroveId(account)); + } + static async getTroveEntireDebt(contracts, trove) { return this.toBN( (await contracts.troveManager.getEntireDebtAndColl(trove))[0] @@ -502,15 +514,19 @@ class TestHelper { return { upperHint, lowerHint }; } - static async getEntireCollAndDebt(contracts, account) { - // console.log(`account: ${account}`) - const rawColl = (await contracts.troveManager.Troves(account))[1]; - const rawDebt = (await contracts.troveManager.Troves(account))[0]; + static async getEntireCollAndDebtByAddress(contracts, account) { + return await this.getEntireCollAndDebt(contracts, this.addressToTroveId(account)); + } + + static async getEntireCollAndDebt(contracts, troveId) { + // console.log(`troveId: ${troveId}`) + const rawColl = (await contracts.troveManager.Troves(troveId))[1]; + const rawDebt = (await contracts.troveManager.Troves(troveId))[0]; const pendingETHReward = await contracts.troveManager.getPendingETHReward( - account + troveId ); const pendingBoldDebtReward = - await contracts.troveManager.getPendingBoldDebtReward(account); + await contracts.troveManager.getPendingBoldDebtReward(troveId); const entireColl = rawColl.add(pendingETHReward); const entireDebt = rawDebt.add(pendingBoldDebtReward); @@ -835,6 +851,7 @@ class TestHelper { static async openTrove( contracts, { + troveIndex, maxFeePercentage, extraBoldAmount, upperHint, @@ -843,6 +860,7 @@ class TestHelper { extraParams, } ) { + if (!troveIndex) troveIndex = 0; if (!maxFeePercentage) maxFeePercentage = this._100pct; if (!extraBoldAmount) extraBoldAmount = this.toBN(0); else if (typeof extraBoldAmount == "string") @@ -881,6 +899,8 @@ class TestHelper { await contracts.WETH.approve(contracts.borrowerOperations.address, extraParams.value, { from: extraParams.from }); const tx = await contracts.borrowerOperations.openTrove( + extraParams.from, + troveIndex, maxFeePercentage, extraParams.value, boldAmount, @@ -893,7 +913,10 @@ class TestHelper { } ); + const troveId = this.getTroveIdFromTx(tx); + return { + troveId, boldAmount, netDebt, totalDebt, @@ -916,6 +939,8 @@ class TestHelper { await contracts.WETH.approve(contracts.borrowerOperations.address, extraParams.value, { from: extraParams.from }); const tx = await contracts.borrowerOperations.openTrove( + extraParams.from, + 0, maxFeePercentage, extraParams.value, boldAmount, @@ -926,14 +951,29 @@ class TestHelper { from: extraParams.from, } ); - return tx; + + const troveId = this.getTroveIdFromTx(tx); + + return troveId; + } + + static getTroveIdFromTx(tx) { + for (let i = 0; i < tx.logs.length; i++) { + if (tx.logs[i].event === "TroveCreated") { + const troveId = tx.logs[i].args['_troveId']; + + return troveId; + } + } + throw "The transaction logs do not contain a trove creation event"; } static async withdrawBold( contracts, - { maxFeePercentage, boldAmount, ICR, extraParams } + { troveId, maxFeePercentage, boldAmount, ICR, extraParams } ) { if (!maxFeePercentage) maxFeePercentage = this._100pct; + if (!troveId) troveId = this.addressToTroveId(extraParams.from); assert( !(boldAmount && ICR) && (boldAmount || ICR), @@ -943,9 +983,7 @@ class TestHelper { let increasedTotalDebt; if (ICR) { assert(extraParams.from, "A from account is needed"); - const { debt, coll } = await contracts.troveManager.getEntireDebtAndColl( - extraParams.from - ); + const { debt, coll } = await contracts.troveManager.getEntireDebtAndColl(troveId); const price = await contracts.priceFeedTestnet.getPrice(); const targetDebt = coll.mul(price).div(ICR); assert( @@ -965,6 +1003,7 @@ class TestHelper { } await contracts.borrowerOperations.withdrawBold( + troveId, maxFeePercentage, boldAmount, extraParams @@ -1167,7 +1206,10 @@ class TestHelper { // approve ERC20 ETH await contracts.WETH.approve(contracts.borrowerOperations.address, extraParams.value, { from: extraParams.from }); + const troveId = this.addressToTroveId(extraParams.from); + const tx = await contracts.borrowerOperations.addColl( + troveId, extraParams.value, { from: extraParams.from, @@ -1456,36 +1498,8 @@ class TestHelper { maxFee = 0, gasPrice_toUse = 0 ) { - const redemptionhint = await contracts.hintHelpers.getRedemptionHints( - BoldAmount, - price, - gasPrice_toUse - ); - - const firstRedemptionHint = redemptionhint[0]; - const partialRedemptionNewICR = redemptionhint[1]; - - const { hintAddress: approxPartialRedemptionHint, latestRandomSeed } = - await contracts.hintHelpers.getApproxHint( - partialRedemptionNewICR, - 50, - this.latestRandomSeed - ); - this.latestRandomSeed = latestRandomSeed; - - const exactPartialRedemptionHint = - await contracts.sortedTroves.findInsertPosition( - partialRedemptionNewICR, - approxPartialRedemptionHint, - approxPartialRedemptionHint - ); - const tx = await contracts.troveManager.redeemCollateral( BoldAmount, - firstRedemptionHint, - exactPartialRedemptionHint[0], - exactPartialRedemptionHint[1], - partialRedemptionNewICR, 0, maxFee, { from: redeemer, gasPrice: gasPrice_toUse }