From 7723169e7a93a62373cdc417af9089dde4f1385e Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 3 Apr 2024 15:55:25 +0100 Subject: [PATCH 01/19] =?UTF-8?q?TroveManagerTest:=20make=20use=20of=20har?= =?UTF-8?q?dhat=E2=80=99s=20loadFixture()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a test of migrating to loadFixture() using TroveManagerTest only for now. The migration consists of converting beforeEach() into a fixture, which is recommended by Hardhat mostly for performance reasons [1]. On my computer, this test went from ~54s to ~18s (~67% faster). Before: pnpm test test/TroveManagerTest.js 53.90s user 6.48s system 145% cpu 41.495 total After: pnpm test test/TroveManagerTest.js 17.98s user 1.81s system 138% cpu 14.309 total [1] https://hardhat.org/hardhat-runner/docs/guides/test-contracts#using-fixtures --- contracts/test/TroveManagerTest.js | 288 ++++++++++++++++++++++++----- 1 file changed, 245 insertions(+), 43 deletions(-) diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index 2a6ab2e3c..0504a1ecd 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -3,6 +3,7 @@ const testHelpers = require("../utils/testHelpers.js"); const { fundAccounts } = require("../utils/fundAccounts.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); const BoldToken = artifacts.require("./BoldToken.sol"); +const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); const th = testHelpers.TestHelper; const dec = th.dec; @@ -47,51 +48,14 @@ contract("TroveManager", async (accounts) => { E, ] = accounts; - const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); - - let priceFeed; - let boldToken; - let sortedTroves; - let troveManager; - let activePool; - let stabilityPool; - let collSurplusPool; - let defaultPool; - let borrowerOperations; - let hintHelpers; - - let contracts; - - const getOpenTroveTotalDebt = async (boldAmount) => - th.getOpenTroveTotalDebt(contracts, boldAmount); - const getOpenTroveBoldAmount = async (totalDebt) => - th.getOpenTroveBoldAmount(contracts, totalDebt); - const getActualDebtFromComposite = async (compositeDebt) => - th.getActualDebtFromComposite(compositeDebt, contracts); - const getNetBorrowingAmount = async (debtWithFee) => - th.getNetBorrowingAmount(contracts, debtWithFee); - const openTrove = async (params) => th.openTrove(contracts, params); - const withdrawBold = async (params) => th.withdrawBold(contracts, params); - - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); + async function deployContractsAndFundFixture() { + const contracts = await deploymentHelper.deployLiquityCore(); contracts.troveManager = await TroveManagerTester.new(); contracts.boldToken = await BoldToken.new( contracts.troveManager.address, contracts.stabilityPool.address, - contracts.borrowerOperations.address - ) - - priceFeed = contracts.priceFeedTestnet; - boldToken = contracts.boldToken; - sortedTroves = contracts.sortedTroves; - troveManager = contracts.troveManager; - activePool = contracts.activePool; - stabilityPool = contracts.stabilityPool; - defaultPool = contracts.defaultPool; - collSurplusPool = contracts.collSurplusPool; - borrowerOperations = contracts.borrowerOperations; - hintHelpers = contracts.hintHelpers; + contracts.borrowerOperations.address, + ); await deploymentHelper.connectCoreContracts(contracts); await fundAccounts([ @@ -116,9 +80,28 @@ contract("TroveManager", async (accounts) => { D, E, ], contracts.WETH); - }); + + return { + getOpenTroveBoldAmount: async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt), + getNetBorrowingAmount: async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee), + openTrove: async (params) => th.openTrove(contracts, params), + withdrawBold: async (params) => th.withdrawBold(contracts, params), + contracts: { + ...contracts, + priceFeed: contracts.priceFeedTestnet, + }, + }; + } it("liquidate(): closes a Trove that has ICR < MCR", async () => { + const { + getNetBorrowingAmount, + openTrove, + withdrawBold, + contracts, + } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -155,6 +138,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): decreases ActivePool ETH and BoldDebt by correct amounts", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, activePool } = contracts; + // --- SETUP --- const { collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -204,6 +190,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): increases DefaultPool ETH and Bold debt by correct amounts", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, defaultPool } = contracts; + // --- SETUP --- const { collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -250,6 +239,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): removes the Trove's stake from the total stakes", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager } = contracts; + // --- SETUP --- const { collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -277,6 +269,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Removes the correct trove from the TroveOwners array, and moves the last array element to the new empty slot", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -342,6 +337,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the snapshots of total stakes and total collateral", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager } = contracts; + // --- SETUP --- const { collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -389,6 +387,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the L_ETH and L_boldDebt reward-per-unit-staked totals", async () => { + const { contracts, openTrove, withdrawBold } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + // --- SETUP --- const { collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); @@ -489,6 +490,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Liquidates undercollateralized trove if there are two troves in the system", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: bob, value: dec(100, "ether") }, @@ -534,6 +538,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove is non-existent", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(21, 17)), extraParams: { from: bob } }); @@ -555,6 +562,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove has been closed", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, sortedTroves, priceFeed } = contracts; + 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 } }); @@ -586,6 +596,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does nothing if trove has >= 110% ICR", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, sortedTroves, priceFeed } = contracts; + await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: whale } }); await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: bob } }); @@ -619,6 +632,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Given the same price and no other trove changes, complete Pool offsets restore the TCR to its value prior to the defaulters opening troves", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // Whale provides Bold to SP const spDeposit = toBN(dec(100, 24)); await openTrove({ @@ -684,6 +700,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Pool offsets increase the TCR", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // Whale provides Bold to SP const spDeposit = toBN(dec(100, 24)); await openTrove({ @@ -750,6 +769,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): a pure redistribution reduces the TCR only as a result of compensation", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: whale } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); @@ -861,6 +883,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not affect the SP deposit or ETH gain when called on an SP depositor's address that has no trove", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, boldToken, stabilityPool } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const spDeposit = toBN(dec(1, 24)); await openTrove({ @@ -927,6 +952,9 @@ 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 () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const spDeposit = toBN(dec(1, 24)); await openTrove({ @@ -992,6 +1020,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates a SP depositor's trove with ICR < 110%, and the liquidation correctly impacts their SP deposit and ETH gain", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + const A_spDeposit = toBN(dec(3, 24)); const B_spDeposit = toBN(dec(1, 24)); await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -1107,6 +1138,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not alter the liquidated user's token balance", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { activePool, priceFeed, troveManager, sortedTroves, boldToken, defaultPool } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const { boldAmount: A_boldAmount } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -1161,6 +1195,9 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(8, 18)), extraBoldAmount: toBN(dec(100, 18)), @@ -1263,6 +1300,9 @@ contract("TroveManager", async (accounts) => { // --- batchLiquidateTroves() --- it("batchLiquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + 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 } }); @@ -1339,6 +1379,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): liquidates troves with ICR < MCR", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // A, B, C open troves that will remain active when price drops to 100 @@ -1397,6 +1440,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not affect the liquidated user's token balances", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, boldToken } = contracts; + 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 @@ -1442,6 +1488,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): A liquidation sequence containing Pool offsets increases the TCR", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // Whale provides 500 Bold to SP await openTrove({ ICR: toBN(dec(100, 18)), @@ -1516,6 +1565,9 @@ 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 { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + const { collateral: W_coll, totalDebt: W_debt } = await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale }, @@ -1613,7 +1665,7 @@ contract("TroveManager", async (accounts) => { totalCollNonDefaulters .add(th.applyLiquidationFee(totalCollDefaulters)) .mul(price) - .div(totalDebt) + .div(totalDebt), ), 1000 ); @@ -1622,6 +1674,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): Liquidating troves with SP deposits correctly impacts their SP deposit and ETH gain", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // Whale provides 400 Bold to the SP const whaleDeposit = toBN(dec(40000, 18)); await openTrove({ @@ -1791,6 +1846,9 @@ contract("TroveManager", async (accounts) => { // Can we achieve / test the same thing using another liquidation function? it("batchLiquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool, defaultPool, borrowerOperations } = contracts; + // 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 } }); @@ -1876,6 +1934,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): closes every trove with ICR < MCR in the given array", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -1939,6 +2000,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not liquidate troves that are not in the given array", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2008,6 +2072,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not close troves with ICR >= MCR in the given array", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2071,6 +2138,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): reverts if array is empty", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2113,6 +2183,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if trove is non-existent", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; + // --- SETUP --- const spDeposit = toBN(dec(500000, 18)); await openTrove({ @@ -2197,6 +2270,9 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if a trove has been closed", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves, stabilityPool, boldToken, borrowerOperations } = contracts; + // --- SETUP --- const spDeposit = toBN(dec(500000, 18)); await openTrove({ @@ -2296,6 +2372,8 @@ contract("TroveManager", async (accounts) => { // Many of these tests rely on specific ICR ordering in the setup, and close fully redeemed. // It may be more efficient to write wholly new redemption tests in Solidity for Foundry. it.skip("getRedemptionHints(): gets the address of the first Trove and the final ICR of the last Trove involved in a redemption", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- const partialRedemptionAmount = toBN(dec(100, 18)); const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ @@ -2331,6 +2409,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("getRedemptionHints(): returns 0 as partialRedemptionHintNICR when reaching _maxIterations", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- await openTrove({ ICR: toBN(dec(310, 16)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(290, 16)), extraParams: { from: bob } }); @@ -2353,6 +2433,9 @@ 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 () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, priceFeed, sortedTroves } = contracts; + // --- SETUP --- const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2471,6 +2554,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, zero address", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, priceFeed, sortedTroves } = contracts; + // --- SETUP --- const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2580,6 +2666,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, non-existent trove", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + // --- SETUP --- const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2689,6 +2778,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, trove below MCR", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, troveManager, sortedTroves } = contracts; + // --- SETUP --- const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2803,6 +2895,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when the token redemption request has been filled", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2900,6 +2994,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when max iterations have been reached", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2975,6 +3071,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): performs partial redemption if resultant debt is > minimum net debt", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, sortedTroves } = contracts; + await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), @@ -3029,6 +3128,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't perform partial redemption if resultant debt would be < minimum net debt", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, sortedTroves } = contracts; + await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), @@ -3084,6 +3186,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesnt perform the final partial redemption in the sequence if the hint is out-of-date", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, priceFeed, sortedTroves } = contracts; + // --- SETUP --- const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(363, 16)), @@ -3214,6 +3319,9 @@ contract("TroveManager", async (accounts) => { // active debt cannot be zero, as there’s a positive min debt enforced, and at least a trove must exist it.skip("redeemCollateral(): can redeem if there is zero active debt but non-zero debt in DefaultPool", async () => { + const { contracts, getOpenTroveBoldAmount, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, priceFeed } = contracts; + // --- SETUP --- const amount = await getOpenTroveBoldAmount(dec(110, 18)); @@ -3273,6 +3381,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't touch Troves with ICR < 110%", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- const { netDebt: A_debt } = await openTrove({ @@ -3321,6 +3431,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): finds the last Trove with ICR == 110% even if there is more than one", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- const amount1 = toBN(dec(100, 18)); const { totalDebt: A_totalDebt } = await openTrove({ @@ -3397,6 +3509,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when TCR < MCR", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + 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 } }); @@ -3423,6 +3538,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when argument _amount is 0", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // Alice opens trove and transfers 500Bold to Erin, the would-be redeemer @@ -3462,6 +3579,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee > 100%", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(10, 18), @@ -3512,6 +3631,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee < 0.5%", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(10, 18), @@ -3572,6 +3693,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if fee exceeds max fee percentage", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { boldToken, troveManager } = contracts; + const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(80, 18), @@ -3657,6 +3781,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't affect the Stability Pool deposits or ETH gain of redeemed-from troves", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, stabilityPool, priceFeed, sortedTroves } = contracts; + await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // B, C, D, F open trove @@ -3794,6 +3921,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): caller can redeem their entire BoldToken balance", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -3894,6 +4023,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when requested redemption amount exceeds caller's Bold token balance", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -4103,6 +4234,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): value of issued ETH == face value of redeemed Bold (assuming 1 Bold has value of $1)", async () => { + const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { boldToken, troveManager, priceFeed, activePool, sortedTroves } = contracts; + const { collateral: W_coll } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -4260,6 +4394,9 @@ contract("TroveManager", async (accounts) => { // it doesn’t make much sense as there’s now min debt enforced and at least one trove must remain active // the only way to test it is before any trove is opened it.skip("redeemCollateral(): reverts if there is zero outstanding system debt", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken } = contracts; + // --- SETUP --- illegally mint Bold to Bob await boldToken.unprotectedMint(bob, dec(100, 18)); @@ -4300,6 +4437,8 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if caller's tries to redeem more than the outstanding system debt", async () => { + const { openTrove } = await loadFixture(deployContractsAndFundFixture); + // --- SETUP --- illegally mint Bold to Bob await boldToken.unprotectedMint(bob, "101000000000000000000"); @@ -4360,6 +4499,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption sends the ETH remainder (ETHDrawn - gas) to the redeemer", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed, activePool, defaultPool } = contracts; + // time fast-forwards 1 year, and multisig stakes 1 LQTY await th.fastForwardTime( timeValues.SECONDS_IN_ONE_YEAR, @@ -4591,6 +4733,9 @@ contract("TroveManager", async (accounts) => { }; it.skip("redeemCollateral(): emits correct debt and coll values in each redeemed trove's TroveUpdated event", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { sortedTroves } = contracts; + const { netDebt: W_netDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraBoldAmount: dec(10000, 18), @@ -4682,6 +4827,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner to claim", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { collSurplusPool } = contracts; + const { A_netDebt, A_coll, B_netDebt, B_coll, C_netDebt, C_coll } = await redeemCollateral3Full1Partial(); @@ -4716,6 +4864,9 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner after re-opening trove", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + const { A_netDebt, A_coll: A_collBefore, @@ -4777,6 +4928,9 @@ contract("TroveManager", async (accounts) => { }); it("getPendingBoldDebtReward(): Returns 0 if there is no pending BoldDebt reward", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; + // Make some troves const { totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -4820,6 +4974,9 @@ contract("TroveManager", async (accounts) => { }); it("getPendingETHReward(): Returns 0 if there is no pending ETH reward", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; + // make some troves const { totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -4864,6 +5021,9 @@ contract("TroveManager", async (accounts) => { // --- computeICR --- it("computeICR(): Returns 0 if trove's coll is worth 0", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = 0; const coll = dec(1, "ether"); const debt = dec(100, 18); @@ -4874,6 +5034,9 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 for ETH:USD = 100, coll = 1 ETH, debt = 100 Bold", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = dec(100, 18); const coll = dec(1, "ether"); const debt = dec(100, 18); @@ -4884,6 +5047,9 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 200 ETH, debt = 30 Bold", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = dec(100, 18); const coll = dec(200, "ether"); const debt = dec(30, 18); @@ -4894,6 +5060,9 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 250, coll = 1350 ETH, debt = 127 Bold", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = "250000000000000000000"; const coll = "1350000000000000000000"; const debt = "127000000000000000000"; @@ -4904,6 +5073,9 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 1 ETH, debt = 54321 Bold", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = dec(100, 18); const coll = dec(1, "ether"); const debt = "54321000000000000000000"; @@ -4914,6 +5086,9 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 if trove has non-zero coll and zero debt", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const price = dec(100, 18); const coll = dec(1, "ether"); const debt = 0; @@ -4931,6 +5106,9 @@ contract("TroveManager", async (accounts) => { //TCR < 150% it("checkRecoveryMode(): Returns true when TCR < 150%", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -4947,6 +5125,9 @@ contract("TroveManager", async (accounts) => { // TCR == 150% it("checkRecoveryMode(): Returns false when TCR == 150%", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -4961,6 +5142,9 @@ contract("TroveManager", async (accounts) => { // > 150% it("checkRecoveryMode(): Returns false when TCR > 150%", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -4977,6 +5161,9 @@ contract("TroveManager", async (accounts) => { // check 0 it("checkRecoveryMode(): Returns false when TCR == 0", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -4994,6 +5181,9 @@ contract("TroveManager", async (accounts) => { // --- Getters --- it("getTroveStake(): Returns stake", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5011,6 +5201,9 @@ contract("TroveManager", async (accounts) => { }); it("getTroveColl(): Returns coll", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5025,6 +5218,9 @@ contract("TroveManager", async (accounts) => { }); it("getTroveDebt(): Returns debt", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + const { totalDebt: totalDebtA } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5044,6 +5240,9 @@ contract("TroveManager", async (accounts) => { }); it("getTroveStatus(): Returns status", async () => { + const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { troveManager, boldToken, borrowerOperations } = contracts; + const { totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, @@ -5068,6 +5267,9 @@ contract("TroveManager", async (accounts) => { }); it("hasPendingRewards(): Returns false it trove is not active", async () => { + const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { troveManager } = contracts; + assert.isFalse(await troveManager.hasPendingRewards(alice)); }); }); From 9ceffaaa52a9705a65b445c54873b40eccec4d25 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 4 Apr 2024 14:06:05 +0100 Subject: [PATCH 02/19] Fixtures: add BorrowerOperationsTest, TroveManager_LiquidationRewardsTest This ocmmit also adds the createDeployAndFundFixture() utility. --- contracts/test/BorrowerOperationsTest.js | 519 +++++++++++++++--- contracts/test/TroveManagerTest.js | 232 ++++---- .../TroveManager_LiquidationRewardsTest.js | 173 +++--- contracts/utils/testFixtures.js | 66 +++ 4 files changed, 701 insertions(+), 289 deletions(-) create mode 100644 contracts/utils/testFixtures.js diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index ad10aa308..04b0f161b 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -1,20 +1,13 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); -const testHelpers = require("../utils/testHelpers.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const BorrowerOperationsTester = artifacts.require( "./BorrowerOperationsTester.sol" ); const TroveManagerTester = artifacts.require("TroveManagerTester"); -const th = testHelpers.TestHelper; - const dec = th.dec; const toBN = th.toBN; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; - -const ZERO_ADDRESS = th.ZERO_ADDRESS; const assertRevert = th.assertRevert; contract("BorrowerOperations", async (accounts) => { @@ -38,87 +31,47 @@ contract("BorrowerOperations", async (accounts) => { frontEnd_3, ] = accounts; - const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); - - let priceFeed; - let boldToken; - let sortedTroves; - let troveManager; - let activePool; - let stabilityPool; - let defaultPool; - let borrowerOperations; - let lqtyToken; - - let contracts; - - const getOpenTroveBoldAmount = async (totalDebt) => - th.getOpenTroveBoldAmount(contracts, totalDebt); - const getNetBorrowingAmount = async (debtWithFee) => - th.getNetBorrowingAmount(contracts, debtWithFee); - const getActualDebtFromComposite = async (compositeDebt) => - th.getActualDebtFromComposite(compositeDebt, contracts); - const openTrove = async (params) => th.openTrove(contracts, params); - const getTroveEntireColl = async (trove) => - th.getTroveEntireColl(contracts, trove); - const getTroveEntireDebt = async (trove) => - th.getTroveEntireDebt(contracts, trove); - const getTroveStake = async (trove) => th.getTroveStake(contracts, trove); - - let BOLD_GAS_COMPENSATION; - let MIN_NET_DEBT; - let BORROWING_FEE_FLOOR; - - before(async () => {}); - - const testCorpus = () => { - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.borrowerOperations = await BorrowerOperationsTester.new(contracts.WETH.address); + const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 17), { + async afterDeploy(contracts) { + contracts.borrowerOperations = await BorrowerOperationsTester.new( + contracts.WETH.address, + ); contracts.troveManager = await TroveManagerTester.new(); - contracts = await deploymentHelper.deployBoldToken(contracts); - - await deploymentHelper.connectCoreContracts(contracts); - - priceFeed = contracts.priceFeedTestnet; - boldToken = contracts.boldToken; - sortedTroves = contracts.sortedTroves; - troveManager = contracts.troveManager; - activePool = contracts.activePool; - stabilityPool = contracts.stabilityPool; - defaultPool = contracts.defaultPool; - borrowerOperations = contracts.borrowerOperations; - hintHelpers = contracts.hintHelpers; - - BOLD_GAS_COMPENSATION = await borrowerOperations.BOLD_GAS_COMPENSATION(); - MIN_NET_DEBT = await borrowerOperations.MIN_NET_DEBT(); - BORROWING_FEE_FLOOR = await borrowerOperations.BORROWING_FEE_FLOOR(); - - await fundAccounts([ - owner, - alice, - bob, - carol, - dennis, - whale, - A, - B, - C, - D, - E, - F, - G, - H, - frontEnd_1, - frontEnd_2, - frontEnd_3, - bountyAddress, - lpRewardsAddress, - multisig, - ], contracts.WETH); - }); + }, + async afterConnect(contracts) { + const { borrowerOperations } = contracts; + return { + BOLD_GAS_COMPENSATION: await borrowerOperations.BOLD_GAS_COMPENSATION(), + MIN_NET_DEBT: await borrowerOperations.MIN_NET_DEBT(), + BORROWING_FEE_FLOOR: await borrowerOperations.BORROWING_FEE_FLOOR(), + + async getOpenTroveBoldAmount(totalDebt) { + return th.getOpenTroveBoldAmount(contracts, totalDebt); + }, + async getNetBorrowingAmount(debtWithFee) { + return th.getNetBorrowingAmount(contracts, debtWithFee); + }, + async openTrove(params) { + return th.openTrove(contracts, params); + }, + async getTroveEntireColl(trove) { + return th.getTroveEntireColl(contracts, trove); + }, + async getTroveEntireDebt(trove) { + return th.getTroveEntireDebt(contracts, trove); + }, + async getTroveStake(trove) { + return th.getTroveStake(contracts, trove); + }, + }; + }, + }); + const testCorpus = () => { it("addColl(): reverts when top-up would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -144,6 +97,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(): Increases the activePool ETH and raw ether balance by correct amount", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool } = contracts; + const { collateral: aliceColl } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -175,6 +131,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: adds the correct collateral amount to the Trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -201,6 +160,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: Trove is in sortedList before and after", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { sortedTroves } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -223,6 +185,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: updates the stake and updates the total stakes", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + // Alice creates initial Trove with 1 ether await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -252,6 +217,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: applies pending rewards and updates user's L_ETH, L_boldDebt snapshots", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- const { collateral: aliceCollBefore, totalDebt: aliceDebtBefore } = @@ -423,6 +391,9 @@ contract("BorrowerOperations", async (accounts) => { // }) it("addColl(), reverts if trove is non-existent or closed", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, troveManager } = contracts; + // A, B open troves await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -461,6 +432,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(): can add collateral in Recovery Mode", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, troveManager } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(alice); assert.isFalse(await th.checkRecoveryMode(contracts)); @@ -483,6 +457,9 @@ contract("BorrowerOperations", async (accounts) => { // --- withdrawColl() --- it("withdrawColl(): reverts when withdrawal would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -506,6 +483,9 @@ contract("BorrowerOperations", async (accounts) => { // reverts when calling address does not have active trove it("withdrawColl(): reverts when calling address does not have active trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -539,6 +519,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -568,6 +551,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when requested ETH withdrawal is > the trove's collateral", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + 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 } }); @@ -596,6 +582,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when withdrawal would bring the user's ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); // 110% ICR @@ -613,6 +602,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts if system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + // --- SETUP --- // A and B open troves at 150% ICR @@ -640,6 +632,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): doesn’t allow a user to completely withdraw all collateral from their Trove (due to gas compensation)", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, sortedTroves, troveManager } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -661,6 +656,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): leaves the Trove active when the user withdraws less than all the collateral", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, sortedTroves, troveManager } = contracts; + // Open Trove await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -683,6 +681,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reduces the Trove's collateral by the correct amount", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, troveManager } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(alice); @@ -701,6 +702,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reduces ActivePool ETH and raw ether by correct amount", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(alice); @@ -732,6 +736,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): updates the stake and updates the total stakes", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, troveManager } = contracts; + // Alice creates initial Trove with 2 ether await openTrove({ ICR: toBN(dec(2, 18)), @@ -766,6 +773,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): sends the correct amount of ETH to the user", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice, value: dec(2, "ether") }, @@ -788,6 +798,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): applies pending rewards and updates user's L_ETH, L_boldDebt snapshots", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + // --- SETUP --- // Alice adds 15 ether, Bob adds 5 ether, Carol adds 1 ether await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -927,6 +940,9 @@ contract("BorrowerOperations", async (accounts) => { // --- withdrawBold() --- it("withdrawBold(): reverts when withdrawal would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -953,6 +969,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when calling address does not have active trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -979,6 +998,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when requested withdrawal amount is zero Bold", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -1004,6 +1026,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + 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 } }); @@ -1036,6 +1061,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when withdrawal would bring the trove's ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); @@ -1054,6 +1082,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when a withdrawal would cause the TCR of the system to fall below the CCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); @@ -1080,6 +1111,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts if system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + // --- SETUP --- await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); @@ -1104,6 +1138,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases the Trove's Bold debt by the correct amount", async () => { + const { contracts, getNetBorrowingAmount, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // check before @@ -1126,6 +1163,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases Bold debt in ActivePool by correct amount", async () => { + const { contracts, getNetBorrowingAmount, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice, value: toBN(dec(100, "ether")) }, @@ -1154,6 +1194,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases user BoldToken balance by correct amount", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraParams: { value: toBN(dec(100, "ether")), from: alice }, }); @@ -1180,6 +1223,9 @@ contract("BorrowerOperations", async (accounts) => { // --- repayBold() --- it("repayBold(): reverts when repayment would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -1204,6 +1250,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): Succeeds when it would leave trove with net debt >= minimum net debt", async () => { + const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + // 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, th._100pct, @@ -1229,6 +1278,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when it would leave trove with net debt < minimum net debt", async () => { + const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, troveManager } = contracts; + // Open the trove with min debt + 1 wei await th.openTroveWrapper(contracts, th._100pct, @@ -1254,12 +1306,14 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if repaid amount is greater than current debt", async () => { + const { BOLD_GAS_COMPENSATION, contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + const { totalDebt } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); - BOLD_GAS_COMPENSATION = await borrowerOperations.BOLD_GAS_COMPENSATION(); const repayAmount = totalDebt.sub(BOLD_GAS_COMPENSATION).add(toBN(1)); await openTrove({ extraBoldAmount: repayAmount, @@ -1283,6 +1337,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when calling address does not have active trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1313,6 +1370,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when attempted repayment is > the debt of the trove", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1345,6 +1405,9 @@ contract("BorrowerOperations", async (accounts) => { //repayBold: reduces Bold debt in Trove it("repayBold(): reduces the Trove's Bold debt by the correct amount", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1374,6 +1437,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases Bold debt in ActivePool by correct amount", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1406,6 +1472,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases user BoldToken balance by correct amount", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1438,6 +1507,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): can repay debt in Recovery Mode", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1473,6 +1545,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): Reverts if borrower has insufficient Bold balance to cover his debt repayment", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1511,6 +1586,9 @@ contract("BorrowerOperations", async (accounts) => { // --- adjustTrove() --- it("adjustTrove(): reverts when adjustment would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -1543,6 +1621,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when calling address has no active trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1586,6 +1667,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts in Recovery Mode when the adjustment would reduce the TCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1664,6 +1748,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): collateral withdrawal reverts in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1696,6 +1783,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would leave ICR < 150% reverts in Recovery Mode", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1747,6 +1837,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would reduce the ICR reverts in Recovery Mode", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), @@ -1838,6 +1931,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): A trove with ICR < CCR in Recovery Mode can adjust their trove to ICR > CCR", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1892,6 +1988,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): A trove with ICR > CCR in Recovery Mode can improve their ICR", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), @@ -1946,6 +2045,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when change would cause the TCR of the system to fall below the CCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); @@ -1973,6 +2075,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when Bold repaid is > debt of the trove", async () => { + const { BOLD_GAS_COMPENSATION, contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, troveManager } = contracts; + await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const bobOpenTx = ( await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }) @@ -2005,6 +2110,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when attempted ETH withdrawal is >= the trove's collateral", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + 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 } }); @@ -2028,6 +2136,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when change would cause the ICR of the trove to fall below the MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(100, 18)), @@ -2067,6 +2178,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 coll change, doesnt change borrower's coll or ActivePool coll", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2097,6 +2211,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 debt change, doesnt change borrower's debt or ActivePool debt", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2129,6 +2246,15 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with an increase in both", async () => { + const { + contracts, + getNetBorrowingAmount, + getTroveEntireColl, + getTroveEntireDebt, + openTrove, + } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2174,6 +2300,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with a decrease in both", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2209,6 +2338,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with coll increase, debt decrease", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2254,6 +2386,10 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with coll decrease, debt increase", async () => { + const { contracts, getNetBorrowingAmount, getTroveEntireColl, getTroveEntireDebt, openTrove } = + await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2297,6 +2433,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's stake and totalStakes with a coll increase", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2336,6 +2475,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's stake and totalStakes with a coll decrease", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2373,6 +2515,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): changes BoldToken balance by the requested decrease", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2408,6 +2553,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): changes BoldToken balance by the requested increase", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2445,6 +2593,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the activePool ETH and raw ether balance by the requested decrease", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2489,6 +2640,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the activePool ETH and raw ether balance by the amount of ETH sent", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2535,6 +2689,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the Bold debt in ActivePool by requested decrease", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2571,6 +2728,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the Bold debt in ActivePool by requested increase", async () => { + const { contracts, getNetBorrowingAmount, openTrove } = await loadDeployAndFundFixture(); + const { activePool, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2606,6 +2766,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): new coll = 0 and new debt = 0 is not allowed, as gas compensation still counts toward ICR", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2639,6 +2802,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if requested debt increase and amount is zero", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2659,6 +2825,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if it’s zero adjustment", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2674,6 +2843,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if requested coll withdrawal is greater than trove's collateral", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2711,6 +2883,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if borrower has insufficient Bold balance to cover his debt repayment", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2747,6 +2922,9 @@ contract("BorrowerOperations", async (accounts) => { // no need to test this with proxies it("Internal _adjustTrove(): reverts when op is a withdrawal and _borrower param is not the msg.sender", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2799,6 +2977,9 @@ contract("BorrowerOperations", async (accounts) => { // --- closeTrove() --- it("closeTrove(): reverts when it would lower the TCR below CCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, priceFeed, troveManager } = contracts; + await openTrove({ ICR: toBN(dec(300, 16)), extraParams: { from: alice }, @@ -2823,6 +3004,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts when calling address does not have active trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2844,6 +3028,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts when system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(2, 18)), @@ -2884,6 +3071,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces a Trove's collateral to zero", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2914,6 +3104,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces a Trove's debt to zero", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2944,6 +3137,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): sets Trove's stake to zero", async () => { + const { contracts, getTroveStake, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2977,6 +3173,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): zero's the troves reward snapshots", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // Dennis opens trove and transfers tokens to alice await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -3061,6 +3260,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): sets trove's status to closed and removes it from sorted troves list", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3096,6 +3298,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces ActivePool ETH and raw ether by correct amount", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { activePool, boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3139,6 +3344,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces ActivePool debt by correct amount", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { activePool, boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3174,6 +3382,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): updates the the total stakes", async () => { + const { contracts, getTroveStake, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3226,6 +3437,9 @@ contract("BorrowerOperations", async (accounts) => { // TODO: wrap contracts.WETH.balanceOf to be able to go through proxies it("closeTrove(): sends the correct amount of ETH to the user", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3260,6 +3474,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): subtracts the debt of the closed Trove from the Borrower's BoldToken balance", async () => { + const { BOLD_GAS_COMPENSATION, contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3294,6 +3511,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): applies pending rewards", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, defaultPool, priceFeed, troveManager } = contracts; + // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(1000000, 18)), @@ -3430,6 +3650,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts if borrower has insufficient Bold balance to repay his entire debt", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), @@ -3463,6 +3686,9 @@ contract("BorrowerOperations", async (accounts) => { // TODO: use rawLogs instead of logs it("openTrove(): emits a TroveUpdated event with the correct collateral and debt", async () => { + const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + const txA = ( await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), @@ -3571,6 +3797,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Opens a trove with net debt >= minimum net debt", async () => { + const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + const { sortedTroves } = contracts; + // Add 1 wei to correct for rounding error in helper function const txA = await th.openTroveWrapper(contracts, th._100pct, @@ -3596,7 +3825,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts if net debt < minimum net debt", async () => { - const txAPromise = th.openTroveWrapper(contracts,th._100pct, 0, A, A, 0, { + const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + + const txAPromise = th.openTroveWrapper(contracts, th._100pct, 0, A, A, 0, { from: A, value: dec(100, 30), }); @@ -3624,6 +3855,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when system is in Recovery Mode and ICR < CCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), @@ -3655,6 +3889,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when trove ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), @@ -3701,6 +3938,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when opening the trove would cause the TCR of the system to fall below the CCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed } = contracts; + await priceFeed.setPrice(dec(100, 18)); // Alice creates trove with 150% ICR. System TCR = 150%. @@ -3728,6 +3968,8 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts if trove is already active", async () => { + const { openTrove } = await loadDeployAndFundFixture(); + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -3770,6 +4012,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Can open a trove with ICR == CCR when system is in Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- // Alice and Bob add coll and withdraw such that the TCR is ~150% await openTrove({ @@ -3811,6 +4056,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Reverts opening a trove with min debt when system is in Recovery Mode", async () => { + const { MIN_NET_DEBT, contracts, getNetBorrowingAmount, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed } = contracts; + // --- SETUP --- // Alice and Bob add coll and withdraw such that the TCR is ~150% await openTrove({ @@ -3845,6 +4093,15 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): creates a new Trove and assigns the correct collateral and debt amount", async () => { + const { + BOLD_GAS_COMPENSATION, + MIN_NET_DEBT, + contracts, + getTroveEntireColl, + getTroveEntireDebt, + } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + const debt_Before = await getTroveEntireDebt(alice); const coll_Before = await getTroveEntireColl(alice); const status_Before = await troveManager.getTroveStatus(alice); @@ -3880,6 +4137,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): adds Trove owner to TroveOwners array", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + const TroveOwnersCount_Before = ( await troveManager.getTroveOwnersCount() ).toString(); @@ -3898,6 +4158,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): creates a stake and adds it to total stakes", async () => { + const { contracts, getTroveEntireColl, getTroveStake, openTrove } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + const aliceStakeBefore = await getTroveStake(alice); const totalStakesBefore = await troveManager.totalStakes(); @@ -3920,6 +4183,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): inserts Trove to Sorted Troves list", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { sortedTroves } = contracts; + // Check before const aliceTroveInList_Before = await sortedTroves.contains(alice); const listIsEmpty_Before = await sortedTroves.isEmpty(); @@ -3940,6 +4206,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Increases the activePool ETH and raw ether balance by correct amount", async () => { + const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); + const { activePool } = contracts; + const activePool_ETH_Before = await activePool.getETHBalance(); const activePool_RawEther_Before = await contracts.WETH.balanceOf( activePool.address @@ -3963,6 +4232,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): records up-to-date initial snapshots of L_ETH and L_boldDebt", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, troveManager } = contracts; + // --- SETUP --- await openTrove({ @@ -4017,6 +4289,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): allows a user to open a Trove, then close it, then re-open it", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, sortedTroves, troveManager } = contracts; + // Open Troves await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -4067,6 +4342,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases the Trove's Bold debt by the correct amount", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { troveManager } = contracts; + // check before const alice_Trove_Before = await troveManager.Troves(alice); const debt_Before = alice_Trove_Before[0]; @@ -4088,6 +4366,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases Bold debt in ActivePool by the debt of the trove", async () => { + const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); + const { activePool } = contracts; + const activePool_BoldDebt_Before = await activePool.getBoldDebt(); assert.equal(activePool_BoldDebt_Before, 0); @@ -4104,6 +4385,9 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases user BoldToken balance by correct amount", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { boldToken } = contracts; + // check before const alice_BoldTokenBalance_Before = await boldToken.balanceOf(alice); assert.equal(alice_BoldTokenBalance_Before, 0); @@ -4127,6 +4411,9 @@ contract("BorrowerOperations", async (accounts) => { describe("getNewICRFromTroveChange() returns the correct ICR", async () => { // 0, 0 it("collChange = 0, debtChange = 0", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4149,6 +4436,9 @@ contract("BorrowerOperations", async (accounts) => { // 0, +ve it("collChange = 0, debtChange is positive", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4171,6 +4461,9 @@ contract("BorrowerOperations", async (accounts) => { // 0, -ve it("collChange = 0, debtChange is negative", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4193,6 +4486,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, 0 it("collChange is positive, debtChange is 0", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4215,6 +4511,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, 0 it("collChange is negative, debtChange is 0", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4237,6 +4536,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, -ve it("collChange is negative, debtChange is negative", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4259,6 +4561,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, +ve it("collChange is positive, debtChange is positive", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4281,6 +4586,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, -ve it("collChange is positive, debtChange is negative", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4303,6 +4611,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, +ve it("collChange is negative, debtChange is positive", async () => { + const { contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed } = contracts; + price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4327,6 +4638,9 @@ contract("BorrowerOperations", async (accounts) => { // --- getCompositeDebt --- it("getCompositeDebt(): returns debt + gas comp", async () => { + const { BOLD_GAS_COMPENSATION, contracts } = await loadDeployAndFundFixture(); + const { borrowerOperations } = contracts; + const res1 = await borrowerOperations.getCompositeDebt("0"); assert.equal(res1, BOLD_GAS_COMPENSATION.toString()); @@ -4350,6 +4664,9 @@ contract("BorrowerOperations", async (accounts) => { describe("getNewTCRFromTroveChange() returns the correct TCR", async () => { // 0, 0 it("collChange = 0, debtChange = 0", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4403,6 +4720,9 @@ contract("BorrowerOperations", async (accounts) => { // 0, +ve it("collChange = 0, debtChange is positive", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4456,6 +4776,9 @@ contract("BorrowerOperations", async (accounts) => { // 0, -ve it("collChange = 0, debtChange is negative", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4508,6 +4831,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, 0 it("collChange is positive, debtChange is 0", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4561,6 +4887,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, 0 it("collChange is negative, debtChange is 0", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4615,6 +4944,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, -ve it("collChange is negative, debtChange is negative", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4669,6 +5001,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, +ve it("collChange is positive, debtChange is positive", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4723,6 +5058,9 @@ contract("BorrowerOperations", async (accounts) => { // +ve, -ve it("collChange is positive, debtChange is negative", async () => { + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); @@ -4777,6 +5115,9 @@ contract("BorrowerOperations", async (accounts) => { // -ve, +ve it("collChange is negative, debtChange is positive", async () => { + const { contracts, getNetBorrowingAmount, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const troveColl = toBN(dec(1000, "ether")); const troveTotalDebt = toBN(dec(100000, 18)); diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index 0504a1ecd..05ff002a7 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -1,9 +1,5 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); -const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); -const BoldToken = artifacts.require("./BoldToken.sol"); -const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const th = testHelpers.TestHelper; const dec = th.dec; @@ -48,50 +44,34 @@ contract("TroveManager", async (accounts) => { E, ] = accounts; - async function deployContractsAndFundFixture() { - const contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - ); - - await deploymentHelper.connectCoreContracts(contracts); - await fundAccounts([ - owner, - alice, - bob, - carol, - dennis, - erin, - flyn, - graham, - harriet, - ida, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - whale, - A, - B, - C, - D, - E, - ], contracts.WETH); - - return { - getOpenTroveBoldAmount: async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt), - getNetBorrowingAmount: async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee), - openTrove: async (params) => th.openTrove(contracts, params), - withdrawBold: async (params) => th.withdrawBold(contracts, params), - contracts: { - ...contracts, - priceFeed: contracts.priceFeedTestnet, + const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { + afterConnect: async (contracts) => ({ + async getOpenTroveBoldAmount(totalDebt) { + return th.getOpenTroveBoldAmount(contracts, totalDebt); }, - }; - } + async getNetBorrowingAmount(debtWithFee) { + return th.getNetBorrowingAmount(contracts, debtWithFee); + }, + async openTrove(params) { + return th.openTrove(contracts, params); + }, + async withdrawBold(params) { + return th.withdrawBold(contracts, params); + }, + async getActualDebtFromComposite(compositeDebt) { + return th.getActualDebtFromComposite(compositeDebt, contracts); + }, + async getTroveEntireColl(trove) { + return th.getTroveEntireColl(contracts, trove); + }, + async getTroveEntireDebt(trove) { + return th.getTroveEntireDebt(contracts, trove); + }, + async getTroveStake(trove) { + return th.getTroveStake(contracts, trove); + }, + }), + }); it("liquidate(): closes a Trove that has ICR < MCR", async () => { const { @@ -99,7 +79,7 @@ contract("TroveManager", async (accounts) => { openTrove, withdrawBold, contracts, - } = await loadFixture(deployContractsAndFundFixture); + } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -138,7 +118,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): decreases ActivePool ETH and BoldDebt by correct amounts", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, activePool } = contracts; // --- SETUP --- @@ -190,7 +170,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): increases DefaultPool ETH and Bold debt by correct amounts", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, defaultPool } = contracts; // --- SETUP --- @@ -239,7 +219,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): removes the Trove's stake from the total stakes", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager } = contracts; // --- SETUP --- @@ -269,7 +249,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Removes the correct trove from the TroveOwners array, and moves the last array element to the new empty slot", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; // --- SETUP --- @@ -337,7 +317,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the snapshots of total stakes and total collateral", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager } = contracts; // --- SETUP --- @@ -387,7 +367,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the L_ETH and L_boldDebt reward-per-unit-staked totals", async () => { - const { contracts, openTrove, withdrawBold } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove, withdrawBold } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; // --- SETUP --- @@ -490,7 +470,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Liquidates undercollateralized trove if there are two troves in the system", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; await openTrove({ @@ -538,7 +518,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove is non-existent", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { troveManager, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -562,7 +542,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove has been closed", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { troveManager, sortedTroves, priceFeed } = contracts; await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); @@ -596,7 +576,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does nothing if trove has >= 110% ICR", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { troveManager, sortedTroves, priceFeed } = contracts; await openTrove({ ICR: toBN(dec(3, 18)), extraParams: { from: whale } }); @@ -632,7 +612,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Given the same price and no other trove changes, complete Pool offsets restore the TCR to its value prior to the defaulters opening troves", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // Whale provides Bold to SP @@ -700,7 +680,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Pool offsets increase the TCR", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // Whale provides Bold to SP @@ -769,7 +749,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): a pure redistribution reduces the TCR only as a result of compensation", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: whale } }); @@ -883,7 +863,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not affect the SP deposit or ETH gain when called on an SP depositor's address that has no trove", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, boldToken, stabilityPool } = contracts; await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -952,7 +932,7 @@ 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 () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -1020,7 +1000,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates a SP depositor's trove with ICR < 110%, and the liquidation correctly impacts their SP deposit and ETH gain", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; const A_spDeposit = toBN(dec(3, 24)); @@ -1138,7 +1118,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not alter the liquidated user's token balance", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { activePool, priceFeed, troveManager, sortedTroves, boldToken, defaultPool } = contracts; await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -1195,7 +1175,7 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; await openTrove({ @@ -1300,7 +1280,7 @@ contract("TroveManager", async (accounts) => { // --- batchLiquidateTroves() --- it("batchLiquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice } }); @@ -1379,7 +1359,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): liquidates troves with ICR < MCR", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -1440,7 +1420,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not affect the liquidated user's token balances", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, boldToken } = contracts; await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -1488,7 +1468,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): A liquidation sequence containing Pool offsets increases the TCR", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // Whale provides 500 Bold to SP @@ -1565,7 +1545,7 @@ 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 { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; const { collateral: W_coll, totalDebt: W_debt } = await openTrove({ @@ -1674,7 +1654,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): Liquidating troves with SP deposits correctly impacts their SP deposit and ETH gain", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // Whale provides 400 Bold to the SP @@ -1846,7 +1826,7 @@ contract("TroveManager", async (accounts) => { // Can we achieve / test the same thing using another liquidation function? it("batchLiquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool, defaultPool, borrowerOperations } = contracts; // A, B, C, D, E open troves @@ -1934,7 +1914,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): closes every trove with ICR < MCR in the given array", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // --- SETUP --- @@ -2000,7 +1980,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not liquidate troves that are not in the given array", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // --- SETUP --- @@ -2072,7 +2052,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not close troves with ICR >= MCR in the given array", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // --- SETUP --- @@ -2138,7 +2118,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): reverts if array is empty", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // --- SETUP --- @@ -2183,7 +2163,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if trove is non-existent", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; // --- SETUP --- @@ -2270,7 +2250,7 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if a trove has been closed", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves, stabilityPool, boldToken, borrowerOperations } = contracts; // --- SETUP --- @@ -2372,7 +2352,7 @@ contract("TroveManager", async (accounts) => { // Many of these tests rely on specific ICR ordering in the setup, and close fully redeemed. // It may be more efficient to write wholly new redemption tests in Solidity for Foundry. it.skip("getRedemptionHints(): gets the address of the first Trove and the final ICR of the last Trove involved in a redemption", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- const partialRedemptionAmount = toBN(dec(100, 18)); @@ -2409,7 +2389,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("getRedemptionHints(): returns 0 as partialRedemptionHintNICR when reaching _maxIterations", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- await openTrove({ ICR: toBN(dec(310, 16)), extraParams: { from: alice } }); @@ -2433,7 +2413,7 @@ 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 () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { troveManager, boldToken, priceFeed, sortedTroves } = contracts; // --- SETUP --- @@ -2554,7 +2534,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, zero address", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, priceFeed, sortedTroves } = contracts; // --- SETUP --- @@ -2666,7 +2646,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, non-existent trove", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; // --- SETUP --- @@ -2778,7 +2758,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, trove below MCR", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, troveManager, sortedTroves } = contracts; // --- SETUP --- @@ -2895,7 +2875,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when the token redemption request has been filled", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2994,7 +2974,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when max iterations have been reached", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -3071,7 +3051,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): performs partial redemption if resultant debt is > minimum net debt", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadFixture(deployContractsAndFundFixture); + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); const { troveManager, boldToken, sortedTroves } = contracts; await th.openTroveWrapper(contracts, @@ -3128,7 +3108,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't perform partial redemption if resultant debt would be < minimum net debt", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadFixture(deployContractsAndFundFixture); + const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); const { troveManager, boldToken, sortedTroves } = contracts; await th.openTroveWrapper(contracts, @@ -3186,7 +3166,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesnt perform the final partial redemption in the sequence if the hint is out-of-date", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, priceFeed, sortedTroves } = contracts; // --- SETUP --- @@ -3319,7 +3299,7 @@ contract("TroveManager", async (accounts) => { // active debt cannot be zero, as there’s a positive min debt enforced, and at least a trove must exist it.skip("redeemCollateral(): can redeem if there is zero active debt but non-zero debt in DefaultPool", async () => { - const { contracts, getOpenTroveBoldAmount, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, getOpenTroveBoldAmount, openTrove } = await loadDeployAndFundFixture(); const { troveManager, boldToken, priceFeed } = contracts; // --- SETUP --- @@ -3381,7 +3361,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't touch Troves with ICR < 110%", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- @@ -3431,7 +3411,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): finds the last Trove with ICR == 110% even if there is more than one", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- const amount1 = toBN(dec(100, 18)); @@ -3509,7 +3489,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when TCR < MCR", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); @@ -3538,7 +3518,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when argument _amount is 0", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -3579,7 +3559,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee > 100%", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); await openTrove({ ICR: toBN(dec(400, 16)), @@ -3631,7 +3611,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee < 0.5%", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); await openTrove({ ICR: toBN(dec(400, 16)), @@ -3693,7 +3673,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if fee exceeds max fee percentage", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { boldToken, troveManager } = contracts; const { totalDebt: A_totalDebt } = await openTrove({ @@ -3781,7 +3761,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't affect the Stability Pool deposits or ETH gain of redeemed-from troves", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, boldToken, stabilityPool, priceFeed, sortedTroves } = contracts; await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -3921,7 +3901,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): caller can redeem their entire BoldToken balance", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), @@ -4023,7 +4003,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when requested redemption amount exceeds caller's Bold token balance", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), @@ -4234,7 +4214,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): value of issued ETH == face value of redeemed Bold (assuming 1 Bold has value of $1)", async () => { - const { openTrove, contracts } = await loadFixture(deployContractsAndFundFixture); + const { openTrove, contracts } = await loadDeployAndFundFixture(); const { boldToken, troveManager, priceFeed, activePool, sortedTroves } = contracts; const { collateral: W_coll } = await openTrove({ @@ -4394,7 +4374,7 @@ contract("TroveManager", async (accounts) => { // it doesn’t make much sense as there’s now min debt enforced and at least one trove must remain active // the only way to test it is before any trove is opened it.skip("redeemCollateral(): reverts if there is zero outstanding system debt", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager, boldToken } = contracts; // --- SETUP --- illegally mint Bold to Bob @@ -4437,7 +4417,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if caller's tries to redeem more than the outstanding system debt", async () => { - const { openTrove } = await loadFixture(deployContractsAndFundFixture); + const { openTrove } = await loadDeployAndFundFixture(); // --- SETUP --- illegally mint Bold to Bob await boldToken.unprotectedMint(bob, "101000000000000000000"); @@ -4499,7 +4479,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption sends the ETH remainder (ETHDrawn - gas) to the redeemer", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed, activePool, defaultPool } = contracts; // time fast-forwards 1 year, and multisig stakes 1 LQTY @@ -4733,7 +4713,7 @@ contract("TroveManager", async (accounts) => { }; it.skip("redeemCollateral(): emits correct debt and coll values in each redeemed trove's TroveUpdated event", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { sortedTroves } = contracts; const { netDebt: W_netDebt } = await openTrove({ @@ -4827,7 +4807,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner to claim", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { collSurplusPool } = contracts; const { A_netDebt, A_coll, B_netDebt, B_coll, C_netDebt, C_coll } = @@ -4864,7 +4844,7 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner after re-opening trove", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; const { @@ -4928,7 +4908,7 @@ contract("TroveManager", async (accounts) => { }); it("getPendingBoldDebtReward(): Returns 0 if there is no pending BoldDebt reward", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; // Make some troves @@ -4974,7 +4954,7 @@ contract("TroveManager", async (accounts) => { }); it("getPendingETHReward(): Returns 0 if there is no pending ETH reward", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; // make some troves @@ -5021,7 +5001,7 @@ contract("TroveManager", async (accounts) => { // --- computeICR --- it("computeICR(): Returns 0 if trove's coll is worth 0", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = 0; @@ -5034,7 +5014,7 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 for ETH:USD = 100, coll = 1 ETH, debt = 100 Bold", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = dec(100, 18); @@ -5047,7 +5027,7 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 200 ETH, debt = 30 Bold", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = dec(100, 18); @@ -5060,7 +5040,7 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 250, coll = 1350 ETH, debt = 127 Bold", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = "250000000000000000000"; @@ -5073,7 +5053,7 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 1 ETH, debt = 54321 Bold", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = dec(100, 18); @@ -5086,7 +5066,7 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 if trove has non-zero coll and zero debt", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const price = dec(100, 18); @@ -5106,7 +5086,7 @@ contract("TroveManager", async (accounts) => { //TCR < 150% it("checkRecoveryMode(): Returns true when TCR < 150%", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; await priceFeed.setPrice(dec(100, 18)); @@ -5125,7 +5105,7 @@ contract("TroveManager", async (accounts) => { // TCR == 150% it("checkRecoveryMode(): Returns false when TCR == 150%", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; await priceFeed.setPrice(dec(100, 18)); @@ -5142,7 +5122,7 @@ contract("TroveManager", async (accounts) => { // > 150% it("checkRecoveryMode(): Returns false when TCR > 150%", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; await priceFeed.setPrice(dec(100, 18)); @@ -5161,7 +5141,7 @@ contract("TroveManager", async (accounts) => { // check 0 it("checkRecoveryMode(): Returns false when TCR == 0", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { priceFeed } = contracts; await priceFeed.setPrice(dec(100, 18)); @@ -5181,7 +5161,7 @@ contract("TroveManager", async (accounts) => { // --- Getters --- it("getTroveStake(): Returns stake", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const { collateral: A_coll } = await openTrove({ @@ -5201,7 +5181,7 @@ contract("TroveManager", async (accounts) => { }); it("getTroveColl(): Returns coll", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const { collateral: A_coll } = await openTrove({ @@ -5218,7 +5198,7 @@ contract("TroveManager", async (accounts) => { }); it("getTroveDebt(): Returns debt", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager } = contracts; const { totalDebt: totalDebtA } = await openTrove({ @@ -5240,7 +5220,7 @@ contract("TroveManager", async (accounts) => { }); it("getTroveStatus(): Returns status", async () => { - const { contracts, openTrove } = await loadFixture(deployContractsAndFundFixture); + const { contracts, openTrove } = await loadDeployAndFundFixture(); const { troveManager, boldToken, borrowerOperations } = contracts; const { totalDebt: B_totalDebt } = await openTrove({ @@ -5267,7 +5247,7 @@ contract("TroveManager", async (accounts) => { }); it("hasPendingRewards(): Returns false it trove is not active", async () => { - const { contracts } = await loadFixture(deployContractsAndFundFixture); + const { contracts } = await loadDeployAndFundFixture(); const { troveManager } = contracts; assert.isFalse(await troveManager.hasPendingRewards(alice)); diff --git a/contracts/test/TroveManager_LiquidationRewardsTest.js b/contracts/test/TroveManager_LiquidationRewardsTest.js index a6589fce7..d36800856 100644 --- a/contracts/test/TroveManager_LiquidationRewardsTest.js +++ b/contracts/test/TroveManager_LiquidationRewardsTest.js @@ -1,15 +1,12 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); + +const TroveManagerTester = artifacts.require("TroveManagerTester"); const th = testHelpers.TestHelper; const dec = th.dec; const toBN = th.toBN; const getDifference = th.getDifference; -const mv = testHelpers.MoneyValues; - -const TroveManagerTester = artifacts.require("TroveManagerTester"); -const BoldToken = artifacts.require("BoldToken"); contract( "TroveManager - Redistribution reward calculations", @@ -37,77 +34,23 @@ contract( defaulter_4, ] = accounts; - const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice( - 997, - 1000 - ); - - let priceFeed; - let boldToken; - let sortedTroves; - let troveManager; - let nameRegistry; - let activePool; - let stabilityPool; - let defaultPool; - let functionCaller; - let borrowerOperations; - - let contracts; - - const getOpenTroveBoldAmount = async (totalDebt) => - th.getOpenTroveBoldAmount(contracts, totalDebt); - const getNetBorrowingAmount = async (debtWithFee) => - th.getNetBorrowingAmount(contracts, debtWithFee); - const openTrove = async (params) => th.openTrove(contracts, params); - - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address - ); - - priceFeed = contracts.priceFeedTestnet; - boldToken = contracts.boldToken; - sortedTroves = contracts.sortedTroves; - troveManager = contracts.troveManager; - nameRegistry = contracts.nameRegistry; - activePool = contracts.activePool; - stabilityPool = contracts.stabilityPool; - defaultPool = contracts.defaultPool; - functionCaller = contracts.functionCaller; - borrowerOperations = contracts.borrowerOperations; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, - alice, - bob, - carol, - dennis, - erin, - freddy, - greta, - harry, - ida, - A, - B, - C, - D, - E, - whale, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - ], contracts.WETH); + const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { + async afterDeploy(contracts) { + contracts.troveManager = await TroveManagerTester.new(); + }, }); it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + troveManager, + priceFeed, + activePool, + defaultPool, + boldToken, + sortedTroves, + } = contracts; + // A, B open trove const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -207,6 +150,9 @@ contract( }); it("redistribution: A, B, C Open. C Liquidated. D, E, F Open. F Liquidated. Distributes correct rewards", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; + // A, B C open troves const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -330,6 +276,9 @@ contract( //// it("redistribution: Sequence of alternate opening/liquidation: final surviving trove has ETH from all previously liquidated troves", async () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; + // A, B open troves const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -481,6 +430,9 @@ 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 () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { troveManager, sortedTroves, priceFeed } = contracts; + // A, B, C, D, E open troves const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -625,6 +577,9 @@ 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 () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { priceFeed, troveManager, sortedTroves } = contracts; + // A, B, C, D, E open troves const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -802,6 +757,9 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B adds coll. Liq(A). B acquires all coll and debt", async () => { + const { openTrove, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; + // A, B, C open troves const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -879,6 +837,9 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B tops up coll. D Opens. Liq(D). Distributes correct rewards.", async () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, sortedTroves, troveManager } = contracts; + // A, B, C open troves const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -993,6 +954,9 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); + const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; + const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { collateral: A_coll } = await openTrove({ @@ -1159,6 +1123,9 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); + const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; + const _998_Ether = toBN("998000000000000000000"); // A, B, C open troves const { collateral: A_coll } = await openTrove({ @@ -1339,6 +1306,9 @@ contract( // --- Trove withdraws collateral --- it("redistribution: A,B,C Open. Liq(C). B withdraws coll. Liq(A). B acquires all coll and debt", async () => { + const { openTrove, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, troveManager, sortedTroves, priceFeed } = contracts; + // A, B, C open troves const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -1419,6 +1389,17 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B withdraws coll. D Opens. Liq(D). Distributes correct rewards.", async () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + activePool, + boldToken, + borrowerOperations, + defaultPool, + priceFeed, + sortedTroves, + troveManager, + } = contracts; + // A, B, C open troves const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -1553,6 +1534,17 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + activePool, + boldToken, + borrowerOperations, + defaultPool, + priceFeed, + sortedTroves, + troveManager, + } = contracts; + const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { collateral: A_coll } = await openTrove({ @@ -1715,6 +1707,17 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + activePool, + boldToken, + borrowerOperations, + defaultPool, + priceFeed, + sortedTroves, + troveManager, + } = contracts; + const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { collateral: A_coll } = await openTrove({ @@ -1929,6 +1932,17 @@ contract( // For calculations of correct values used in test, see scenario 1: // 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 () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + activePool, + boldToken, + borrowerOperations, + defaultPool, + priceFeed, + sortedTroves, + troveManager, + } = contracts; + // A, B, C open troves const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -2220,6 +2234,17 @@ contract( // For calculations of correct values used in test, see scenario 2: // 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). Varying coll. Distributes correct rewards", async () => { + const { openTrove, contracts } = await loadDeployAndFundFixture(); + const { + activePool, + boldToken, + defaultPool, + borrowerOperations, + troveManager, + sortedTroves, + priceFeed, + } = contracts; + /* A, B, C open troves. A: 450 ETH B: 8901 ETH diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js new file mode 100644 index 000000000..ebff274c2 --- /dev/null +++ b/contracts/utils/testFixtures.js @@ -0,0 +1,66 @@ +const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); +const deploymentHelper = require("./deploymentHelpers.js"); +const { fundAccounts } = require("./fundAccounts.js"); +const { TestHelper: th } = require("./testHelpers.js"); + +// Returns a fixture utility to be called in every test. The only required parameter +// is the list of accounts to be funded. Callback parameters can be used to run code +// after the deployment and after the connection. They take the contracts as a +// parameter, which can be modified as needed. The returned object will be merged +// with the object returned by the fixture loader utility. +function createDeployAndFundFixture(accounts, { + afterDeploy = async () => null, + afterConnect = async () => null, +} = {}) { + const fixture = async () => { + const contracts = await deploymentHelper.deployLiquityCore(); + + const afterDeployResult = await afterDeploy(contracts); + + await deploymentHelper.deployBoldToken(contracts); + await deploymentHelper.connectCoreContracts(contracts); + contracts.priceFeed = contracts.priceFeedTestnet; + + const afterConnectResult = await afterConnect(contracts); + + if (!accounts) { + throw new Error("No accounts provided to the fixture"); + } + await fundAccounts(accounts, contracts.WETH); + + return { + contracts, + getOpenTroveBoldAmount: async (totalDebt) => { + return th.getOpenTroveBoldAmount(contracts, totalDebt); + }, + getNetBorrowingAmount: async (debtWithFee) => { + return th.getNetBorrowingAmount(contracts, debtWithFee); + }, + openTrove: async (params) => { + return th.openTrove(contracts, params); + }, + withdrawBold: async (params) => { + return th.withdrawBold(contracts, params); + }, + getActualDebtFromComposite: async (compositeDebt) => { + return th.getActualDebtFromComposite(compositeDebt, contracts); + }, + getTroveEntireColl: async (trove) => { + return th.getTroveEntireColl(contracts, trove); + }, + getTroveEntireDebt: async (trove) => { + return th.getTroveEntireDebt(contracts, trove); + }, + getTroveStake: async (trove) => { + return th.getTroveStake(contracts, trove); + }, + ...afterDeployResult, + ...afterConnectResult, + }; + }; + return () => loadFixture(fixture); +} + +module.exports = { + createDeployAndFundFixture, +}; From 717051bc8e0b35fb5340c5871b05bdb26ec2d7c7 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 4 Apr 2024 14:28:07 +0100 Subject: [PATCH 03/19] Fixtures: add FeeArithmeticTest --- contracts/test/FeeArithmeticTest.js | 60 ++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/contracts/test/FeeArithmeticTest.js b/contracts/test/FeeArithmeticTest.js index 8b7f75285..e6124e55c 100644 --- a/contracts/test/FeeArithmeticTest.js +++ b/contracts/test/FeeArithmeticTest.js @@ -1,9 +1,9 @@ const Decimal = require("decimal.js"); -const deploymentHelper = require("../utils/deploymentHelpers.js") const { BNConverter } = require("../utils/BNConverter.js") const testHelpers = require("../utils/testHelpers.js") const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const LiquityMathTester = artifacts.require("./LiquityMathTester.sol") +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const th = testHelpers.TestHelper const timeValues = testHelpers.TimeValues @@ -12,15 +12,8 @@ const toBN = th.toBN const getDifference = th.getDifference contract('Fee arithmetic tests', async accounts => { - let contracts - let troveManagerTester - let mathTester - - const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000) - // see: https://docs.google.com/spreadsheets/d/1RbD8VGzq7xFgeK1GOkz_9bbKVIx-xkOz0VsVelnUFdc/edit#gid=0 // Results array, maps seconds to expected hours passed output (rounded down to nearest hour). - const secondsToMinutesRoundedDown = [ [0, 0], [1, 0], @@ -330,20 +323,21 @@ contract('Fee arithmetic tests', async accounts => { [919877008002166000, 85, 826094891277916], ] - before(async () => { - troveManagerTester = await TroveManagerTester.new() - TroveManagerTester.setAsDeployed(troveManagerTester) + const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { + afterDeploy: async () => { + const troveManagerTester = await TroveManagerTester.new() + TroveManagerTester.setAsDeployed(troveManagerTester) - mathTester = await LiquityMathTester.new() - LiquityMathTester.setAsDeployed(mathTester) - }) + const mathTester = await LiquityMathTester.new() + LiquityMathTester.setAsDeployed(mathTester) - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore() - await deploymentHelper.connectCoreContracts(contracts) - }) + return { mathTester, troveManagerTester } + } + }); it("minutesPassedSinceLastFeeOp(): returns minutes passed for no time increase", async () => { + const { troveManagerTester } = await loadDeployAndFundFixture() + await troveManagerTester.setLastFeeOpTimeToNow() const minutesPassed = await troveManagerTester.minutesPassedSinceLastFeeOp() @@ -351,6 +345,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("minutesPassedSinceLastFeeOp(): returns minutes passed between time of last fee operation and current block.timestamp, rounded down to nearest minutes", async () => { + const { troveManagerTester } = await loadDeployAndFundFixture() + for (testPair of secondsToMinutesRoundedDown) { await troveManagerTester.setLastFeeOpTimeToNow() @@ -370,6 +366,8 @@ contract('Fee arithmetic tests', async accounts => { describe('Basic exponentiation', async accounts => { // for exponent = 0, returns 1 it("decPow(): for exponent = 0, returns 1, regardless of base", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const a = '0' const b = '1' const c = dec(1, 18) @@ -400,6 +398,8 @@ contract('Fee arithmetic tests', async accounts => { // for exponent = 1, returns base it("decPow(): for exponent = 1, returns base, regardless of base", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const a = '0' const b = '1' const c = dec(1, 18) @@ -433,6 +433,8 @@ contract('Fee arithmetic tests', async accounts => { // for base = 0, returns 0 for any exponent other than 1 it("decPow(): for base = 0, returns 0 for any exponent other than 0", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const res_a = await mathTester.callDecPow(0, 1) const res_b = await mathTester.callDecPow(0, 3) const res_c = await mathTester.callDecPow(0, 17) @@ -459,6 +461,8 @@ contract('Fee arithmetic tests', async accounts => { // for base = 1, returns 1 for any exponent it("decPow(): for base = 1, returns 1 for any exponent", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const ONE = dec(1, 18) const res_a = await mathTester.callDecPow(ONE, 1) const res_b = await mathTester.callDecPow(ONE, 3) @@ -487,6 +491,8 @@ contract('Fee arithmetic tests', async accounts => { // for exponent = 2, returns base**2 it("decPow(): for exponent = 2, returns the square of the base", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const a = dec(1, 18) // 1 const b = dec(15, 17) // 1.5 const c = dec(5, 17) // 0.5 @@ -522,6 +528,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): correct output for various bases and exponents", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (list of exponentiationResults) { const base = list[0].toString() const exponent = list[1].toString() @@ -534,6 +542,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 7776000 (seconds in three months)", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.SECONDS_IN_ONE_MONTH * 3 @@ -560,6 +570,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 2592000 (seconds in one month)", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.SECONDS_IN_ONE_MONTH @@ -586,6 +598,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 43200 (minutes in one month)", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_MONTH @@ -612,6 +626,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 525600 (minutes in one year)", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR @@ -638,6 +654,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 2628000 (minutes in five years)", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 5 @@ -664,6 +682,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = minutes in ten years", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 10 @@ -690,6 +710,8 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = minutes in one hundred years", async () => { + const { mathTester } = await loadDeployAndFundFixture() + for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 100 @@ -716,6 +738,8 @@ contract('Fee arithmetic tests', async accounts => { }) it.skip("decPow(): overflow test: doesn't overflow for exponent = minutes in 1000 years", async () => { + const { mathTester } = await loadDeployAndFundFixture() + const exponent = (timeValues.MINUTES_IN_ONE_YEAR * 1000) + 9 // Test base = 0 From 4a67996e9e15e8b0558bb8c3d6b85dca18020a4c Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Fri, 5 Apr 2024 10:06:41 +0100 Subject: [PATCH 04/19] Fixtures: StabilityPoolTest, PoolsTest --- contracts/test/PoolsTest.js | 76 +++++---- contracts/test/StabilityPoolTest.js | 237 +++++++++++++++++++--------- contracts/test/TroveManagerTest.js | 55 +++---- contracts/utils/testFixtures.js | 11 +- 4 files changed, 233 insertions(+), 146 deletions(-) diff --git a/contracts/test/PoolsTest.js b/contracts/test/PoolsTest.js index 414bbf33e..299b34c6e 100644 --- a/contracts/test/PoolsTest.js +++ b/contracts/test/PoolsTest.js @@ -4,36 +4,38 @@ const DefaultPool = artifacts.require("./DefaultPool.sol") const NonPayableSwitch = artifacts.require("./NonPayableSwitch.sol") const ERC20 = artifacts.require("./ERC20MinterMock.sol"); -const testHelpers = require("../utils/testHelpers.js") +const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); +const { TestHelper: th } = require("../utils/testHelpers.js") -const th = testHelpers.TestHelper -const dec = th.dec +const { dec } = th const _minus_1_Ether = web3.utils.toWei('-1', 'ether') contract('StabilityPool', async accounts => { - /* mock* are EOA’s, temporarily used to call protected functions. - TODO: Replace with mock contracts, and later complete transactions from EOA - */ - let stabilityPool - let WETH const [owner, alice] = accounts; - beforeEach(async () => { - WETH = await ERC20.new("WETH", "WETH"); - stabilityPool = await StabilityPool.new(WETH.address) - const mockActivePoolAddress = (await NonPayableSwitch.new()).address - const dumbContractAddress = (await NonPayableSwitch.new()).address + const deployFixture = async () => { + /* mock* are EOA’s, temporarily used to call protected functions. + TODO: Replace with mock contracts, and later complete transactions from EOA + */ + const WETH = await ERC20.new("WETH", "WETH"); + const stabilityPool = await StabilityPool.new(WETH.address) + const { address: mockActivePoolAddress } = await NonPayableSwitch.new() + const { address: dumbContractAddress } = await NonPayableSwitch.new() await stabilityPool.setAddresses(dumbContractAddress, dumbContractAddress, mockActivePoolAddress, dumbContractAddress, dumbContractAddress, dumbContractAddress) - }) + + return stabilityPool + } it('getETHBalance(): gets the recorded ETH balance', async () => { + const stabilityPool = await loadFixture(deployFixture) const recordedETHBalance = await stabilityPool.getETHBalance() assert.equal(recordedETHBalance, 0) }) it('getTotalBoldDeposits(): gets the recorded BOLD balance', async () => { + const stabilityPool = await loadFixture(deployFixture) const recordedETHBalance = await stabilityPool.getTotalBoldDeposits() assert.equal(recordedETHBalance, 0) }) @@ -41,28 +43,32 @@ contract('StabilityPool', async accounts => { contract('ActivePool', async accounts => { - let activePool, mockBorrowerOperations, WETH - const [owner, alice] = accounts; - beforeEach(async () => { - WETH = await ERC20.new("WETH", "WETH"); - activePool = await ActivePool.new(WETH.address) - mockBorrowerOperations = await NonPayableSwitch.new() - const dumbContractAddress = (await NonPayableSwitch.new()).address + + const deployFixture = async () => { + const WETH = await ERC20.new("WETH", "WETH"); + const activePool = await ActivePool.new(WETH.address) + const mockBorrowerOperations = await NonPayableSwitch.new() + const { address: dumbContractAddress } = await NonPayableSwitch.new() await activePool.setAddresses(mockBorrowerOperations.address, dumbContractAddress, dumbContractAddress, dumbContractAddress, dumbContractAddress, dumbContractAddress) - }) + + return { activePool, mockBorrowerOperations, WETH } + } it('getETHBalance(): gets the recorded ETH balance', async () => { + const { activePool } = await loadFixture(deployFixture) const recordedETHBalance = await activePool.getETHBalance() assert.equal(recordedETHBalance, 0) }) it('getBoldDebt(): gets the recorded BOLD balance', async () => { + const { activePool } = await loadFixture(deployFixture) const recordedETHBalance = await activePool.getRecordedDebtSum() assert.equal(recordedETHBalance, 0) }) it('increaseRecordedDebtSum(): increases the recorded BOLD balance by the correct amount', async () => { + const { activePool, mockBorrowerOperations } = await loadFixture(deployFixture) const recordedBold_balanceBefore = await activePool.getRecordedDebtSum() assert.equal(recordedBold_balanceBefore, 0) @@ -75,6 +81,7 @@ contract('ActivePool', async accounts => { }) // Decrease it('decreaseBoldDebt(): decreases the recorded BOLD balance by the correct amount', async () => { + const { activePool, mockBorrowerOperations } = await loadFixture(deployFixture) // start the pool on 100 wei //await activePool.increaseBoldDebt(100, { from: mockBorrowerOperationsAddress }) const increaseBoldDebtData = th.getTransactionData('increaseRecordedDebtSum(uint256)', ['0x64']) @@ -94,6 +101,7 @@ contract('ActivePool', async accounts => { // send raw ether it('sendETH(): decreases the recorded ETH balance by the correct amount', async () => { + const { activePool, mockBorrowerOperations, WETH } = await loadFixture(deployFixture) // setup: give pool 2 ether const activePool_initialBalance = web3.utils.toBN(await WETH.balanceOf(activePool.address)) assert.equal(activePool_initialBalance, 0) @@ -115,7 +123,7 @@ contract('ActivePool', async accounts => { assert.equal(activePool_BalanceBeforeTx, dec(2, 'ether')) // send ether from pool to alice - th.logBN("eth bal", await WETH.balanceOf(activePool.address)) + // th.logBN("eth bal", await WETH.balanceOf(activePool.address)) //await activePool.sendETH(alice, dec(1, 'ether'), { from: mockBorrowerOperationsAddress }) const sendETHData = th.getTransactionData('sendETH(address,uint256)', [alice, web3.utils.toHex(dec(1, 'ether'))]) const tx2 = await mockBorrowerOperations.forward(activePool.address, sendETHData, { from: owner }) @@ -133,29 +141,33 @@ contract('ActivePool', async accounts => { contract('DefaultPool', async accounts => { - let defaultPool, mockTroveManager, mockActivePool, WETH - const [owner, alice] = accounts; - beforeEach(async () => { - WETH = await ERC20.new("WETH", "WETH"); - defaultPool = await DefaultPool.new(WETH.address) - mockTroveManager = await NonPayableSwitch.new() - mockActivePool = await NonPayableSwitch.new() + + const deployFixture = async () => { + const WETH = await ERC20.new("WETH", "WETH"); + const defaultPool = await DefaultPool.new(WETH.address) + const mockTroveManager = await NonPayableSwitch.new() + const mockActivePool = await NonPayableSwitch.new() await mockActivePool.setETH(WETH.address) await defaultPool.setAddresses(mockTroveManager.address, mockActivePool.address) - }) + + return { defaultPool, mockTroveManager, mockActivePool, WETH } + } it('getETHBalance(): gets the recorded BOLD balance', async () => { + const { defaultPool } = await loadFixture(deployFixture) const recordedETHBalance = await defaultPool.getETHBalance() assert.equal(recordedETHBalance, 0) }) it('getBoldDebt(): gets the recorded BOLD balance', async () => { + const { defaultPool } = await loadFixture(deployFixture) const recordedETHBalance = await defaultPool.getBoldDebt() assert.equal(recordedETHBalance, 0) }) it('increaseBold(): increases the recorded BOLD balance by the correct amount', async () => { + const { defaultPool, mockTroveManager } = await loadFixture(deployFixture) const recordedBold_balanceBefore = await defaultPool.getBoldDebt() assert.equal(recordedBold_balanceBefore, 0) @@ -169,6 +181,7 @@ contract('DefaultPool', async accounts => { }) it('decreaseBold(): decreases the recorded BOLD balance by the correct amount', async () => { + const { defaultPool, mockTroveManager } = await loadFixture(deployFixture) // start the pool on 100 wei //await defaultPool.increaseBoldDebt(100, { from: mockTroveManagerAddress }) const increaseBoldDebtData = th.getTransactionData('increaseBoldDebt(uint256)', ['0x64']) @@ -189,6 +202,7 @@ contract('DefaultPool', async accounts => { // send raw ether it('sendETHToActivePool(): decreases the recorded ETH balance by the correct amount', async () => { + const { defaultPool, mockTroveManager, mockActivePool, WETH } = await loadFixture(deployFixture) // setup: give pool 2 ether const defaultPool_initialBalance = web3.utils.toBN(await WETH.balanceOf(defaultPool.address)) assert.equal(defaultPool_initialBalance, 0) diff --git a/contracts/test/StabilityPoolTest.js b/contracts/test/StabilityPoolTest.js index 9f8cfdfae..b02d09b9c 100644 --- a/contracts/test/StabilityPoolTest.js +++ b/contracts/test/StabilityPoolTest.js @@ -1,15 +1,18 @@ const { time } = require('@nomicfoundation/hardhat-network-helpers'); -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; +const { + MoneyValues: mv, + TestHelper: th, + TimeValues: timeValues, +} = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); + +const { + assertRevert, + dec, + toBN, +} = th; const TroveManagerTester = artifacts.require("TroveManagerTester"); -const BoldToken = artifacts.require("BoldToken"); const NonPayableSwitch = artifacts.require("NonPayableSwitch.sol"); const ZERO = toBN("0"); @@ -49,77 +52,22 @@ contract("StabilityPool", async (accounts) => { const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); const frontEnds = [frontEnd_1, frontEnd_2, frontEnd_3]; - let contracts; - let priceFeed; - let boldToken; - let sortedTroves; - let troveManager; - let activePool; - let stabilityPool; - let defaultPool; - let borrowerOperations; - - let gasPriceInWei; - - const getOpenTroveBoldAmount = async (totalDebt) => - th.getOpenTroveBoldAmount(contracts, totalDebt); - const openTrove = async (params) => th.openTrove(contracts, params); - const assertRevert = th.assertRevert; - describe("Stability Pool Mechanisms", async () => { - before(async () => { - gasPriceInWei = await web3.eth.getGasPrice(); - }); - - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); + const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { + afterDeploy: async (contracts) => { contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - - priceFeed = contracts.priceFeedTestnet; - boldToken = contracts.boldToken; - sortedTroves = contracts.sortedTroves; - troveManager = contracts.troveManager; - activePool = contracts.activePool; - stabilityPool = contracts.stabilityPool; - defaultPool = contracts.defaultPool; - borrowerOperations = contracts.borrowerOperations; - hintHelpers = contracts.hintHelpers; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, - defaulter_1, - defaulter_2, - defaulter_3, - whale, - alice, - bob, - carol, - dennis, - erin, - flyn, - A, - B, - C, - D, - E, - F, - frontEnd_1, - frontEnd_2, - frontEnd_3, - ], contracts.WETH); - }); + TroveManagerTester.setAsDeployed(contracts.troveManager); + } + }); + + describe("Stability Pool Mechanisms", async () => { // --- provideToSP() --- // increases recorded Bold at Stability Pool it("provideToSP(): increases the Stability Pool Bold balance", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -139,6 +87,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): updates the user's deposit record in StabilityPool", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -162,6 +113,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reduces the user's Bold balance by the correct amount", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, stabilityPool } = contracts; + // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -185,6 +139,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): increases totalBoldDeposits by correct amount", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + // --- SETUP --- // Whale opens Trove with 50 ETH, adds 2000 Bold to StabilityPool @@ -202,6 +159,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): Correctly updates user snapshots of accumulated rewards per unit staked", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale opens Trove and deposits to SP @@ -275,6 +235,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), multiple deposits: updates user's deposit and snapshots", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale opens Trove and deposits to SP await openTrove({ @@ -392,6 +355,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if user tries to provide more than their Bold balance", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -429,6 +395,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if user tries to provide 2^256-1 Bold, which exceeds their balance", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -461,6 +430,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if cannot receive ETH Gain", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, troveManager, priceFeed, stabilityPool } = contracts; + // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -532,6 +504,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact other users' deposits or ETH gains", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -657,6 +632,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact system debt, collateral or TCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, defaultPool, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -746,6 +724,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact any troves, including the caller's trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { troveManager, priceFeed, stabilityPool } = contracts; + const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -892,6 +873,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't protect the depositor's trove from liquidation", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -944,6 +928,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): providing 0 Bold reverts", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -992,6 +979,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), new deposit: depositor does not receive ETH gains", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1068,6 +1058,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), new deposit after past full withdrawal: depositor does not receive ETH gains", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1181,6 +1174,9 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts when amount is zero", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1228,6 +1224,9 @@ contract("StabilityPool", async (accounts) => { // --- withdrawFromSP --- it("withdrawFromSP(): reverts when user has no active deposit", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100, 18)), ICR: toBN(dec(2, 18)), @@ -1272,6 +1271,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): partial retrieval - retrieves correct Bold amount and the entire ETH Gain, and updates deposit", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1367,6 +1369,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): partial retrieval - leaves the correct amount of Bold in the Stability Pool", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1438,6 +1443,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): full retrieval - leaves the correct amount of Bold in the Stability Pool", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1529,6 +1537,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero ETH", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -1603,6 +1614,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): it correctly updates the user's Bold and ETH snapshots of entitled reward per unit staked", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1664,6 +1678,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): decreases StabilityPool ETH", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1734,6 +1751,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): All depositors are able to withdraw from the SP to their account", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, troveManager, stabilityPool } = contracts; + // Whale opens trove await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -1783,6 +1803,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): increases depositor's Bold token balance by the expected amount", async () => { + const { contracts, openTrove, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { boldToken, borrowerOperations, priceFeed, stabilityPool, troveManager } = contracts; + // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -1864,6 +1887,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact other users Stability deposits or ETH gains", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -1970,6 +1996,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact system debt, collateral or TCR ", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, defaultPool, priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -2054,6 +2083,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact any troves, including the caller's trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -2180,6 +2212,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): succeeds when amount is 0 and system has an undercollateralized trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100, 18)), ICR: toBN(dec(2, 18)), @@ -2240,6 +2275,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): withdrawing 0 Bold doesn't alter the caller's deposit or the total Bold in the Stability Pool", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { stabilityPool } = contracts; + // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2296,6 +2334,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): withdrawing 0 ETH Gain does not alter the caller's ETH balance, their trove collateral, or the ETH in the Stability Pool", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2379,6 +2420,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Request to withdraw > caller's deposit only withdraws the caller's compounded deposit", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2479,6 +2523,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Request to withdraw 2^256-1 Bold only withdraws the caller's compounded deposit", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2564,6 +2611,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): caller can withdraw full deposit and ETH gain during Recovery Mode", async () => { + const { contracts, openTrove, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Price doubles @@ -2762,6 +2812,9 @@ contract("StabilityPool", async (accounts) => { }); it("getDepositorETHGain(): depositor does not earn further ETH gains from liquidations while their compounded deposit == 0: ", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(1, 24)), ICR: toBN(dec(10, 18)), @@ -2870,6 +2923,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(), full withdrawal: zero's depositor's snapshots", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(1000000, 18)), ICR: toBN(dec(10, 18)), @@ -2978,6 +3034,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(), reverts when initial deposit value is 0", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -3039,6 +3098,9 @@ contract("StabilityPool", async (accounts) => { // --- withdrawETHGainToTrove --- it("withdrawETHGainToTrove(): reverts when user has no active deposit", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -3092,6 +3154,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): Applies BoldLoss to user's deposit, and redirects ETH reward to user's Trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -3182,6 +3247,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts if it would leave trove with ICR < MCR", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -3230,6 +3298,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero ETH", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -3301,6 +3372,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): decreases StabilityPool ETH and increases activePool ETH", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { activePool, priceFeed, stabilityPool, troveManager } = contracts; + // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -3374,6 +3448,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): All depositors are able to withdraw their ETH gain from the SP to their Trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -3434,6 +3511,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): All depositors withdraw, each withdraw their correct ETH gain", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { priceFeed, stabilityPool, troveManager } = contracts; + // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -3523,6 +3603,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): caller can withdraw full deposit and ETH gain to their trove during Recovery Mode", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { troveManager, sortedTroves, priceFeed, stabilityPool } = contracts; + // --- SETUP --- // Defaulter opens @@ -3617,6 +3700,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts if user has no trove", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, priceFeed, stabilityPool, troveManager, sortedTroves } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -3671,6 +3757,9 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts when depositor has no ETH gain", async () => { + const { contracts, openTrove } = await loadDeployAndFundFixture(); + const { boldToken, stabilityPool } = contracts; + await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index d74cb3d27..5acb9bd22 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -1,13 +1,18 @@ const { time } = require('@nomicfoundation/hardhat-network-helpers'); -const testHelpers = require("../utils/testHelpers.js"); +const { + MoneyValues: mv, + TestHelper: th, + TimeValues: timeValues, +} = require("../utils/testHelpers.js"); const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const assertRevert = th.assertRevert; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; +const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); + +const { + assertRevert, + dec, + toBN, +} = th; const GAS_PRICE = 10000000; @@ -46,42 +51,20 @@ contract("TroveManager", async (accounts) => { ] = accounts; const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { - afterConnect: async (contracts) => ({ - async getOpenTroveBoldAmount(totalDebt) { - return th.getOpenTroveBoldAmount(contracts, totalDebt); - }, - async getNetBorrowingAmount(debtWithFee) { - return th.getNetBorrowingAmount(contracts, debtWithFee); - }, - async openTrove(params) { - return th.openTrove(contracts, params); - }, - async withdrawBold(params) { - return th.withdrawBold(contracts, params); - }, - async getActualDebtFromComposite(compositeDebt) { - return th.getActualDebtFromComposite(compositeDebt, contracts); - }, - async getTroveEntireColl(trove) { - return th.getTroveEntireColl(contracts, trove); - }, - async getTroveEntireDebt(trove) { - return th.getTroveEntireDebt(contracts, trove); - }, - async getTroveStake(trove) { - return th.getTroveStake(contracts, trove); - }, - }), + afterDeploy: async (contracts) => { + contracts.troveManager = await TroveManagerTester.new(); + TroveManagerTester.setAsDeployed(contracts.troveManager); + } }); it("liquidate(): closes a Trove that has ICR < MCR", async () => { const { + contracts, getNetBorrowingAmount, openTrove, withdrawBold, - contracts, } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; + const { priceFeed, sortedTroves, troveManager } = contracts; await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -416,7 +399,7 @@ contract("TroveManager", async (accounts) => { ); assert.isTrue(await sortedTroves.contains(bobTroveId)); - th.logBN("bob icr", await troveManager.getCurrentICR(bob, await priceFeed.getPrice())); + // th.logBN("bob icr", await troveManager.getCurrentICR(bob, await priceFeed.getPrice())); // Bob now withdraws Bold, bringing his ICR to 1.11 const { increasedTotalDebt: B_increasedTotalDebt } = await withdrawBold({ ICR: toBN(dec(111, 16)), diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js index ebff274c2..7d5291b46 100644 --- a/contracts/utils/testFixtures.js +++ b/contracts/utils/testFixtures.js @@ -3,11 +3,12 @@ const deploymentHelper = require("./deploymentHelpers.js"); const { fundAccounts } = require("./fundAccounts.js"); const { TestHelper: th } = require("./testHelpers.js"); -// Returns a fixture utility to be called in every test. The only required parameter -// is the list of accounts to be funded. Callback parameters can be used to run code -// after the deployment and after the connection. They take the contracts as a -// parameter, which can be modified as needed. The returned object will be merged -// with the object returned by the fixture loader utility. +// Returns a fixture utility to be called in every test (it()). +// The only required parameter is the list of accounts to be funded. +// Callback parameters can be used to run code after the deployment +// and after the connection. They take the contracts as a parameter, +// which can be modified as needed. The returned object will be +// merged with the object returned by the fixture loader utility. function createDeployAndFundFixture(accounts, { afterDeploy = async () => null, afterConnect = async () => null, From 57b719af652805038616b0475b84d2a80d055c1c Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 8 Apr 2024 02:13:52 +0100 Subject: [PATCH 05/19] Fix failing tests by forcing a block to be mined after funding accounts --- contracts/utils/testFixtures.js | 83 +++++++++++++++++---------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js index 7d5291b46..2c2bc5517 100644 --- a/contracts/utils/testFixtures.js +++ b/contracts/utils/testFixtures.js @@ -1,4 +1,4 @@ -const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); +const { loadFixture, mine } = require("@nomicfoundation/hardhat-network-helpers"); const deploymentHelper = require("./deploymentHelpers.js"); const { fundAccounts } = require("./fundAccounts.js"); const { TestHelper: th } = require("./testHelpers.js"); @@ -9,56 +9,59 @@ const { TestHelper: th } = require("./testHelpers.js"); // and after the connection. They take the contracts as a parameter, // which can be modified as needed. The returned object will be // merged with the object returned by the fixture loader utility. -function createDeployAndFundFixture(accounts, { - afterDeploy = async () => null, - afterConnect = async () => null, +function createDeployAndFundFixture({ + accounts = [], + callback = async () => null, + mocks = {}, // e.g. { Contract: MockContract } } = {}) { const fixture = async () => { - const contracts = await deploymentHelper.deployLiquityCore(); - - const afterDeployResult = await afterDeploy(contracts); - - await deploymentHelper.deployBoldToken(contracts); + const contracts = await deploymentHelper.deployLiquityCore(mocks); await deploymentHelper.connectCoreContracts(contracts); - contracts.priceFeed = contracts.priceFeedTestnet; - const afterConnectResult = await afterConnect(contracts); + contracts.priceFeed = contracts.priceFeedTestnet; - if (!accounts) { - throw new Error("No accounts provided to the fixture"); - } await fundAccounts(accounts, contracts.WETH); + // Without forcing a block to be mined, the tests were sometimes + // failing due to the accounts not being funded. + await mine(); + + const helpers = { + getOpenTroveBoldAmount: async (totalDebt) => ( + th.getOpenTroveBoldAmount(contracts, totalDebt) + ), + getNetBorrowingAmount: async (debtWithFee) => ( + th.getNetBorrowingAmount(contracts, debtWithFee) + ), + openTrove: async (params) => ( + th.openTrove(contracts, params) + ), + withdrawBold: async (params) => ( + th.withdrawBold(contracts, params) + ), + getActualDebtFromComposite: async (compositeDebt) => ( + th.getActualDebtFromComposite(compositeDebt, contracts) + ), + getTroveEntireColl: async (trove) => ( + th.getTroveEntireColl(contracts, trove) + ), + getTroveEntireDebt: async (trove) => ( + th.getTroveEntireDebt(contracts, trove) + ), + getTroveStake: async (trove) => ( + th.getTroveStake(contracts, trove) + ), + }; + + const callbackResult = await callback(contracts); + return { contracts, - getOpenTroveBoldAmount: async (totalDebt) => { - return th.getOpenTroveBoldAmount(contracts, totalDebt); - }, - getNetBorrowingAmount: async (debtWithFee) => { - return th.getNetBorrowingAmount(contracts, debtWithFee); - }, - openTrove: async (params) => { - return th.openTrove(contracts, params); - }, - withdrawBold: async (params) => { - return th.withdrawBold(contracts, params); - }, - getActualDebtFromComposite: async (compositeDebt) => { - return th.getActualDebtFromComposite(compositeDebt, contracts); - }, - getTroveEntireColl: async (trove) => { - return th.getTroveEntireColl(contracts, trove); - }, - getTroveEntireDebt: async (trove) => { - return th.getTroveEntireDebt(contracts, trove); - }, - getTroveStake: async (trove) => { - return th.getTroveStake(contracts, trove); - }, - ...afterDeployResult, - ...afterConnectResult, + ...helpers, + ...callbackResult, }; }; + return () => loadFixture(fixture); } From 021eec5ecfdbd9e78236cafd0fc91fa58acdfe7b Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 8 Apr 2024 02:18:34 +0100 Subject: [PATCH 06/19] createDeployAndFundFixture(): allow to pass mock contracts This commit also adds the possibility to pass mocks to deployLiquityCoreHardhat() and deployBoldToken(). --- contracts/test/BorrowerOperationsTest.js | 13 ++- contracts/test/FeeArithmeticTest.js | 5 +- contracts/test/TroveManagerTest.js | 8 +- .../TroveManager_LiquidationRewardsTest.js | 9 +- contracts/utils/deploymentHelpers.js | 93 ++++++++++++------- 5 files changed, 77 insertions(+), 51 deletions(-) diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index 0d33df697..2d04fa402 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -31,14 +31,13 @@ contract("BorrowerOperations", async (accounts) => { frontEnd_3, ] = accounts; - const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 17), { - async afterDeploy(contracts) { - contracts.borrowerOperations = await BorrowerOperationsTester.new( - contracts.WETH.address, - ); - contracts.troveManager = await TroveManagerTester.new(); + const loadDeployAndFundFixture = createDeployAndFundFixture({ + accounts: accounts.slice(0, 17), + mocks: { + BorrowerOperations: BorrowerOperationsTester, + TroveManager: TroveManagerTester, }, - async afterConnect(contracts) { + callback: async (contracts) => { const { borrowerOperations } = contracts; return { BOLD_GAS_COMPENSATION: await borrowerOperations.BOLD_GAS_COMPENSATION(), diff --git a/contracts/test/FeeArithmeticTest.js b/contracts/test/FeeArithmeticTest.js index 0d28122e1..9d8c839aa 100644 --- a/contracts/test/FeeArithmeticTest.js +++ b/contracts/test/FeeArithmeticTest.js @@ -325,8 +325,9 @@ contract('Fee arithmetic tests', async accounts => { [919877008002166000, 85, 826094891277916], ] - const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { - afterDeploy: async () => { + const loadDeployAndFundFixture = createDeployAndFundFixture({ + accounts: accounts.slice(0, 20), + callback: async () => { const troveManagerTester = await TroveManagerTester.new() TroveManagerTester.setAsDeployed(troveManagerTester) diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index 5acb9bd22..37b34f75c 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -50,10 +50,10 @@ contract("TroveManager", async (accounts) => { E, ] = accounts; - const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { - afterDeploy: async (contracts) => { - contracts.troveManager = await TroveManagerTester.new(); - TroveManagerTester.setAsDeployed(contracts.troveManager); + const loadDeployAndFundFixture = createDeployAndFundFixture({ + accounts: accounts.slice(0, 20), + mocks: { + TroveManager: TroveManagerTester, } }); diff --git a/contracts/test/TroveManager_LiquidationRewardsTest.js b/contracts/test/TroveManager_LiquidationRewardsTest.js index 077c7bd7f..78682909c 100644 --- a/contracts/test/TroveManager_LiquidationRewardsTest.js +++ b/contracts/test/TroveManager_LiquidationRewardsTest.js @@ -34,10 +34,11 @@ contract( defaulter_4, ] = accounts; - const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { - async afterDeploy(contracts) { - contracts.troveManager = await TroveManagerTester.new(); - }, + const loadDeployAndFundFixture = createDeployAndFundFixture({ + accounts: accounts.slice(0, 20), + mocks: { + TroveManager: TroveManagerTester, + } }); it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { diff --git a/contracts/utils/deploymentHelpers.js b/contracts/utils/deploymentHelpers.js index 6ee7e8cfe..39e3f78bb 100644 --- a/contracts/utils/deploymentHelpers.js +++ b/contracts/utils/deploymentHelpers.js @@ -24,33 +24,58 @@ const { fundAccounts } = require("./fundAccounts.js"); const maxBytes32 = "0x" + "f".repeat(64); class DeploymentHelper { - static async deployLiquityCore() { - return await this.deployLiquityCoreHardhat(); + static async deployLiquityCore(mocks = {}) { + return await this.deployLiquityCoreHardhat(mocks); } - static async deployLiquityCoreHardhat() { + static async deployLiquityCoreHardhat(mocks = { + PriceFeed: PriceFeedMock, // PriceFeed gets a mock by default + }) { const WETH = await ERC20.new("WETH", "WETH"); - // Borrowing contracts - const activePool = await ActivePool.new(WETH.address); - const borrowerOperations = await BorrowerOperations.new(WETH.address); - const collSurplusPool = await CollSurplusPool.new(WETH.address); - const defaultPool = await DefaultPool.new(WETH.address); - const gasPool = await GasPool.new(); - const priceFeedTestnet = await PriceFeedTestnet.new(); - const priceFeed = await PriceFeedMock.new(); - const sortedTroves = await SortedTroves.new(); - const stabilityPool = await StabilityPool.new(WETH.address); - const troveManager = await TroveManager.new(); - const boldToken = await BoldToken.new( - troveManager.address, - stabilityPool.address, - borrowerOperations.address, - activePool.address + // Contracts, with mocks overriding defaults + const Contracts = Object.fromEntries( + Object.entries({ + ActivePool, + BorrowerOperations, + CollSurplusPool, + DefaultPool, + GasPool, + PriceFeedTestnet, + PriceFeedMock, + SortedTroves, + StabilityPool, + TroveManager, + BoldToken, + HintHelpers, + }) + .map(([name, contract]) => [ + name, + mocks[name] ?? contract + ]) ); - const mockInterestRouter = await MockInterestRouter.new(); - const hintHelpers = await HintHelpers.new(); + // Borrowing contracts + const activePool = await Contracts.ActivePool.new(WETH.address); + const borrowerOperations = await Contracts.BorrowerOperations.new(WETH.address); + const collSurplusPool = await Contracts.CollSurplusPool.new(WETH.address); + const defaultPool = await Contracts.DefaultPool.new(WETH.address); + const gasPool = await Contracts.GasPool.new(); + const priceFeedTestnet = await Contracts.PriceFeedTestnet.new(); + const priceFeed = await Contracts.PriceFeedMock.new(); + const sortedTroves = await Contracts.SortedTroves.new(); + const stabilityPool = await Contracts.StabilityPool.new(WETH.address); + const troveManager = await Contracts.TroveManager.new(); + + const { boldToken } = await this.deployBoldToken({ + troveManager, + stabilityPool, + borrowerOperations, + activePool, + }, Contracts.BoldToken) + + const mockInterestRouter = await MockInterestRouter.new(); + const hintHelpers = await Contracts.HintHelpers.new(); // // Needed? // const price = await priceFeed.getPrice(); @@ -63,17 +88,17 @@ class DeploymentHelper { // TODO: setAsDeployed all above? - BoldToken.setAsDeployed(boldToken); - DefaultPool.setAsDeployed(defaultPool); - PriceFeedTestnet.setAsDeployed(priceFeedTestnet); - SortedTroves.setAsDeployed(sortedTroves); - TroveManager.setAsDeployed(troveManager); - ActivePool.setAsDeployed(activePool); - StabilityPool.setAsDeployed(stabilityPool); - GasPool.setAsDeployed(gasPool); - CollSurplusPool.setAsDeployed(collSurplusPool); - BorrowerOperations.setAsDeployed(borrowerOperations); - HintHelpers.setAsDeployed(hintHelpers); + Contracts.BoldToken.setAsDeployed(boldToken); + Contracts.DefaultPool.setAsDeployed(defaultPool); + Contracts.PriceFeedTestnet.setAsDeployed(priceFeedTestnet); + Contracts.SortedTroves.setAsDeployed(sortedTroves); + Contracts.TroveManager.setAsDeployed(troveManager); + Contracts.ActivePool.setAsDeployed(activePool); + Contracts.StabilityPool.setAsDeployed(stabilityPool); + Contracts.GasPool.setAsDeployed(gasPool); + Contracts.CollSurplusPool.setAsDeployed(collSurplusPool); + Contracts.BorrowerOperations.setAsDeployed(borrowerOperations); + Contracts.HintHelpers.setAsDeployed(hintHelpers); MockInterestRouter.setAsDeployed(mockInterestRouter); const coreContracts = { @@ -94,8 +119,8 @@ class DeploymentHelper { return coreContracts; } - static async deployBoldToken(contracts) { - contracts.boldToken = await BoldToken.new( + static async deployBoldToken(contracts, MockedBoldToken = BoldToken) { + contracts.boldToken = await MockedBoldToken.new( contracts.troveManager.address, contracts.stabilityPool.address, contracts.borrowerOperations.address, From 13fc17f8b4dba8dd0c4236d3854988c837df09f0 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 8 Apr 2024 02:21:47 +0100 Subject: [PATCH 07/19] StabilityPoolTest: move back to forEach() But still using fixtures. --- contracts/test/StabilityPoolTest.js | 185 +++++----------------------- 1 file changed, 32 insertions(+), 153 deletions(-) diff --git a/contracts/test/StabilityPoolTest.js b/contracts/test/StabilityPoolTest.js index b02d09b9c..d637dec4f 100644 --- a/contracts/test/StabilityPoolTest.js +++ b/contracts/test/StabilityPoolTest.js @@ -6,11 +6,7 @@ const { } = require("../utils/testHelpers.js"); const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); -const { - assertRevert, - dec, - toBN, -} = th; +const { dec, toBN } = th; const TroveManagerTester = artifacts.require("TroveManagerTester"); const NonPayableSwitch = artifacts.require("NonPayableSwitch.sol"); @@ -53,21 +49,45 @@ contract("StabilityPool", async (accounts) => { const frontEnds = [frontEnd_1, frontEnd_2, frontEnd_3]; - const loadDeployAndFundFixture = createDeployAndFundFixture(accounts.slice(0, 20), { - afterDeploy: async (contracts) => { - contracts.troveManager = await TroveManagerTester.new(); - TroveManagerTester.setAsDeployed(contracts.troveManager); + let contracts; + let priceFeed; + let boldToken; + let sortedTroves; + let troveManager; + let activePool; + let stabilityPool; + let defaultPool; + let borrowerOperations; + + const getOpenTroveBoldAmount = async (totalDebt) => + th.getOpenTroveBoldAmount(contracts, totalDebt); + const openTrove = async (params) => th.openTrove(contracts, params); + const assertRevert = th.assertRevert; + + const deployFixture = createDeployAndFundFixture({ + accounts: accounts.slice(0, 20), + mocks: { + TroveManager: TroveManagerTester, } }); describe("Stability Pool Mechanisms", async () => { + beforeEach(async () => { + const f = await deployFixture(); + contracts = f.contracts; + priceFeed = contracts.priceFeed; + boldToken = contracts.boldToken; + sortedTroves = contracts.sortedTroves; + troveManager = contracts.troveManager; + activePool = contracts.activePool; + stabilityPool = contracts.stabilityPool; + defaultPool = contracts.defaultPool; + borrowerOperations = contracts.borrowerOperations; + }); // --- provideToSP() --- // increases recorded Bold at Stability Pool it("provideToSP(): increases the Stability Pool Bold balance", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -87,9 +107,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): updates the user's deposit record in StabilityPool", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -113,9 +130,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reduces the user's Bold balance by the correct amount", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, stabilityPool } = contracts; - // --- SETUP --- Give Alice a least 200 await openTrove({ extraBoldAmount: toBN(200), @@ -139,9 +153,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): increases totalBoldDeposits by correct amount", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - // --- SETUP --- // Whale opens Trove with 50 ETH, adds 2000 Bold to StabilityPool @@ -159,9 +170,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): Correctly updates user snapshots of accumulated rewards per unit staked", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale opens Trove and deposits to SP @@ -235,9 +243,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), multiple deposits: updates user's deposit and snapshots", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale opens Trove and deposits to SP await openTrove({ @@ -355,9 +360,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if user tries to provide more than their Bold balance", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -395,9 +397,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if user tries to provide 2^256-1 Bold, which exceeds their balance", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -430,9 +429,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts if cannot receive ETH Gain", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, troveManager, priceFeed, stabilityPool } = contracts; - // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -504,9 +500,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact other users' deposits or ETH gains", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -632,9 +625,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact system debt, collateral or TCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, defaultPool, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -724,9 +714,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't impact any troves, including the caller's trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, priceFeed, stabilityPool } = contracts; - const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -873,9 +860,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): doesn't protect the depositor's trove from liquidation", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -928,9 +912,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): providing 0 Bold reverts", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -979,9 +960,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), new deposit: depositor does not receive ETH gains", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1058,9 +1036,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(), new deposit after past full withdrawal: depositor does not receive ETH gains", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1174,9 +1149,6 @@ contract("StabilityPool", async (accounts) => { }); it("provideToSP(): reverts when amount is zero", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1224,9 +1196,6 @@ contract("StabilityPool", async (accounts) => { // --- withdrawFromSP --- it("withdrawFromSP(): reverts when user has no active deposit", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100, 18)), ICR: toBN(dec(2, 18)), @@ -1271,9 +1240,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): partial retrieval - retrieves correct Bold amount and the entire ETH Gain, and updates deposit", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1369,9 +1335,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): partial retrieval - leaves the correct amount of Bold in the Stability Pool", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1443,9 +1406,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): full retrieval - leaves the correct amount of Bold in the Stability Pool", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1537,9 +1497,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero ETH", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -1614,9 +1571,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): it correctly updates the user's Bold and ETH snapshots of entitled reward per unit staked", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1678,9 +1632,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): decreases StabilityPool ETH", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -1751,9 +1702,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): All depositors are able to withdraw from the SP to their account", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, stabilityPool } = contracts; - // Whale opens trove await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -1803,9 +1751,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): increases depositor's Bold token balance by the expected amount", async () => { - const { contracts, openTrove, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, priceFeed, stabilityPool, troveManager } = contracts; - // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -1887,9 +1832,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact other users Stability deposits or ETH gains", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -1996,9 +1938,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact system debt, collateral or TCR ", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, defaultPool, priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -2083,9 +2022,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): doesn't impact any troves, including the caller's trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -2212,9 +2148,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): succeeds when amount is 0 and system has an undercollateralized trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100, 18)), ICR: toBN(dec(2, 18)), @@ -2275,9 +2208,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): withdrawing 0 Bold doesn't alter the caller's deposit or the total Bold in the Stability Pool", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { stabilityPool } = contracts; - // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2334,9 +2264,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): withdrawing 0 ETH Gain does not alter the caller's ETH balance, their trove collateral, or the ETH in the Stability Pool", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2420,9 +2347,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Request to withdraw > caller's deposit only withdraws the caller's compounded deposit", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2523,9 +2447,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): Request to withdraw 2^256-1 Bold only withdraws the caller's compounded deposit", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -2611,9 +2532,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(): caller can withdraw full deposit and ETH gain during Recovery Mode", async () => { - const { contracts, openTrove, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Price doubles @@ -2812,9 +2730,6 @@ contract("StabilityPool", async (accounts) => { }); it("getDepositorETHGain(): depositor does not earn further ETH gains from liquidations while their compounded deposit == 0: ", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(1, 24)), ICR: toBN(dec(10, 18)), @@ -2923,9 +2838,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(), full withdrawal: zero's depositor's snapshots", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(1000000, 18)), ICR: toBN(dec(10, 18)), @@ -3034,9 +2946,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawFromSP(), reverts when initial deposit value is 0", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -3098,9 +3007,6 @@ contract("StabilityPool", async (accounts) => { // --- withdrawETHGainToTrove --- it("withdrawETHGainToTrove(): reverts when user has no active deposit", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, stabilityPool, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), @@ -3154,9 +3060,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): Applies BoldLoss to user's deposit, and redirects ETH reward to user's Trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -3247,9 +3150,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts if it would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -3298,9 +3198,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): Subsequent deposit and withdrawal attempt from same account, with no intermediate liquidations, withdraws zero ETH", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 1850 Bold in StabilityPool await openTrove({ @@ -3372,9 +3269,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): decreases StabilityPool ETH and increases activePool ETH", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, priceFeed, stabilityPool, troveManager } = contracts; - // --- SETUP --- // Whale deposits 185000 Bold in StabilityPool await openTrove({ @@ -3448,9 +3342,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): All depositors are able to withdraw their ETH gain from the SP to their Trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -3511,9 +3402,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): All depositors withdraw, each withdraw their correct ETH gain", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, stabilityPool, troveManager } = contracts; - // Whale opens trove await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), @@ -3603,9 +3491,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): caller can withdraw full deposit and ETH gain to their trove during Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, sortedTroves, priceFeed, stabilityPool } = contracts; - // --- SETUP --- // Defaulter opens @@ -3700,9 +3585,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts if user has no trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, stabilityPool, troveManager, sortedTroves } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -3757,9 +3639,6 @@ contract("StabilityPool", async (accounts) => { }); it("withdrawETHGainToTrove(): reverts when depositor has no ETH gain", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, stabilityPool } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(10, 18)), From 21a899fa401f32fe79cd4928f7169ead85c967cb Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 8 Apr 2024 23:30:36 +0100 Subject: [PATCH 08/19] fundAccounts(): make sure its promises are awaited I suspect this was the root cause for the finicky tests. --- contracts/test/BorrowerOperationsTest.js | 504 ++++------------------- contracts/utils/fundAccounts.js | 11 +- 2 files changed, 78 insertions(+), 437 deletions(-) diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index 2d04fa402..8180b843d 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -11,6 +11,8 @@ const toBN = th.toBN; const assertRevert = th.assertRevert; contract("BorrowerOperations", async (accounts) => { + const accountsToFund = accounts.slice(0, 17); + const [ owner, alice, @@ -29,48 +31,79 @@ contract("BorrowerOperations", async (accounts) => { frontEnd_1, frontEnd_2, frontEnd_3, - ] = accounts; - - const loadDeployAndFundFixture = createDeployAndFundFixture({ - accounts: accounts.slice(0, 17), + ] = accountsToFund; + + let contracts + + let priceFeed; + let boldToken; + let sortedTroves; + let troveManager; + let activePool; + let defaultPool; + let borrowerOperations; + + let BOLD_GAS_COMPENSATION; + let MIN_NET_DEBT; + let BORROWING_FEE_FLOOR; + + const getOpenTroveBoldAmount = async (totalDebt) => + th.getOpenTroveBoldAmount(contracts, totalDebt); + const getNetBorrowingAmount = async (debtWithFee) => + th.getNetBorrowingAmount(contracts, debtWithFee); + const getActualDebtFromComposite = async (compositeDebt) => + th.getActualDebtFromComposite(compositeDebt, contracts); + const openTrove = async (params) => th.openTrove(contracts, params); + const getTroveEntireColl = async (trove) => + th.getTroveEntireColl(contracts, trove); + const getTroveEntireDebt = async (trove) => + th.getTroveEntireDebt(contracts, trove); + const getTroveStake = async (trove) => th.getTroveStake(contracts, trove); + + const deployFixture = createDeployAndFundFixture({ + accounts: accountsToFund, mocks: { BorrowerOperations: BorrowerOperationsTester, TroveManager: TroveManagerTester, }, callback: async (contracts) => { const { borrowerOperations } = contracts; + const [ + BOLD_GAS_COMPENSATION, + MIN_NET_DEBT, + BORROWING_FEE_FLOOR, + ] = await Promise.all([ + borrowerOperations.BOLD_GAS_COMPENSATION(), + borrowerOperations.MIN_NET_DEBT(), + borrowerOperations.BORROWING_FEE_FLOOR(), + ]); return { - BOLD_GAS_COMPENSATION: await borrowerOperations.BOLD_GAS_COMPENSATION(), - MIN_NET_DEBT: await borrowerOperations.MIN_NET_DEBT(), - BORROWING_FEE_FLOOR: await borrowerOperations.BORROWING_FEE_FLOOR(), - - async getOpenTroveBoldAmount(totalDebt) { - return th.getOpenTroveBoldAmount(contracts, totalDebt); - }, - async getNetBorrowingAmount(debtWithFee) { - return th.getNetBorrowingAmount(contracts, debtWithFee); - }, - async openTrove(params) { - return th.openTrove(contracts, params); - }, - async getTroveEntireColl(trove) { - return th.getTroveEntireColl(contracts, trove); - }, - async getTroveEntireDebt(trove) { - return th.getTroveEntireDebt(contracts, trove); - }, - async getTroveStake(trove) { - return th.getTroveStake(contracts, trove); - }, - }; + BOLD_GAS_COMPENSATION, + MIN_NET_DEBT, + BORROWING_FEE_FLOOR, + } }, }); + beforeEach(async () => { + const result = await deployFixture() + + contracts = result.contracts + priceFeed = contracts.priceFeedTestnet + boldToken = contracts.boldToken + sortedTroves = contracts.sortedTroves + troveManager = contracts.troveManager + activePool = contracts.activePool + defaultPool = contracts.defaultPool + borrowerOperations = contracts.borrowerOperations + + BOLD_GAS_COMPENSATION = result.BOLD_GAS_COMPENSATION + MIN_NET_DEBT = result.MIN_NET_DEBT + BORROWING_FEE_FLOOR = result.BORROWING_FEE_FLOOR + }); + const testCorpus = () => { it("addColl(): reverts when top-up would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -96,9 +129,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(): Increases the activePool ETH and raw ether balance by correct amount", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool } = contracts; - const { collateral: aliceColl } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice }, @@ -130,9 +160,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: adds the correct collateral amount to the Trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -159,9 +186,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: Trove is in sortedList before and after", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { sortedTroves } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -184,9 +208,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: updates the stake and updates the total stakes", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - // Alice creates initial Trove with 1 ether const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -216,9 +237,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(), active Trove: applies pending rewards and updates user's L_ETH, L_boldDebt snapshots", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: aliceCollBefore, totalDebt: aliceDebtBefore } = @@ -386,9 +404,6 @@ contract("BorrowerOperations", async (accounts) => { // }) it("addColl(), reverts if trove is non-existent or closed", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, troveManager } = contracts; - // A, B open troves await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -427,9 +442,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("addColl(): can add collateral in Recovery Mode", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(aliceTroveId); assert.isFalse(await th.checkRecoveryMode(contracts)); @@ -452,9 +464,6 @@ contract("BorrowerOperations", async (accounts) => { // --- withdrawColl() --- it("withdrawColl(): reverts when withdrawal would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -478,9 +487,6 @@ contract("BorrowerOperations", async (accounts) => { // reverts when calling address does not have active trove it("withdrawColl(): reverts when calling address does not have active trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -514,9 +520,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - 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 } }); @@ -546,9 +549,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when requested ETH withdrawal is > the trove's collateral", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); 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 } }); @@ -577,9 +577,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts when withdrawal would bring the user's ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); // 110% ICR @@ -597,9 +594,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reverts if system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - // --- SETUP --- // A and B open troves at 150% ICR @@ -628,9 +622,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): doesn’t allow a user to completely withdraw all collateral from their Trove (due to gas compensation)", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, sortedTroves, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -652,9 +643,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): leaves the Trove active when the user withdraws less than all the collateral", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, sortedTroves, troveManager } = contracts; - // Open Trove const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -677,9 +665,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reduces the Trove's collateral by the correct amount", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(aliceTroveId); @@ -698,9 +683,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): reduces ActivePool ETH and raw ether by correct amount", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const aliceCollBefore = await getTroveEntireColl(aliceTroveId); @@ -732,9 +714,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): updates the stake and updates the total stakes", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, troveManager } = contracts; - // Alice creates initial Trove with 2 ether const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -769,9 +748,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): sends the correct amount of ETH to the user", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice, value: dec(2, "ether") }, @@ -794,9 +770,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawColl(): applies pending rewards and updates user's L_ETH, L_boldDebt snapshots", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - // --- SETUP --- // Alice adds 15 ether, Bob adds 5 ether, Carol adds 1 ether await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -932,9 +905,6 @@ contract("BorrowerOperations", async (accounts) => { // --- withdrawBold() --- it("withdrawBold(): reverts when withdrawal would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -962,9 +932,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when calling address does not have active trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -992,9 +959,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when requested withdrawal amount is zero Bold", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - 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 } }); @@ -1022,9 +986,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - 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 } }); @@ -1059,9 +1020,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when withdrawal would bring the trove's ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(11, 17)), extraParams: { from: bob } }); @@ -1080,9 +1038,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts when a withdrawal would cause the TCR of the system to fall below the CCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); const price = await priceFeed.getPrice(); @@ -1109,9 +1064,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): reverts if system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - // --- SETUP --- const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: bob } }); @@ -1136,9 +1088,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases the Trove's Bold debt by the correct amount", async () => { - const { contracts, getNetBorrowingAmount, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); // check before @@ -1161,9 +1110,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases Bold debt in ActivePool by correct amount", async () => { - const { contracts, getNetBorrowingAmount, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice, value: toBN(dec(100, "ether")) }, @@ -1192,9 +1138,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("withdrawBold(): increases user BoldToken balance by correct amount", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraParams: { value: toBN(dec(100, "ether")), from: alice }, }); @@ -1221,9 +1164,6 @@ contract("BorrowerOperations", async (accounts) => { // --- repayBold() --- it("repayBold(): reverts when repayment would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -1248,9 +1188,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): Succeeds when it would leave trove with net debt >= minimum net debt", async () => { - const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - // Make the Bold request 2 wei above min net debt to correct for floor division, and make net debt = min net debt + 1 wei const ATroveId = await th.openTroveWrapper(contracts, th._100pct, @@ -1276,9 +1213,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when it would leave trove with net debt < minimum net debt", async () => { - const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, troveManager } = contracts; - // Open the trove with min debt + 1 wei const ATroveId = await th.openTroveWrapper(contracts, th._100pct, @@ -1304,9 +1238,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if repaid amount is greater than current debt", async () => { - const { BOLD_GAS_COMPENSATION, contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - const { troveId: aliceTroveId, totalDebt } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -1336,9 +1267,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when calling address does not have active trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1369,9 +1297,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): reverts when attempted repayment is > the debt of the trove", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1405,9 +1330,6 @@ contract("BorrowerOperations", async (accounts) => { //repayBold: reduces Bold debt in Trove it("repayBold(): reduces the Trove's Bold debt by the correct amount", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1437,9 +1359,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases Bold debt in ActivePool by correct amount", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1472,9 +1391,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): decreases user BoldToken balance by correct amount", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1507,9 +1423,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): can repay debt in Recovery Mode", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1545,9 +1458,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("repayBold(): Reverts if borrower has insufficient Bold balance to cover his debt repayment", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1586,9 +1496,6 @@ contract("BorrowerOperations", async (accounts) => { // --- adjustTrove() --- it("adjustTrove(): reverts when adjustment would leave trove with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: bob } }); @@ -1622,9 +1529,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when calling address has no active trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1670,9 +1574,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts in Recovery Mode when the adjustment would reduce the TCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1755,9 +1656,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): collateral withdrawal reverts in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1791,9 +1689,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would leave ICR < 150% reverts in Recovery Mode", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -1846,9 +1741,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): debt increase that would reduce the ICR reverts in Recovery Mode", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), @@ -1942,9 +1834,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): A trove with ICR < CCR in Recovery Mode can adjust their trove to ICR > CCR", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2000,9 +1889,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): A trove with ICR > CCR in Recovery Mode can improve their ICR", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(3, 18)), @@ -2058,9 +1944,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when change would cause the TCR of the system to fall below the CCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(15, 17)), extraParams: { from: alice } }); @@ -2089,9 +1972,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when Bold repaid is > debt of the trove", async () => { - const { BOLD_GAS_COMPENSATION, contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, troveManager } = contracts; - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); @@ -2123,9 +2003,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when attempted ETH withdrawal is >= the trove's collateral", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: bob } }); const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); @@ -2150,9 +2027,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): reverts when change would cause the ICR of the trove to fall below the MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(100, 18)), @@ -2193,9 +2067,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 coll change, doesnt change borrower's coll or ActivePool coll", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2227,9 +2098,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): With 0 debt change, doesnt change borrower's debt or ActivePool debt", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -2263,15 +2131,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with an increase in both", async () => { - const { - contracts, - getNetBorrowingAmount, - getTroveEntireColl, - getTroveEntireDebt, - openTrove, - } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2318,9 +2177,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with a decrease in both", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2357,9 +2213,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with coll increase, debt decrease", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2406,10 +2259,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's debt and coll with coll decrease, debt increase", async () => { - const { contracts, getNetBorrowingAmount, getTroveEntireColl, getTroveEntireDebt, openTrove } = - await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2454,9 +2303,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's stake and totalStakes with a coll increase", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2497,9 +2343,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): updates borrower's stake and totalStakes with a coll decrease", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2538,9 +2381,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): changes BoldToken balance by the requested decrease", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2577,9 +2417,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): changes BoldToken balance by the requested increase", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2618,9 +2455,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the activePool ETH and raw ether balance by the requested decrease", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2666,9 +2500,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the activePool ETH and raw ether balance by the amount of ETH sent", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2716,9 +2547,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the Bold debt in ActivePool by requested decrease", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2756,9 +2584,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Changes the Bold debt in ActivePool by requested increase", async () => { - const { contracts, getNetBorrowingAmount, openTrove } = await loadDeployAndFundFixture(); - const { activePool, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2795,9 +2620,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): new coll = 0 and new debt = 0 is not allowed, as gas compensation still counts toward ICR", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2832,9 +2654,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if requested debt increase and amount is zero", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2855,9 +2674,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if it’s zero adjustment", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const { troveId: aliceTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2873,9 +2689,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if requested coll withdrawal is greater than trove's collateral", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2915,9 +2728,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("adjustTrove(): Reverts if borrower has insufficient Bold balance to cover his debt repayment", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -2955,9 +2765,6 @@ contract("BorrowerOperations", async (accounts) => { // no need to test this with proxies it("Internal _adjustTrove(): reverts when op is a withdrawal and _borrower param is not the msg.sender", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -3010,9 +2817,6 @@ contract("BorrowerOperations", async (accounts) => { // --- closeTrove() --- it("closeTrove(): reverts when it would lower the TCR below CCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, priceFeed, troveManager } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(300, 16)), extraParams: { from: alice }, @@ -3037,9 +2841,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts when calling address does not have active trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -3061,9 +2862,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts when system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, priceFeed } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(100000, 18)), ICR: toBN(dec(2, 18)), @@ -3104,9 +2902,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces a Trove's collateral to zero", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3137,9 +2932,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces a Trove's debt to zero", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3170,9 +2962,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): sets Trove's stake to zero", async () => { - const { contracts, getTroveStake, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3206,9 +2995,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): zero's the troves reward snapshots", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // Dennis opens trove and transfers tokens to alice await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -3293,9 +3079,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): sets trove's status to closed and removes it from sorted troves list", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, sortedTroves, troveManager } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3331,9 +3114,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces ActivePool ETH and raw ether by correct amount", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { activePool, boldToken, borrowerOperations } = contracts; - const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3377,9 +3157,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reduces ActivePool debt by correct amount", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { activePool, boldToken, borrowerOperations } = contracts; - const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3415,9 +3192,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): updates the the total stakes", async () => { - const { contracts, getTroveStake, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, troveManager } = contracts; - const { troveId: dennisTroveId } = await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3470,9 +3244,6 @@ contract("BorrowerOperations", async (accounts) => { // TODO: wrap contracts.WETH.balanceOf to be able to go through proxies it("closeTrove(): sends the correct amount of ETH to the user", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3507,9 +3278,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): subtracts the debt of the closed Trove from the Borrower's BoldToken balance", async () => { - const { BOLD_GAS_COMPENSATION, contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(2, 18)), @@ -3544,9 +3312,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): applies pending rewards", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, defaultPool, priceFeed, troveManager } = contracts; - // --- SETUP --- const { troveId: whaleTroveId } = await openTrove({ extraBoldAmount: toBN(dec(1000000, 18)), @@ -3683,9 +3448,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("closeTrove(): reverts if borrower has insufficient Bold balance to repay his entire debt", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), @@ -3719,9 +3481,6 @@ contract("BorrowerOperations", async (accounts) => { // TODO: use rawLogs instead of logs it("openTrove(): emits a TroveUpdated event with the correct collateral and debt", async () => { - const { contracts, getTroveEntireColl, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const { troveId: ATroveId, tx: txA } = await openTrove({ extraBoldAmount: toBN(dec(15000, 18)), ICR: toBN(dec(2, 18)), @@ -3820,9 +3579,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Opens a trove with net debt >= minimum net debt", async () => { - const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const { sortedTroves } = contracts; - // Add 1 wei to correct for rounding error in helper function const ATroveId = await th.openTroveWrapper(contracts, th._100pct, @@ -3846,8 +3602,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts if net debt < minimum net debt", async () => { - const { MIN_NET_DEBT, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const txAPromise = th.openTroveWrapper(contracts, th._100pct, 0, A, A, 0, { from: A, value: dec(100, 30), @@ -3876,9 +3630,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when system is in Recovery Mode and ICR < CCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), @@ -3910,9 +3661,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when trove ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await openTrove({ extraBoldAmount: toBN(dec(5000, 18)), ICR: toBN(dec(2, 18)), @@ -3959,9 +3707,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts when opening the trove would cause the TCR of the system to fall below the CCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); // Alice creates trove with 150% ICR. System TCR = 150%. @@ -3989,8 +3734,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts if trove is already active", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), ICR: toBN(dec(10, 18)), @@ -4033,9 +3776,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Can open a trove with ICR == CCR when system is in Recovery Mode", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- // Alice and Bob add coll and withdraw such that the TCR is ~150% await openTrove({ @@ -4077,9 +3817,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Reverts opening a trove with min debt when system is in Recovery Mode", async () => { - const { MIN_NET_DEBT, contracts, getNetBorrowingAmount, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - // --- SETUP --- // Alice and Bob add coll and withdraw such that the TCR is ~150% await openTrove({ @@ -4114,15 +3851,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): creates a new Trove and assigns the correct collateral and debt amount", async () => { - const { - BOLD_GAS_COMPENSATION, - MIN_NET_DEBT, - contracts, - getTroveEntireColl, - getTroveEntireDebt, - } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - /* const debt_Before = await getTroveEntireDebt(aliceTroveId); const coll_Before = await getTroveEntireColl(aliceTroveId); @@ -4160,9 +3888,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): adds Trove owner to TroveIds array", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const TroveIdsCount_Before = ( await troveManager.getTroveIdsCount() ).toString(); @@ -4181,9 +3906,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): creates a stake and adds it to total stakes", async () => { - const { contracts, getTroveEntireColl, getTroveStake, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - //const aliceStakeBefore = await getTroveStake(aliceTroveId); const totalStakesBefore = await troveManager.totalStakes(); @@ -4206,9 +3928,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): inserts Trove to Sorted Troves list", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { sortedTroves } = contracts; - // Check before //const aliceTroveInList_Before = await sortedTroves.contains(aliceTroveId); const listIsEmpty_Before = await sortedTroves.isEmpty(); @@ -4229,9 +3948,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): Increases the activePool ETH and raw ether balance by correct amount", async () => { - const { contracts, getTroveEntireColl, openTrove } = await loadDeployAndFundFixture(); - const { activePool } = contracts; - const activePool_ETH_Before = await activePool.getETHBalance(); const activePool_RawEther_Before = await contracts.WETH.balanceOf( activePool.address @@ -4255,9 +3971,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): records up-to-date initial snapshots of L_ETH and L_boldDebt", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager } = contracts; - // --- SETUP --- await openTrove({ @@ -4312,9 +4025,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): allows a user to open a Trove, then close it, then re-open it", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, sortedTroves, troveManager } = contracts; - // Open Troves await openTrove({ extraBoldAmount: toBN(dec(10000, 18)), @@ -4366,9 +4076,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases the Trove's Bold debt by the correct amount", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - // check before const alice_Trove_Before = await troveManager.Troves(th.addressToTroveId(alice)); const debt_Before = alice_Trove_Before[0]; @@ -4390,9 +4097,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases Bold debt in ActivePool by the debt of the trove", async () => { - const { contracts, getTroveEntireDebt, openTrove } = await loadDeployAndFundFixture(); - const { activePool } = contracts; - const activePool_BoldDebt_Before = await activePool.getRecordedDebtSum(); assert.equal(activePool_BoldDebt_Before, 0); @@ -4409,9 +4113,6 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): increases user BoldToken balance by correct amount", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { boldToken } = contracts; - // check before const alice_BoldTokenBalance_Before = await boldToken.balanceOf(alice); assert.equal(alice_BoldTokenBalance_Before, 0); @@ -4435,9 +4136,6 @@ contract("BorrowerOperations", async (accounts) => { describe("getNewICRFromTroveChange() returns the correct ICR", async () => { // 0, 0 it("collChange = 0, debtChange = 0", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4460,9 +4158,6 @@ contract("BorrowerOperations", async (accounts) => { // 0, +ve it("collChange = 0, debtChange is positive", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4485,9 +4180,6 @@ contract("BorrowerOperations", async (accounts) => { // 0, -ve it("collChange = 0, debtChange is negative", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4510,9 +4202,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, 0 it("collChange is positive, debtChange is 0", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4535,9 +4224,6 @@ contract("BorrowerOperations", async (accounts) => { // -ve, 0 it("collChange is negative, debtChange is 0", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4560,9 +4246,6 @@ contract("BorrowerOperations", async (accounts) => { // -ve, -ve it("collChange is negative, debtChange is negative", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4585,9 +4268,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, +ve it("collChange is positive, debtChange is positive", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4610,9 +4290,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, -ve it("collChange is positive, debtChange is negative", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4635,9 +4312,6 @@ contract("BorrowerOperations", async (accounts) => { // -ve, +ve it("collChange is negative, debtChange is positive", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed } = contracts; - price = await priceFeed.getPrice(); const initialColl = dec(1, "ether"); const initialDebt = dec(100, 18); @@ -4662,9 +4336,6 @@ contract("BorrowerOperations", async (accounts) => { // --- getCompositeDebt --- it("getCompositeDebt(): returns debt + gas comp", async () => { - const { BOLD_GAS_COMPENSATION, contracts } = await loadDeployAndFundFixture(); - const { borrowerOperations } = contracts; - const res1 = await borrowerOperations.getCompositeDebt("0"); assert.equal(res1, BOLD_GAS_COMPENSATION.toString()); @@ -4688,9 +4359,6 @@ contract("BorrowerOperations", async (accounts) => { describe("getNewTCRFromTroveChange() returns the correct TCR", async () => { // 0, 0 it("collChange = 0, debtChange = 0", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -4717,7 +4385,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -4749,9 +4417,6 @@ contract("BorrowerOperations", async (accounts) => { // 0, +ve it("collChange = 0, debtChange is positive", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -4779,7 +4444,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -4811,9 +4476,6 @@ contract("BorrowerOperations", async (accounts) => { // 0, -ve it("collChange = 0, debtChange is negative", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -4841,7 +4503,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -4873,9 +4535,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, 0 it("collChange is positive, debtChange = 0", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -4902,7 +4561,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -4934,9 +4593,6 @@ contract("BorrowerOperations", async (accounts) => { // -ve, 0 it("collChange is negative, debtChange = 0", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -4964,7 +4620,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -4996,9 +4652,6 @@ contract("BorrowerOperations", async (accounts) => { // -ve, -ve it("collChange is negative, debtChange is negative", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -5026,7 +4679,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -5058,9 +4711,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, +ve it("collChange is positive, debtChange is positive", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -5088,7 +4738,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -5120,9 +4770,6 @@ contract("BorrowerOperations", async (accounts) => { // +ve, -ve it("collChange is positive, debtChange is negative", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -5150,7 +4797,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -5182,9 +4829,6 @@ contract("BorrowerOperations", async (accounts) => { // ive, +ve it("collChange is negative, debtChange is positive", async () => { - const { contracts, getNetBorrowingAmount, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // --- SETUP --- Create a Liquity instance with an Active Pool and pending rewards (Default Pool) const bobColl = toBN(dec(1000, "ether")); const whaleColl = toBN(dec(10000, "ether")); @@ -5212,7 +4856,7 @@ contract("BorrowerOperations", async (accounts) => { ); const liqPrice = th.toBN(dec(100,18)) - th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) + // th.logBN("Bob ICR before liq", await troveManager.getCurrentICR(bob, liqPrice)) await priceFeed.setPrice(liqPrice); // Confirm we are in Normal Mode assert.isFalse(await troveManager.checkRecoveryMode(liqPrice)) @@ -5244,9 +4888,7 @@ contract("BorrowerOperations", async (accounts) => { }); }; - describe("Test", async () => { - testCorpus(); - }); + testCorpus(); }); contract("Reset chain state", async (accounts) => {}); diff --git a/contracts/utils/fundAccounts.js b/contracts/utils/fundAccounts.js index e8f689f16..e80a18198 100644 --- a/contracts/utils/fundAccounts.js +++ b/contracts/utils/fundAccounts.js @@ -1,15 +1,14 @@ -const _1e36Str = "1000000000000000000000000000000000000"; - const fundAccounts = async (accounts, token) => { // const areAccountsAlreadyFunded = await token // .balanceOf(accounts[0]) // .gte(_1e36Str); // if (areAccountsAlreadyFunded) return; - // console.log("Funding accounts with stETH"); - return accounts.forEach(async (account) => { - await token.mint(account, _1e36Str); - }); + return Promise.all( + accounts.map((account) => ( + token.mint(account, String(10n ** 36n)) + )) + ); }; module.exports = { fundAccounts }; From 76a49c05ae1919c11e47cb10d9a33fa415c1a015 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Mon, 8 Apr 2024 23:33:11 +0100 Subject: [PATCH 09/19] Move more tests to the beforeEach() + loadFixture() approach --- contracts/test/FeeArithmeticTest.js | 46 +-- contracts/test/SP_P_TruncationTest.js | 59 ++-- contracts/test/StabilityPoolTest.js | 14 +- .../test/StabilityPool_SPWithdrawalTest.js | 62 +--- .../StabilityPool_SPWithdrawalToCDPTest.js | 56 +--- contracts/test/TroveManagerTest.js | 271 +++--------------- .../TroveManager_LiquidationRewardsTest.js | 143 +++------ contracts/utils/testFixtures.js | 54 +--- 8 files changed, 153 insertions(+), 552 deletions(-) diff --git a/contracts/test/FeeArithmeticTest.js b/contracts/test/FeeArithmeticTest.js index 9d8c839aa..97aaae8aa 100644 --- a/contracts/test/FeeArithmeticTest.js +++ b/contracts/test/FeeArithmeticTest.js @@ -13,6 +13,10 @@ const toBN = th.toBN const getDifference = th.getDifference contract('Fee arithmetic tests', async accounts => { + let contracts + let troveManagerTester + let mathTester + // see: https://docs.google.com/spreadsheets/d/1RbD8VGzq7xFgeK1GOkz_9bbKVIx-xkOz0VsVelnUFdc/edit#gid=0 // Results array, maps seconds to expected minutes passed output (rounded down to nearest hour). @@ -325,8 +329,7 @@ contract('Fee arithmetic tests', async accounts => { [919877008002166000, 85, 826094891277916], ] - const loadDeployAndFundFixture = createDeployAndFundFixture({ - accounts: accounts.slice(0, 20), + const deployFixture = createDeployAndFundFixture({ callback: async () => { const troveManagerTester = await TroveManagerTester.new() TroveManagerTester.setAsDeployed(troveManagerTester) @@ -338,9 +341,14 @@ contract('Fee arithmetic tests', async accounts => { } }); - it("minutesPassedSinceLastFeeOp(): returns minutes passed for no time increase", async () => { - const { troveManagerTester } = await loadDeployAndFundFixture() + beforeEach(async () => { + const result = await deployFixture() + contracts = result.contracts + troveManagerTester = result.troveManagerTester + mathTester = result.mathTester + }) + it("minutesPassedSinceLastFeeOp(): returns minutes passed for no time increase", async () => { await troveManagerTester.setLastFeeOpTimeToNow() const minutesPassed = await troveManagerTester.minutesPassedSinceLastFeeOp() @@ -348,8 +356,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("minutesPassedSinceLastFeeOp(): returns minutes passed between time of last fee operation and current block.timestamp, rounded down to nearest minutes", async () => { - const { troveManagerTester } = await loadDeployAndFundFixture() - for (const [seconds, expectedMinutesPassed] of secondsToMinutesRoundedDown) { await troveManagerTester.setLastFeeOpTimeToNow() @@ -368,8 +374,6 @@ contract('Fee arithmetic tests', async accounts => { describe('Basic exponentiation', async accounts => { // for exponent = 0, returns 1 it("decPow(): for exponent = 0, returns 1, regardless of base", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const a = '0' const b = '1' const c = dec(1, 18) @@ -400,8 +404,6 @@ contract('Fee arithmetic tests', async accounts => { // for exponent = 1, returns base it("decPow(): for exponent = 1, returns base, regardless of base", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const a = '0' const b = '1' const c = dec(1, 18) @@ -435,8 +437,6 @@ contract('Fee arithmetic tests', async accounts => { // for base = 0, returns 0 for any exponent other than 1 it("decPow(): for base = 0, returns 0 for any exponent other than 0", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const res_a = await mathTester.callDecPow(0, 1) const res_b = await mathTester.callDecPow(0, 3) const res_c = await mathTester.callDecPow(0, 17) @@ -463,8 +463,6 @@ contract('Fee arithmetic tests', async accounts => { // for base = 1, returns 1 for any exponent it("decPow(): for base = 1, returns 1 for any exponent", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const ONE = dec(1, 18) const res_a = await mathTester.callDecPow(ONE, 1) const res_b = await mathTester.callDecPow(ONE, 3) @@ -493,8 +491,6 @@ contract('Fee arithmetic tests', async accounts => { // for exponent = 2, returns base**2 it("decPow(): for exponent = 2, returns the square of the base", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const a = dec(1, 18) // 1 const b = dec(15, 17) // 1.5 const c = dec(5, 17) // 0.5 @@ -530,8 +526,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): correct output for various bases and exponents", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (list of exponentiationResults) { const base = list[0].toString() const exponent = list[1].toString() @@ -544,8 +538,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 7776000 (seconds in three months)", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.SECONDS_IN_ONE_MONTH * 3 @@ -572,8 +564,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 2592000 (seconds in one month)", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.SECONDS_IN_ONE_MONTH @@ -600,8 +590,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 43200 (minutes in one month)", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_MONTH @@ -628,8 +616,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 525600 (minutes in one year)", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR @@ -656,8 +642,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = 2628000 (minutes in five years)", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 5 @@ -684,8 +668,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = minutes in ten years", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 10 @@ -712,8 +694,6 @@ contract('Fee arithmetic tests', async accounts => { }) it("decPow(): abs. error < 1e-9 for exponent = minutes in one hundred years", async () => { - const { mathTester } = await loadDeployAndFundFixture() - for (let i = 1; i <= 200; i++) { const exponent = timeValues.MINUTES_IN_ONE_YEAR * 100 @@ -740,8 +720,6 @@ contract('Fee arithmetic tests', async accounts => { }) it.skip("decPow(): overflow test: doesn't overflow for exponent = minutes in 1000 years", async () => { - const { mathTester } = await loadDeployAndFundFixture() - const exponent = (timeValues.MINUTES_IN_ONE_YEAR * 1000) + 9 // Test base = 0 diff --git a/contracts/test/SP_P_TruncationTest.js b/contracts/test/SP_P_TruncationTest.js index f98bdb227..f1b90f640 100644 --- a/contracts/test/SP_P_TruncationTest.js +++ b/contracts/test/SP_P_TruncationTest.js @@ -1,12 +1,7 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); -const th = testHelpers.TestHelper; -const timeValues = testHelpers.TimeValues; -const dec = th.dec; -const toBN = th.toBN; -const getDifference = th.getDifference; +const { dec } = th; const TroveManagerTester = artifacts.require("TroveManagerTester"); const BoldToken = artifacts.require("BoldToken"); @@ -14,7 +9,9 @@ const BoldToken = artifacts.require("BoldToken"); const GAS_PRICE = 10000000; contract("StabilityPool Scale Factor issue tests", async (accounts) => { - const [owner, whale, A, B, C, D, E, F, F1, F2, F3] = accounts; + const fundedAccounts = accounts.slice(0, 11); + + const [owner, whale, A, B, C, D, E, F, F1, F2, F3] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); @@ -35,32 +32,28 @@ contract("StabilityPool Scale Factor issue tests", async (accounts) => { const getBoldAmountForDesiredDebt = async (desiredDebt) => (await getOpenTroveBoldAmount(dec(desiredDebt, 18))); - describe("Scale Factor issue tests", async () => { - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - - priceFeed = contracts.priceFeedTestnet; - boldToken = contracts.boldToken; - stabilityPool = contracts.stabilityPool; - sortedTroves = contracts.sortedTroves; - troveManager = contracts.troveManager; - stabilityPool = contracts.stabilityPool; - borrowerOperations = contracts.borrowerOperations; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([owner, whale, A, B, C, D, E, F, F1, F2, F3], contracts.WETH); + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + callback: async (contracts) => { + await contracts.priceFeed.setPrice(dec(200, 18)); + }, + mocks: { + TroveManager: TroveManagerTester, + } + }); - await priceFeed.setPrice(dec(200, 18)); - }); + beforeEach(async () => { + const result = await deployFixture(); + contracts = result.contracts; + priceFeed = contracts.priceFeed; + boldToken = contracts.boldToken; + stabilityPool = contracts.stabilityPool; + sortedTroves = contracts.sortedTroves; + troveManager = contracts.troveManager; + borrowerOperations = contracts.borrowerOperations; + }); + describe("Scale Factor issue tests", async () => { it.skip("1. Liquidation succeeds after P reduced to 1", async () => { // Whale opens Trove with 100k ETH and sends 50k Bold to A await th.openTroveWrapper(contracts, diff --git a/contracts/test/StabilityPoolTest.js b/contracts/test/StabilityPoolTest.js index d637dec4f..d19f4840e 100644 --- a/contracts/test/StabilityPoolTest.js +++ b/contracts/test/StabilityPoolTest.js @@ -22,6 +22,8 @@ const getFrontEndTag = async (stabilityPool, depositor) => { }; contract("StabilityPool", async (accounts) => { + const fundedAccounts = accounts.slice(0, 20); + const [ owner, defaulter_1, @@ -43,7 +45,7 @@ contract("StabilityPool", async (accounts) => { frontEnd_1, frontEnd_2, frontEnd_3, - ] = accounts; + ] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); @@ -65,16 +67,14 @@ contract("StabilityPool", async (accounts) => { const assertRevert = th.assertRevert; const deployFixture = createDeployAndFundFixture({ - accounts: accounts.slice(0, 20), - mocks: { - TroveManager: TroveManagerTester, - } + accounts: fundedAccounts.slice(0, 20), + mocks: { TroveManager: TroveManagerTester } }); describe("Stability Pool Mechanisms", async () => { beforeEach(async () => { - const f = await deployFixture(); - contracts = f.contracts; + const result = await deployFixture() + contracts = result.contracts; priceFeed = contracts.priceFeed; boldToken = contracts.boldToken; sortedTroves = contracts.sortedTroves; diff --git a/contracts/test/StabilityPool_SPWithdrawalTest.js b/contracts/test/StabilityPool_SPWithdrawalTest.js index 8f98f8c89..d9b1fd575 100644 --- a/contracts/test/StabilityPool_SPWithdrawalTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalTest.js @@ -1,14 +1,15 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const { dec, toBN } = testHelpers.TestHelper const th = testHelpers.TestHelper contract('StabilityPool - Withdrawal of stability deposit - Reward calculations', async accounts => { + const fundedAccounts = accounts.slice(0, 22); - const [owner, + const [ + owner, defaulter_1, defaulter_2, defaulter_3, @@ -31,7 +32,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' D, E, F - ] = accounts; + ] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000) @@ -39,66 +40,27 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' let priceFeed let boldToken - let sortedTroves let troveManager - let activePool let stabilityPool - let defaultPool - let borrowerOperations - - let gasPriceInWei const ZERO_ADDRESS = th.ZERO_ADDRESS const getOpenTroveBoldAmount = async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt) - describe("Stability Pool Withdrawal", async () => { + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester } + }); - before(async () => { - gasPriceInWei = await web3.eth.getGasPrice() - }) + describe("Stability Pool Withdrawal", async () => { beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore() - contracts.troveManager = await TroveManagerTester.new() - contracts = await deploymentHelper.deployBoldToken(contracts) - + const result = await deployFixture() + contracts = result.contracts priceFeed = contracts.priceFeedTestnet boldToken = contracts.boldToken - sortedTroves = contracts.sortedTroves troveManager = contracts.troveManager - activePool = contracts.activePool stabilityPool = contracts.stabilityPool - defaultPool = contracts.defaultPool - borrowerOperations = contracts.borrowerOperations - - await deploymentHelper.connectCoreContracts(contracts) - - await fundAccounts([ - owner, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - defaulter_5, - defaulter_6, - whale, - // whale_2, - alice, - bob, - carol, - dennis, - erin, - flyn, - graham, - harriet, - A, - B, - C, - D, - E, - F - ], contracts.WETH); }) // --- Compounding tests --- diff --git a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js index e0f057e32..b0dd1bb6e 100644 --- a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js @@ -1,14 +1,15 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const { dec, toBN } = testHelpers.TestHelper const th = testHelpers.TestHelper contract('StabilityPool - Withdrawal of stability deposit - Reward calculations', async accounts => { + const fundedAccounts = accounts.slice(0, 22); - const [owner, + const [ + owner, defaulter_1, defaulter_2, defaulter_3, @@ -31,7 +32,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' D, E, F - ] = accounts; + ] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000) @@ -39,12 +40,8 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' let priceFeed let boldToken - let sortedTroves let troveManager - let activePool let stabilityPool - let defaultPool - let borrowerOperations let gasPriceInWei @@ -52,6 +49,11 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' const getOpenTroveBoldAmount = async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt) + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester } + }); + describe("Stability Pool Withdrawal", async () => { before(async () => { @@ -59,46 +61,12 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' }) beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore() - contracts.troveManager = await TroveManagerTester.new() - contracts = await deploymentHelper.deployBoldToken(contracts) - + const result = await deployFixture() + contracts = result.contracts priceFeed = contracts.priceFeedTestnet boldToken = contracts.boldToken - sortedTroves = contracts.sortedTroves troveManager = contracts.troveManager - activePool = contracts.activePool stabilityPool = contracts.stabilityPool - defaultPool = contracts.defaultPool - borrowerOperations = contracts.borrowerOperations - - await deploymentHelper.connectCoreContracts(contracts) - - await fundAccounts([ - owner, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - defaulter_5, - defaulter_6, - whale, - // whale_2, - alice, - bob, - carol, - dennis, - erin, - flyn, - graham, - harriet, - A, - B, - C, - D, - E, - F - ], contracts.WETH); }) // --- Compounding tests --- diff --git a/contracts/test/TroveManagerTest.js b/contracts/test/TroveManagerTest.js index 37b34f75c..4cedbf19a 100644 --- a/contracts/test/TroveManagerTest.js +++ b/contracts/test/TroveManagerTest.js @@ -24,6 +24,8 @@ const GAS_PRICE = 10000000; * */ contract("TroveManager", async (accounts) => { + const fundedAccounts = accounts.slice(0, 20); + const _18_zeros = "000000000000000000"; const ZERO_ADDRESS = th.ZERO_ADDRESS; @@ -48,24 +50,44 @@ contract("TroveManager", async (accounts) => { C, D, E, - ] = accounts; - - const loadDeployAndFundFixture = createDeployAndFundFixture({ - accounts: accounts.slice(0, 20), - mocks: { - TroveManager: TroveManagerTester, - } + ] = fundedAccounts; + + let contracts + + let priceFeed + let boldToken + let sortedTroves + let troveManager + let activePool + let stabilityPool + let defaultPool + let borrowerOperations + + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester, } + }); + const getOpenTroveTotalDebt = async (boldAmount) => th.getOpenTroveTotalDebt(contracts, boldAmount); + const getOpenTroveBoldAmount = async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt); + const getActualDebtFromComposite = async (compositeDebt) => th.getActualDebtFromComposite(compositeDebt, contracts); + const getNetBorrowingAmount = async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee); + const openTrove = async (params) => th.openTrove(contracts, params); + const withdrawBold = async (params) => th.withdrawBold(contracts, params); + + beforeEach(async () => { + const result = await deployFixture() + contracts = result.contracts + priceFeed = contracts.priceFeedTestnet + boldToken = contracts.boldToken + sortedTroves = contracts.sortedTroves + troveManager = contracts.troveManager + activePool = contracts.activePool + stabilityPool = contracts.stabilityPool + defaultPool = contracts.defaultPool + borrowerOperations = contracts.borrowerOperations }); it("liquidate(): closes a Trove that has ICR < MCR", async () => { - const { - contracts, - getNetBorrowingAmount, - openTrove, - withdrawBold, - } = await loadDeployAndFundFixture(); - const { priceFeed, sortedTroves, troveManager } = contracts; - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -102,9 +124,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): decreases ActivePool ETH and BoldDebt by correct amounts", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, activePool } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -154,9 +173,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): increases DefaultPool ETH and Bold debt by correct amounts", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, defaultPool } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -203,9 +219,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): removes the Trove's stake from the total stakes", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -233,9 +246,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Removes the correct trove from the TroveIds array, and moves the last array element to the new empty slot", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - // --- SETUP --- const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); @@ -301,9 +311,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the snapshots of total stakes and total collateral", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }); @@ -351,9 +358,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): updates the L_ETH and L_boldDebt reward-per-unit-staked totals", async () => { - const { contracts, openTrove, withdrawBold } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, collateral: A_collateral, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); @@ -456,9 +460,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Liquidates undercollateralized trove if there are two troves in the system", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - const { troveId: bobTroveId } = await openTrove({ ICR: toBN(dec(200, 18)), extraParams: { from: bob, value: dec(100, "ether") }, @@ -504,9 +505,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove is non-existent", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { troveManager, sortedTroves } = contracts; - 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 } }); @@ -528,9 +526,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): reverts if trove has been closed", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { troveManager, sortedTroves, priceFeed } = contracts; - await openTrove({ ICR: toBN(dec(8, 18)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: bob } }); const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: carol } }); @@ -562,9 +557,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does nothing if trove has >= 110% ICR", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { troveManager, sortedTroves, priceFeed } = contracts; - 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 } }); @@ -598,9 +590,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Given the same price and no other trove changes, complete Pool offsets restore the TCR to its value prior to the defaulters opening troves", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // Whale provides Bold to SP const spDeposit = toBN(dec(100, 24)); await openTrove({ @@ -666,9 +655,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): Pool offsets increase the TCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // Whale provides Bold to SP const spDeposit = toBN(dec(100, 24)); await openTrove({ @@ -735,9 +721,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): a pure redistribution reduces the TCR only as a result of compensation", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: whale } }); await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: alice } }); @@ -850,9 +833,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not affect the SP deposit or ETH gain when called on an SP depositor's address that has no trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, boldToken, stabilityPool } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const spDeposit = toBN(dec(1, 24)); await openTrove({ @@ -919,9 +899,6 @@ 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 () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const spDeposit = toBN(dec(1, 24)); const { troveId: bobTroveId } = await openTrove({ @@ -987,9 +964,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates a SP depositor's trove with ICR < 110%, and the liquidation correctly impacts their SP deposit and ETH gain", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - const A_spDeposit = toBN(dec(3, 24)); const B_spDeposit = toBN(dec(1, 24)); await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); @@ -1105,9 +1079,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): does not alter the liquidated user's token balance", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, priceFeed, troveManager, sortedTroves, boldToken, defaultPool } = contracts; - await openTrove({ ICR: toBN(dec(10, 18)), extraParams: { from: whale } }); const { troveId: aliceTroveId, boldAmount: A_boldAmount } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -1162,9 +1133,6 @@ contract("TroveManager", async (accounts) => { }); it("liquidate(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(8, 18)), extraBoldAmount: toBN(dec(100, 18)), @@ -1267,9 +1235,6 @@ contract("TroveManager", async (accounts) => { // --- batchLiquidateTroves() --- it("batchLiquidateTroves(): liquidates based on entire/collateral debt (including pending rewards), not raw collateral/debt", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - 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 } }); @@ -1346,9 +1311,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): liquidates troves with ICR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - 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 @@ -1407,9 +1369,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not affect the liquidated user's token balances", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, boldToken } = contracts; - 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 @@ -1455,9 +1414,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): A liquidation sequence containing Pool offsets increases the TCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // Whale provides 500 Bold to SP const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(100, 18)), @@ -1532,9 +1488,6 @@ 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 { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - const { troveId: whaleTroveId, collateral: W_coll, totalDebt: W_debt } = await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale }, @@ -1641,9 +1594,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): Liquidating troves with SP deposits correctly impacts their SP deposit and ETH gain", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // Whale provides 400 Bold to the SP const whaleDeposit = toBN(dec(40000, 18)); const { troveId: whaleTroveId } = await openTrove({ @@ -1813,9 +1763,6 @@ contract("TroveManager", async (accounts) => { // Can we achieve / test the same thing using another liquidation function? it("batchLiquidateTroves(): liquidates a Trove that a) was skipped in a previous liquidation and b) has pending rewards", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool, defaultPool, borrowerOperations } = contracts; - // A, B, C, D, E open troves 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 } }); @@ -1901,9 +1848,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): closes every trove with ICR < MCR in the given array", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -1967,9 +1911,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not liquidate troves that are not in the given array", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2039,9 +1980,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): does not close troves with ICR >= MCR in the given array", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // --- SETUP --- const { troveId: whaleTroveId } = await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2105,9 +2043,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): reverts if array is empty", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2150,9 +2085,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if trove is non-existent", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool } = contracts; - // --- SETUP --- const spDeposit = toBN(dec(500000, 18)); await openTrove({ @@ -2237,9 +2169,6 @@ contract("TroveManager", async (accounts) => { }); it("batchLiquidateTroves(): skips if a trove has been closed", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves, stabilityPool, boldToken, borrowerOperations } = contracts; - // --- SETUP --- const spDeposit = toBN(dec(500000, 18)); await openTrove({ @@ -2339,8 +2268,6 @@ contract("TroveManager", async (accounts) => { // Many of these tests rely on specific ICR ordering in the setup, and close fully redeemed. // It may be more efficient to write wholly new redemption tests in Solidity for Foundry. it.skip("getRedemptionHints(): gets the address of the first Trove and the final ICR of the last Trove involved in a redemption", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- const partialRedemptionAmount = toBN(dec(100, 18)); const { collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ @@ -2376,8 +2303,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("getRedemptionHints(): returns 0 as partialRedemptionHintNICR when reaching _maxIterations", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- await openTrove({ ICR: toBN(dec(310, 16)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(290, 16)), extraParams: { from: bob } }); @@ -2400,9 +2325,6 @@ 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 () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, priceFeed, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2518,9 +2440,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, zero address", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, priceFeed, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2627,9 +2546,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, non-existent trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2736,9 +2652,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): with invalid first hint, trove below MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(310, 16)), @@ -2850,8 +2763,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when the token redemption request has been filled", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -2946,8 +2857,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): ends the redemption sequence when max iterations have been reached", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- await openTrove({ ICR: toBN(dec(100, 18)), extraParams: { from: whale } }); @@ -3020,9 +2929,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): performs partial redemption if resultant debt is > minimum net debt", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, sortedTroves } = contracts; - const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(10000, 18)), @@ -3074,9 +2980,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't perform partial redemption if resultant debt would be < minimum net debt", async () => { - const { contracts, getOpenTroveBoldAmount } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, sortedTroves } = contracts; - const ATroveId = await th.openTroveWrapper(contracts, th._100pct, await getOpenTroveBoldAmount(dec(6000, 18)), @@ -3129,9 +3032,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesnt perform the final partial redemption in the sequence if the hint is out-of-date", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, priceFeed, sortedTroves } = contracts; - // --- SETUP --- const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(363, 16)), @@ -3259,9 +3159,6 @@ contract("TroveManager", async (accounts) => { // active debt cannot be zero, as there’s a positive min debt enforced, and at least a trove must exist it.skip("redeemCollateral(): can redeem if there is zero active debt but non-zero debt in DefaultPool", async () => { - const { contracts, getOpenTroveBoldAmount, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, priceFeed } = contracts; - // --- SETUP --- const amount = await getOpenTroveBoldAmount(dec(110, 18)); @@ -3318,8 +3215,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't touch Troves with ICR < 110%", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- const { troveId: aliceTroveId, netDebt: A_debt } = await openTrove({ @@ -3365,8 +3260,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): finds the last Trove with ICR == 110% even if there is more than one", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- const amount1 = toBN(dec(100, 18)); const { troveId: aliceTroveId, totalDebt: A_totalDebt } = await openTrove({ @@ -3440,9 +3333,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when TCR < MCR", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: alice } }); await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: bob } }); const { troveId: carolTroveId } = await openTrove({ ICR: toBN(dec(200, 16)), extraParams: { from: carol } }); @@ -3466,8 +3356,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when argument _amount is 0", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // Alice opens trove and transfers 500Bold to Erin, the would-be redeemer @@ -3504,8 +3392,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee > 100%", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(10, 18), @@ -3553,8 +3439,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if max fee < 0.5%", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(10, 18), @@ -3612,9 +3496,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if fee exceeds max fee percentage", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { boldToken, troveManager } = contracts; - const { totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), extraBoldAmount: dec(80, 18), @@ -3697,9 +3578,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): doesn't affect the Stability Pool deposits or ETH gain of redeemed-from troves", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, stabilityPool, priceFeed, sortedTroves } = contracts; - await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }); // B, C, D, F open trove @@ -3834,8 +3712,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): caller can redeem their entire BoldToken balance", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -3933,8 +3809,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts when requested redemption amount exceeds caller's Bold token balance", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - const { collateral: W_coll, totalDebt: W_totalDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -4141,9 +4015,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): value of issued ETH == face value of redeemed Bold (assuming 1 Bold has value of $1)", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { boldToken, troveManager, priceFeed, activePool, sortedTroves } = contracts; - const { collateral: W_coll } = await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale }, @@ -4298,9 +4169,6 @@ contract("TroveManager", async (accounts) => { // it doesn’t make much sense as there’s now min debt enforced and at least one trove must remain active // the only way to test it is before any trove is opened it.skip("redeemCollateral(): reverts if there is zero outstanding system debt", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager, boldToken } = contracts; - // --- SETUP --- illegally mint Bold to Bob await boldToken.unprotectedMint(bob, dec(100, 18)); @@ -4341,8 +4209,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): reverts if caller's tries to redeem more than the outstanding system debt", async () => { - const { openTrove } = await loadDeployAndFundFixture(); - // --- SETUP --- illegally mint Bold to Bob await boldToken.unprotectedMint(bob, "101000000000000000000"); @@ -4400,9 +4266,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption sends the ETH remainder (ETHDrawn - gas) to the redeemer", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed, activePool, defaultPool } = contracts; - // time fast-forwards 1 year, and multisig stakes 1 LQTY await time.increase(timeValues.SECONDS_IN_ONE_YEAR); @@ -4625,9 +4488,6 @@ contract("TroveManager", async (accounts) => { }; it.skip("redeemCollateral(): emits correct debt and coll values in each redeemed trove's TroveUpdated event", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { sortedTroves } = contracts; - const { netDebt: W_netDebt } = await openTrove({ ICR: toBN(dec(20, 18)), extraBoldAmount: dec(10000, 18), @@ -4716,9 +4576,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner to claim", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { collSurplusPool } = contracts; - const { A_netDebt, A_coll, B_netDebt, B_coll, C_netDebt, C_coll } = await redeemCollateral3Full1Partial(); @@ -4753,9 +4610,6 @@ contract("TroveManager", async (accounts) => { }); it.skip("redeemCollateral(): a redemption that closes a trove leaves the trove's ETH surplus (collateral - ETH drawn) available for the trove owner after re-opening trove", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - const { A_netDebt, A_coll: A_collBefore, @@ -4817,9 +4671,6 @@ contract("TroveManager", async (accounts) => { }); it("getPendingBoldDebtReward(): Returns 0 if there is no pending BoldDebt reward", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; - // Make some troves const { troveId: defaulter_1_TroveId, totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -4863,9 +4714,6 @@ contract("TroveManager", async (accounts) => { }); it("getPendingETHReward(): Returns 0 if there is no pending ETH reward", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, stabilityPool, priceFeed, sortedTroves } = contracts; - // make some troves const { troveId: defaulter_1_TroveId, totalDebt } = await openTrove({ ICR: toBN(dec(2, 18)), @@ -4910,9 +4758,6 @@ contract("TroveManager", async (accounts) => { // --- computeICR --- it("computeICR(): Returns 0 if trove's coll is worth 0", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = 0; const coll = dec(1, "ether"); const debt = dec(100, 18); @@ -4923,9 +4768,6 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 for ETH:USD = 100, coll = 1 ETH, debt = 100 Bold", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = dec(100, 18); const coll = dec(1, "ether"); const debt = dec(100, 18); @@ -4936,9 +4778,6 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 200 ETH, debt = 30 Bold", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = dec(100, 18); const coll = dec(200, "ether"); const debt = dec(30, 18); @@ -4949,9 +4788,6 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 250, coll = 1350 ETH, debt = 127 Bold", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = "250000000000000000000"; const coll = "1350000000000000000000"; const debt = "127000000000000000000"; @@ -4962,9 +4798,6 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): returns correct ICR for ETH:USD = 100, coll = 1 ETH, debt = 54321 Bold", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = dec(100, 18); const coll = dec(1, "ether"); const debt = "54321000000000000000000"; @@ -4975,9 +4808,6 @@ contract("TroveManager", async (accounts) => { }); it("computeICR(): Returns 2^256-1 if trove has non-zero coll and zero debt", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const price = dec(100, 18); const coll = dec(1, "ether"); const debt = 0; @@ -4995,9 +4825,6 @@ contract("TroveManager", async (accounts) => { //TCR < 150% it("checkRecoveryMode(): Returns true when TCR < 150%", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -5014,9 +4841,6 @@ contract("TroveManager", async (accounts) => { // TCR == 150% it("checkRecoveryMode(): Returns false when TCR == 150%", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -5031,9 +4855,6 @@ contract("TroveManager", async (accounts) => { // > 150% it("checkRecoveryMode(): Returns false when TCR > 150%", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -5050,9 +4871,6 @@ contract("TroveManager", async (accounts) => { // check 0 it("checkRecoveryMode(): Returns false when TCR == 0", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { priceFeed } = contracts; - await priceFeed.setPrice(dec(100, 18)); await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }); @@ -5070,9 +4888,6 @@ contract("TroveManager", async (accounts) => { // --- Getters --- it("getTroveStake(): Returns stake", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5090,9 +4905,6 @@ contract("TroveManager", async (accounts) => { }); it("getTroveColl(): Returns coll", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5107,9 +4919,6 @@ contract("TroveManager", async (accounts) => { }); it("getTroveDebt(): Returns debt", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - const { troveId: ATroveId, totalDebt: totalDebtA } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: A }, @@ -5129,9 +4938,6 @@ contract("TroveManager", async (accounts) => { }); it("getTroveStatus(): Returns status", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { troveManager, boldToken, borrowerOperations } = contracts; - const { troveId: BTroveId, totalDebt: B_totalDebt } = await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: B }, @@ -5156,9 +4962,6 @@ contract("TroveManager", async (accounts) => { }); it("hasRedistributionGains(): Returns false it trove is not active", async () => { - const { contracts } = await loadDeployAndFundFixture(); - const { troveManager } = contracts; - assert.isFalse(await troveManager.hasRedistributionGains(th.addressToTroveId(alice))); }); }); diff --git a/contracts/test/TroveManager_LiquidationRewardsTest.js b/contracts/test/TroveManager_LiquidationRewardsTest.js index 78682909c..7e217e195 100644 --- a/contracts/test/TroveManager_LiquidationRewardsTest.js +++ b/contracts/test/TroveManager_LiquidationRewardsTest.js @@ -1,16 +1,14 @@ -const testHelpers = require("../utils/testHelpers.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("TroveManagerTester"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const getDifference = th.getDifference; +const { dec, getDifference, toBN } = th; -contract( - "TroveManager - Redistribution reward calculations", +contract( "TroveManager - Redistribution reward calculations", async (accounts) => { + const fundedAccounts = accounts.slice(0, 20); + const [ owner, alice, @@ -32,26 +30,47 @@ contract( defaulter_2, defaulter_3, defaulter_4, - ] = accounts; - - const loadDeployAndFundFixture = createDeployAndFundFixture({ - accounts: accounts.slice(0, 20), + ] = fundedAccounts; + + let contracts + + let priceFeed + let boldToken + let sortedTroves + let troveManager + let activePool + let stabilityPool + let defaultPool + let borrowerOperations + + const getOpenTroveBoldAmount = async (totalDebt) => + th.getOpenTroveBoldAmount(contracts, totalDebt); + const getNetBorrowingAmount = async (debtWithFee) => + th.getNetBorrowingAmount(contracts, debtWithFee); + const openTrove = async (params) => th.openTrove(contracts, params); + + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, mocks: { TroveManager: TroveManagerTester, } }); - it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - troveManager, - priceFeed, - activePool, - defaultPool, - boldToken, - sortedTroves, - } = contracts; + beforeEach(async () => { + const result = await deployFixture(); + + contracts = result.contracts + priceFeed = contracts.priceFeed + boldToken = contracts.boldToken + sortedTroves = contracts.sortedTroves + troveManager = contracts.troveManager + activePool = contracts.activePool + stabilityPool = contracts.stabilityPool + defaultPool = contracts.defaultPool + borrowerOperations = contracts.borrowerOperations + }); + it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { // A, B open trove const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -151,9 +170,6 @@ contract( }); it("redistribution: A, B, C Open. C Liquidated. D, E, F Open. F Liquidated. Distributes correct rewards", async () => { - const { contracts, openTrove } = await loadDeployAndFundFixture(); - const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; - // A, B C open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -277,9 +293,6 @@ contract( //// it("redistribution: Sequence of alternate opening/liquidation: final surviving trove has ETH from all previously liquidated troves", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; - // A, B open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -431,9 +444,6 @@ 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 () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { troveManager, sortedTroves, priceFeed } = contracts; - // A, B, C, D, E open troves const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -578,9 +588,6 @@ 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 () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { priceFeed, troveManager, sortedTroves } = contracts; - // A, B, C, D, E open troves const { troveId: ATroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -758,9 +765,6 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B adds coll. Liq(A). B acquires all coll and debt", async () => { - const { openTrove, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const { borrowerOperations, priceFeed, sortedTroves, troveManager } = contracts; - // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -839,9 +843,6 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B tops up coll. D Opens. Liq(D). Distributes correct rewards.", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { boldToken, priceFeed, sortedTroves, troveManager } = contracts; - // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -956,9 +957,6 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); - const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; - const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ @@ -1125,9 +1123,6 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); - const { activePool, boldToken, defaultPool, priceFeed, sortedTroves, troveManager } = contracts; - const _998_Ether = toBN("998000000000000000000"); // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ @@ -1308,9 +1303,6 @@ contract( // --- Trove withdraws collateral --- it("redistribution: A,B,C Open. Liq(C). B withdraws coll. Liq(A). B acquires all coll and debt", async () => { - const { openTrove, contracts, getNetBorrowingAmount } = await loadDeployAndFundFixture(); - const { boldToken, borrowerOperations, troveManager, sortedTroves, priceFeed } = contracts; - // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(400, 16)), @@ -1392,17 +1384,6 @@ contract( }); it("redistribution: A,B,C Open. Liq(C). B withdraws coll. D Opens. Liq(D). Distributes correct rewards.", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - activePool, - boldToken, - borrowerOperations, - defaultPool, - priceFeed, - sortedTroves, - troveManager, - } = contracts; - // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll, totalDebt: A_totalDebt } = await openTrove({ ICR: toBN(dec(500, 16)), @@ -1524,17 +1505,6 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - activePool, - boldToken, - borrowerOperations, - defaultPool, - priceFeed, - sortedTroves, - troveManager, - } = contracts; - const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ @@ -1697,17 +1667,6 @@ 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 { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - activePool, - boldToken, - borrowerOperations, - defaultPool, - priceFeed, - sortedTroves, - troveManager, - } = contracts; - const _998_Ether = toBN("998000000000000000000"); // A, B, C, D open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ @@ -1922,17 +1881,6 @@ contract( // For calculations of correct values used in test, see scenario 1: // 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 () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - activePool, - boldToken, - borrowerOperations, - defaultPool, - priceFeed, - sortedTroves, - troveManager, - } = contracts; - // A, B, C open troves const { troveId: aliceTroveId, collateral: A_coll } = await openTrove({ ICR: toBN(dec(200, 16)), @@ -2224,17 +2172,6 @@ contract( // For calculations of correct values used in test, see scenario 2: // 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). Varying coll. Distributes correct rewards", async () => { - const { openTrove, contracts } = await loadDeployAndFundFixture(); - const { - activePool, - boldToken, - defaultPool, - borrowerOperations, - troveManager, - sortedTroves, - priceFeed, - } = contracts; - /* A, B, C open troves. A: 450 ETH B: 8901 ETH diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js index 2c2bc5517..87f9bb19c 100644 --- a/contracts/utils/testFixtures.js +++ b/contracts/utils/testFixtures.js @@ -1,14 +1,12 @@ -const { loadFixture, mine } = require("@nomicfoundation/hardhat-network-helpers"); +const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); const deploymentHelper = require("./deploymentHelpers.js"); const { fundAccounts } = require("./fundAccounts.js"); -const { TestHelper: th } = require("./testHelpers.js"); -// Returns a fixture utility to be called in every test (it()). -// The only required parameter is the list of accounts to be funded. -// Callback parameters can be used to run code after the deployment -// and after the connection. They take the contracts as a parameter, -// which can be modified as needed. The returned object will be -// merged with the object returned by the fixture loader utility. +// Returns a fixture utility to be called in every test. +// The callback parameter can be used to run code after the +// deployment. They take the contracts as a parameter, which +// can be modified as needed. The returned object will be merged +// with the object returned by the fixture loader utility. function createDeployAndFundFixture({ accounts = [], callback = async () => null, @@ -17,51 +15,13 @@ function createDeployAndFundFixture({ const fixture = async () => { const contracts = await deploymentHelper.deployLiquityCore(mocks); await deploymentHelper.connectCoreContracts(contracts); - contracts.priceFeed = contracts.priceFeedTestnet; - await fundAccounts(accounts, contracts.WETH); - - // Without forcing a block to be mined, the tests were sometimes - // failing due to the accounts not being funded. - await mine(); - - const helpers = { - getOpenTroveBoldAmount: async (totalDebt) => ( - th.getOpenTroveBoldAmount(contracts, totalDebt) - ), - getNetBorrowingAmount: async (debtWithFee) => ( - th.getNetBorrowingAmount(contracts, debtWithFee) - ), - openTrove: async (params) => ( - th.openTrove(contracts, params) - ), - withdrawBold: async (params) => ( - th.withdrawBold(contracts, params) - ), - getActualDebtFromComposite: async (compositeDebt) => ( - th.getActualDebtFromComposite(compositeDebt, contracts) - ), - getTroveEntireColl: async (trove) => ( - th.getTroveEntireColl(contracts, trove) - ), - getTroveEntireDebt: async (trove) => ( - th.getTroveEntireDebt(contracts, trove) - ), - getTroveStake: async (trove) => ( - th.getTroveStake(contracts, trove) - ), - }; - - const callbackResult = await callback(contracts); - return { contracts, - ...helpers, - ...callbackResult, + ...await callback(contracts), }; }; - return () => loadFixture(fixture); } From 889d5b7dd155169766267b08571d6a44c292b743 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 9 Apr 2024 00:30:43 +0100 Subject: [PATCH 10/19] Remove cleanup changes (reduce the PR diff size) --- contracts/test/AccessControlTest.js | 71 +++++----- contracts/test/BorrowerOperationsTest.js | 39 +++--- contracts/test/CollSurplusPool.js | 51 +++---- contracts/test/FeeArithmeticTest.js | 4 +- contracts/test/GasCompensationTest.js | 62 +++------ .../test/HintHelpers_getApproxHintTest.js | 43 +++--- contracts/test/SortedTrovesTest.js | 125 ++++++++---------- .../test/TroveManager_RecoveryModeTest.js | 66 +++------ ...ager_RecoveryMode_Batch_Liqudation_Test.js | 55 ++------ contracts/test/stakeDeclineTest.js | 40 ++---- 10 files changed, 201 insertions(+), 355 deletions(-) diff --git a/contracts/test/AccessControlTest.js b/contracts/test/AccessControlTest.js index 4e59f5a07..2dca1dd81 100644 --- a/contracts/test/AccessControlTest.js +++ b/contracts/test/AccessControlTest.js @@ -1,13 +1,8 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("TroveManagerTester"); -const th = testHelpers.TestHelper; -const timeValues = testHelpers.TimeValues; - -const dec = th.dec; -const toBN = th.toBN; +const { dec, toBN } = th; /* The majority of access control tests are contained in this file. However, tests for restrictions on the Liquity admin address's capabilities during the first year are found in: @@ -17,55 +12,53 @@ test/launchSequenceTest/DuringLockupPeriodTest.js */ contract( "Access Control: Liquity functions with the caller restricted to Liquity contract(s)", async (accounts) => { - const [owner, alice, bob, carol] = accounts; + const fundedAccounts = accounts.slice(0, 10); + + const [owner, alice, bob, carol] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice( 997, 1000 ); - let coreContracts; + let contracts; let priceFeed; let boldToken; let sortedTroves; let troveManager; - let nameRegistry; let activePool; let stabilityPool; let defaultPool; - let functionCaller; let borrowerOperations; - before(async () => { - coreContracts = await deploymentHelper.deployLiquityCore(); - coreContracts.troveManager = await TroveManagerTester.new(); - // TODO: coreContracts = await deploymentHelper.deployBoldTokenTester(coreContracts) - - priceFeed = coreContracts.priceFeed; - boldToken = coreContracts.boldToken; - sortedTroves = coreContracts.sortedTroves; - troveManager = coreContracts.troveManager; - nameRegistry = coreContracts.nameRegistry; - activePool = coreContracts.activePool; - stabilityPool = coreContracts.stabilityPool; - defaultPool = coreContracts.defaultPool; - functionCaller = coreContracts.functionCaller; - borrowerOperations = coreContracts.borrowerOperations; - - await deploymentHelper.connectCoreContracts(coreContracts); - - - await fundAccounts(accounts.slice(0, 10), coreContracts.WETH); - - for (const account of accounts.slice(0, 10)) { - await th.openTrove(coreContracts, { - extraBoldAmount: toBN(dec(20000, 18)), - ICR: toBN(dec(2, 18)), - extraParams: { from: account }, - }); + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + callback: async (contracts) => { + await Promise.all(fundedAccounts.map( + (account) => th.openTrove(contracts, { + extraBoldAmount: toBN(dec(20000, 18)), + ICR: toBN(dec(2, 18)), + extraParams: { from: account }, + }) + )) } }); + beforeEach(async () => { + const result = await deployFixture(); + + contracts = result.contracts; + priceFeed = contracts.priceFeed; + boldToken = contracts.boldToken; + sortedTroves = contracts.sortedTroves; + troveManager = contracts.troveManager; + activePool = contracts.activePool; + stabilityPool = contracts.stabilityPool; + defaultPool = contracts.defaultPool; + borrowerOperations = contracts.borrowerOperations; + }); + describe("BorrowerOperations", async (accounts) => { it("moveETHGainToTrove(): reverts when called by an account that is not StabilityPool", async () => { // Attempt call from alice diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index 8180b843d..717e0dc3d 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -33,6 +33,8 @@ contract("BorrowerOperations", async (accounts) => { frontEnd_3, ] = accountsToFund; + const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); + let contracts let priceFeed; @@ -85,24 +87,24 @@ contract("BorrowerOperations", async (accounts) => { }, }); - beforeEach(async () => { - const result = await deployFixture() - - contracts = result.contracts - priceFeed = contracts.priceFeedTestnet - boldToken = contracts.boldToken - sortedTroves = contracts.sortedTroves - troveManager = contracts.troveManager - activePool = contracts.activePool - defaultPool = contracts.defaultPool - borrowerOperations = contracts.borrowerOperations - - BOLD_GAS_COMPENSATION = result.BOLD_GAS_COMPENSATION - MIN_NET_DEBT = result.MIN_NET_DEBT - BORROWING_FEE_FLOOR = result.BORROWING_FEE_FLOOR - }); - const testCorpus = () => { + beforeEach(async () => { + const result = await deployFixture() + + contracts = result.contracts + priceFeed = contracts.priceFeedTestnet + boldToken = contracts.boldToken + sortedTroves = contracts.sortedTroves + troveManager = contracts.troveManager + activePool = contracts.activePool + defaultPool = contracts.defaultPool + borrowerOperations = contracts.borrowerOperations + + BOLD_GAS_COMPENSATION = result.BOLD_GAS_COMPENSATION + MIN_NET_DEBT = result.MIN_NET_DEBT + BORROWING_FEE_FLOOR = result.BORROWING_FEE_FLOOR + }); + it("addColl(): reverts when top-up would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral const { troveId: aliceTroveId } = await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }); @@ -1243,6 +1245,7 @@ contract("BorrowerOperations", async (accounts) => { ICR: toBN(dec(10, 18)), extraParams: { from: alice }, }); + BOLD_GAS_COMPENSATION = await borrowerOperations.BOLD_GAS_COMPENSATION(); const repayAmount = totalDebt.sub(BOLD_GAS_COMPENSATION).add(toBN(1)); await openTrove({ extraBoldAmount: repayAmount, @@ -3602,7 +3605,7 @@ contract("BorrowerOperations", async (accounts) => { }); it("openTrove(): reverts if net debt < minimum net debt", async () => { - const txAPromise = th.openTroveWrapper(contracts, th._100pct, 0, A, A, 0, { + const txAPromise = th.openTroveWrapper(contracts,th._100pct, 0, A, A, 0, { from: A, value: dec(100, 30), }); diff --git a/contracts/test/CollSurplusPool.js b/contracts/test/CollSurplusPool.js index f4ffc6fbf..d347cb4b3 100644 --- a/contracts/test/CollSurplusPool.js +++ b/contracts/test/CollSurplusPool.js @@ -1,51 +1,42 @@ const { time } = require('@nomicfoundation/hardhat-network-helpers'); -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); +const { + MoneyValues: mv, + TestHelper: th, + TimeValues: timeValues, +} = require("../utils/testHelpers.js"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; +const { dec, toBN } = th; const TroveManagerTester = artifacts.require("TroveManagerTester"); -const BoldToken = artifacts.require("BoldToken"); contract("CollSurplusPool", async (accounts) => { - const [owner, A, B, C, D, E] = accounts; + const fundedAccounts = accounts.slice(0, 6); + + const [owner, A, B, C, D, E] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); + let contracts; let borrowerOperations; - let priceFeed; let collSurplusPool; - - let contracts; + let priceFeed; const getOpenTroveBoldAmount = async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt); const openTrove = async (params) => th.openTrove(contracts, params); + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - - priceFeed = contracts.priceFeedTestnet; - collSurplusPool = contracts.collSurplusPool; + const result = await deployFixture(); + contracts = result.contracts; borrowerOperations = contracts.borrowerOperations; - - await deploymentHelper.connectCoreContracts(contracts); - await fundAccounts([ - owner, A, B, C, D, E, - bountyAddress, lpRewardsAddress, multisig - ], contracts.WETH); + collSurplusPool = contracts.collSurplusPool; + priceFeed = contracts.priceFeedTestnet; }); it("CollSurplusPool::getETHBalance(): Returns the ETH balance of the CollSurplusPool after redemption", async () => { diff --git a/contracts/test/FeeArithmeticTest.js b/contracts/test/FeeArithmeticTest.js index 97aaae8aa..5ee8a5a5a 100644 --- a/contracts/test/FeeArithmeticTest.js +++ b/contracts/test/FeeArithmeticTest.js @@ -2,9 +2,9 @@ const { time } = require('@nomicfoundation/hardhat-network-helpers'); const Decimal = require("decimal.js"); const { BNConverter } = require("../utils/BNConverter.js") const testHelpers = require("../utils/testHelpers.js") +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const LiquityMathTester = artifacts.require("./LiquityMathTester.sol") -const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const th = testHelpers.TestHelper const timeValues = testHelpers.TimeValues @@ -17,6 +17,8 @@ contract('Fee arithmetic tests', async accounts => { let troveManagerTester let mathTester + const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000) + // see: https://docs.google.com/spreadsheets/d/1RbD8VGzq7xFgeK1GOkz_9bbKVIx-xkOz0VsVelnUFdc/edit#gid=0 // Results array, maps seconds to expected minutes passed output (rounded down to nearest hour). diff --git a/contracts/test/GasCompensationTest.js b/contracts/test/GasCompensationTest.js index 2519ae4d7..5c65f77f2 100644 --- a/contracts/test/GasCompensationTest.js +++ b/contracts/test/GasCompensationTest.js @@ -1,22 +1,18 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { TestHelper: th, MoneyValues: mv } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); const BorrowerOperationsTester = artifacts.require( "./BorrowerOperationsTester.sol" ); -const BoldToken = artifacts.require("BoldToken"); const ERC20 = artifacts.require("./ERC20MinterMock.sol"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const mv = testHelpers.MoneyValues; -const ZERO_ADDRESS = th.ZERO_ADDRESS; +const { dec, toBN, ZERO_ADDRESS } = th; const GAS_PRICE = 10000000; contract("Gas compensation tests", async (accounts) => { + const fundedAccounts = accounts.slice(0, 16); + const [ owner, liquidator, @@ -34,20 +30,18 @@ contract("Gas compensation tests", async (accounts) => { defaulter_3, defaulter_4, whale, - ] = accounts; + ] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); + let contracts; + let priceFeed; let boldToken; - let sortedTroves; let troveManager; - let activePool; let stabilityPool; - let defaultPool; let borrowerOperations; - let contracts; let troveManagerTester; let borrowerOperationsTester; @@ -61,6 +55,11 @@ contract("Gas compensation tests", async (accounts) => { } }; + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + before(async () => { troveManagerTester = await TroveManagerTester.new(); const WETH = await ERC20.new("WETH", "WETH"); @@ -71,44 +70,13 @@ contract("Gas compensation tests", async (accounts) => { }); beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - + const result = await deployFixture(); + contracts = result.contracts; priceFeed = contracts.priceFeedTestnet; boldToken = contracts.boldToken; - sortedTroves = contracts.sortedTroves; troveManager = contracts.troveManager; - activePool = contracts.activePool; stabilityPool = contracts.stabilityPool; - defaultPool = contracts.defaultPool; borrowerOperations = contracts.borrowerOperations; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, - liquidator, - alice, - bob, - carol, - dennis, - erin, - flyn, - graham, - harriet, - ida, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - whale, - ], contracts.WETH); }); // --- Raw gas compensation calculations --- diff --git a/contracts/test/HintHelpers_getApproxHintTest.js b/contracts/test/HintHelpers_getApproxHintTest.js index 46e9c17ef..9fc3a0881 100644 --- a/contracts/test/HintHelpers_getApproxHintTest.js +++ b/contracts/test/HintHelpers_getApproxHintTest.js @@ -1,15 +1,11 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); const { fundAccounts } = require("../utils/fundAccounts.js"); -const th = testHelpers.TestHelper; const { dec, toBN } = th; -const moneyVals = testHelpers.MoneyValues; let latestRandomSeed = 31337; const TroveManagerTester = artifacts.require("TroveManagerTester"); -const BoldToken = artifacts.require("BoldToken"); const INITIAL_PRICE = dec(100, 18); @@ -26,7 +22,7 @@ contract("HintHelpers", async (accounts) => { let contracts; - let numAccounts; + let numAccounts = 10; const getNetBorrowingAmount = async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee); @@ -93,33 +89,24 @@ contract("HintHelpers", async (accounts) => { // console.timeEnd('makeTrovesInSequence') }; - before(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - + const deployFixture = createDeployAndFundFixture({ + accounts: [owner, bountyAddress, lpRewardsAddress, multisig], + mocks: { TroveManager: TroveManagerTester }, + callback: async (contracts) => { + await priceFeed.setPrice(INITIAL_PRICE); + await makeTrovesInSequence(accounts, numAccounts); + // await makeTrovesInParallel(accounts, numAccounts) + } + }); + + beforeEach(async () => { + const result = await deployFixture(); + contracts = result.contracts; sortedTroves = contracts.sortedTroves; troveManager = contracts.troveManager; borrowerOperations = contracts.borrowerOperations; hintHelpers = contracts.hintHelpers; priceFeed = contracts.priceFeedTestnet; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, bountyAddress, lpRewardsAddress, multisig - ], contracts.WETH); - - numAccounts = 10; - - 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 () => { diff --git a/contracts/test/SortedTrovesTest.js b/contracts/test/SortedTrovesTest.js index edb68d3e5..5e9e7ad44 100644 --- a/contracts/test/SortedTrovesTest.js +++ b/contracts/test/SortedTrovesTest.js @@ -1,17 +1,14 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); -const testHelpers = require("../utils/testHelpers.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); const SortedTroves = artifacts.require("SortedTroves"); const SortedTrovesTester = artifacts.require("SortedTrovesTester"); const TroveManagerTester = artifacts.require("TroveManagerTester"); -const BoldToken = artifacts.require("BoldToken"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; +const { dec, toBN } = th; contract("SortedTroves", async (accounts) => { + const fundedAccounts = accounts.slice(0, 28); + const assertSortedListIsOrdered = async (contracts) => { const price = await contracts.priceFeedTestnet.getPrice(); @@ -23,14 +20,14 @@ contract("SortedTroves", async (accounts) => { const troveICR = await contracts.troveManager.getCurrentICR(trove, price); const prevTroveICR = await contracts.troveManager.getCurrentICR( prevTrove, - price + price, ); assert.isTrue(prevTroveICR.gte(troveICR)); const troveNICR = await contracts.troveManager.getNominalICR(trove); const prevTroveNICR = await contracts.troveManager.getNominalICR( - prevTrove + prevTrove, ); assert.isTrue(prevTroveNICR.gte(troveNICR)); @@ -66,7 +63,7 @@ contract("SortedTroves", async (accounts) => { I, J, whale, - ] = accounts; + ] = fundedAccounts; let priceFeed; let sortedTroves; @@ -78,60 +75,22 @@ contract("SortedTroves", async (accounts) => { let contracts; + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + const openTrove = async (params) => th.openTrove(contracts, params); describe("SortedTroves", () => { beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - + const result = await deployFixture(); + contracts = result.contracts; priceFeed = contracts.priceFeedTestnet; sortedTroves = contracts.sortedTroves; troveManager = contracts.troveManager; borrowerOperations = contracts.borrowerOperations; boldToken = contracts.boldToken; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts( - [ - owner, - alice, - bob, - carol, - dennis, - erin, - flyn, - graham, - harriet, - ida, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - whale, - bountyAddress, - lpRewardsAddress, - multisig, - ], - contracts.WETH - ); }); it("contains(): returns true for addresses that have opened troves", async () => { @@ -312,11 +271,23 @@ contract("SortedTroves", async (accounts) => { ICR: toBN(dec(500, 18)), extraParams: { from: whale }, }); - 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 - const { troveId: ETroveId } = await openTrove({ ICR: toBN(dec(125, 16)), extraParams: { from: E, annualInterestRate: toBN(dec(1, 16))}}); // 1% 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 + 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)); @@ -339,7 +310,7 @@ contract("SortedTroves", async (accounts) => { }); describe("SortedTroves with mock dependencies", () => { - let sortedTrovesTester; + let sortedTrovesTester; beforeEach(async () => { sortedTroves = await SortedTroves.new(); @@ -355,9 +326,9 @@ contract("SortedTroves", async (accounts) => { 0, // The SortedTrovesTester is being used here as both a wrapper for SortedTroves and a mock TroveManager. sortedTrovesTester.address, - sortedTrovesTester.address + sortedTrovesTester.address, ), - "SortedTroves: Size can’t be zero" + "SortedTroves: Size can’t be zero", ); }); }); @@ -367,7 +338,7 @@ contract("SortedTroves", async (accounts) => { await sortedTroves.setParams( 2, sortedTrovesTester.address, - sortedTrovesTester.address + sortedTrovesTester.address, ); }); @@ -376,7 +347,7 @@ contract("SortedTroves", async (accounts) => { await sortedTrovesTester.insert(bob, 1, alice, alice); await th.assertRevert( sortedTrovesTester.insert(carol, 1, alice, alice), - "SortedTroves: List is full" + "SortedTroves: List is full", ); }); @@ -384,37 +355,47 @@ contract("SortedTroves", async (accounts) => { await sortedTrovesTester.insert(alice, 1, alice, alice); await th.assertRevert( sortedTrovesTester.insert(alice, 1, alice, alice), - "SortedTroves: List already contains the node" + "SortedTroves: List already contains the node", ); }); it("insert(): fails if id is zero", async () => { await th.assertRevert( sortedTrovesTester.insert(toBN(0), 1, alice, alice), - "SortedTroves: Id cannot be zero" + "SortedTroves: Id cannot be zero", ); }); it("remove(): fails if id is not in the list", async () => { await th.assertRevert( sortedTrovesTester.remove(th.addressToTroveId(alice)), - "SortedTroves: List does not contain the id" + "SortedTroves: List does not contain the id", ); }); it("reInsert(): fails if list doesn’t contain the node", async () => { await th.assertRevert( - sortedTrovesTester.reInsert(th.addressToTroveId(alice), 1, th.addressToTroveId(alice), th.addressToTroveId(alice)), - "SortedTroves: List does not contain the id" + 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(th.addressToTroveId(alice), 1, th.addressToTroveId(alice), th.addressToTroveId(alice)); + await sortedTrovesTester.insert( + th.addressToTroveId(alice), + 1, + th.addressToTroveId(alice), + th.addressToTroveId(alice), + ); const pos = await sortedTroves.findInsertPosition( 1, toBN(0), - th.addressToTroveId(alice) + th.addressToTroveId(alice), ); 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/TroveManager_RecoveryModeTest.js b/contracts/test/TroveManager_RecoveryModeTest.js index 7669b760e..43cfcbb0a 100644 --- a/contracts/test/TroveManager_RecoveryModeTest.js +++ b/contracts/test/TroveManager_RecoveryModeTest.js @@ -1,19 +1,17 @@ const { time } = require('@nomicfoundation/hardhat-network-helpers'); -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { + MoneyValues: mv, + TestHelper: th, + TimeValues: timeValues, +} = require("../utils/testHelpers.js"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const assertRevert = th.assertRevert; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; +const { assertRevert, dec, toBN } = th; const TroveManagerTester = artifacts.require("./TroveManagerTester"); -const BoldToken = artifacts.require("./BoldToken.sol"); contract.skip("TroveManager - in Recovery Mode", async (accounts) => { + const fundedAccounts = accounts.slice(0, 24); + const _1_Ether = web3.utils.toWei("1", "ether"); const _2_Ether = web3.utils.toWei("2", "ether"); const _3_Ether = web3.utils.toWei("3", "ether"); @@ -27,7 +25,6 @@ contract.skip("TroveManager - in Recovery Mode", async (accounts) => { const _25_Ether = web3.utils.toWei("25", "ether"); const _30_Ether = web3.utils.toWei("30", "ether"); - const ZERO_ADDRESS = th.ZERO_ADDRESS; const [ owner, alice, @@ -53,7 +50,7 @@ contract.skip("TroveManager - in Recovery Mode", async (accounts) => { G, H, I, - ] = accounts; + ] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); @@ -76,16 +73,14 @@ contract.skip("TroveManager - in Recovery Mode", async (accounts) => { th.getNetBorrowingAmount(contracts, debtWithFee); const openTrove = async (params) => th.openTrove(contracts, params); + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - + const result = await deployFixture(); + contracts = result.contracts; priceFeed = contracts.priceFeedTestnet; boldToken = contracts.boldToken; sortedTroves = contracts.sortedTroves; @@ -96,35 +91,6 @@ contract.skip("TroveManager - in Recovery Mode", async (accounts) => { functionCaller = contracts.functionCaller; borrowerOperations = contracts.borrowerOperations; collSurplusPool = contracts.collSurplusPool; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, - alice, - bob, - carol, - dennis, - erin, - freddy, - greta, - harry, - ida, - whale, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - A, - B, - C, - D, - E, - F, - G, - H, - I, - ], contracts.WETH); }); it("checkRecoveryMode(): Returns true if TCR falls below CCR", async () => { diff --git a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js index eb631593c..24df8fbed 100644 --- a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js +++ b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js @@ -1,14 +1,14 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); const { TestHelper: th, MoneyValues: mv } = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); -const { toBN, dec, ZERO_ADDRESS } = th; + +const { toBN, dec } = th; const TroveManagerTester = artifacts.require("./TroveManagerTester"); -const BoldToken = artifacts.require("./BoldToken.sol"); contract.skip( "TroveManager - in Recovery Mode - back to normal mode in 1 tx", async (accounts) => { + const fundedAccounts = accounts.slice(0, 24); + const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice( 997, 1000 @@ -38,7 +38,7 @@ contract.skip( G, H, I, - ] = accounts; + ] = fundedAccounts; let contracts; let troveManager; @@ -48,49 +48,18 @@ contract.skip( const openTrove = async (params) => th.openTrove(contracts, params); + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ); - + const result = await deployFixture(); + contracts = result.contracts; troveManager = contracts.troveManager; stabilityPool = contracts.stabilityPool; priceFeed = contracts.priceFeedTestnet; sortedTroves = contracts.sortedTroves; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([ - owner, - alice, - bob, - carol, - dennis, - erin, - freddy, - greta, - harry, - ida, - whale, - defaulter_1, - defaulter_2, - defaulter_3, - defaulter_4, - A, - B, - C, - D, - E, - F, - G, - H, - I, - ], contracts.WETH); }); context("Batch liquidations", () => { diff --git a/contracts/test/stakeDeclineTest.js b/contracts/test/stakeDeclineTest.js index c2cb84de3..e89d60667 100644 --- a/contracts/test/stakeDeclineTest.js +++ b/contracts/test/stakeDeclineTest.js @@ -1,15 +1,7 @@ -const deploymentHelper = require("../utils/deploymentHelpers.js"); -const testHelpers = require("../utils/testHelpers.js"); -const { fundAccounts } = require("../utils/fundAccounts.js"); +const { TestHelper: th } = require("../utils/testHelpers.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); -const BoldToken = artifacts.require("./BoldToken.sol"); -const th = testHelpers.TestHelper; -const dec = th.dec; -const toBN = th.toBN; -const assertRevert = th.assertRevert; -const mv = testHelpers.MoneyValues; -const timeValues = testHelpers.TimeValues; +const { dec, toBN, ZERO_ADDRESS } = th; /* NOTE: Some tests involving ETH redemption fees do not test for specific fee values. * Some only test that the fees are non-zero when they should occur. @@ -19,11 +11,13 @@ const timeValues = testHelpers.TimeValues; * */ contract("TroveManager", async (accounts) => { - const ZERO_ADDRESS = th.ZERO_ADDRESS; - const [owner, A, B, C, D, E, F] = accounts.slice(0, 7); + const fundedAccounts = accounts.slice(0, 7); + + const [owner, A, B, C, D, E, F] = fundedAccounts; const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000); + let contracts; let priceFeed; let boldToken; let sortedTroves; @@ -35,8 +29,6 @@ contract("TroveManager", async (accounts) => { let borrowerOperations; let hintHelpers; - let contracts; - const getOpenTroveBoldAmount = async (totalDebt) => th.getOpenTroveBoldAmount(contracts, totalDebt); @@ -48,16 +40,14 @@ contract("TroveManager", async (accounts) => { return ratio; }; - beforeEach(async () => { - contracts = await deploymentHelper.deployLiquityCore(); - contracts.troveManager = await TroveManagerTester.new(); - contracts.boldToken = await BoldToken.new( - contracts.troveManager.address, - contracts.stabilityPool.address, - contracts.borrowerOperations.address, - contracts.activePool.address - ) + const deployFixture = createDeployAndFundFixture({ + accounts: fundedAccounts, + mocks: { TroveManager: TroveManagerTester }, + }); + beforeEach(async () => { + const result = await deployFixture(); + contracts = result.contracts; priceFeed = contracts.priceFeedTestnet; boldToken = contracts.boldToken; sortedTroves = contracts.sortedTroves; @@ -68,10 +58,6 @@ contract("TroveManager", async (accounts) => { collSurplusPool = contracts.collSurplusPool; borrowerOperations = contracts.borrowerOperations; hintHelpers = contracts.hintHelpers; - - await deploymentHelper.connectCoreContracts(contracts); - - await fundAccounts([owner, A, B, C, D, E, F], contracts.WETH); }); it("A given trove's stake decline is negligible with adjustments and tiny liquidations", async () => { From 262dd7072d8a7878a7250672b09588944cae06e3 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 9 Apr 2024 01:12:16 +0100 Subject: [PATCH 11/19] Run tests in parallel --- contracts/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/package.json b/contracts/package.json index 834a6a872..fbb421a47 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -7,7 +7,7 @@ "lib": "lib" }, "scripts": { - "test": "hardhat test", + "test": "hardhat test --parallel", "coverage": "hardhat coverage" }, "repository": { From cb1f4e8d28366f1200c75fb11b2c8f103686e5cd Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 9 Apr 2024 11:39:44 +0100 Subject: [PATCH 12/19] Remove more log from output --- contracts/test/StabilityPool_SPWithdrawalTest.js | 3 +-- contracts/test/StabilityPool_SPWithdrawalToCDPTest.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/test/StabilityPool_SPWithdrawalTest.js b/contracts/test/StabilityPool_SPWithdrawalTest.js index d9b1fd575..1a3a719f7 100644 --- a/contracts/test/StabilityPool_SPWithdrawalTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalTest.js @@ -463,7 +463,6 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' const carol_ETHWithdrawn = th.getEventArgByName(txC, 'ETHGainWithdrawn', '_ETH').toString() const dennis_ETHWithdrawn = th.getEventArgByName(txD, 'ETHGainWithdrawn', '_ETH').toString() - console.log() assert.isAtMost(th.getDifference((await boldToken.balanceOf(alice)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference((await boldToken.balanceOf(bob)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference((await boldToken.balanceOf(carol)).toString(), '1666666666666666666666'), 100000) @@ -1452,7 +1451,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isTrue(txL1.receipt.status) const aliceDeposit = (await stabilityPool.getCompoundedBoldDeposit(alice)).toString() - console.log(`alice deposit: ${aliceDeposit}`) + // console.log(`alice deposit: ${aliceDeposit}`) assert.equal(aliceDeposit, 0) }) diff --git a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js index b0dd1bb6e..93e489ccf 100644 --- a/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js +++ b/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js @@ -515,7 +515,6 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' const carol_ETHWithdrawn = th.getEventArgByName(txC, 'ETHGainWithdrawn', '_ETH').toString() const dennis_ETHWithdrawn = th.getEventArgByName(txD, 'ETHGainWithdrawn', '_ETH').toString() - console.log() assert.isAtMost(th.getDifference((await stabilityPool.getCompoundedBoldDeposit(alice)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference((await stabilityPool.getCompoundedBoldDeposit(bob)).toString(), '1666666666666666666666'), 100000) assert.isAtMost(th.getDifference((await stabilityPool.getCompoundedBoldDeposit(carol)).toString(), '1666666666666666666666'), 100000) @@ -1592,7 +1591,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' assert.isTrue(txL1.receipt.status) const aliceDeposit = (await stabilityPool.getCompoundedBoldDeposit(alice)).toString() - console.log(`alice deposit: ${aliceDeposit}`) + // console.log(`alice deposit: ${aliceDeposit}`) assert.equal(aliceDeposit, 0) }) From db1d666d8c5c58482a27191567bd33f1091f818e Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 9 Apr 2024 11:51:15 +0100 Subject: [PATCH 13/19] fundAccounts: remove unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s probably better to not rely on `accounts[0]` to know if all accounts have been funded, since `accounts` is dynamic. --- contracts/utils/fundAccounts.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/contracts/utils/fundAccounts.js b/contracts/utils/fundAccounts.js index e80a18198..4f0f6e49f 100644 --- a/contracts/utils/fundAccounts.js +++ b/contracts/utils/fundAccounts.js @@ -1,9 +1,4 @@ const fundAccounts = async (accounts, token) => { - // const areAccountsAlreadyFunded = await token - // .balanceOf(accounts[0]) - // .gte(_1e36Str); - // if (areAccountsAlreadyFunded) return; - return Promise.all( accounts.map((account) => ( token.mint(account, String(10n ** 36n)) From 545098f901769fe47e06392510c339c8498dd486 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Tue, 9 Apr 2024 12:58:45 +0100 Subject: [PATCH 14/19] Align coding style --- contracts/test/BorrowerOperationsTest.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contracts/test/BorrowerOperationsTest.js b/contracts/test/BorrowerOperationsTest.js index 717e0dc3d..2906809d5 100644 --- a/contracts/test/BorrowerOperationsTest.js +++ b/contracts/test/BorrowerOperationsTest.js @@ -6,9 +6,7 @@ const BorrowerOperationsTester = artifacts.require( ); const TroveManagerTester = artifacts.require("TroveManagerTester"); -const dec = th.dec; -const toBN = th.toBN; -const assertRevert = th.assertRevert; +const { dec, toBN, assertRevert } = th; contract("BorrowerOperations", async (accounts) => { const accountsToFund = accounts.slice(0, 17); From 1091e3b56ffd84e3b4f11dc84aa77a936eee5a8c Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Wed, 10 Apr 2024 13:36:58 +0100 Subject: [PATCH 15/19] Minor tweak --- contracts/utils/testFixtures.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js index 87f9bb19c..be14673e1 100644 --- a/contracts/utils/testFixtures.js +++ b/contracts/utils/testFixtures.js @@ -13,14 +13,13 @@ function createDeployAndFundFixture({ mocks = {}, // e.g. { Contract: MockContract } } = {}) { const fixture = async () => { + const time = Date.now(); const contracts = await deploymentHelper.deployLiquityCore(mocks); await deploymentHelper.connectCoreContracts(contracts); contracts.priceFeed = contracts.priceFeedTestnet; await fundAccounts(accounts, contracts.WETH); - return { - contracts, - ...await callback(contracts), - }; + const callbackResult = await callback(contracts); + return { contracts, ...callbackResult }; }; return () => loadFixture(fixture); } From 95eed5e77dfb4f1b5a603595a193bedc779be220 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 11 Apr 2024 12:04:52 +0100 Subject: [PATCH 16/19] Remove debugging code --- contracts/utils/testFixtures.js | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/utils/testFixtures.js b/contracts/utils/testFixtures.js index be14673e1..02170c0d7 100644 --- a/contracts/utils/testFixtures.js +++ b/contracts/utils/testFixtures.js @@ -13,7 +13,6 @@ function createDeployAndFundFixture({ mocks = {}, // e.g. { Contract: MockContract } } = {}) { const fixture = async () => { - const time = Date.now(); const contracts = await deploymentHelper.deployLiquityCore(mocks); await deploymentHelper.connectCoreContracts(contracts); contracts.priceFeed = contracts.priceFeedTestnet; From 77b757bf41a39efaa6f39ed165232ce7713fc8b1 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 11 Apr 2024 13:06:48 +0100 Subject: [PATCH 17/19] Add missing imports --- contracts/test/SortedTrovesTest.js | 1 + .../test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js | 1 + contracts/test/stakeDeclineTest.js | 1 + 3 files changed, 3 insertions(+) diff --git a/contracts/test/SortedTrovesTest.js b/contracts/test/SortedTrovesTest.js index a53fac243..f5aaacc92 100644 --- a/contracts/test/SortedTrovesTest.js +++ b/contracts/test/SortedTrovesTest.js @@ -1,4 +1,5 @@ const { TestHelper: th } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const SortedTroves = artifacts.require("SortedTroves"); const SortedTrovesTester = artifacts.require("SortedTrovesTester"); diff --git a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js index 24df8fbed..b0084a679 100644 --- a/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js +++ b/contracts/test/TroveManager_RecoveryMode_Batch_Liqudation_Test.js @@ -1,4 +1,5 @@ const { TestHelper: th, MoneyValues: mv } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const { toBN, dec } = th; diff --git a/contracts/test/stakeDeclineTest.js b/contracts/test/stakeDeclineTest.js index e89d60667..76f338462 100644 --- a/contracts/test/stakeDeclineTest.js +++ b/contracts/test/stakeDeclineTest.js @@ -1,5 +1,6 @@ const { TestHelper: th } = require("../utils/testHelpers.js"); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const { dec, toBN, ZERO_ADDRESS } = th; From 4aac6352e77da033273315987e35a2bcae8e9e98 Mon Sep 17 00:00:00 2001 From: Pierre Bertet Date: Thu, 11 Apr 2024 13:07:17 +0100 Subject: [PATCH 18/19] Remove output from tests --- contracts/test/stakeDeclineTest.js | 48 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/contracts/test/stakeDeclineTest.js b/contracts/test/stakeDeclineTest.js index 76f338462..0063446c3 100644 --- a/contracts/test/stakeDeclineTest.js +++ b/contracts/test/stakeDeclineTest.js @@ -138,19 +138,19 @@ contract("TroveManager", async (accounts) => { ); await troveManager.liquidate(ATroveId); - console.log( - `totalStakesSnapshot after L1: ${await troveManager.totalStakesSnapshot()}` - ); - console.log( - `totalCollateralSnapshot after L1: ${await troveManager.totalCollateralSnapshot()}` - ); - console.log(`Snapshots ratio after L1: ${await getSnapshotsRatio()}`); - console.log( - `B pending ETH reward after L1: ${await troveManager.getPendingETHReward( - B - )}` - ); - console.log(`B stake after L1: ${(await troveManager.Troves(BTroveId))[2]}`); + // console.log( + // `totalStakesSnapshot after L1: ${await troveManager.totalStakesSnapshot()}` + // ); + // console.log( + // `totalCollateralSnapshot after L1: ${await troveManager.totalCollateralSnapshot()}` + // ); + // console.log(`Snapshots ratio after L1: ${await getSnapshotsRatio()}`); + // console.log( + // `B pending ETH reward after L1: ${await troveManager.getPendingETHReward( + // B + // )}` + // ); + // console.log(`B stake after L1: ${(await troveManager.Troves(BTroveId))[2]}`); // adjust trove B 1 wei: apply rewards await borrowerOperations.adjustTrove( @@ -162,20 +162,20 @@ contract("TroveManager", async (accounts) => { false, { from: B } ); // B repays 1 wei - console.log(`B stake after A1: ${(await troveManager.Troves(BTroveId))[2]}`); - console.log(`Snapshots ratio after A1: ${await getSnapshotsRatio()}`); + // 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(th.addressToTroveId(trove)); - console.log( - `B stake after L${idx + 2}: ${(await troveManager.Troves(BTroveId))[2]}` - ); - console.log( - `Snapshots ratio after L${idx + 2}: ${await getSnapshotsRatio()}` - ); + // console.log( + // `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, @@ -185,9 +185,9 @@ contract("TroveManager", async (accounts) => { false, { from: B } ); // A repays 1 wei - console.log( - `B stake after A${idx + 2}: ${(await troveManager.Troves(B))[2]}` - ); + // console.log( + // `B stake after A${idx + 2}: ${(await troveManager.Troves(B))[2]}` + // ); } }); From 30c1b784f0394d88792719f617de2ad6eb90da01 Mon Sep 17 00:00:00 2001 From: Daniel Simon Date: Fri, 12 Apr 2024 09:11:07 +0700 Subject: [PATCH 19/19] test: add missing import Some skipped test cases weren't being counted towards the total. Although they're currently skipped, it's better to fix this or we might forget about them in the future. --- contracts/test/TroveManager_RecoveryModeTest.js | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/test/TroveManager_RecoveryModeTest.js b/contracts/test/TroveManager_RecoveryModeTest.js index 43cfcbb0a..71fff691c 100644 --- a/contracts/test/TroveManager_RecoveryModeTest.js +++ b/contracts/test/TroveManager_RecoveryModeTest.js @@ -4,6 +4,7 @@ const { TestHelper: th, TimeValues: timeValues, } = require("../utils/testHelpers.js"); +const { createDeployAndFundFixture } = require("../utils/testFixtures.js"); const { assertRevert, dec, toBN } = th;