diff --git a/packages/contracts/package.json b/packages/contracts/package.json index af59bc71f..f8763ddc7 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -34,6 +34,7 @@ "@openzeppelin/contracts": "^3.3.0", "@openzeppelin/test-helpers": "^0.5.10", "eth-gas-reporter": "^0.2.22", + "ganache-time-traveler": "1.0.15", "hardhat": "^2.1.1", "hardhat-gas-reporter": "^1.0.1", "npm-run-all": "^4.1.5", diff --git a/packages/contracts/test/BorrowerOperationsTest.js b/packages/contracts/test/BorrowerOperationsTest.js index b98ee259a..9c9db9856 100644 --- a/packages/contracts/test/BorrowerOperationsTest.js +++ b/packages/contracts/test/BorrowerOperationsTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const BorrowerOperationsTester = artifacts.require("./BorrowerOperationsTester.sol") const NonPayable = artifacts.require('NonPayable.sol') @@ -67,7 +68,7 @@ contract('BorrowerOperations', async accounts => { }) const testCorpus = ({ withProxy = false }) => { - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.borrowerOperations = await BorrowerOperationsTester.new() contracts.troveManager = await TroveManagerTester.new() @@ -103,6 +104,17 @@ contract('BorrowerOperations', async accounts => { BORROWING_FEE_FLOOR = await borrowerOperations.BORROWING_FEE_FLOOR() }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("addColl(): reverts when top-up would leave trove with ICR < MCR", async () => { // alice creates a Trove and adds first collateral await openTrove({ ICR: toBN(dec(2, 18)), extraParams: { from: alice } }) @@ -117,7 +129,7 @@ contract('BorrowerOperations', async accounts => { const collTopUp = 1 // 1 wei top up - await assertRevert(borrowerOperations.addColl(alice, alice, { from: alice, value: collTopUp }), + await assertRevert(borrowerOperations.addColl(alice, alice, { from: alice, value: collTopUp }), "BorrowerOps: An operation that would result in ICR < MCR is not permitted") }) diff --git a/packages/contracts/test/CollSurplusPool.js b/packages/contracts/test/CollSurplusPool.js index 995f8266d..f8cffe1e1 100644 --- a/packages/contracts/test/CollSurplusPool.js +++ b/packages/contracts/test/CollSurplusPool.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const NonPayable = artifacts.require('NonPayable.sol') const th = testHelpers.TestHelper @@ -27,7 +28,7 @@ contract('CollSurplusPool', async accounts => { const getOpenTroveLUSDAmount = async (totalDebt) => th.getOpenTroveLUSDAmount(contracts, totalDebt) const openTrove = async (params) => th.openTrove(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -46,6 +47,17 @@ contract('CollSurplusPool', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("CollSurplusPool::getETH(): Returns the ETH balance of the CollSurplusPool after redemption", async () => { const ETH_1 = await collSurplusPool.getETH() assert.equal(ETH_1, '0') diff --git a/packages/contracts/test/FeeArithmeticTest.js b/packages/contracts/test/FeeArithmeticTest.js index 7417291d2..7fb97102f 100644 --- a/packages/contracts/test/FeeArithmeticTest.js +++ b/packages/contracts/test/FeeArithmeticTest.js @@ -2,6 +2,7 @@ const Decimal = require("decimal.js"); const deploymentHelper = require("../utils/deploymentHelpers.js") const { BNConverter } = require("../utils/BNConverter.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const LiquityMathTester = artifacts.require("./LiquityMathTester.sol") @@ -336,17 +337,25 @@ contract('Fee arithmetic tests', async accounts => { mathTester = await LiquityMathTester.new() LiquityMathTester.setAsDeployed(mathTester) - }) - - beforeEach(async () => { contracts = await deploymentHelper.deployLiquityCore() const LQTYContracts = await deploymentHelper.deployLQTYContracts(bountyAddress, lpRewardsAddress, multisig) - + await deploymentHelper.connectLQTYContracts(LQTYContracts) await deploymentHelper.connectCoreContracts(contracts, LQTYContracts) await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("minutesPassedSinceLastFeeOp(): returns minutes passed for no time increase", async () => { await troveManagerTester.setLastFeeOpTimeToNow() const minutesPassed = await troveManagerTester.minutesPassedSinceLastFeeOp() diff --git a/packages/contracts/test/GasCompensationTest.js b/packages/contracts/test/GasCompensationTest.js index 2b2684e94..751be1487 100644 --- a/packages/contracts/test/GasCompensationTest.js +++ b/packages/contracts/test/GasCompensationTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const BorrowerOperationsTester = artifacts.require("./BorrowerOperationsTester.sol") const LUSDToken = artifacts.require("LUSDToken") @@ -46,9 +47,6 @@ contract('Gas compensation tests', async accounts => { TroveManagerTester.setAsDeployed(troveManagerTester) BorrowerOperationsTester.setAsDeployed(borrowerOperationsTester) - }) - - beforeEach(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -57,7 +55,7 @@ contract('Gas compensation tests', async accounts => { contracts.borrowerOperations.address ) const LQTYContracts = await deploymentHelper.deployLQTYContracts(bountyAddress, lpRewardsAddress, multisig) - + priceFeed = contracts.priceFeedTestnet lusdToken = contracts.lusdToken sortedTroves = contracts.sortedTroves @@ -66,12 +64,23 @@ contract('Gas compensation tests', async accounts => { stabilityPool = contracts.stabilityPool defaultPool = contracts.defaultPool borrowerOperations = contracts.borrowerOperations - + await deploymentHelper.connectLQTYContracts(LQTYContracts) await deploymentHelper.connectCoreContracts(contracts, LQTYContracts) await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + // --- Raw gas compensation calculations --- it('_getCollGasCompensation(): returns the 0.5% of collaterall if it is < $10 in value', async () => { diff --git a/packages/contracts/test/GrowthTokenTest.js b/packages/contracts/test/GrowthTokenTest.js index a369fe821..300a4f14f 100644 --- a/packages/contracts/test/GrowthTokenTest.js +++ b/packages/contracts/test/GrowthTokenTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const { keccak256 } = require('@ethersproject/keccak256'); const { defaultAbiCoder } = require('@ethersproject/abi'); @@ -107,7 +108,7 @@ contract('LQTY Token', async accounts => { return { v, r, s, tx } } - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() const LQTYContracts = await deploymentHelper.deployLQTYTesterContractsHardhat(bountyAddress, lpRewardsAddress, multisig) @@ -124,6 +125,17 @@ contract('LQTY Token', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('balanceOf(): gets the balance of the account', async () => { await mintToABC() diff --git a/packages/contracts/test/LQTYIssuanceArithmeticTest.js b/packages/contracts/test/LQTYIssuanceArithmeticTest.js index 47850f434..5fc7b3670 100644 --- a/packages/contracts/test/LQTYIssuanceArithmeticTest.js +++ b/packages/contracts/test/LQTYIssuanceArithmeticTest.js @@ -2,6 +2,7 @@ const Decimal = require("decimal.js"); const deploymentHelper = require("../utils/deploymentHelpers.js") const { BNConverter } = require("../utils/BNConverter.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const StabilityPool = artifacts.require("./StabilityPool.sol") const th = testHelpers.TestHelper @@ -45,10 +46,6 @@ contract('LQTY community issuance arithmetic tests', async accounts => { const [bountyAddress, lpRewardsAddress, multisig] = accounts.slice(997, 1000) before(async () => { - - }) - - beforeEach(async () => { contracts = await deploymentHelper.deployLiquityCore() const LQTYContracts = await deploymentHelper.deployLQTYTesterContractsHardhat(bountyAddress, lpRewardsAddress, multisig) contracts.stabilityPool = await StabilityPool.new() @@ -65,6 +62,17 @@ contract('LQTY community issuance arithmetic tests', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + // Accuracy tests it("getCumulativeIssuanceFraction(): fraction doesn't increase if less than a minute has passed", async () => { // progress time 1 week diff --git a/packages/contracts/test/LQTYStakingFeeRewardsTest.js b/packages/contracts/test/LQTYStakingFeeRewardsTest.js index bde3750e1..470524e71 100644 --- a/packages/contracts/test/LQTYStakingFeeRewardsTest.js +++ b/packages/contracts/test/LQTYStakingFeeRewardsTest.js @@ -2,6 +2,7 @@ const Decimal = require("decimal.js"); const deploymentHelper = require("../utils/deploymentHelpers.js") const { BNConverter } = require("../utils/BNConverter.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const LQTYStakingTester = artifacts.require('LQTYStakingTester') const TroveManagerTester = artifacts.require("TroveManagerTester") @@ -45,7 +46,7 @@ contract('LQTYStaking revenue share tests', async accounts => { const openTrove = async (params) => th.openTrove(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts = await deploymentHelper.deployLUSDTokenTester(contracts) @@ -70,6 +71,17 @@ contract('LQTYStaking revenue share tests', async accounts => { lqtyStaking = LQTYContracts.lqtyStaking }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('stake(): reverts if amount is zero', async () => { // FF time one year so owner can transfer LQTY await th.fastForwardTime(timeValues.SECONDS_IN_ONE_YEAR, web3.currentProvider) diff --git a/packages/contracts/test/LUSDTokenTest.js b/packages/contracts/test/LUSDTokenTest.js index f3345a3c3..253d552db 100644 --- a/packages/contracts/test/LUSDTokenTest.js +++ b/packages/contracts/test/LUSDTokenTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const { keccak256 } = require('@ethersproject/keccak256'); const { defaultAbiCoder } = require('@ethersproject/abi'); @@ -64,7 +65,7 @@ contract('LUSDToken', async accounts => { let tokenVersion const testCorpus = ({ withProxy = false }) => { - beforeEach(async () => { + before(async () => { const contracts = await deploymentHelper.deployTesterContractsHardhat() @@ -105,6 +106,17 @@ contract('LUSDToken', async accounts => { } }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('balanceOf(): gets the balance of the account', async () => { const aliceBalance = (await lusdTokenTester.balanceOf(alice)).toNumber() const bobBalance = (await lusdTokenTester.balanceOf(bob)).toNumber() diff --git a/packages/contracts/test/LiquitySafeMath128Test.js b/packages/contracts/test/LiquitySafeMath128Test.js index 4e0c809b5..ad75bfaf6 100644 --- a/packages/contracts/test/LiquitySafeMath128Test.js +++ b/packages/contracts/test/LiquitySafeMath128Test.js @@ -6,7 +6,7 @@ const LiquitySafeMath128Tester = artifacts.require("LiquitySafeMath128Tester") contract('LiquitySafeMath128Tester', async accounts => { let mathTester - beforeEach(async () => { + before(async () => { mathTester = await LiquitySafeMath128Tester.new() }) diff --git a/packages/contracts/test/PoolsTest.js b/packages/contracts/test/PoolsTest.js index 09dd12ffb..901339ddc 100644 --- a/packages/contracts/test/PoolsTest.js +++ b/packages/contracts/test/PoolsTest.js @@ -4,6 +4,7 @@ const DefaultPool = artifacts.require("./DefaultPool.sol") const NonPayable = artifacts.require("./NonPayable.sol") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const th = testHelpers.TestHelper const dec = th.dec @@ -18,13 +19,24 @@ contract('StabilityPool', async accounts => { const [owner, alice] = accounts; - beforeEach(async () => { + before(async () => { stabilityPool = await StabilityPool.new() const mockActivePoolAddress = (await NonPayable.new()).address const dumbContractAddress = (await NonPayable.new()).address await stabilityPool.setAddresses(dumbContractAddress, dumbContractAddress, mockActivePoolAddress, dumbContractAddress, dumbContractAddress, dumbContractAddress, dumbContractAddress) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('getETH(): gets the recorded ETH balance', async () => { const recordedETHBalance = await stabilityPool.getETH() assert.equal(recordedETHBalance, 0) diff --git a/packages/contracts/test/PriceFeedTest.js b/packages/contracts/test/PriceFeedTest.js index 40771e178..ec70d6f1a 100644 --- a/packages/contracts/test/PriceFeedTest.js +++ b/packages/contracts/test/PriceFeedTest.js @@ -6,6 +6,7 @@ const MockTellor = artifacts.require("./MockTellor.sol") const TellorCaller = artifacts.require("./TellorCaller.sol") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const th = testHelpers.TestHelper const { dec, assertRevert, toBN } = th @@ -22,7 +23,7 @@ contract('PriceFeed', async accounts => { await priceFeed.setAddresses(mockChainlink.address, tellorCaller.address, { from: owner }) } - beforeEach(async () => { + before(async () => { priceFeedTestnet = await PriceFeedTestnet.new() PriceFeedTestnet.setAsDeployed(priceFeedTestnet) @@ -56,6 +57,17 @@ contract('PriceFeed', async accounts => { await mockTellor.setUpdateTime(now) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + describe('PriceFeed internal testing contract', async accounts => { it("fetchPrice before setPrice should return the default price", async () => { const price = await priceFeedTestnet.getPrice() diff --git a/packages/contracts/test/ProxyBorrowerWrappersScript.js b/packages/contracts/test/ProxyBorrowerWrappersScript.js index faa2a52f5..3bce8393d 100644 --- a/packages/contracts/test/ProxyBorrowerWrappersScript.js +++ b/packages/contracts/test/ProxyBorrowerWrappersScript.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("TroveManagerTester") const LQTYTokenTester = artifacts.require("LQTYTokenTester") @@ -60,7 +61,7 @@ contract('BorrowerWrappers', async accounts => { const getNetBorrowingAmount = async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee) const openTrove = async (params) => th.openTrove(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts = await deploymentHelper.deployLUSDToken(contracts) @@ -92,6 +93,17 @@ contract('BorrowerWrappers', async accounts => { LUSD_GAS_COMPENSATION = await borrowerOperations.LUSD_GAS_COMPENSATION() }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('proxy owner can recover ETH', async () => { const amount = toBN(dec(1, 18)) const proxyAddress = borrowerWrappers.getProxyAddressFromUser(alice) diff --git a/packages/contracts/test/SortedTrovesTest.js b/packages/contracts/test/SortedTrovesTest.js index f49a1f0cc..f4c687312 100644 --- a/packages/contracts/test/SortedTrovesTest.js +++ b/packages/contracts/test/SortedTrovesTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const SortedTroves = artifacts.require("SortedTroves") const SortedTrovesTester = artifacts.require("SortedTrovesTester") @@ -57,7 +58,7 @@ contract('SortedTroves', async accounts => { const openTrove = async (params) => th.openTrove(contracts, params) describe('SortedTroves', () => { - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -78,6 +79,17 @@ contract('SortedTroves', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('contains(): returns true for addresses that have opened troves', async () => { await openTrove({ ICR: toBN(dec(150, 16)), extraParams: { from: alice } }) await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: bob } }) @@ -277,13 +289,24 @@ contract('SortedTroves', async accounts => { describe('SortedTroves with mock dependencies', () => { let sortedTrovesTester - beforeEach(async () => { + before(async () => { sortedTroves = await SortedTroves.new() sortedTrovesTester = await SortedTrovesTester.new() await sortedTrovesTester.setSortedTroves(sortedTroves.address) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + context('when params are wrongly set', () => { it('setParams(): reverts if size is zero', async () => { await th.assertRevert(sortedTroves.setParams(0, sortedTrovesTester.address, sortedTrovesTester.address), 'SortedTroves: Size can’t be zero') diff --git a/packages/contracts/test/StabilityPool_LQTYIssuanceTest.js b/packages/contracts/test/StabilityPool_LQTYIssuanceTest.js index 8e5c7141d..21c68cb4b 100644 --- a/packages/contracts/test/StabilityPool_LQTYIssuanceTest.js +++ b/packages/contracts/test/StabilityPool_LQTYIssuanceTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const th = testHelpers.TestHelper const timeValues = testHelpers.TimeValues @@ -48,7 +49,7 @@ contract('StabilityPool - LQTY Rewards', async accounts => { const openTrove = async (params) => th.openTrove(contracts, params) describe("LQTY Rewards", async () => { - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -98,6 +99,17 @@ contract('StabilityPool - LQTY Rewards', async accounts => { issuance_M6 = toBN('41651488815552900').mul(communityLQTYSupply).div(toBN(dec(1, 18))) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("liquidation < 1 minute after a deposit does not change totalLQTYIssued", async () => { diff --git a/packages/contracts/test/StabilityPool_SPWithdrawalTest.js b/packages/contracts/test/StabilityPool_SPWithdrawalTest.js index 2efe9ca7c..3eea253f0 100644 --- a/packages/contracts/test/StabilityPool_SPWithdrawalTest.js +++ b/packages/contracts/test/StabilityPool_SPWithdrawalTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const { dec, toBN } = testHelpers.TestHelper @@ -55,9 +56,6 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' before(async () => { gasPriceInWei = await web3.eth.getGasPrice() - }) - - beforeEach(async () => { contracts = await deploymentHelper.deployLiquityCore() const LQTYContracts = await deploymentHelper.deployLQTYContracts(bountyAddress, lpRewardsAddress, multisig) contracts.troveManager = await TroveManagerTester.new() @@ -77,6 +75,16 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); // --- Compounding tests --- // --- withdrawFromSP() diff --git a/packages/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js b/packages/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js index 4f9bf5bb9..1216880fe 100644 --- a/packages/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js +++ b/packages/contracts/test/StabilityPool_SPWithdrawalToCDPTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const { dec, toBN } = testHelpers.TestHelper @@ -57,7 +58,7 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' gasPriceInWei = await web3.eth.getGasPrice() }) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() const LQTYContracts = await deploymentHelper.deployLQTYContracts(bountyAddress, lpRewardsAddress, multisig) contracts.troveManager = await TroveManagerTester.new() @@ -77,6 +78,17 @@ contract('StabilityPool - Withdrawal of stability deposit - Reward calculations' await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + // --- Compounding tests --- // --- withdrawETHGainToTrove() --- diff --git a/packages/contracts/test/TroveManagerTest.js b/packages/contracts/test/TroveManagerTest.js index d597351a4..5a54d12da 100644 --- a/packages/contracts/test/TroveManagerTest.js +++ b/packages/contracts/test/TroveManagerTest.js @@ -1,5 +1,7 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); + const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const LUSDTokenTester = artifacts.require("./LUSDTokenTester.sol") @@ -51,7 +53,7 @@ contract('TroveManager', async accounts => { const openTrove = async (params) => th.openTrove(contracts, params) const withdrawLUSD = async (params) => th.withdrawLUSD(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDTokenTester.new( @@ -82,6 +84,17 @@ contract('TroveManager', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('liquidate(): closes a Trove that has ICR < MCR', async () => { await openTrove({ ICR: toBN(dec(20, 18)), extraParams: { from: whale } }) await openTrove({ ICR: toBN(dec(4, 18)), extraParams: { from: alice } }) diff --git a/packages/contracts/test/TroveManager_LiquidationRewardsTest.js b/packages/contracts/test/TroveManager_LiquidationRewardsTest.js index e77810950..2d6d0edc0 100644 --- a/packages/contracts/test/TroveManager_LiquidationRewardsTest.js +++ b/packages/contracts/test/TroveManager_LiquidationRewardsTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const th = testHelpers.TestHelper const dec = th.dec @@ -37,7 +38,7 @@ contract('TroveManager - Redistribution reward calculations', async accounts => const getNetBorrowingAmount = async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee) const openTrove = async (params) => th.openTrove(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -63,6 +64,17 @@ contract('TroveManager - Redistribution reward calculations', async accounts => await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("redistribution: A, B Open. B Liquidated. C, D Open. D Liquidated. Distributes correct rewards", async () => { // A, B open trove const { collateral: A_coll } = await openTrove({ ICR: toBN(dec(400, 16)), extraParams: { from: alice } }) diff --git a/packages/contracts/test/TroveManager_RecoveryModeTest.js b/packages/contracts/test/TroveManager_RecoveryModeTest.js index afcf66b70..865ecc612 100644 --- a/packages/contracts/test/TroveManager_RecoveryModeTest.js +++ b/packages/contracts/test/TroveManager_RecoveryModeTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const th = testHelpers.TestHelper const dec = th.dec @@ -51,7 +52,7 @@ contract('TroveManager - in Recovery Mode', async accounts => { const getNetBorrowingAmount = async (debtWithFee) => th.getNetBorrowingAmount(contracts, debtWithFee) const openTrove = async (params) => th.openTrove(contracts, params) - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDToken.new( @@ -77,6 +78,17 @@ contract('TroveManager - in Recovery Mode', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("checkRecoveryMode(): Returns true if TCR falls below CCR", async () => { // --- SETUP --- // Alice and Bob withdraw such that the TCR is ~150% diff --git a/packages/contracts/test/Unipool.js b/packages/contracts/test/Unipool.js index 3d157712f..1ab594658 100644 --- a/packages/contracts/test/Unipool.js +++ b/packages/contracts/test/Unipool.js @@ -3,6 +3,7 @@ const { BN, time } = require('@openzeppelin/test-helpers'); const { expect } = require('chai'); const { TestHelper } = require('../utils/testHelpers.js'); +const timeMachine = require('ganache-time-traveler'); const { assertRevert } = TestHelper; @@ -75,11 +76,22 @@ contract('Unipool', function ([_, wallet1, wallet2, wallet3, wallet4, bountyAddr }; describe('Unipool', async function () { - beforeEach(async function () { + before(async function () { await deploy(this); await this.pool.setParams(this.lqty.address, this.uni.address, this.DURATION); }); + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it('Two stakers with the same stakes wait DURATION', async function () { expect(await this.pool.rewardPerToken()).to.be.bignumber.almostEqualDiv1e18('0'); expect(await this.pool.earned(wallet1)).to.be.bignumber.equal('0'); diff --git a/packages/contracts/test/stakeDeclineTest.js b/packages/contracts/test/stakeDeclineTest.js index 2473baa44..534986991 100644 --- a/packages/contracts/test/stakeDeclineTest.js +++ b/packages/contracts/test/stakeDeclineTest.js @@ -1,5 +1,6 @@ const deploymentHelper = require("../utils/deploymentHelpers.js") const testHelpers = require("../utils/testHelpers.js") +const timeMachine = require('ganache-time-traveler'); const TroveManagerTester = artifacts.require("./TroveManagerTester.sol") const LUSDTokenTester = artifacts.require("./LUSDTokenTester.sol") @@ -48,7 +49,7 @@ contract('TroveManager', async accounts => { return ratio } - beforeEach(async () => { + before(async () => { contracts = await deploymentHelper.deployLiquityCore() contracts.troveManager = await TroveManagerTester.new() contracts.lusdToken = await LUSDTokenTester.new( @@ -79,6 +80,17 @@ contract('TroveManager', async accounts => { await deploymentHelper.connectLQTYContractsToCore(LQTYContracts, contracts) }) + let revertToSnapshot; + + beforeEach(async() => { + let snapshot = await timeMachine.takeSnapshot(); + revertToSnapshot = () => timeMachine.revertToSnapshot(snapshot['result']) + }); + + afterEach(async() => { + await revertToSnapshot(); + }); + it("A given trove's stake decline is negligible with adjustments and tiny liquidations", async () => { await priceFeed.setPrice(dec(100, 18)) diff --git a/yarn.lock b/yarn.lock index 848dfff14..724ebea0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9878,6 +9878,11 @@ ganache-cli@^6.11.0: source-map-support "0.5.12" yargs "13.2.4" +ganache-time-traveler@1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/ganache-time-traveler/-/ganache-time-traveler-1.0.15.tgz#07c575abeb1e110903b76a2181e18598066617e9" + integrity sha512-3yoSbvvqSRA13w/SrNGy5tniwdwuRSAMrltGaOZAoqjnhpWkbVlGOVkdiEA/69dN4ZTArwJr1lWpiPzwqTWNCA== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"